1
Arm queue -- I have more stuff pending but I prefer to push
1
target-arm queue: I have a lot more still in my to-review
2
this first lot out and keep the pull below 50 patches.
2
queue, but my rule of thumb is when I get to 50 patches or
3
Most of this is Alex's FP16 support work.
3
so to send out what I have.
4
4
5
thanks
5
-- PMM
6
-- PMM
6
7
8
The following changes since commit 9a7beaad3dbba982f7a461d676b55a5c3851d312:
7
9
8
The following changes since commit 6697439794f72b3501ee16bb95d16854f9981421:
10
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20210304' into staging (2021-03-05 10:47:46 +0000)
9
10
Merge remote-tracking branch 'remotes/kraxel/tags/usb-20180227-pull-request' into staging (2018-02-27 17:50:46 +0000)
11
11
12
are available in the Git repository at:
12
are available in the Git repository at:
13
13
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180301
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210305
15
15
16
for you to fetch changes up to c22e580c2ad1cccef582e1490e732f254d4ac064:
16
for you to fetch changes up to 2c669ff88ec6733420a000103a2b8b9e93df4945:
17
17
18
MAINTAINERS: Update my email address (2018-03-01 11:13:59 +0000)
18
hw/arm/mps2: Update old infocenter.arm.com URLs (2021-03-05 15:17:38 +0000)
19
19
20
----------------------------------------------------------------
20
----------------------------------------------------------------
21
target-arm queue:
21
* sbsa-ref: remove cortex-a53 from list of supported cpus
22
* update MAINTAINERS for Alistair's new email address
22
* sbsa-ref: add 'max' to list of allowed cpus
23
* add Arm v8.2 FP16 arithmetic extension for linux-user
23
* target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
24
* implement display connector emulation for vexpress board
24
* npcm7xx: add EMC model
25
* xilinx_spips: Enable only two slaves when reading/writing with stripe
25
* xlnx-zynqmp: Remove obsolete 'has_rpu' property
26
* xilinx_spips: Use 8 dummy cycles with the QIOR/QIOR4 commands
26
* target/arm: Speed up aarch64 TBL/TBX
27
* hw: register: Run post_write hook on reset
27
* virtio-mmio: improve virtio-mmio get_dev_path alog
28
* target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
29
* target/arm: Restrict v8M IDAU to TCG
30
* target/arm/cpu: Update coding style to make checkpatch.pl happy
31
* musicpal, tc6393xb, omap_lcdc, tcx: drop dead code for non-32-bit-RGB surfaces
32
* Add new board: mps3-an524
28
33
29
----------------------------------------------------------------
34
----------------------------------------------------------------
30
Alex Bennée (31):
35
Doug Evans (3):
31
include/exec/helper-head.h: support f16 in helper calls
36
hw/net: Add npcm7xx emc model
32
target/arm/cpu64: introduce ARM_V8_FP16 feature bit
37
hw/arm: Add npcm7xx emc model
33
target/arm/cpu.h: update comment for half-precision values
38
tests/qtests: Add npcm7xx emc model test
34
target/arm/cpu.h: add additional float_status flags
35
target/arm/helper: pass explicit fpst to set_rmode
36
arm/translate-a64: implement half-precision F(MIN|MAX)(V|NMV)
37
arm/translate-a64: handle_3same_64 comment fix
38
arm/translate-a64: initial decode for simd_three_reg_same_fp16
39
arm/translate-a64: add FP16 FADD/FABD/FSUB/FMUL/FDIV to simd_three_reg_same_fp16
40
arm/translate-a64: add FP16 F[A]C[EQ/GE/GT] to simd_three_reg_same_fp16
41
arm/translate-a64: add FP16 FMULA/X/S to simd_three_reg_same_fp16
42
arm/translate-a64: add FP16 FR[ECP/SQRT]S to simd_three_reg_same_fp16
43
arm/translate-a64: add FP16 pairwise ops simd_three_reg_same_fp16
44
arm/translate-a64: add FP16 FMULX/MLS/FMLA to simd_indexed
45
arm/translate-a64: add FP16 x2 ops for simd_indexed
46
arm/translate-a64: initial decode for simd_two_reg_misc_fp16
47
arm/translate-a64: add FP16 FPRINTx to simd_two_reg_misc_fp16
48
arm/translate-a64: add FCVTxx to simd_two_reg_misc_fp16
49
arm/translate-a64: add FP16 FCMxx (zero) to simd_two_reg_misc_fp16
50
arm/translate-a64: add FP16 SCVTF/UCVFT to simd_two_reg_misc_fp16
51
arm/translate-a64: add FP16 FNEG/FABS to simd_two_reg_misc_fp16
52
arm/helper.c: re-factor recpe and add recepe_f16
53
arm/translate-a64: add FP16 FRECPE
54
arm/translate-a64: add FP16 FRCPX to simd_two_reg_misc_fp16
55
arm/translate-a64: add FP16 FSQRT to simd_two_reg_misc_fp16
56
arm/helper.c: re-factor rsqrte and add rsqrte_f16
57
arm/translate-a64: add FP16 FRSQRTE to simd_two_reg_misc_fp16
58
arm/translate-a64: add FP16 FMOV to simd_mod_imm
59
arm/translate-a64: add all FP16 ops in simd_scalar_pairwise
60
arm/translate-a64: implement simd_scalar_three_reg_same_fp16
61
arm/translate-a64: add all single op FP16 to handle_fp_1src_half
62
39
63
Alistair Francis (2):
40
Marcin Juszkiewicz (2):
64
hw: register: Run post_write hook on reset
41
sbsa-ref: remove cortex-a53 from list of supported cpus
65
MAINTAINERS: Update my email address
42
sbsa-ref: add 'max' to list of allowed cpus
66
43
67
Corey Minyard (2):
44
Peter Collingbourne (1):
68
i2c: Fix some brace style issues
45
target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
69
i2c: Move the bus class to i2c.h
70
46
71
Francisco Iglesias (2):
47
Peter Maydell (34):
72
xilinx_spips: Enable only two slaves when reading/writing with stripe
48
hw/arm/musicpal: Remove dead code for non-32-bit-RGB surfaces
73
xilinx_spips: Use 8 dummy cycles with the QIOR/QIOR4 commands
49
hw/display/tc6393xb: Remove dead code for handling non-32bpp surfaces
50
hw/display/tc6393xb: Expand out macros in template header
51
hw/display/tc6393xb: Inline tc6393xb_draw_graphic32() at its callsite
52
hw/display/omap_lcdc: Expand out macros in template header
53
hw/display/omap_lcdc: Drop broken bigendian ifdef
54
hw/display/omap_lcdc: Fix coding style issues in template header
55
hw/display/omap_lcdc: Inline template header into C file
56
hw/display/omap_lcdc: Delete unnecessary macro
57
hw/display/tcx: Drop unnecessary code for handling BGR format outputs
58
hw/arm/mps2-tz: Make SYSCLK frequency board-specific
59
hw/misc/mps2-scc: Support configurable number of OSCCLK values
60
hw/arm/mps2-tz: Correct the OSCCLK settings for mps2-an505 and mps2-an511
61
hw/arm/mps2-tz: Make the OSCCLK settings be configurable per-board
62
hw/misc/mps2-fpgaio: Make number of LEDs configurable by board
63
hw/misc/mps2-fpgaio: Support SWITCH register
64
hw/arm/mps2-tz: Make FPGAIO switch and LED config per-board
65
hw/arm/mps2-tz: Condition IRQ splitting on number of CPUs, not board type
66
hw/arm/mps2-tz: Make number of IRQs board-specific
67
hw/misc/mps2-scc: Implement CFG_REG5 and CFG_REG6 for MPS3 AN524
68
hw/arm/mps2-tz: Correct wrong interrupt numbers for DMA and SPI
69
hw/arm/mps2-tz: Allow PPCPortInfo structures to specify device interrupts
70
hw/arm/mps2-tz: Move device IRQ info to data structures
71
hw/arm/mps2-tz: Size the uart-irq-orgate based on the number of UARTs
72
hw/arm/mps2-tz: Allow boards to have different PPCInfo data
73
hw/arm/mps2-tz: Make RAM arrangement board-specific
74
hw/arm/mps2-tz: Set MachineClass default_ram info from RAMInfo data
75
hw/arm/mps2-tz: Support ROMs as well as RAMs
76
hw/arm/mps2-tz: Get armv7m_load_kernel() size argument from RAMInfo
77
hw/arm/mps2-tz: Add new mps3-an524 board
78
hw/arm/mps2-tz: Stub out USB controller for mps3-an524
79
hw/arm/mps2-tz: Provide PL031 RTC on mps3-an524
80
docs/system/arm/mps2.rst: Document the new mps3-an524 board
81
hw/arm/mps2: Update old infocenter.arm.com URLs
74
82
75
Linus Walleij (3):
83
Philippe Mathieu-Daudé (4):
76
hw/i2c-ddc: Do not fail writes
84
hw/arm/xlnx-zynqmp: Remove obsolete 'has_rpu' property
77
hw/sii9022: Add support for Silicon Image SII9022
85
hw/i2c/npcm7xx_smbus: Simplify npcm7xx_smbus_init()
78
arm/vexpress: Add proper display connector emulation
86
target/arm: Restrict v8M IDAU to TCG
87
target/arm/cpu: Update coding style to make checkpatch.pl happy
79
88
80
Peter Maydell (2):
89
Rebecca Cran (3):
81
target/arm: Enable ARM_V8_FP16 feature bit for the AArch64 "any" CPU
90
target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
82
linux-user: Report AArch64 FP16 support via hwcap bits
91
target/arm: Enable FEAT_SSBS for "max" AARCH64 CPU
92
target/arm: Set ID_PFR2.SSBS to 1 for "max" 32-bit CPU
83
93
84
hw/display/Makefile.objs | 1 +
94
Richard Henderson (1):
85
include/exec/helper-head.h | 3 +
95
target/arm: Speed up aarch64 TBL/TBX
86
include/fpu/softfloat.h | 18 +-
87
include/hw/i2c/i2c.h | 23 +-
88
include/hw/register.h | 6 +-
89
target/arm/cpu.h | 34 +-
90
target/arm/helper-a64.h | 33 +
91
target/arm/helper.h | 14 +-
92
hw/arm/vexpress.c | 6 +-
93
hw/core/register.c | 8 +
94
hw/display/sii9022.c | 191 ++++++
95
hw/i2c/core.c | 18 -
96
hw/i2c/i2c-ddc.c | 4 +-
97
hw/ssi/xilinx_spips.c | 43 +-
98
linux-user/elfload.c | 2 +
99
target/arm/cpu64.c | 1 +
100
target/arm/helper-a64.c | 269 +++++++++
101
target/arm/helper.c | 481 ++++++++-------
102
target/arm/translate-a64.c | 1266 +++++++++++++++++++++++++++++++++------
103
target/arm/translate.c | 12 +-
104
MAINTAINERS | 12 +-
105
default-configs/arm-softmmu.mak | 2 +
106
hw/display/trace-events | 5 +
107
23 files changed, 1981 insertions(+), 471 deletions(-)
108
create mode 100644 hw/display/sii9022.c
109
96
97
schspa (1):
98
virtio-mmio: improve virtio-mmio get_dev_path alog
99
100
docs/system/arm/mps2.rst | 24 +-
101
docs/system/arm/nuvoton.rst | 3 +-
102
hw/display/omap_lcd_template.h | 169 --------
103
hw/display/tc6393xb_template.h | 72 ----
104
include/hw/arm/armsse.h | 4 +-
105
include/hw/arm/npcm7xx.h | 2 +
106
include/hw/arm/xlnx-zynqmp.h | 2 -
107
include/hw/misc/armsse-cpuid.h | 2 +-
108
include/hw/misc/armsse-mhu.h | 2 +-
109
include/hw/misc/iotkit-secctl.h | 2 +-
110
include/hw/misc/iotkit-sysctl.h | 2 +-
111
include/hw/misc/iotkit-sysinfo.h | 2 +-
112
include/hw/misc/mps2-fpgaio.h | 8 +-
113
include/hw/misc/mps2-scc.h | 10 +-
114
include/hw/net/npcm7xx_emc.h | 286 +++++++++++++
115
include/ui/console.h | 10 -
116
target/arm/cpu.h | 15 +-
117
target/arm/helper-a64.h | 2 +-
118
target/arm/internals.h | 6 +
119
hw/arm/mps2-tz.c | 632 +++++++++++++++++++++++-----
120
hw/arm/mps2.c | 5 +
121
hw/arm/musicpal.c | 64 ++-
122
hw/arm/npcm7xx.c | 50 ++-
123
hw/arm/sbsa-ref.c | 2 +-
124
hw/arm/xlnx-zynqmp.c | 6 -
125
hw/display/omap_lcdc.c | 129 +++++-
126
hw/display/tc6393xb.c | 48 +--
127
hw/display/tcx.c | 31 +-
128
hw/i2c/npcm7xx_smbus.c | 1 -
129
hw/misc/armsse-cpuid.c | 2 +-
130
hw/misc/armsse-mhu.c | 2 +-
131
hw/misc/iotkit-sysctl.c | 2 +-
132
hw/misc/iotkit-sysinfo.c | 2 +-
133
hw/misc/mps2-fpgaio.c | 43 +-
134
hw/misc/mps2-scc.c | 93 ++++-
135
hw/net/npcm7xx_emc.c | 857 ++++++++++++++++++++++++++++++++++++++
136
hw/virtio/virtio-mmio.c | 13 +-
137
target/arm/cpu.c | 23 +-
138
target/arm/cpu64.c | 5 +
139
target/arm/cpu_tcg.c | 8 +
140
target/arm/helper-a64.c | 32 --
141
target/arm/helper.c | 39 +-
142
target/arm/mte_helper.c | 13 +-
143
target/arm/translate-a64.c | 70 +---
144
target/arm/vec_helper.c | 48 +++
145
tests/qtest/npcm7xx_emc-test.c | 862 +++++++++++++++++++++++++++++++++++++++
146
hw/net/meson.build | 1 +
147
hw/net/trace-events | 17 +
148
tests/qtest/meson.build | 3 +-
149
49 files changed, 3098 insertions(+), 628 deletions(-)
150
delete mode 100644 hw/display/omap_lcd_template.h
151
delete mode 100644 hw/display/tc6393xb_template.h
152
create mode 100644 include/hw/net/npcm7xx_emc.h
153
create mode 100644 hw/net/npcm7xx_emc.c
154
create mode 100644 tests/qtest/npcm7xx_emc-test.c
155
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
3
Cortex-A53 supports 40bits of address space. sbsa-ref's memory starts
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
above this limit.
5
Message-id: 20180227143852.11175-4-alex.bennee@linaro.org
5
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Acked-by: Leif Lindholm <leif@nuviainc.com>
9
Message-id: 20210216150122.3830863-2-marcin.juszkiewicz@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
target/arm/cpu.h | 1 +
12
hw/arm/sbsa-ref.c | 1 -
9
1 file changed, 1 insertion(+)
13
1 file changed, 1 deletion(-)
10
14
11
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu.h
17
--- a/hw/arm/sbsa-ref.c
14
+++ b/target/arm/cpu.h
18
+++ b/hw/arm/sbsa-ref.c
15
@@ -XXX,XX +XXX,XX @@ typedef struct {
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
16
* Qn = regs[n].d[1]:regs[n].d[0]
20
};
17
* Dn = regs[n].d[0]
21
18
* Sn = regs[n].d[0] bits 31..0
22
static const char * const valid_cpus[] = {
19
+ * Hn = regs[n].d[0] bits 15..0
23
- ARM_CPU_TYPE_NAME("cortex-a53"),
20
*
24
ARM_CPU_TYPE_NAME("cortex-a57"),
21
* This corresponds to the architecturally defined mapping between
25
ARM_CPU_TYPE_NAME("cortex-a72"),
22
* the two execution states, and means we do not need to explicitly
26
};
23
--
27
--
24
2.16.2
28
2.20.1
25
29
26
30
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
3
Let add 'max' cpu while work goes on adding newer CPU types than
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Cortex-A72. This allows us to check SVE etc support.
5
Message-id: 20180227143852.11175-3-alex.bennee@linaro.org
5
6
[PMM: postpone actually enabling feature until end of the
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
7
patch series]
7
Acked-by: Leif Lindholm <leif@nuviainc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210216150122.3830863-3-marcin.juszkiewicz@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
target/arm/cpu.h | 1 +
12
hw/arm/sbsa-ref.c | 1 +
11
1 file changed, 1 insertion(+)
13
1 file changed, 1 insertion(+)
12
14
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
17
--- a/hw/arm/sbsa-ref.c
16
+++ b/target/arm/cpu.h
18
+++ b/hw/arm/sbsa-ref.c
17
@@ -XXX,XX +XXX,XX @@ enum arm_features {
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
18
ARM_FEATURE_V8_SHA3, /* implements SHA3 part of v8 Crypto Extensions */
20
static const char * const valid_cpus[] = {
19
ARM_FEATURE_V8_SM3, /* implements SM3 part of v8 Crypto Extensions */
21
ARM_CPU_TYPE_NAME("cortex-a57"),
20
ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
22
ARM_CPU_TYPE_NAME("cortex-a72"),
21
+ ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
23
+ ARM_CPU_TYPE_NAME("max"),
22
};
24
};
23
25
24
static inline int arm_feature(CPUARMState *env, int feature)
26
static bool cpu_type_valid(const char *cpu)
25
--
27
--
26
2.16.2
28
2.20.1
27
29
28
30
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
2
3
Half-precision flush to zero behaviour is controlled by a separate
3
Add support for FEAT_SSBS. SSBS (Speculative Store Bypass Safe) is an
4
FZ16 bit in the FPCR. To handle this we pass a pointer to
4
optional feature in ARMv8.0, and mandatory in ARMv8.5.
5
fp_status_fp16 when working on half-precision operations. The value of
6
the presented FPCR is calculated from an amalgam of the two when read.
7
5
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180227143852.11175-5-alex.bennee@linaro.org
8
Message-id: 20210216224543.16142-2-rebecca@nuviainc.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
target/arm/cpu.h | 32 ++++++++++++++++++++++------
11
target/arm/cpu.h | 15 ++++++++++++++-
14
target/arm/helper.c | 26 ++++++++++++++++++-----
12
target/arm/internals.h | 6 ++++++
15
target/arm/translate-a64.c | 53 +++++++++++++++++++++++++---------------------
13
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++++++++
16
3 files changed, 75 insertions(+), 36 deletions(-)
14
target/arm/translate-a64.c | 12 ++++++++++++
15
4 files changed, 69 insertions(+), 1 deletion(-)
17
16
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
21
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
23
/* scratch space when Tn are not sufficient. */
22
#define SCTLR_TE (1U << 30) /* AArch32 only */
24
uint32_t scratch[8];
23
#define SCTLR_EnIB (1U << 30) /* v8.3, AArch64 only */
25
24
#define SCTLR_EnIA (1U << 31) /* v8.3, AArch64 only */
26
- /* fp_status is the "normal" fp status. standard_fp_status retains
25
+#define SCTLR_DSSBS_32 (1U << 31) /* v8.5, AArch32 only */
27
- * values corresponding to the ARM "Standard FPSCR Value", ie
26
#define SCTLR_BT0 (1ULL << 35) /* v8.5-BTI */
28
- * default-NaN, flush-to-zero, round-to-nearest and is used by
27
#define SCTLR_BT1 (1ULL << 36) /* v8.5-BTI */
29
- * any operations (generally Neon) which the architecture defines
28
#define SCTLR_ITFSB (1ULL << 37) /* v8.5-MemTag */
30
- * as controlled by the standard FPSCR value rather than the FPSCR.
29
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
31
+ /* There are a number of distinct float control structures:
30
#define SCTLR_TCF (3ULL << 40) /* v8.5-MemTag */
32
+ *
31
#define SCTLR_ATA0 (1ULL << 42) /* v8.5-MemTag */
33
+ * fp_status: is the "normal" fp status.
32
#define SCTLR_ATA (1ULL << 43) /* v8.5-MemTag */
34
+ * fp_status_fp16: used for half-precision calculations
33
-#define SCTLR_DSSBS (1ULL << 44) /* v8.5 */
35
+ * standard_fp_status : the ARM "Standard FPSCR Value"
34
+#define SCTLR_DSSBS_64 (1ULL << 44) /* v8.5, AArch64 only */
36
+ *
35
37
+ * Half-precision operations are governed by a separate
36
#define CPTR_TCPAC (1U << 31)
38
+ * flush-to-zero control bit in FPSCR:FZ16. We pass a separate
37
#define CPTR_TTA (1U << 20)
39
+ * status structure to control this.
38
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
40
+ *
39
#define CPSR_IL (1U << 20)
41
+ * The "Standard FPSCR", ie default-NaN, flush-to-zero,
40
#define CPSR_DIT (1U << 21)
42
+ * round-to-nearest and is used by any operations (generally
41
#define CPSR_PAN (1U << 22)
43
+ * Neon) which the architecture defines as controlled by the
42
+#define CPSR_SSBS (1U << 23)
44
+ * standard FPSCR value rather than the FPSCR.
43
#define CPSR_J (1U << 24)
45
*
44
#define CPSR_IT_0_1 (3U << 25)
46
* To avoid having to transfer exception bits around, we simply
45
#define CPSR_Q (1U << 27)
47
* say that the FPSCR cumulative exception flags are the logical
46
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
48
- * OR of the flags in the two fp statuses. This relies on the
47
#define PSTATE_A (1U << 8)
49
+ * OR of the flags in the three fp statuses. This relies on the
48
#define PSTATE_D (1U << 9)
50
* only thing which needs to read the exception flags being
49
#define PSTATE_BTYPE (3U << 10)
51
* an explicit FPSCR read.
50
+#define PSTATE_SSBS (1U << 12)
52
*/
51
#define PSTATE_IL (1U << 20)
53
float_status fp_status;
52
#define PSTATE_SS (1U << 21)
54
+ float_status fp_status_f16;
53
#define PSTATE_PAN (1U << 22)
55
float_status standard_fp_status;
54
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_dit(const ARMISARegisters *id)
56
55
return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0;
57
/* ZCR_EL[1-3] */
56
}
58
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
57
59
uint32_t vfp_get_fpscr(CPUARMState *env);
58
+static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
60
void vfp_set_fpscr(CPUARMState *env, uint32_t val);
59
+{
61
60
+ return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
62
-/* For A64 the FPSCR is split into two logically distinct registers,
61
+}
63
+/* FPCR, Floating Point Control Register
62
+
64
+ * FPSR, Floating Poiht Status Register
63
/*
65
+ *
64
* 64-bit feature tests via id registers.
66
+ * For A64 the FPSCR is split into two logically distinct registers,
67
* FPCR and FPSR. However since they still use non-overlapping bits
68
* we store the underlying state in fpscr and just mask on read/write.
69
*/
65
*/
70
#define FPSR_MASK 0xf800009f
66
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
71
#define FPCR_MASK 0x07f79f00
67
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
68
}
69
70
+static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
71
+{
72
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
73
+}
72
+
74
+
73
+#define FPCR_FZ16 (1 << 19) /* ARMv8.2+, FP16 flush-to-zero */
75
/*
74
+#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
76
* Feature tests for "does this exist in either 32-bit or 64-bit?"
75
+#define FPCR_DN (1 << 25) /* Default NaN enable bit */
77
*/
76
+
78
diff --git a/target/arm/internals.h b/target/arm/internals.h
77
static inline uint32_t vfp_get_fpsr(CPUARMState *env)
79
index XXXXXXX..XXXXXXX 100644
78
{
80
--- a/target/arm/internals.h
79
return vfp_get_fpscr(env) & FPSR_MASK;
81
+++ b/target/arm/internals.h
82
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
83
if (isar_feature_aa32_dit(id)) {
84
valid |= CPSR_DIT;
85
}
86
+ if (isar_feature_aa32_ssbs(id)) {
87
+ valid |= CPSR_SSBS;
88
+ }
89
90
return valid;
91
}
92
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
93
if (isar_feature_aa64_dit(id)) {
94
valid |= PSTATE_DIT;
95
}
96
+ if (isar_feature_aa64_ssbs(id)) {
97
+ valid |= PSTATE_SSBS;
98
+ }
99
if (isar_feature_aa64_mte(id)) {
100
valid |= PSTATE_TCO;
101
}
80
diff --git a/target/arm/helper.c b/target/arm/helper.c
102
diff --git a/target/arm/helper.c b/target/arm/helper.c
81
index XXXXXXX..XXXXXXX 100644
103
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/helper.c
104
--- a/target/arm/helper.c
83
+++ b/target/arm/helper.c
105
+++ b/target/arm/helper.c
84
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
106
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dit_reginfo = {
85
| (env->vfp.vec_stride << 20);
107
.readfn = aa64_dit_read, .writefn = aa64_dit_write
86
i = get_float_exception_flags(&env->vfp.fp_status);
108
};
87
i |= get_float_exception_flags(&env->vfp.standard_fp_status);
109
88
+ i |= get_float_exception_flags(&env->vfp.fp_status_f16);
110
+static uint64_t aa64_ssbs_read(CPUARMState *env, const ARMCPRegInfo *ri)
89
fpscr |= vfp_exceptbits_from_host(i);
111
+{
90
return fpscr;
112
+ return env->pstate & PSTATE_SSBS;
91
}
113
+}
92
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
114
+
93
break;
115
+static void aa64_ssbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
94
}
116
+ uint64_t value)
95
set_float_rounding_mode(i, &env->vfp.fp_status);
117
+{
96
+ set_float_rounding_mode(i, &env->vfp.fp_status_f16);
118
+ env->pstate = (env->pstate & ~PSTATE_SSBS) | (value & PSTATE_SSBS);
119
+}
120
+
121
+static const ARMCPRegInfo ssbs_reginfo = {
122
+ .name = "SSBS", .state = ARM_CP_STATE_AA64,
123
+ .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 6,
124
+ .type = ARM_CP_NO_RAW, .access = PL0_RW,
125
+ .readfn = aa64_ssbs_read, .writefn = aa64_ssbs_write
126
+};
127
+
128
static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
129
const ARMCPRegInfo *ri,
130
bool isread)
131
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
132
if (cpu_isar_feature(aa64_dit, cpu)) {
133
define_one_arm_cp_reg(cpu, &dit_reginfo);
97
}
134
}
98
- if (changed & (1 << 24)) {
135
+ if (cpu_isar_feature(aa64_ssbs, cpu)) {
99
- set_flush_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
136
+ define_one_arm_cp_reg(cpu, &ssbs_reginfo);
100
- set_flush_inputs_to_zero((val & (1 << 24)) != 0, &env->vfp.fp_status);
101
+ if (changed & FPCR_FZ16) {
102
+ bool ftz_enabled = val & FPCR_FZ16;
103
+ set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_f16);
104
+ set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_f16);
105
+ }
137
+ }
106
+ if (changed & FPCR_FZ) {
138
107
+ bool ftz_enabled = val & FPCR_FZ;
139
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
108
+ set_flush_to_zero(ftz_enabled, &env->vfp.fp_status);
140
define_arm_cp_regs(cpu, vhe_reginfo);
109
+ set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status);
141
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
142
env->uncached_cpsr &= ~(CPSR_IL | CPSR_J);
143
env->daif |= mask;
144
145
+ if (cpu_isar_feature(aa32_ssbs, env_archcpu(env))) {
146
+ if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_32) {
147
+ env->uncached_cpsr |= CPSR_SSBS;
148
+ } else {
149
+ env->uncached_cpsr &= ~CPSR_SSBS;
150
+ }
110
+ }
151
+ }
111
+ if (changed & FPCR_DN) {
152
+
112
+ bool dnan_enabled = val & FPCR_DN;
153
if (new_mode == ARM_CPU_MODE_HYP) {
113
+ set_default_nan_mode(dnan_enabled, &env->vfp.fp_status);
154
env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0;
114
+ set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16);
155
env->elr_el[2] = env->regs[15];
156
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
157
new_mode |= PSTATE_TCO;
115
}
158
}
116
- if (changed & (1 << 25))
159
117
- set_default_nan_mode((val & (1 << 25)) != 0, &env->vfp.fp_status);
160
+ if (cpu_isar_feature(aa64_ssbs, cpu)) {
118
161
+ if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_64) {
119
+ /* The exception flags are ORed together when we read fpscr so we
162
+ new_mode |= PSTATE_SSBS;
120
+ * only need to preserve the current state in one of our
163
+ } else {
121
+ * float_status values.
164
+ new_mode &= ~PSTATE_SSBS;
122
+ */
165
+ }
123
i = vfp_exceptbits_to_host(val);
166
+ }
124
set_float_exception_flags(i, &env->vfp.fp_status);
167
+
125
+ set_float_exception_flags(0, &env->vfp.fp_status_f16);
168
pstate_write(env, PSTATE_DAIF | new_mode);
126
set_float_exception_flags(0, &env->vfp.standard_fp_status);
169
env->aarch64 = 1;
127
}
170
aarch64_restore_sp(env, new_el);
128
129
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
171
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
130
index XXXXXXX..XXXXXXX 100644
172
index XXXXXXX..XXXXXXX 100644
131
--- a/target/arm/translate-a64.c
173
--- a/target/arm/translate-a64.c
132
+++ b/target/arm/translate-a64.c
174
+++ b/target/arm/translate-a64.c
133
@@ -XXX,XX +XXX,XX @@ static void write_fp_sreg(DisasContext *s, int reg, TCGv_i32 v)
175
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
134
tcg_temp_free_i64(tmp);
176
tcg_temp_free_i32(t1);
135
}
136
137
-static TCGv_ptr get_fpstatus_ptr(void)
138
+static TCGv_ptr get_fpstatus_ptr(bool is_f16)
139
{
140
TCGv_ptr statusptr = tcg_temp_new_ptr();
141
int offset;
142
143
- /* In A64 all instructions (both FP and Neon) use the FPCR;
144
- * there is no equivalent of the A32 Neon "standard FPSCR value"
145
- * and all operations use vfp.fp_status.
146
+ /* In A64 all instructions (both FP and Neon) use the FPCR; there
147
+ * is no equivalent of the A32 Neon "standard FPSCR value".
148
+ * However half-precision operations operate under a different
149
+ * FZ16 flag and use vfp.fp_status_f16 instead of vfp.fp_status.
150
*/
151
- offset = offsetof(CPUARMState, vfp.fp_status);
152
+ if (is_f16) {
153
+ offset = offsetof(CPUARMState, vfp.fp_status_f16);
154
+ } else {
155
+ offset = offsetof(CPUARMState, vfp.fp_status);
156
+ }
157
tcg_gen_addi_ptr(statusptr, cpu_env, offset);
158
return statusptr;
159
}
160
@@ -XXX,XX +XXX,XX @@ static void handle_fp_compare(DisasContext *s, bool is_double,
161
bool cmp_with_zero, bool signal_all_nans)
162
{
163
TCGv_i64 tcg_flags = tcg_temp_new_i64();
164
- TCGv_ptr fpst = get_fpstatus_ptr();
165
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
166
167
if (is_double) {
168
TCGv_i64 tcg_vn, tcg_vm;
169
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
170
TCGv_i32 tcg_op;
171
TCGv_i32 tcg_res;
172
173
- fpst = get_fpstatus_ptr();
174
+ fpst = get_fpstatus_ptr(false);
175
tcg_op = read_fp_sreg(s, rn);
176
tcg_res = tcg_temp_new_i32();
177
178
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
179
return;
180
}
181
182
- fpst = get_fpstatus_ptr();
183
+ fpst = get_fpstatus_ptr(false);
184
tcg_op = read_fp_dreg(s, rn);
185
tcg_res = tcg_temp_new_i64();
186
187
@@ -XXX,XX +XXX,XX @@ static void handle_fp_2src_single(DisasContext *s, int opcode,
188
TCGv_ptr fpst;
189
190
tcg_res = tcg_temp_new_i32();
191
- fpst = get_fpstatus_ptr();
192
+ fpst = get_fpstatus_ptr(false);
193
tcg_op1 = read_fp_sreg(s, rn);
194
tcg_op2 = read_fp_sreg(s, rm);
195
196
@@ -XXX,XX +XXX,XX @@ static void handle_fp_2src_double(DisasContext *s, int opcode,
197
TCGv_ptr fpst;
198
199
tcg_res = tcg_temp_new_i64();
200
- fpst = get_fpstatus_ptr();
201
+ fpst = get_fpstatus_ptr(false);
202
tcg_op1 = read_fp_dreg(s, rn);
203
tcg_op2 = read_fp_dreg(s, rm);
204
205
@@ -XXX,XX +XXX,XX @@ static void handle_fp_3src_single(DisasContext *s, bool o0, bool o1,
206
{
207
TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
208
TCGv_i32 tcg_res = tcg_temp_new_i32();
209
- TCGv_ptr fpst = get_fpstatus_ptr();
210
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
211
212
tcg_op1 = read_fp_sreg(s, rn);
213
tcg_op2 = read_fp_sreg(s, rm);
214
@@ -XXX,XX +XXX,XX @@ static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
215
{
216
TCGv_i64 tcg_op1, tcg_op2, tcg_op3;
217
TCGv_i64 tcg_res = tcg_temp_new_i64();
218
- TCGv_ptr fpst = get_fpstatus_ptr();
219
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
220
221
tcg_op1 = read_fp_dreg(s, rn);
222
tcg_op2 = read_fp_dreg(s, rm);
223
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
224
TCGv_ptr tcg_fpstatus;
225
TCGv_i32 tcg_shift;
226
227
- tcg_fpstatus = get_fpstatus_ptr();
228
+ tcg_fpstatus = get_fpstatus_ptr(false);
229
230
tcg_shift = tcg_const_i32(64 - scale);
231
232
@@ -XXX,XX +XXX,XX @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
233
TCGv_i32 tcg_elt1 = tcg_temp_new_i32();
234
TCGv_i32 tcg_elt2 = tcg_temp_new_i32();
235
TCGv_i32 tcg_elt3 = tcg_temp_new_i32();
236
- TCGv_ptr fpst = get_fpstatus_ptr();
237
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
238
239
assert(esize == 32);
240
assert(elements == 4);
241
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
242
}
243
244
size = extract32(size, 0, 1) ? 3 : 2;
245
- fpst = get_fpstatus_ptr();
246
+ fpst = get_fpstatus_ptr(false);
247
break;
177
break;
248
default:
178
249
unallocated_encoding(s);
179
+ case 0x19: /* SSBS */
250
@@ -XXX,XX +XXX,XX @@ static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn,
180
+ if (!dc_isar_feature(aa64_ssbs, s)) {
251
int fracbits, int size)
181
+ goto do_unallocated;
252
{
182
+ }
253
bool is_double = size == 3 ? true : false;
183
+ if (crm & 1) {
254
- TCGv_ptr tcg_fpst = get_fpstatus_ptr();
184
+ set_pstate_bits(PSTATE_SSBS);
255
+ TCGv_ptr tcg_fpst = get_fpstatus_ptr(false);
185
+ } else {
256
TCGv_i32 tcg_shift = tcg_const_i32(fracbits);
186
+ clear_pstate_bits(PSTATE_SSBS);
257
TCGv_i64 tcg_int = tcg_temp_new_i64();
187
+ }
258
TCGMemOp mop = size | (is_signed ? MO_SIGN : 0);
188
+ /* Don't need to rebuild hflags since SSBS is a nop */
259
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
189
+ break;
260
190
+
261
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(FPROUNDING_ZERO));
191
case 0x1a: /* DIT */
262
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
192
if (!dc_isar_feature(aa64_dit, s)) {
263
- tcg_fpstatus = get_fpstatus_ptr();
193
goto do_unallocated;
264
+ tcg_fpstatus = get_fpstatus_ptr(false);
265
tcg_shift = tcg_const_i32(fracbits);
266
267
if (is_double) {
268
@@ -XXX,XX +XXX,XX @@ static void handle_3same_float(DisasContext *s, int size, int elements,
269
int fpopcode, int rd, int rn, int rm)
270
{
271
int pass;
272
- TCGv_ptr fpst = get_fpstatus_ptr();
273
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
274
275
for (pass = 0; pass < elements; pass++) {
276
if (size) {
277
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
278
return;
279
}
280
281
- fpst = get_fpstatus_ptr();
282
+ fpst = get_fpstatus_ptr(false);
283
284
if (is_double) {
285
TCGv_i64 tcg_op = tcg_temp_new_i64();
286
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_reciprocal(DisasContext *s, int opcode,
287
int size, int rn, int rd)
288
{
289
bool is_double = (size == 3);
290
- TCGv_ptr fpst = get_fpstatus_ptr();
291
+ TCGv_ptr fpst = get_fpstatus_ptr(false);
292
293
if (is_double) {
294
TCGv_i64 tcg_op = tcg_temp_new_i64();
295
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
296
if (is_fcvt) {
297
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
298
gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
299
- tcg_fpstatus = get_fpstatus_ptr();
300
+ tcg_fpstatus = get_fpstatus_ptr(false);
301
} else {
302
tcg_rmode = NULL;
303
tcg_fpstatus = NULL;
304
@@ -XXX,XX +XXX,XX @@ static void handle_simd_3same_pair(DisasContext *s, int is_q, int u, int opcode,
305
306
/* Floating point operations need fpst */
307
if (opcode >= 0x58) {
308
- fpst = get_fpstatus_ptr();
309
+ fpst = get_fpstatus_ptr(false);
310
} else {
311
fpst = NULL;
312
}
313
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
314
}
315
316
if (need_fpstatus) {
317
- tcg_fpstatus = get_fpstatus_ptr();
318
+ tcg_fpstatus = get_fpstatus_ptr(false);
319
} else {
320
tcg_fpstatus = NULL;
321
}
322
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
323
}
324
325
if (is_fp) {
326
- fpst = get_fpstatus_ptr();
327
+ fpst = get_fpstatus_ptr(false);
328
} else {
329
fpst = NULL;
330
}
331
--
194
--
332
2.16.2
195
2.20.1
333
196
334
197
diff view generated by jsdifflib
1
Now we have implemented FP16 we can enable it for the "any" CPU.
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
2
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
3
Set ID_AA64PFR1_EL1.SSBS to 2 and ID_PFR2.SSBS to 1.
4
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
[PMM: split out from an earlier patch in the series]
7
Message-id: 20210216224543.16142-3-rebecca@nuviainc.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
9
---
8
target/arm/cpu64.c | 1 +
10
target/arm/cpu64.c | 5 +++++
9
1 file changed, 1 insertion(+)
11
1 file changed, 5 insertions(+)
10
12
11
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
13
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu64.c
15
--- a/target/arm/cpu64.c
14
+++ b/target/arm/cpu64.c
16
+++ b/target/arm/cpu64.c
15
@@ -XXX,XX +XXX,XX @@ static void aarch64_any_initfn(Object *obj)
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
16
set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
18
17
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
19
t = cpu->isar.id_aa64pfr1;
18
set_feature(&cpu->env, ARM_FEATURE_CRC);
20
t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
19
+ set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
21
+ t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2);
20
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
22
/*
21
cpu->dcz_blocksize = 7; /* 512 bytes */
23
* Begin with full support for MTE. This will be downgraded to MTE=0
22
}
24
* during realize if the board provides no tag memory, much like
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
26
u = FIELD_DP32(u, ID_PFR0, DIT, 1);
27
cpu->isar.id_pfr0 = u;
28
29
+ u = cpu->isar.id_pfr2;
30
+ u = FIELD_DP32(u, ID_PFR2, SSBS, 1);
31
+ cpu->isar.id_pfr2 = u;
32
+
33
u = cpu->isar.id_mmfr3;
34
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
35
cpu->isar.id_mmfr3 = u;
23
--
36
--
24
2.16.2
37
2.20.1
25
38
26
39
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
2
3
I am leaving Xilinx, so to avoid having an email address that bounces
3
Enable FEAT_SSBS for the "max" 32-bit CPU.
4
update my maintainer address to point to my personal email address.
5
4
6
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
7
Signed-off-by: Alistair Francis <alistair@alistair23.me>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210216224543.16142-4-rebecca@nuviainc.com
9
Message-id: 7bb690382e3370aa1c1e047a84e36603c787ec0e.1519749987.git.alistair.francis@xilinx.com
8
[PMM: fix typo causing compilation failure]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
MAINTAINERS | 12 ++++++------
11
target/arm/cpu.c | 4 ++++
13
1 file changed, 6 insertions(+), 6 deletions(-)
12
1 file changed, 4 insertions(+)
14
13
15
diff --git a/MAINTAINERS b/MAINTAINERS
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/MAINTAINERS
16
--- a/target/arm/cpu.c
18
+++ b/MAINTAINERS
17
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ F: hw/misc/arm_sysctl.c
18
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
20
19
t = cpu->isar.id_pfr0;
21
Xilinx Zynq
20
t = FIELD_DP32(t, ID_PFR0, DIT, 1);
22
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
21
cpu->isar.id_pfr0 = t;
23
-M: Alistair Francis <alistair.francis@xilinx.com>
22
+
24
+M: Alistair Francis <alistair@alistair23.me>
23
+ t = cpu->isar.id_pfr2;
25
L: qemu-arm@nongnu.org
24
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
26
S: Maintained
25
+ cpu->isar.id_pfr2 = t;
27
F: hw/*/xilinx_*
26
}
28
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/zynq*
27
#endif
29
X: hw/ssi/xilinx_*
28
}
30
31
Xilinx ZynqMP
32
-M: Alistair Francis <alistair.francis@xilinx.com>
33
+M: Alistair Francis <alistair@alistair23.me>
34
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
35
L: qemu-arm@nongnu.org
36
S: Maintained
37
@@ -XXX,XX +XXX,XX @@ T: git git://github.com/bonzini/qemu.git scsi-next
38
39
SSI
40
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
41
-M: Alistair Francis <alistair.francis@xilinx.com>
42
+M: Alistair Francis <alistair@alistair23.me>
43
S: Maintained
44
F: hw/ssi/*
45
F: hw/block/m25p80.c
46
@@ -XXX,XX +XXX,XX @@ X: hw/ssi/xilinx_*
47
F: tests/m25p80-test.c
48
49
Xilinx SPI
50
-M: Alistair Francis <alistair.francis@xilinx.com>
51
+M: Alistair Francis <alistair@alistair23.me>
52
M: Peter Crosthwaite <crosthwaite.peter@gmail.com>
53
S: Maintained
54
F: hw/ssi/xilinx_*
55
@@ -XXX,XX +XXX,XX @@ S: Maintained
56
F: hw/net/eepro100.c
57
58
Generic Loader
59
-M: Alistair Francis <alistair.francis@xilinx.com>
60
+M: Alistair Francis <alistair@alistair23.me>
61
S: Maintained
62
F: hw/core/generic-loader.c
63
F: include/hw/core/generic-loader.h
64
@@ -XXX,XX +XXX,XX @@ F: tests/qmp-test.c
65
T: git git://repo.or.cz/qemu/armbru.git qapi-next
66
67
Register API
68
-M: Alistair Francis <alistair.francis@xilinx.com>
69
+M: Alistair Francis <alistair@alistair23.me>
70
S: Maintained
71
F: hw/core/register.c
72
F: include/hw/register.h
73
--
29
--
74
2.16.2
30
2.20.1
75
31
76
32
diff view generated by jsdifflib
1
From: Linus Walleij <linus.walleij@linaro.org>
1
From: Doug Evans <dje@google.com>
2
2
3
This adds support for emulating the Silicon Image SII9022 DVI/HDMI
3
This is a 10/100 ethernet device that has several features.
4
bridge. It's not very clever right now, it just acknowledges
4
Only the ones needed by the Linux driver have been implemented.
5
the switch into DDC I2C mode and back. Combining this with the
5
See npcm7xx_emc.c for a list of unimplemented features.
6
existing DDC I2C emulation gives the right behavior on the Versatile
7
Express emulation passing through the QEMU EDID to the emulated
8
platform.
9
6
10
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
11
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
12
Message-id: 20180227104903.21353-5-linus.walleij@linaro.org
9
Signed-off-by: Doug Evans <dje@google.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20210218212453.831406-2-dje@google.com
14
[PMM: explictly reset ddc_req/ddc_skip_finish/ddc]
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
12
---
17
hw/display/Makefile.objs | 1 +
13
include/hw/net/npcm7xx_emc.h | 286 ++++++++++++
18
hw/display/sii9022.c | 191 +++++++++++++++++++++++++++++++++++++++++++++++
14
hw/net/npcm7xx_emc.c | 857 +++++++++++++++++++++++++++++++++++
19
hw/display/trace-events | 5 ++
15
hw/net/meson.build | 1 +
20
3 files changed, 197 insertions(+)
16
hw/net/trace-events | 17 +
21
create mode 100644 hw/display/sii9022.c
17
4 files changed, 1161 insertions(+)
18
create mode 100644 include/hw/net/npcm7xx_emc.h
19
create mode 100644 hw/net/npcm7xx_emc.c
22
20
23
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
21
diff --git a/include/hw/net/npcm7xx_emc.h b/include/hw/net/npcm7xx_emc.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/display/Makefile.objs
26
+++ b/hw/display/Makefile.objs
27
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_VGA_CIRRUS) += cirrus_vga.o
28
common-obj-$(CONFIG_G364FB) += g364fb.o
29
common-obj-$(CONFIG_JAZZ_LED) += jazz_led.o
30
common-obj-$(CONFIG_PL110) += pl110.o
31
+common-obj-$(CONFIG_SII9022) += sii9022.o
32
common-obj-$(CONFIG_SSD0303) += ssd0303.o
33
common-obj-$(CONFIG_SSD0323) += ssd0323.o
34
common-obj-$(CONFIG_XEN) += xenfb.o
35
diff --git a/hw/display/sii9022.c b/hw/display/sii9022.c
36
new file mode 100644
22
new file mode 100644
37
index XXXXXXX..XXXXXXX
23
index XXXXXXX..XXXXXXX
38
--- /dev/null
24
--- /dev/null
39
+++ b/hw/display/sii9022.c
25
+++ b/include/hw/net/npcm7xx_emc.h
40
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@
41
+/*
27
+/*
42
+ * Silicon Image SiI9022
28
+ * Nuvoton NPCM7xx EMC Module
43
+ *
29
+ *
44
+ * This is a pretty hollow emulation: all we do is acknowledge that we
30
+ * Copyright 2020 Google LLC
45
+ * exist (chip ID) and confirm that we get switched over into DDC mode
46
+ * so the emulated host can proceed to read out EDID data. All subsequent
47
+ * set-up of connectors etc will be acknowledged and ignored.
48
+ *
31
+ *
49
+ * Copyright (C) 2018 Linus Walleij
32
+ * This program is free software; you can redistribute it and/or modify it
33
+ * under the terms of the GNU General Public License as published by the
34
+ * Free Software Foundation; either version 2 of the License, or
35
+ * (at your option) any later version.
50
+ *
36
+ *
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
37
+ * This program is distributed in the hope that it will be useful, but WITHOUT
52
+ * See the COPYING file in the top-level directory.
38
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
53
+ * SPDX-License-Identifier: GPL-2.0-or-later
39
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
40
+ * for more details.
54
+ */
41
+ */
55
+
42
+
43
+#ifndef NPCM7XX_EMC_H
44
+#define NPCM7XX_EMC_H
45
+
46
+#include "hw/irq.h"
47
+#include "hw/sysbus.h"
48
+#include "net/net.h"
49
+
50
+/* 32-bit register indices. */
51
+enum NPCM7xxPWMRegister {
52
+ /* Control registers. */
53
+ REG_CAMCMR,
54
+ REG_CAMEN,
55
+
56
+ /* There are 16 CAMn[ML] registers. */
57
+ REG_CAMM_BASE,
58
+ REG_CAML_BASE,
59
+ REG_CAMML_LAST = 0x21,
60
+
61
+ REG_TXDLSA = 0x22,
62
+ REG_RXDLSA,
63
+ REG_MCMDR,
64
+ REG_MIID,
65
+ REG_MIIDA,
66
+ REG_FFTCR,
67
+ REG_TSDR,
68
+ REG_RSDR,
69
+ REG_DMARFC,
70
+ REG_MIEN,
71
+
72
+ /* Status registers. */
73
+ REG_MISTA,
74
+ REG_MGSTA,
75
+ REG_MPCNT,
76
+ REG_MRPC,
77
+ REG_MRPCC,
78
+ REG_MREPC,
79
+ REG_DMARFS,
80
+ REG_CTXDSA,
81
+ REG_CTXBSA,
82
+ REG_CRXDSA,
83
+ REG_CRXBSA,
84
+
85
+ NPCM7XX_NUM_EMC_REGS,
86
+};
87
+
88
+/* REG_CAMCMR fields */
89
+/* Enable CAM Compare */
90
+#define REG_CAMCMR_ECMP (1 << 4)
91
+/* Complement CAM Compare */
92
+#define REG_CAMCMR_CCAM (1 << 3)
93
+/* Accept Broadcast Packet */
94
+#define REG_CAMCMR_ABP (1 << 2)
95
+/* Accept Multicast Packet */
96
+#define REG_CAMCMR_AMP (1 << 1)
97
+/* Accept Unicast Packet */
98
+#define REG_CAMCMR_AUP (1 << 0)
99
+
100
+/* REG_MCMDR fields */
101
+/* Software Reset */
102
+#define REG_MCMDR_SWR (1 << 24)
103
+/* Internal Loopback Select */
104
+#define REG_MCMDR_LBK (1 << 21)
105
+/* Operation Mode Select */
106
+#define REG_MCMDR_OPMOD (1 << 20)
107
+/* Enable MDC Clock Generation */
108
+#define REG_MCMDR_ENMDC (1 << 19)
109
+/* Full-Duplex Mode Select */
110
+#define REG_MCMDR_FDUP (1 << 18)
111
+/* Enable SQE Checking */
112
+#define REG_MCMDR_ENSEQ (1 << 17)
113
+/* Send PAUSE Frame */
114
+#define REG_MCMDR_SDPZ (1 << 16)
115
+/* No Defer */
116
+#define REG_MCMDR_NDEF (1 << 9)
117
+/* Frame Transmission On */
118
+#define REG_MCMDR_TXON (1 << 8)
119
+/* Strip CRC Checksum */
120
+#define REG_MCMDR_SPCRC (1 << 5)
121
+/* Accept CRC Error Packet */
122
+#define REG_MCMDR_AEP (1 << 4)
123
+/* Accept Control Packet */
124
+#define REG_MCMDR_ACP (1 << 3)
125
+/* Accept Runt Packet */
126
+#define REG_MCMDR_ARP (1 << 2)
127
+/* Accept Long Packet */
128
+#define REG_MCMDR_ALP (1 << 1)
129
+/* Frame Reception On */
130
+#define REG_MCMDR_RXON (1 << 0)
131
+
132
+/* REG_MIEN fields */
133
+/* Enable Transmit Descriptor Unavailable Interrupt */
134
+#define REG_MIEN_ENTDU (1 << 23)
135
+/* Enable Transmit Completion Interrupt */
136
+#define REG_MIEN_ENTXCP (1 << 18)
137
+/* Enable Transmit Interrupt */
138
+#define REG_MIEN_ENTXINTR (1 << 16)
139
+/* Enable Receive Descriptor Unavailable Interrupt */
140
+#define REG_MIEN_ENRDU (1 << 10)
141
+/* Enable Receive Good Interrupt */
142
+#define REG_MIEN_ENRXGD (1 << 4)
143
+/* Enable Receive Interrupt */
144
+#define REG_MIEN_ENRXINTR (1 << 0)
145
+
146
+/* REG_MISTA fields */
147
+/* TODO: Add error fields and support simulated errors? */
148
+/* Transmit Bus Error Interrupt */
149
+#define REG_MISTA_TXBERR (1 << 24)
150
+/* Transmit Descriptor Unavailable Interrupt */
151
+#define REG_MISTA_TDU (1 << 23)
152
+/* Transmit Completion Interrupt */
153
+#define REG_MISTA_TXCP (1 << 18)
154
+/* Transmit Interrupt */
155
+#define REG_MISTA_TXINTR (1 << 16)
156
+/* Receive Bus Error Interrupt */
157
+#define REG_MISTA_RXBERR (1 << 11)
158
+/* Receive Descriptor Unavailable Interrupt */
159
+#define REG_MISTA_RDU (1 << 10)
160
+/* DMA Early Notification Interrupt */
161
+#define REG_MISTA_DENI (1 << 9)
162
+/* Maximum Frame Length Interrupt */
163
+#define REG_MISTA_DFOI (1 << 8)
164
+/* Receive Good Interrupt */
165
+#define REG_MISTA_RXGD (1 << 4)
166
+/* Packet Too Long Interrupt */
167
+#define REG_MISTA_PTLE (1 << 3)
168
+/* Receive Interrupt */
169
+#define REG_MISTA_RXINTR (1 << 0)
170
+
171
+/* REG_MGSTA fields */
172
+/* Transmission Halted */
173
+#define REG_MGSTA_TXHA (1 << 11)
174
+/* Receive Halted */
175
+#define REG_MGSTA_RXHA (1 << 11)
176
+
177
+/* REG_DMARFC fields */
178
+/* Maximum Receive Frame Length */
179
+#define REG_DMARFC_RXMS(word) extract32((word), 0, 16)
180
+
181
+/* REG MIIDA fields */
182
+/* Busy Bit */
183
+#define REG_MIIDA_BUSY (1 << 17)
184
+
185
+/* Transmit and receive descriptors */
186
+typedef struct NPCM7xxEMCTxDesc NPCM7xxEMCTxDesc;
187
+typedef struct NPCM7xxEMCRxDesc NPCM7xxEMCRxDesc;
188
+
189
+struct NPCM7xxEMCTxDesc {
190
+ uint32_t flags;
191
+ uint32_t txbsa;
192
+ uint32_t status_and_length;
193
+ uint32_t ntxdsa;
194
+};
195
+
196
+struct NPCM7xxEMCRxDesc {
197
+ uint32_t status_and_length;
198
+ uint32_t rxbsa;
199
+ uint32_t reserved;
200
+ uint32_t nrxdsa;
201
+};
202
+
203
+/* NPCM7xxEMCTxDesc.flags values */
204
+/* Owner: 0 = cpu, 1 = emc */
205
+#define TX_DESC_FLAG_OWNER_MASK (1 << 31)
206
+/* Transmit interrupt enable */
207
+#define TX_DESC_FLAG_INTEN (1 << 2)
208
+/* CRC append */
209
+#define TX_DESC_FLAG_CRCAPP (1 << 1)
210
+/* Padding enable */
211
+#define TX_DESC_FLAG_PADEN (1 << 0)
212
+
213
+/* NPCM7xxEMCTxDesc.status_and_length values */
214
+/* Collision count */
215
+#define TX_DESC_STATUS_CCNT_SHIFT 28
216
+#define TX_DESC_STATUS_CCNT_BITSIZE 4
217
+/* SQE error */
218
+#define TX_DESC_STATUS_SQE (1 << 26)
219
+/* Transmission paused */
220
+#define TX_DESC_STATUS_PAU (1 << 25)
221
+/* P transmission halted */
222
+#define TX_DESC_STATUS_TXHA (1 << 24)
223
+/* Late collision */
224
+#define TX_DESC_STATUS_LC (1 << 23)
225
+/* Transmission abort */
226
+#define TX_DESC_STATUS_TXABT (1 << 22)
227
+/* No carrier sense */
228
+#define TX_DESC_STATUS_NCS (1 << 21)
229
+/* Defer exceed */
230
+#define TX_DESC_STATUS_EXDEF (1 << 20)
231
+/* Transmission complete */
232
+#define TX_DESC_STATUS_TXCP (1 << 19)
233
+/* Transmission deferred */
234
+#define TX_DESC_STATUS_DEF (1 << 17)
235
+/* Transmit interrupt */
236
+#define TX_DESC_STATUS_TXINTR (1 << 16)
237
+
238
+#define TX_DESC_PKT_LEN(word) extract32((word), 0, 16)
239
+
240
+/* Transmit buffer start address */
241
+#define TX_DESC_TXBSA(word) ((uint32_t) (word) & ~3u)
242
+
243
+/* Next transmit descriptor start address */
244
+#define TX_DESC_NTXDSA(word) ((uint32_t) (word) & ~3u)
245
+
246
+/* NPCM7xxEMCRxDesc.status_and_length values */
247
+/* Owner: 0b00 = cpu, 0b01 = undefined, 0b10 = emc, 0b11 = undefined */
248
+#define RX_DESC_STATUS_OWNER_SHIFT 30
249
+#define RX_DESC_STATUS_OWNER_BITSIZE 2
250
+#define RX_DESC_STATUS_OWNER_MASK (3 << RX_DESC_STATUS_OWNER_SHIFT)
251
+/* Runt packet */
252
+#define RX_DESC_STATUS_RP (1 << 22)
253
+/* Alignment error */
254
+#define RX_DESC_STATUS_ALIE (1 << 21)
255
+/* Frame reception complete */
256
+#define RX_DESC_STATUS_RXGD (1 << 20)
257
+/* Packet too long */
258
+#define RX_DESC_STATUS_PTLE (1 << 19)
259
+/* CRC error */
260
+#define RX_DESC_STATUS_CRCE (1 << 17)
261
+/* Receive interrupt */
262
+#define RX_DESC_STATUS_RXINTR (1 << 16)
263
+
264
+#define RX_DESC_PKT_LEN(word) extract32((word), 0, 16)
265
+
266
+/* Receive buffer start address */
267
+#define RX_DESC_RXBSA(word) ((uint32_t) (word) & ~3u)
268
+
269
+/* Next receive descriptor start address */
270
+#define RX_DESC_NRXDSA(word) ((uint32_t) (word) & ~3u)
271
+
272
+/* Minimum packet length, when TX_DESC_FLAG_PADEN is set. */
273
+#define MIN_PACKET_LENGTH 64
274
+
275
+struct NPCM7xxEMCState {
276
+ /*< private >*/
277
+ SysBusDevice parent;
278
+ /*< public >*/
279
+
280
+ MemoryRegion iomem;
281
+
282
+ qemu_irq tx_irq;
283
+ qemu_irq rx_irq;
284
+
285
+ NICState *nic;
286
+ NICConf conf;
287
+
288
+ /* 0 or 1, for log messages */
289
+ uint8_t emc_num;
290
+
291
+ uint32_t regs[NPCM7XX_NUM_EMC_REGS];
292
+
293
+ /*
294
+ * tx is active. Set to true by TSDR and then switches off when out of
295
+ * descriptors. If the TXON bit in REG_MCMDR is off then this is off.
296
+ */
297
+ bool tx_active;
298
+
299
+ /*
300
+ * rx is active. Set to true by RSDR and then switches off when out of
301
+ * descriptors. If the RXON bit in REG_MCMDR is off then this is off.
302
+ */
303
+ bool rx_active;
304
+};
305
+
306
+typedef struct NPCM7xxEMCState NPCM7xxEMCState;
307
+
308
+#define TYPE_NPCM7XX_EMC "npcm7xx-emc"
309
+#define NPCM7XX_EMC(obj) \
310
+ OBJECT_CHECK(NPCM7xxEMCState, (obj), TYPE_NPCM7XX_EMC)
311
+
312
+#endif /* NPCM7XX_EMC_H */
313
diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c
314
new file mode 100644
315
index XXXXXXX..XXXXXXX
316
--- /dev/null
317
+++ b/hw/net/npcm7xx_emc.c
318
@@ -XXX,XX +XXX,XX @@
319
+/*
320
+ * Nuvoton NPCM7xx EMC Module
321
+ *
322
+ * Copyright 2020 Google LLC
323
+ *
324
+ * This program is free software; you can redistribute it and/or modify it
325
+ * under the terms of the GNU General Public License as published by the
326
+ * Free Software Foundation; either version 2 of the License, or
327
+ * (at your option) any later version.
328
+ *
329
+ * This program is distributed in the hope that it will be useful, but WITHOUT
330
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
331
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
332
+ * for more details.
333
+ *
334
+ * Unsupported/unimplemented features:
335
+ * - MCMDR.FDUP (full duplex) is ignored, half duplex is not supported
336
+ * - Only CAM0 is supported, CAM[1-15] are not
337
+ * - writes to CAMEN.[1-15] are ignored, these bits always read as zeroes
338
+ * - MII is not implemented, MIIDA.BUSY and MIID always return zero
339
+ * - MCMDR.LBK is not implemented
340
+ * - MCMDR.{OPMOD,ENSQE,AEP,ARP} are not supported
341
+ * - H/W FIFOs are not supported, MCMDR.FFTCR is ignored
342
+ * - MGSTA.SQE is not supported
343
+ * - pause and control frames are not implemented
344
+ * - MGSTA.CCNT is not supported
345
+ * - MPCNT, DMARFS are not implemented
346
+ */
347
+
56
+#include "qemu/osdep.h"
348
+#include "qemu/osdep.h"
349
+
350
+/* For crc32 */
351
+#include <zlib.h>
352
+
57
+#include "qemu-common.h"
353
+#include "qemu-common.h"
58
+#include "hw/i2c/i2c.h"
354
+#include "hw/irq.h"
59
+#include "hw/i2c/i2c-ddc.h"
355
+#include "hw/qdev-clock.h"
356
+#include "hw/qdev-properties.h"
357
+#include "hw/net/npcm7xx_emc.h"
358
+#include "net/eth.h"
359
+#include "migration/vmstate.h"
360
+#include "qemu/bitops.h"
361
+#include "qemu/error-report.h"
362
+#include "qemu/log.h"
363
+#include "qemu/module.h"
364
+#include "qemu/units.h"
365
+#include "sysemu/dma.h"
60
+#include "trace.h"
366
+#include "trace.h"
61
+
367
+
62
+#define SII9022_SYS_CTRL_DATA 0x1a
368
+#define CRC_LENGTH 4
63
+#define SII9022_SYS_CTRL_PWR_DWN 0x10
369
+
64
+#define SII9022_SYS_CTRL_AV_MUTE 0x08
370
+/*
65
+#define SII9022_SYS_CTRL_DDC_BUS_REQ 0x04
371
+ * The maximum size of a (layer 2) ethernet frame as defined by 802.3.
66
+#define SII9022_SYS_CTRL_DDC_BUS_GRTD 0x02
372
+ * 1518 = 6(dest macaddr) + 6(src macaddr) + 2(proto) + 4(crc) + 1500(payload)
67
+#define SII9022_SYS_CTRL_OUTPUT_MODE 0x01
373
+ * This does not include an additional 4 for the vlan field (802.1q).
68
+#define SII9022_SYS_CTRL_OUTPUT_HDMI 1
374
+ */
69
+#define SII9022_SYS_CTRL_OUTPUT_DVI 0
375
+#define MAX_ETH_FRAME_SIZE 1518
70
+#define SII9022_REG_CHIPID 0x1b
376
+
71
+#define SII9022_INT_ENABLE 0x3c
377
+static const char *emc_reg_name(int regno)
72
+#define SII9022_INT_STATUS 0x3d
378
+{
73
+#define SII9022_INT_STATUS_HOTPLUG 0x01;
379
+#define REG(name) case REG_ ## name: return #name;
74
+#define SII9022_INT_STATUS_PLUGGED 0x04;
380
+ switch (regno) {
75
+
381
+ REG(CAMCMR)
76
+#define TYPE_SII9022 "sii9022"
382
+ REG(CAMEN)
77
+#define SII9022(obj) OBJECT_CHECK(sii9022_state, (obj), TYPE_SII9022)
383
+ REG(TXDLSA)
78
+
384
+ REG(RXDLSA)
79
+typedef struct sii9022_state {
385
+ REG(MCMDR)
80
+ I2CSlave parent_obj;
386
+ REG(MIID)
81
+ uint8_t ptr;
387
+ REG(MIIDA)
82
+ bool addr_byte;
388
+ REG(FFTCR)
83
+ bool ddc_req;
389
+ REG(TSDR)
84
+ bool ddc_skip_finish;
390
+ REG(RSDR)
85
+ bool ddc;
391
+ REG(DMARFC)
86
+} sii9022_state;
392
+ REG(MIEN)
87
+
393
+ REG(MISTA)
88
+static const VMStateDescription vmstate_sii9022 = {
394
+ REG(MGSTA)
89
+ .name = "sii9022",
395
+ REG(MPCNT)
90
+ .version_id = 1,
396
+ REG(MRPC)
91
+ .minimum_version_id = 1,
397
+ REG(MRPCC)
398
+ REG(MREPC)
399
+ REG(DMARFS)
400
+ REG(CTXDSA)
401
+ REG(CTXBSA)
402
+ REG(CRXDSA)
403
+ REG(CRXBSA)
404
+ case REG_CAMM_BASE + 0: return "CAM0M";
405
+ case REG_CAML_BASE + 0: return "CAM0L";
406
+ case REG_CAMM_BASE + 2 ... REG_CAMML_LAST:
407
+ /* Only CAM0 is supported, fold the others into something simple. */
408
+ if (regno & 1) {
409
+ return "CAM<n>L";
410
+ } else {
411
+ return "CAM<n>M";
412
+ }
413
+ default: return "UNKNOWN";
414
+ }
415
+#undef REG
416
+}
417
+
418
+static void emc_reset(NPCM7xxEMCState *emc)
419
+{
420
+ trace_npcm7xx_emc_reset(emc->emc_num);
421
+
422
+ memset(&emc->regs[0], 0, sizeof(emc->regs));
423
+
424
+ /* These regs have non-zero reset values. */
425
+ emc->regs[REG_TXDLSA] = 0xfffffffc;
426
+ emc->regs[REG_RXDLSA] = 0xfffffffc;
427
+ emc->regs[REG_MIIDA] = 0x00900000;
428
+ emc->regs[REG_FFTCR] = 0x0101;
429
+ emc->regs[REG_DMARFC] = 0x0800;
430
+ emc->regs[REG_MPCNT] = 0x7fff;
431
+
432
+ emc->tx_active = false;
433
+ emc->rx_active = false;
434
+}
435
+
436
+static void npcm7xx_emc_reset(DeviceState *dev)
437
+{
438
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);
439
+ emc_reset(emc);
440
+}
441
+
442
+static void emc_soft_reset(NPCM7xxEMCState *emc)
443
+{
444
+ /*
445
+ * The docs say at least MCMDR.{LBK,OPMOD} bits are not changed during a
446
+ * soft reset, but does not go into further detail. For now, KISS.
447
+ */
448
+ uint32_t mcmdr = emc->regs[REG_MCMDR];
449
+ emc_reset(emc);
450
+ emc->regs[REG_MCMDR] = mcmdr & (REG_MCMDR_LBK | REG_MCMDR_OPMOD);
451
+
452
+ qemu_set_irq(emc->tx_irq, 0);
453
+ qemu_set_irq(emc->rx_irq, 0);
454
+}
455
+
456
+static void emc_set_link(NetClientState *nc)
457
+{
458
+ /* Nothing to do yet. */
459
+}
460
+
461
+/* MISTA.TXINTR is the union of the individual bits with their enables. */
462
+static void emc_update_mista_txintr(NPCM7xxEMCState *emc)
463
+{
464
+ /* Only look at the bits we support. */
465
+ uint32_t mask = (REG_MISTA_TXBERR |
466
+ REG_MISTA_TDU |
467
+ REG_MISTA_TXCP);
468
+ if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & mask) {
469
+ emc->regs[REG_MISTA] |= REG_MISTA_TXINTR;
470
+ } else {
471
+ emc->regs[REG_MISTA] &= ~REG_MISTA_TXINTR;
472
+ }
473
+}
474
+
475
+/* MISTA.RXINTR is the union of the individual bits with their enables. */
476
+static void emc_update_mista_rxintr(NPCM7xxEMCState *emc)
477
+{
478
+ /* Only look at the bits we support. */
479
+ uint32_t mask = (REG_MISTA_RXBERR |
480
+ REG_MISTA_RDU |
481
+ REG_MISTA_RXGD);
482
+ if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & mask) {
483
+ emc->regs[REG_MISTA] |= REG_MISTA_RXINTR;
484
+ } else {
485
+ emc->regs[REG_MISTA] &= ~REG_MISTA_RXINTR;
486
+ }
487
+}
488
+
489
+/* N.B. emc_update_mista_txintr must have already been called. */
490
+static void emc_update_tx_irq(NPCM7xxEMCState *emc)
491
+{
492
+ int level = !!(emc->regs[REG_MISTA] &
493
+ emc->regs[REG_MIEN] &
494
+ REG_MISTA_TXINTR);
495
+ trace_npcm7xx_emc_update_tx_irq(level);
496
+ qemu_set_irq(emc->tx_irq, level);
497
+}
498
+
499
+/* N.B. emc_update_mista_rxintr must have already been called. */
500
+static void emc_update_rx_irq(NPCM7xxEMCState *emc)
501
+{
502
+ int level = !!(emc->regs[REG_MISTA] &
503
+ emc->regs[REG_MIEN] &
504
+ REG_MISTA_RXINTR);
505
+ trace_npcm7xx_emc_update_rx_irq(level);
506
+ qemu_set_irq(emc->rx_irq, level);
507
+}
508
+
509
+/* Update IRQ states due to changes in MIEN,MISTA. */
510
+static void emc_update_irq_from_reg_change(NPCM7xxEMCState *emc)
511
+{
512
+ emc_update_mista_txintr(emc);
513
+ emc_update_tx_irq(emc);
514
+
515
+ emc_update_mista_rxintr(emc);
516
+ emc_update_rx_irq(emc);
517
+}
518
+
519
+static int emc_read_tx_desc(dma_addr_t addr, NPCM7xxEMCTxDesc *desc)
520
+{
521
+ if (dma_memory_read(&address_space_memory, addr, desc, sizeof(*desc))) {
522
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%"
523
+ HWADDR_PRIx "\n", __func__, addr);
524
+ return -1;
525
+ }
526
+ desc->flags = le32_to_cpu(desc->flags);
527
+ desc->txbsa = le32_to_cpu(desc->txbsa);
528
+ desc->status_and_length = le32_to_cpu(desc->status_and_length);
529
+ desc->ntxdsa = le32_to_cpu(desc->ntxdsa);
530
+ return 0;
531
+}
532
+
533
+static int emc_write_tx_desc(const NPCM7xxEMCTxDesc *desc, dma_addr_t addr)
534
+{
535
+ NPCM7xxEMCTxDesc le_desc;
536
+
537
+ le_desc.flags = cpu_to_le32(desc->flags);
538
+ le_desc.txbsa = cpu_to_le32(desc->txbsa);
539
+ le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
540
+ le_desc.ntxdsa = cpu_to_le32(desc->ntxdsa);
541
+ if (dma_memory_write(&address_space_memory, addr, &le_desc,
542
+ sizeof(le_desc))) {
543
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to write descriptor @ 0x%"
544
+ HWADDR_PRIx "\n", __func__, addr);
545
+ return -1;
546
+ }
547
+ return 0;
548
+}
549
+
550
+static int emc_read_rx_desc(dma_addr_t addr, NPCM7xxEMCRxDesc *desc)
551
+{
552
+ if (dma_memory_read(&address_space_memory, addr, desc, sizeof(*desc))) {
553
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read descriptor @ 0x%"
554
+ HWADDR_PRIx "\n", __func__, addr);
555
+ return -1;
556
+ }
557
+ desc->status_and_length = le32_to_cpu(desc->status_and_length);
558
+ desc->rxbsa = le32_to_cpu(desc->rxbsa);
559
+ desc->reserved = le32_to_cpu(desc->reserved);
560
+ desc->nrxdsa = le32_to_cpu(desc->nrxdsa);
561
+ return 0;
562
+}
563
+
564
+static int emc_write_rx_desc(const NPCM7xxEMCRxDesc *desc, dma_addr_t addr)
565
+{
566
+ NPCM7xxEMCRxDesc le_desc;
567
+
568
+ le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
569
+ le_desc.rxbsa = cpu_to_le32(desc->rxbsa);
570
+ le_desc.reserved = cpu_to_le32(desc->reserved);
571
+ le_desc.nrxdsa = cpu_to_le32(desc->nrxdsa);
572
+ if (dma_memory_write(&address_space_memory, addr, &le_desc,
573
+ sizeof(le_desc))) {
574
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to write descriptor @ 0x%"
575
+ HWADDR_PRIx "\n", __func__, addr);
576
+ return -1;
577
+ }
578
+ return 0;
579
+}
580
+
581
+static void emc_set_mista(NPCM7xxEMCState *emc, uint32_t flags)
582
+{
583
+ trace_npcm7xx_emc_set_mista(flags);
584
+ emc->regs[REG_MISTA] |= flags;
585
+ if (extract32(flags, 16, 16)) {
586
+ emc_update_mista_txintr(emc);
587
+ }
588
+ if (extract32(flags, 0, 16)) {
589
+ emc_update_mista_rxintr(emc);
590
+ }
591
+}
592
+
593
+static void emc_halt_tx(NPCM7xxEMCState *emc, uint32_t mista_flag)
594
+{
595
+ emc->tx_active = false;
596
+ emc_set_mista(emc, mista_flag);
597
+}
598
+
599
+static void emc_halt_rx(NPCM7xxEMCState *emc, uint32_t mista_flag)
600
+{
601
+ emc->rx_active = false;
602
+ emc_set_mista(emc, mista_flag);
603
+}
604
+
605
+static void emc_set_next_tx_descriptor(NPCM7xxEMCState *emc,
606
+ const NPCM7xxEMCTxDesc *tx_desc,
607
+ uint32_t desc_addr)
608
+{
609
+ /* Update the current descriptor, if only to reset the owner flag. */
610
+ if (emc_write_tx_desc(tx_desc, desc_addr)) {
611
+ /*
612
+ * We just read it so this shouldn't generally happen.
613
+ * Error already reported.
614
+ */
615
+ emc_set_mista(emc, REG_MISTA_TXBERR);
616
+ }
617
+ emc->regs[REG_CTXDSA] = TX_DESC_NTXDSA(tx_desc->ntxdsa);
618
+}
619
+
620
+static void emc_set_next_rx_descriptor(NPCM7xxEMCState *emc,
621
+ const NPCM7xxEMCRxDesc *rx_desc,
622
+ uint32_t desc_addr)
623
+{
624
+ /* Update the current descriptor, if only to reset the owner flag. */
625
+ if (emc_write_rx_desc(rx_desc, desc_addr)) {
626
+ /*
627
+ * We just read it so this shouldn't generally happen.
628
+ * Error already reported.
629
+ */
630
+ emc_set_mista(emc, REG_MISTA_RXBERR);
631
+ }
632
+ emc->regs[REG_CRXDSA] = RX_DESC_NRXDSA(rx_desc->nrxdsa);
633
+}
634
+
635
+static void emc_try_send_next_packet(NPCM7xxEMCState *emc)
636
+{
637
+ /* Working buffer for sending out packets. Most packets fit in this. */
638
+#define TX_BUFFER_SIZE 2048
639
+ uint8_t tx_send_buffer[TX_BUFFER_SIZE];
640
+ uint32_t desc_addr = TX_DESC_NTXDSA(emc->regs[REG_CTXDSA]);
641
+ NPCM7xxEMCTxDesc tx_desc;
642
+ uint32_t next_buf_addr, length;
643
+ uint8_t *buf;
644
+ g_autofree uint8_t *malloced_buf = NULL;
645
+
646
+ if (emc_read_tx_desc(desc_addr, &tx_desc)) {
647
+ /* Error reading descriptor, already reported. */
648
+ emc_halt_tx(emc, REG_MISTA_TXBERR);
649
+ emc_update_tx_irq(emc);
650
+ return;
651
+ }
652
+
653
+ /* Nothing we can do if we don't own the descriptor. */
654
+ if (!(tx_desc.flags & TX_DESC_FLAG_OWNER_MASK)) {
655
+ trace_npcm7xx_emc_cpu_owned_desc(desc_addr);
656
+ emc_halt_tx(emc, REG_MISTA_TDU);
657
+ emc_update_tx_irq(emc);
658
+ return;
659
+ }
660
+
661
+ /* Give the descriptor back regardless of what happens. */
662
+ tx_desc.flags &= ~TX_DESC_FLAG_OWNER_MASK;
663
+ tx_desc.status_and_length &= 0xffff;
664
+
665
+ /*
666
+ * Despite the h/w documentation saying the tx buffer is word aligned,
667
+ * the linux driver does not word align the buffer. There is value in not
668
+ * aligning the buffer: See the description of NET_IP_ALIGN in linux
669
+ * kernel sources.
670
+ */
671
+ next_buf_addr = tx_desc.txbsa;
672
+ emc->regs[REG_CTXBSA] = next_buf_addr;
673
+ length = TX_DESC_PKT_LEN(tx_desc.status_and_length);
674
+ buf = &tx_send_buffer[0];
675
+
676
+ if (length > sizeof(tx_send_buffer)) {
677
+ malloced_buf = g_malloc(length);
678
+ buf = malloced_buf;
679
+ }
680
+
681
+ if (dma_memory_read(&address_space_memory, next_buf_addr, buf, length)) {
682
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Failed to read packet @ 0x%x\n",
683
+ __func__, next_buf_addr);
684
+ emc_set_mista(emc, REG_MISTA_TXBERR);
685
+ emc_set_next_tx_descriptor(emc, &tx_desc, desc_addr);
686
+ emc_update_tx_irq(emc);
687
+ trace_npcm7xx_emc_tx_done(emc->regs[REG_CTXDSA]);
688
+ return;
689
+ }
690
+
691
+ if ((tx_desc.flags & TX_DESC_FLAG_PADEN) && (length < MIN_PACKET_LENGTH)) {
692
+ memset(buf + length, 0, MIN_PACKET_LENGTH - length);
693
+ length = MIN_PACKET_LENGTH;
694
+ }
695
+
696
+ /* N.B. emc_receive can get called here. */
697
+ qemu_send_packet(qemu_get_queue(emc->nic), buf, length);
698
+ trace_npcm7xx_emc_sent_packet(length);
699
+
700
+ tx_desc.status_and_length |= TX_DESC_STATUS_TXCP;
701
+ if (tx_desc.flags & TX_DESC_FLAG_INTEN) {
702
+ emc_set_mista(emc, REG_MISTA_TXCP);
703
+ }
704
+ if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & REG_MISTA_TXINTR) {
705
+ tx_desc.status_and_length |= TX_DESC_STATUS_TXINTR;
706
+ }
707
+
708
+ emc_set_next_tx_descriptor(emc, &tx_desc, desc_addr);
709
+ emc_update_tx_irq(emc);
710
+ trace_npcm7xx_emc_tx_done(emc->regs[REG_CTXDSA]);
711
+}
712
+
713
+static bool emc_can_receive(NetClientState *nc)
714
+{
715
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(qemu_get_nic_opaque(nc));
716
+
717
+ bool can_receive = emc->rx_active;
718
+ trace_npcm7xx_emc_can_receive(can_receive);
719
+ return can_receive;
720
+}
721
+
722
+/* If result is false then *fail_reason contains the reason. */
723
+static bool emc_receive_filter1(NPCM7xxEMCState *emc, const uint8_t *buf,
724
+ size_t len, const char **fail_reason)
725
+{
726
+ eth_pkt_types_e pkt_type = get_eth_packet_type(PKT_GET_ETH_HDR(buf));
727
+
728
+ switch (pkt_type) {
729
+ case ETH_PKT_BCAST:
730
+ if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) {
731
+ return true;
732
+ } else {
733
+ *fail_reason = "Broadcast packet disabled";
734
+ return !!(emc->regs[REG_CAMCMR] & REG_CAMCMR_ABP);
735
+ }
736
+ case ETH_PKT_MCAST:
737
+ if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) {
738
+ return true;
739
+ } else {
740
+ *fail_reason = "Multicast packet disabled";
741
+ return !!(emc->regs[REG_CAMCMR] & REG_CAMCMR_AMP);
742
+ }
743
+ case ETH_PKT_UCAST: {
744
+ bool matches;
745
+ if (emc->regs[REG_CAMCMR] & REG_CAMCMR_AUP) {
746
+ return true;
747
+ }
748
+ matches = ((emc->regs[REG_CAMCMR] & REG_CAMCMR_ECMP) &&
749
+ /* We only support one CAM register, CAM0. */
750
+ (emc->regs[REG_CAMEN] & (1 << 0)) &&
751
+ memcmp(buf, emc->conf.macaddr.a, ETH_ALEN) == 0);
752
+ if (emc->regs[REG_CAMCMR] & REG_CAMCMR_CCAM) {
753
+ *fail_reason = "MACADDR matched, comparison complemented";
754
+ return !matches;
755
+ } else {
756
+ *fail_reason = "MACADDR didn't match";
757
+ return matches;
758
+ }
759
+ }
760
+ default:
761
+ g_assert_not_reached();
762
+ }
763
+}
764
+
765
+static bool emc_receive_filter(NPCM7xxEMCState *emc, const uint8_t *buf,
766
+ size_t len)
767
+{
768
+ const char *fail_reason = NULL;
769
+ bool ok = emc_receive_filter1(emc, buf, len, &fail_reason);
770
+ if (!ok) {
771
+ trace_npcm7xx_emc_packet_filtered_out(fail_reason);
772
+ }
773
+ return ok;
774
+}
775
+
776
+static ssize_t emc_receive(NetClientState *nc, const uint8_t *buf, size_t len1)
777
+{
778
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(qemu_get_nic_opaque(nc));
779
+ const uint32_t len = len1;
780
+ size_t max_frame_len;
781
+ bool long_frame;
782
+ uint32_t desc_addr;
783
+ NPCM7xxEMCRxDesc rx_desc;
784
+ uint32_t crc;
785
+ uint8_t *crc_ptr;
786
+ uint32_t buf_addr;
787
+
788
+ trace_npcm7xx_emc_receiving_packet(len);
789
+
790
+ if (!emc_can_receive(nc)) {
791
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Unexpected packet\n", __func__);
792
+ return -1;
793
+ }
794
+
795
+ if (len < ETH_HLEN ||
796
+ /* Defensive programming: drop unsupportable large packets. */
797
+ len > 0xffff - CRC_LENGTH) {
798
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Dropped frame of %u bytes\n",
799
+ __func__, len);
800
+ return len;
801
+ }
802
+
803
+ /*
804
+ * DENI is set if EMC received the Length/Type field of the incoming
805
+ * packet, so it will be set regardless of what happens next.
806
+ */
807
+ emc_set_mista(emc, REG_MISTA_DENI);
808
+
809
+ if (!emc_receive_filter(emc, buf, len)) {
810
+ emc_update_rx_irq(emc);
811
+ return len;
812
+ }
813
+
814
+ /* Huge frames (> DMARFC) are dropped. */
815
+ max_frame_len = REG_DMARFC_RXMS(emc->regs[REG_DMARFC]);
816
+ if (len + CRC_LENGTH > max_frame_len) {
817
+ trace_npcm7xx_emc_packet_dropped(len);
818
+ emc_set_mista(emc, REG_MISTA_DFOI);
819
+ emc_update_rx_irq(emc);
820
+ return len;
821
+ }
822
+
823
+ /*
824
+ * Long Frames (> MAX_ETH_FRAME_SIZE) are also dropped, unless MCMDR.ALP
825
+ * is set.
826
+ */
827
+ long_frame = false;
828
+ if (len + CRC_LENGTH > MAX_ETH_FRAME_SIZE) {
829
+ if (emc->regs[REG_MCMDR] & REG_MCMDR_ALP) {
830
+ long_frame = true;
831
+ } else {
832
+ trace_npcm7xx_emc_packet_dropped(len);
833
+ emc_set_mista(emc, REG_MISTA_PTLE);
834
+ emc_update_rx_irq(emc);
835
+ return len;
836
+ }
837
+ }
838
+
839
+ desc_addr = RX_DESC_NRXDSA(emc->regs[REG_CRXDSA]);
840
+ if (emc_read_rx_desc(desc_addr, &rx_desc)) {
841
+ /* Error reading descriptor, already reported. */
842
+ emc_halt_rx(emc, REG_MISTA_RXBERR);
843
+ emc_update_rx_irq(emc);
844
+ return len;
845
+ }
846
+
847
+ /* Nothing we can do if we don't own the descriptor. */
848
+ if (!(rx_desc.status_and_length & RX_DESC_STATUS_OWNER_MASK)) {
849
+ trace_npcm7xx_emc_cpu_owned_desc(desc_addr);
850
+ emc_halt_rx(emc, REG_MISTA_RDU);
851
+ emc_update_rx_irq(emc);
852
+ return len;
853
+ }
854
+
855
+ crc = 0;
856
+ crc_ptr = (uint8_t *) &crc;
857
+ if (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC)) {
858
+ crc = cpu_to_be32(crc32(~0, buf, len));
859
+ }
860
+
861
+ /* Give the descriptor back regardless of what happens. */
862
+ rx_desc.status_and_length &= ~RX_DESC_STATUS_OWNER_MASK;
863
+
864
+ buf_addr = rx_desc.rxbsa;
865
+ emc->regs[REG_CRXBSA] = buf_addr;
866
+ if (dma_memory_write(&address_space_memory, buf_addr, buf, len) ||
867
+ (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC) &&
868
+ dma_memory_write(&address_space_memory, buf_addr + len, crc_ptr,
869
+ 4))) {
870
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bus error writing packet\n",
871
+ __func__);
872
+ emc_set_mista(emc, REG_MISTA_RXBERR);
873
+ emc_set_next_rx_descriptor(emc, &rx_desc, desc_addr);
874
+ emc_update_rx_irq(emc);
875
+ trace_npcm7xx_emc_rx_done(emc->regs[REG_CRXDSA]);
876
+ return len;
877
+ }
878
+
879
+ trace_npcm7xx_emc_received_packet(len);
880
+
881
+ /* Note: We've already verified len+4 <= 0xffff. */
882
+ rx_desc.status_and_length = len;
883
+ if (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC)) {
884
+ rx_desc.status_and_length += 4;
885
+ }
886
+ rx_desc.status_and_length |= RX_DESC_STATUS_RXGD;
887
+ emc_set_mista(emc, REG_MISTA_RXGD);
888
+
889
+ if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & REG_MISTA_RXINTR) {
890
+ rx_desc.status_and_length |= RX_DESC_STATUS_RXINTR;
891
+ }
892
+ if (long_frame) {
893
+ rx_desc.status_and_length |= RX_DESC_STATUS_PTLE;
894
+ }
895
+
896
+ emc_set_next_rx_descriptor(emc, &rx_desc, desc_addr);
897
+ emc_update_rx_irq(emc);
898
+ trace_npcm7xx_emc_rx_done(emc->regs[REG_CRXDSA]);
899
+ return len;
900
+}
901
+
902
+static void emc_try_receive_next_packet(NPCM7xxEMCState *emc)
903
+{
904
+ if (emc_can_receive(qemu_get_queue(emc->nic))) {
905
+ qemu_flush_queued_packets(qemu_get_queue(emc->nic));
906
+ }
907
+}
908
+
909
+static uint64_t npcm7xx_emc_read(void *opaque, hwaddr offset, unsigned size)
910
+{
911
+ NPCM7xxEMCState *emc = opaque;
912
+ uint32_t reg = offset / sizeof(uint32_t);
913
+ uint32_t result;
914
+
915
+ if (reg >= NPCM7XX_NUM_EMC_REGS) {
916
+ qemu_log_mask(LOG_GUEST_ERROR,
917
+ "%s: Invalid offset 0x%04" HWADDR_PRIx "\n",
918
+ __func__, offset);
919
+ return 0;
920
+ }
921
+
922
+ switch (reg) {
923
+ case REG_MIID:
924
+ /*
925
+ * We don't implement MII. For determinism, always return zero as
926
+ * writes record the last value written for debugging purposes.
927
+ */
928
+ qemu_log_mask(LOG_UNIMP, "%s: Read of MIID, returning 0\n", __func__);
929
+ result = 0;
930
+ break;
931
+ case REG_TSDR:
932
+ case REG_RSDR:
933
+ qemu_log_mask(LOG_GUEST_ERROR,
934
+ "%s: Read of write-only reg, %s/%d\n",
935
+ __func__, emc_reg_name(reg), reg);
936
+ return 0;
937
+ default:
938
+ result = emc->regs[reg];
939
+ break;
940
+ }
941
+
942
+ trace_npcm7xx_emc_reg_read(emc->emc_num, result, emc_reg_name(reg), reg);
943
+ return result;
944
+}
945
+
946
+static void npcm7xx_emc_write(void *opaque, hwaddr offset,
947
+ uint64_t v, unsigned size)
948
+{
949
+ NPCM7xxEMCState *emc = opaque;
950
+ uint32_t reg = offset / sizeof(uint32_t);
951
+ uint32_t value = v;
952
+
953
+ g_assert(size == sizeof(uint32_t));
954
+
955
+ if (reg >= NPCM7XX_NUM_EMC_REGS) {
956
+ qemu_log_mask(LOG_GUEST_ERROR,
957
+ "%s: Invalid offset 0x%04" HWADDR_PRIx "\n",
958
+ __func__, offset);
959
+ return;
960
+ }
961
+
962
+ trace_npcm7xx_emc_reg_write(emc->emc_num, emc_reg_name(reg), reg, value);
963
+
964
+ switch (reg) {
965
+ case REG_CAMCMR:
966
+ emc->regs[reg] = value;
967
+ break;
968
+ case REG_CAMEN:
969
+ /* Only CAM0 is supported, don't pretend otherwise. */
970
+ if (value & ~1) {
971
+ qemu_log_mask(LOG_GUEST_ERROR,
972
+ "%s: Only CAM0 is supported, cannot enable others"
973
+ ": 0x%x\n",
974
+ __func__, value);
975
+ }
976
+ emc->regs[reg] = value & 1;
977
+ break;
978
+ case REG_CAMM_BASE + 0:
979
+ emc->regs[reg] = value;
980
+ emc->conf.macaddr.a[0] = value >> 24;
981
+ emc->conf.macaddr.a[1] = value >> 16;
982
+ emc->conf.macaddr.a[2] = value >> 8;
983
+ emc->conf.macaddr.a[3] = value >> 0;
984
+ break;
985
+ case REG_CAML_BASE + 0:
986
+ emc->regs[reg] = value;
987
+ emc->conf.macaddr.a[4] = value >> 24;
988
+ emc->conf.macaddr.a[5] = value >> 16;
989
+ break;
990
+ case REG_MCMDR: {
991
+ uint32_t prev;
992
+ if (value & REG_MCMDR_SWR) {
993
+ emc_soft_reset(emc);
994
+ /* On h/w the reset happens over multiple cycles. For now KISS. */
995
+ break;
996
+ }
997
+ prev = emc->regs[reg];
998
+ emc->regs[reg] = value;
999
+ /* Update tx state. */
1000
+ if (!(prev & REG_MCMDR_TXON) &&
1001
+ (value & REG_MCMDR_TXON)) {
1002
+ emc->regs[REG_CTXDSA] = emc->regs[REG_TXDLSA];
1003
+ /*
1004
+ * Linux kernel turns TX on with CPU still holding descriptor,
1005
+ * which suggests we should wait for a write to TSDR before trying
1006
+ * to send a packet: so we don't send one here.
1007
+ */
1008
+ } else if ((prev & REG_MCMDR_TXON) &&
1009
+ !(value & REG_MCMDR_TXON)) {
1010
+ emc->regs[REG_MGSTA] |= REG_MGSTA_TXHA;
1011
+ }
1012
+ if (!(value & REG_MCMDR_TXON)) {
1013
+ emc_halt_tx(emc, 0);
1014
+ }
1015
+ /* Update rx state. */
1016
+ if (!(prev & REG_MCMDR_RXON) &&
1017
+ (value & REG_MCMDR_RXON)) {
1018
+ emc->regs[REG_CRXDSA] = emc->regs[REG_RXDLSA];
1019
+ } else if ((prev & REG_MCMDR_RXON) &&
1020
+ !(value & REG_MCMDR_RXON)) {
1021
+ emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA;
1022
+ }
1023
+ if (!(value & REG_MCMDR_RXON)) {
1024
+ emc_halt_rx(emc, 0);
1025
+ }
1026
+ break;
1027
+ }
1028
+ case REG_TXDLSA:
1029
+ case REG_RXDLSA:
1030
+ case REG_DMARFC:
1031
+ case REG_MIID:
1032
+ emc->regs[reg] = value;
1033
+ break;
1034
+ case REG_MIEN:
1035
+ emc->regs[reg] = value;
1036
+ emc_update_irq_from_reg_change(emc);
1037
+ break;
1038
+ case REG_MISTA:
1039
+ /* Clear the bits that have 1 in "value". */
1040
+ emc->regs[reg] &= ~value;
1041
+ emc_update_irq_from_reg_change(emc);
1042
+ break;
1043
+ case REG_MGSTA:
1044
+ /* Clear the bits that have 1 in "value". */
1045
+ emc->regs[reg] &= ~value;
1046
+ break;
1047
+ case REG_TSDR:
1048
+ if (emc->regs[REG_MCMDR] & REG_MCMDR_TXON) {
1049
+ emc->tx_active = true;
1050
+ /* Keep trying to send packets until we run out. */
1051
+ while (emc->tx_active) {
1052
+ emc_try_send_next_packet(emc);
1053
+ }
1054
+ }
1055
+ break;
1056
+ case REG_RSDR:
1057
+ if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) {
1058
+ emc->rx_active = true;
1059
+ emc_try_receive_next_packet(emc);
1060
+ }
1061
+ break;
1062
+ case REG_MIIDA:
1063
+ emc->regs[reg] = value & ~REG_MIIDA_BUSY;
1064
+ break;
1065
+ case REG_MRPC:
1066
+ case REG_MRPCC:
1067
+ case REG_MREPC:
1068
+ case REG_CTXDSA:
1069
+ case REG_CTXBSA:
1070
+ case REG_CRXDSA:
1071
+ case REG_CRXBSA:
1072
+ qemu_log_mask(LOG_GUEST_ERROR,
1073
+ "%s: Write to read-only reg %s/%d\n",
1074
+ __func__, emc_reg_name(reg), reg);
1075
+ break;
1076
+ default:
1077
+ qemu_log_mask(LOG_UNIMP, "%s: Write to unimplemented reg %s/%d\n",
1078
+ __func__, emc_reg_name(reg), reg);
1079
+ break;
1080
+ }
1081
+}
1082
+
1083
+static const struct MemoryRegionOps npcm7xx_emc_ops = {
1084
+ .read = npcm7xx_emc_read,
1085
+ .write = npcm7xx_emc_write,
1086
+ .endianness = DEVICE_LITTLE_ENDIAN,
1087
+ .valid = {
1088
+ .min_access_size = 4,
1089
+ .max_access_size = 4,
1090
+ .unaligned = false,
1091
+ },
1092
+};
1093
+
1094
+static void emc_cleanup(NetClientState *nc)
1095
+{
1096
+ /* Nothing to do yet. */
1097
+}
1098
+
1099
+static NetClientInfo net_npcm7xx_emc_info = {
1100
+ .type = NET_CLIENT_DRIVER_NIC,
1101
+ .size = sizeof(NICState),
1102
+ .can_receive = emc_can_receive,
1103
+ .receive = emc_receive,
1104
+ .cleanup = emc_cleanup,
1105
+ .link_status_changed = emc_set_link,
1106
+};
1107
+
1108
+static void npcm7xx_emc_realize(DeviceState *dev, Error **errp)
1109
+{
1110
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);
1111
+ SysBusDevice *sbd = SYS_BUS_DEVICE(emc);
1112
+
1113
+ memory_region_init_io(&emc->iomem, OBJECT(emc), &npcm7xx_emc_ops, emc,
1114
+ TYPE_NPCM7XX_EMC, 4 * KiB);
1115
+ sysbus_init_mmio(sbd, &emc->iomem);
1116
+ sysbus_init_irq(sbd, &emc->tx_irq);
1117
+ sysbus_init_irq(sbd, &emc->rx_irq);
1118
+
1119
+ qemu_macaddr_default_if_unset(&emc->conf.macaddr);
1120
+ emc->nic = qemu_new_nic(&net_npcm7xx_emc_info, &emc->conf,
1121
+ object_get_typename(OBJECT(dev)), dev->id, emc);
1122
+ qemu_format_nic_info_str(qemu_get_queue(emc->nic), emc->conf.macaddr.a);
1123
+}
1124
+
1125
+static void npcm7xx_emc_unrealize(DeviceState *dev)
1126
+{
1127
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);
1128
+
1129
+ qemu_del_nic(emc->nic);
1130
+}
1131
+
1132
+static const VMStateDescription vmstate_npcm7xx_emc = {
1133
+ .name = TYPE_NPCM7XX_EMC,
1134
+ .version_id = 0,
1135
+ .minimum_version_id = 0,
92
+ .fields = (VMStateField[]) {
1136
+ .fields = (VMStateField[]) {
93
+ VMSTATE_I2C_SLAVE(parent_obj, sii9022_state),
1137
+ VMSTATE_UINT8(emc_num, NPCM7xxEMCState),
94
+ VMSTATE_UINT8(ptr, sii9022_state),
1138
+ VMSTATE_UINT32_ARRAY(regs, NPCM7xxEMCState, NPCM7XX_NUM_EMC_REGS),
95
+ VMSTATE_BOOL(addr_byte, sii9022_state),
1139
+ VMSTATE_BOOL(tx_active, NPCM7xxEMCState),
96
+ VMSTATE_BOOL(ddc_req, sii9022_state),
1140
+ VMSTATE_BOOL(rx_active, NPCM7xxEMCState),
97
+ VMSTATE_BOOL(ddc_skip_finish, sii9022_state),
1141
+ VMSTATE_END_OF_LIST(),
98
+ VMSTATE_BOOL(ddc, sii9022_state),
1142
+ },
99
+ VMSTATE_END_OF_LIST()
100
+ }
101
+};
1143
+};
102
+
1144
+
103
+static int sii9022_event(I2CSlave *i2c, enum i2c_event event)
1145
+static Property npcm7xx_emc_properties[] = {
104
+{
1146
+ DEFINE_NIC_PROPERTIES(NPCM7xxEMCState, conf),
105
+ sii9022_state *s = SII9022(i2c);
1147
+ DEFINE_PROP_END_OF_LIST(),
106
+
1148
+};
107
+ switch (event) {
1149
+
108
+ case I2C_START_SEND:
1150
+static void npcm7xx_emc_class_init(ObjectClass *klass, void *data)
109
+ s->addr_byte = true;
110
+ break;
111
+ case I2C_START_RECV:
112
+ break;
113
+ case I2C_FINISH:
114
+ break;
115
+ case I2C_NACK:
116
+ break;
117
+ }
118
+
119
+ return 0;
120
+}
121
+
122
+static int sii9022_rx(I2CSlave *i2c)
123
+{
124
+ sii9022_state *s = SII9022(i2c);
125
+ uint8_t res = 0x00;
126
+
127
+ switch (s->ptr) {
128
+ case SII9022_SYS_CTRL_DATA:
129
+ if (s->ddc_req) {
130
+ /* Acknowledge DDC bus request */
131
+ res = SII9022_SYS_CTRL_DDC_BUS_GRTD | SII9022_SYS_CTRL_DDC_BUS_REQ;
132
+ }
133
+ break;
134
+ case SII9022_REG_CHIPID:
135
+ res = 0xb0;
136
+ break;
137
+ case SII9022_INT_STATUS:
138
+ /* Something is cold-plugged in, no interrupts */
139
+ res = SII9022_INT_STATUS_PLUGGED;
140
+ break;
141
+ default:
142
+ break;
143
+ }
144
+
145
+ trace_sii9022_read_reg(s->ptr, res);
146
+ s->ptr++;
147
+
148
+ return res;
149
+}
150
+
151
+static int sii9022_tx(I2CSlave *i2c, uint8_t data)
152
+{
153
+ sii9022_state *s = SII9022(i2c);
154
+
155
+ if (s->addr_byte) {
156
+ s->ptr = data;
157
+ s->addr_byte = false;
158
+ return 0;
159
+ }
160
+
161
+ switch (s->ptr) {
162
+ case SII9022_SYS_CTRL_DATA:
163
+ if (data & SII9022_SYS_CTRL_DDC_BUS_REQ) {
164
+ s->ddc_req = true;
165
+ if (data & SII9022_SYS_CTRL_DDC_BUS_GRTD) {
166
+ s->ddc = true;
167
+ /* Skip this finish since we just switched to DDC */
168
+ s->ddc_skip_finish = true;
169
+ trace_sii9022_switch_mode("DDC");
170
+ }
171
+ } else {
172
+ s->ddc_req = false;
173
+ s->ddc = false;
174
+ trace_sii9022_switch_mode("normal");
175
+ }
176
+ break;
177
+ default:
178
+ break;
179
+ }
180
+
181
+ trace_sii9022_write_reg(s->ptr, data);
182
+ s->ptr++;
183
+
184
+ return 0;
185
+}
186
+
187
+static void sii9022_reset(DeviceState *dev)
188
+{
189
+ sii9022_state *s = SII9022(dev);
190
+
191
+ s->ptr = 0;
192
+ s->addr_byte = false;
193
+ s->ddc_req = false;
194
+ s->ddc_skip_finish = false;
195
+ s->ddc = false;
196
+}
197
+
198
+static void sii9022_realize(DeviceState *dev, Error **errp)
199
+{
200
+ I2CBus *bus;
201
+
202
+ bus = I2C_BUS(qdev_get_parent_bus(dev));
203
+ i2c_create_slave(bus, TYPE_I2CDDC, 0x50);
204
+}
205
+
206
+static void sii9022_class_init(ObjectClass *klass, void *data)
207
+{
1151
+{
208
+ DeviceClass *dc = DEVICE_CLASS(klass);
1152
+ DeviceClass *dc = DEVICE_CLASS(klass);
209
+ I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
1153
+
210
+
1154
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
211
+ k->event = sii9022_event;
1155
+ dc->desc = "NPCM7xx EMC Controller";
212
+ k->recv = sii9022_rx;
1156
+ dc->realize = npcm7xx_emc_realize;
213
+ k->send = sii9022_tx;
1157
+ dc->unrealize = npcm7xx_emc_unrealize;
214
+ dc->reset = sii9022_reset;
1158
+ dc->reset = npcm7xx_emc_reset;
215
+ dc->realize = sii9022_realize;
1159
+ dc->vmsd = &vmstate_npcm7xx_emc;
216
+ dc->vmsd = &vmstate_sii9022;
1160
+ device_class_set_props(dc, npcm7xx_emc_properties);
217
+}
1161
+}
218
+
1162
+
219
+static const TypeInfo sii9022_info = {
1163
+static const TypeInfo npcm7xx_emc_info = {
220
+ .name = TYPE_SII9022,
1164
+ .name = TYPE_NPCM7XX_EMC,
221
+ .parent = TYPE_I2C_SLAVE,
1165
+ .parent = TYPE_SYS_BUS_DEVICE,
222
+ .instance_size = sizeof(sii9022_state),
1166
+ .instance_size = sizeof(NPCM7xxEMCState),
223
+ .class_init = sii9022_class_init,
1167
+ .class_init = npcm7xx_emc_class_init,
224
+};
1168
+};
225
+
1169
+
226
+static void sii9022_register_types(void)
1170
+static void npcm7xx_emc_register_type(void)
227
+{
1171
+{
228
+ type_register_static(&sii9022_info);
1172
+ type_register_static(&npcm7xx_emc_info);
229
+}
1173
+}
230
+
1174
+
231
+type_init(sii9022_register_types)
1175
+type_init(npcm7xx_emc_register_type)
232
diff --git a/hw/display/trace-events b/hw/display/trace-events
1176
diff --git a/hw/net/meson.build b/hw/net/meson.build
233
index XXXXXXX..XXXXXXX 100644
1177
index XXXXXXX..XXXXXXX 100644
234
--- a/hw/display/trace-events
1178
--- a/hw/net/meson.build
235
+++ b/hw/display/trace-events
1179
+++ b/hw/net/meson.build
236
@@ -XXX,XX +XXX,XX @@ vga_cirrus_read_io(uint32_t addr, uint32_t val) "addr 0x%x, val 0x%x"
1180
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_I82596_COMMON', if_true: files('i82596.c'))
237
vga_cirrus_write_io(uint32_t addr, uint32_t val) "addr 0x%x, val 0x%x"
1181
softmmu_ss.add(when: 'CONFIG_SUNHME', if_true: files('sunhme.c'))
238
vga_cirrus_read_blt(uint32_t offset, uint32_t val) "offset 0x%x, val 0x%x"
1182
softmmu_ss.add(when: 'CONFIG_FTGMAC100', if_true: files('ftgmac100.c'))
239
vga_cirrus_write_blt(uint32_t offset, uint32_t val) "offset 0x%x, val 0x%x"
1183
softmmu_ss.add(when: 'CONFIG_SUNGEM', if_true: files('sungem.c'))
240
+
1184
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c'))
241
+# hw/display/sii9022.c
1185
242
+sii9022_read_reg(uint8_t addr, uint8_t val) "addr 0x%02x, val 0x%02x"
1186
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c'))
243
+sii9022_write_reg(uint8_t addr, uint8_t val) "addr 0x%02x, val 0x%02x"
1187
softmmu_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
244
+sii9022_switch_mode(const char *mode) "mode: %s"
1188
diff --git a/hw/net/trace-events b/hw/net/trace-events
1189
index XXXXXXX..XXXXXXX 100644
1190
--- a/hw/net/trace-events
1191
+++ b/hw/net/trace-events
1192
@@ -XXX,XX +XXX,XX @@ imx_fec_receive_last(int last) "rx frame flags 0x%04x"
1193
imx_enet_receive(size_t size) "len %zu"
1194
imx_enet_receive_len(uint64_t addr, int len) "rx_bd 0x%"PRIx64" length %d"
1195
imx_enet_receive_last(int last) "rx frame flags 0x%04x"
1196
+
1197
+# npcm7xx_emc.c
1198
+npcm7xx_emc_reset(int emc_num) "Resetting emc%d"
1199
+npcm7xx_emc_update_tx_irq(int level) "Setting tx irq to %d"
1200
+npcm7xx_emc_update_rx_irq(int level) "Setting rx irq to %d"
1201
+npcm7xx_emc_set_mista(uint32_t flags) "ORing 0x%x into MISTA"
1202
+npcm7xx_emc_cpu_owned_desc(uint32_t addr) "Can't process cpu-owned descriptor @0x%x"
1203
+npcm7xx_emc_sent_packet(uint32_t len) "Sent %u byte packet"
1204
+npcm7xx_emc_tx_done(uint32_t ctxdsa) "TX done, CTXDSA=0x%x"
1205
+npcm7xx_emc_can_receive(int can_receive) "Can receive: %d"
1206
+npcm7xx_emc_packet_filtered_out(const char* fail_reason) "Packet filtered out: %s"
1207
+npcm7xx_emc_packet_dropped(uint32_t len) "%u byte packet dropped"
1208
+npcm7xx_emc_receiving_packet(uint32_t len) "Receiving %u byte packet"
1209
+npcm7xx_emc_received_packet(uint32_t len) "Received %u byte packet"
1210
+npcm7xx_emc_rx_done(uint32_t crxdsa) "RX done, CRXDSA=0x%x"
1211
+npcm7xx_emc_reg_read(int emc_num, uint32_t result, const char *name, int regno) "emc%d: 0x%x = reg[%s/%d]"
1212
+npcm7xx_emc_reg_write(int emc_num, const char *name, int regno, uint32_t value) "emc%d: reg[%s/%d] = 0x%x"
245
--
1213
--
246
2.16.2
1214
2.20.1
247
1215
248
1216
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Doug Evans <dje@google.com>
2
2
3
This includes FMOV, FABS, FNEG, FSQRT and FRINT[NPMZAXI]. We re-use
3
This is a 10/100 ethernet device that has several features.
4
existing helpers to achieve this.
4
Only the ones needed by the Linux driver have been implemented.
5
See npcm7xx_emc.c for a list of unimplemented features.
5
6
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
8
Message-id: 20180227143852.11175-32-alex.bennee@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Doug Evans <dje@google.com>
11
Message-id: 20210218212453.831406-3-dje@google.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
target/arm/translate-a64.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++
14
docs/system/arm/nuvoton.rst | 3 ++-
12
1 file changed, 71 insertions(+)
15
include/hw/arm/npcm7xx.h | 2 ++
16
hw/arm/npcm7xx.c | 50 +++++++++++++++++++++++++++++++++++--
17
3 files changed, 52 insertions(+), 3 deletions(-)
13
18
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
19
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
21
--- a/docs/system/arm/nuvoton.rst
17
+++ b/target/arm/translate-a64.c
22
+++ b/docs/system/arm/nuvoton.rst
18
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
23
@@ -XXX,XX +XXX,XX @@ Supported devices
19
tcg_temp_free_i64(t_true);
24
* Analog to Digital Converter (ADC)
25
* Pulse Width Modulation (PWM)
26
* SMBus controller (SMBF)
27
+ * Ethernet controller (EMC)
28
29
Missing devices
30
---------------
31
@@ -XXX,XX +XXX,XX @@ Missing devices
32
* Shared memory (SHM)
33
* eSPI slave interface
34
35
- * Ethernet controllers (GMAC and EMC)
36
+ * Ethernet controller (GMAC)
37
* USB device (USBD)
38
* Peripheral SPI controller (PSPI)
39
* SD/MMC host
40
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/include/hw/arm/npcm7xx.h
43
+++ b/include/hw/arm/npcm7xx.h
44
@@ -XXX,XX +XXX,XX @@
45
#include "hw/misc/npcm7xx_gcr.h"
46
#include "hw/misc/npcm7xx_pwm.h"
47
#include "hw/misc/npcm7xx_rng.h"
48
+#include "hw/net/npcm7xx_emc.h"
49
#include "hw/nvram/npcm7xx_otp.h"
50
#include "hw/timer/npcm7xx_timer.h"
51
#include "hw/ssi/npcm7xx_fiu.h"
52
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
53
EHCISysBusState ehci;
54
OHCISysBusState ohci;
55
NPCM7xxFIUState fiu[2];
56
+ NPCM7xxEMCState emc[2];
57
} NPCM7xxState;
58
59
#define TYPE_NPCM7XX "npcm7xx"
60
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/npcm7xx.c
63
+++ b/hw/arm/npcm7xx.c
64
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
65
NPCM7XX_UART1_IRQ,
66
NPCM7XX_UART2_IRQ,
67
NPCM7XX_UART3_IRQ,
68
+ NPCM7XX_EMC1RX_IRQ = 15,
69
+ NPCM7XX_EMC1TX_IRQ,
70
NPCM7XX_TIMER0_IRQ = 32, /* Timer Module 0 */
71
NPCM7XX_TIMER1_IRQ,
72
NPCM7XX_TIMER2_IRQ,
73
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
74
NPCM7XX_SMBUS15_IRQ,
75
NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
76
NPCM7XX_PWM1_IRQ, /* PWM module 1 */
77
+ NPCM7XX_EMC2RX_IRQ = 114,
78
+ NPCM7XX_EMC2TX_IRQ,
79
NPCM7XX_GPIO0_IRQ = 116,
80
NPCM7XX_GPIO1_IRQ,
81
NPCM7XX_GPIO2_IRQ,
82
@@ -XXX,XX +XXX,XX @@ static const hwaddr npcm7xx_smbus_addr[] = {
83
0xf008f000,
84
};
85
86
+/* Register base address for each EMC Module */
87
+static const hwaddr npcm7xx_emc_addr[] = {
88
+ 0xf0825000,
89
+ 0xf0826000,
90
+};
91
+
92
static const struct {
93
hwaddr regs_addr;
94
uint32_t unconnected_pins;
95
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
96
for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
97
object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
98
}
99
+
100
+ for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
101
+ object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
102
+ }
20
}
103
}
21
104
22
+/* Floating-point data-processing (1 source) - half precision */
105
static void npcm7xx_realize(DeviceState *dev, Error **errp)
23
+static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
106
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
24
+{
107
sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
25
+ TCGv_ptr fpst = NULL;
108
}
26
+ TCGv_i32 tcg_op = tcg_temp_new_i32();
109
27
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
110
+ /*
28
+
111
+ * EMC Modules. Cannot fail.
29
+ read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
112
+ * The mapping of the device to its netdev backend works as follows:
30
+
113
+ * emc[i] = nd_table[i]
31
+ switch (opcode) {
114
+ * This works around the inability to specify the netdev property for the
32
+ case 0x0: /* FMOV */
115
+ * emc device: it's not pluggable and thus the -device option can't be
33
+ tcg_gen_mov_i32(tcg_res, tcg_op);
116
+ * used.
34
+ break;
117
+ */
35
+ case 0x1: /* FABS */
118
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_emc_addr) != ARRAY_SIZE(s->emc));
36
+ tcg_gen_andi_i32(tcg_res, tcg_op, 0x7fff);
119
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->emc) != 2);
37
+ break;
120
+ for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
38
+ case 0x2: /* FNEG */
121
+ s->emc[i].emc_num = i;
39
+ tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
122
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->emc[i]);
40
+ break;
123
+ if (nd_table[i].used) {
41
+ case 0x3: /* FSQRT */
124
+ qemu_check_nic_model(&nd_table[i], TYPE_NPCM7XX_EMC);
42
+ gen_helper_sqrt_f16(tcg_res, tcg_op, cpu_env);
125
+ qdev_set_nic_properties(DEVICE(sbd), &nd_table[i]);
43
+ break;
126
+ }
44
+ case 0x8: /* FRINTN */
127
+ /*
45
+ case 0x9: /* FRINTP */
128
+ * The device exists regardless of whether it's connected to a QEMU
46
+ case 0xa: /* FRINTM */
129
+ * netdev backend. So always instantiate it even if there is no
47
+ case 0xb: /* FRINTZ */
130
+ * backend.
48
+ case 0xc: /* FRINTA */
131
+ */
49
+ {
132
+ sysbus_realize(sbd, &error_abort);
50
+ TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
133
+ sysbus_mmio_map(sbd, 0, npcm7xx_emc_addr[i]);
51
+ fpst = get_fpstatus_ptr(true);
134
+ int tx_irq = i == 0 ? NPCM7XX_EMC1TX_IRQ : NPCM7XX_EMC2TX_IRQ;
52
+
135
+ int rx_irq = i == 0 ? NPCM7XX_EMC1RX_IRQ : NPCM7XX_EMC2RX_IRQ;
53
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
136
+ /*
54
+ gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst);
137
+ * N.B. The values for the second argument sysbus_connect_irq are
55
+
138
+ * chosen to match the registration order in npcm7xx_emc_realize.
56
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
139
+ */
57
+ tcg_temp_free_i32(tcg_rmode);
140
+ sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, tx_irq));
58
+ break;
141
+ sysbus_connect_irq(sbd, 1, npcm7xx_irq(s, rx_irq));
59
+ }
60
+ case 0xe: /* FRINTX */
61
+ fpst = get_fpstatus_ptr(true);
62
+ gen_helper_advsimd_rinth_exact(tcg_res, tcg_op, fpst);
63
+ break;
64
+ case 0xf: /* FRINTI */
65
+ fpst = get_fpstatus_ptr(true);
66
+ gen_helper_advsimd_rinth(tcg_res, tcg_op, fpst);
67
+ break;
68
+ default:
69
+ abort();
70
+ }
142
+ }
71
+
143
+
72
+ write_fp_sreg(s, rd, tcg_res);
144
/*
73
+
145
* Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
74
+ if (fpst) {
146
* specified, but this is a programming error.
75
+ tcg_temp_free_ptr(fpst);
147
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
76
+ }
148
create_unimplemented_device("npcm7xx.vcd", 0xf0810000, 64 * KiB);
77
+ tcg_temp_free_i32(tcg_op);
149
create_unimplemented_device("npcm7xx.ece", 0xf0820000, 8 * KiB);
78
+ tcg_temp_free_i32(tcg_res);
150
create_unimplemented_device("npcm7xx.vdma", 0xf0822000, 8 * KiB);
79
+}
151
- create_unimplemented_device("npcm7xx.emc1", 0xf0825000, 4 * KiB);
80
+
152
- create_unimplemented_device("npcm7xx.emc2", 0xf0826000, 4 * KiB);
81
/* Floating-point data-processing (1 source) - single precision */
153
create_unimplemented_device("npcm7xx.usbd[0]", 0xf0830000, 4 * KiB);
82
static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
154
create_unimplemented_device("npcm7xx.usbd[1]", 0xf0831000, 4 * KiB);
83
{
155
create_unimplemented_device("npcm7xx.usbd[2]", 0xf0832000, 4 * KiB);
84
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
85
86
handle_fp_1src_double(s, opcode, rd, rn);
87
break;
88
+ case 3:
89
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
90
+ unallocated_encoding(s);
91
+ return;
92
+ }
93
+
94
+ if (!fp_access_check(s)) {
95
+ return;
96
+ }
97
+
98
+ handle_fp_1src_half(s, opcode, rd, rn);
99
+ break;
100
default:
101
unallocated_encoding(s);
102
}
103
--
156
--
104
2.16.2
157
2.20.1
105
158
106
159
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Doug Evans <dje@google.com>
2
2
3
I only needed to do a little light re-factoring to support the
3
Reviewed-by: Hao Wu <wuhaotsh@google.com>
4
half-precision helpers.
4
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
5
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Doug Evans <dje@google.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210218212453.831406-4-dje@google.com
8
Message-id: 20180227143852.11175-30-alex.bennee@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
9
---
11
target/arm/translate-a64.c | 80 +++++++++++++++++++++++++++++++---------------
10
tests/qtest/npcm7xx_emc-test.c | 862 +++++++++++++++++++++++++++++++++
12
1 file changed, 54 insertions(+), 26 deletions(-)
11
tests/qtest/meson.build | 3 +-
12
2 files changed, 864 insertions(+), 1 deletion(-)
13
create mode 100644 tests/qtest/npcm7xx_emc-test.c
13
14
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
16
new file mode 100644
17
index XXXXXXX..XXXXXXX
18
--- /dev/null
19
+++ b/tests/qtest/npcm7xx_emc-test.c
20
@@ -XXX,XX +XXX,XX @@
21
+/*
22
+ * QTests for Nuvoton NPCM7xx EMC Modules.
23
+ *
24
+ * Copyright 2020 Google LLC
25
+ *
26
+ * This program is free software; you can redistribute it and/or modify it
27
+ * under the terms of the GNU General Public License as published by the
28
+ * Free Software Foundation; either version 2 of the License, or
29
+ * (at your option) any later version.
30
+ *
31
+ * This program is distributed in the hope that it will be useful, but WITHOUT
32
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
33
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
34
+ * for more details.
35
+ */
36
+
37
+#include "qemu/osdep.h"
38
+#include "qemu-common.h"
39
+#include "libqos/libqos.h"
40
+#include "qapi/qmp/qdict.h"
41
+#include "qapi/qmp/qnum.h"
42
+#include "qemu/bitops.h"
43
+#include "qemu/iov.h"
44
+
45
+/* Name of the emc device. */
46
+#define TYPE_NPCM7XX_EMC "npcm7xx-emc"
47
+
48
+/* Timeout for various operations, in seconds. */
49
+#define TIMEOUT_SECONDS 10
50
+
51
+/* Address in memory of the descriptor. */
52
+#define DESC_ADDR (1 << 20) /* 1 MiB */
53
+
54
+/* Address in memory of the data packet. */
55
+#define DATA_ADDR (DESC_ADDR + 4096)
56
+
57
+#define CRC_LENGTH 4
58
+
59
+#define NUM_TX_DESCRIPTORS 3
60
+#define NUM_RX_DESCRIPTORS 2
61
+
62
+/* Size of tx,rx test buffers. */
63
+#define TX_DATA_LEN 64
64
+#define RX_DATA_LEN 64
65
+
66
+#define TX_STEP_COUNT 10000
67
+#define RX_STEP_COUNT 10000
68
+
69
+/* 32-bit register indices. */
70
+typedef enum NPCM7xxPWMRegister {
71
+ /* Control registers. */
72
+ REG_CAMCMR,
73
+ REG_CAMEN,
74
+
75
+ /* There are 16 CAMn[ML] registers. */
76
+ REG_CAMM_BASE,
77
+ REG_CAML_BASE,
78
+
79
+ REG_TXDLSA = 0x22,
80
+ REG_RXDLSA,
81
+ REG_MCMDR,
82
+ REG_MIID,
83
+ REG_MIIDA,
84
+ REG_FFTCR,
85
+ REG_TSDR,
86
+ REG_RSDR,
87
+ REG_DMARFC,
88
+ REG_MIEN,
89
+
90
+ /* Status registers. */
91
+ REG_MISTA,
92
+ REG_MGSTA,
93
+ REG_MPCNT,
94
+ REG_MRPC,
95
+ REG_MRPCC,
96
+ REG_MREPC,
97
+ REG_DMARFS,
98
+ REG_CTXDSA,
99
+ REG_CTXBSA,
100
+ REG_CRXDSA,
101
+ REG_CRXBSA,
102
+
103
+ NPCM7XX_NUM_EMC_REGS,
104
+} NPCM7xxPWMRegister;
105
+
106
+enum { NUM_CAMML_REGS = 16 };
107
+
108
+/* REG_CAMCMR fields */
109
+/* Enable CAM Compare */
110
+#define REG_CAMCMR_ECMP (1 << 4)
111
+/* Accept Unicast Packet */
112
+#define REG_CAMCMR_AUP (1 << 0)
113
+
114
+/* REG_MCMDR fields */
115
+/* Software Reset */
116
+#define REG_MCMDR_SWR (1 << 24)
117
+/* Frame Transmission On */
118
+#define REG_MCMDR_TXON (1 << 8)
119
+/* Accept Long Packet */
120
+#define REG_MCMDR_ALP (1 << 1)
121
+/* Frame Reception On */
122
+#define REG_MCMDR_RXON (1 << 0)
123
+
124
+/* REG_MIEN fields */
125
+/* Enable Transmit Completion Interrupt */
126
+#define REG_MIEN_ENTXCP (1 << 18)
127
+/* Enable Transmit Interrupt */
128
+#define REG_MIEN_ENTXINTR (1 << 16)
129
+/* Enable Receive Good Interrupt */
130
+#define REG_MIEN_ENRXGD (1 << 4)
131
+/* ENable Receive Interrupt */
132
+#define REG_MIEN_ENRXINTR (1 << 0)
133
+
134
+/* REG_MISTA fields */
135
+/* Transmit Bus Error Interrupt */
136
+#define REG_MISTA_TXBERR (1 << 24)
137
+/* Transmit Descriptor Unavailable Interrupt */
138
+#define REG_MISTA_TDU (1 << 23)
139
+/* Transmit Completion Interrupt */
140
+#define REG_MISTA_TXCP (1 << 18)
141
+/* Transmit Interrupt */
142
+#define REG_MISTA_TXINTR (1 << 16)
143
+/* Receive Bus Error Interrupt */
144
+#define REG_MISTA_RXBERR (1 << 11)
145
+/* Receive Descriptor Unavailable Interrupt */
146
+#define REG_MISTA_RDU (1 << 10)
147
+/* DMA Early Notification Interrupt */
148
+#define REG_MISTA_DENI (1 << 9)
149
+/* Maximum Frame Length Interrupt */
150
+#define REG_MISTA_DFOI (1 << 8)
151
+/* Receive Good Interrupt */
152
+#define REG_MISTA_RXGD (1 << 4)
153
+/* Packet Too Long Interrupt */
154
+#define REG_MISTA_PTLE (1 << 3)
155
+/* Receive Interrupt */
156
+#define REG_MISTA_RXINTR (1 << 0)
157
+
158
+typedef struct NPCM7xxEMCTxDesc NPCM7xxEMCTxDesc;
159
+typedef struct NPCM7xxEMCRxDesc NPCM7xxEMCRxDesc;
160
+
161
+struct NPCM7xxEMCTxDesc {
162
+ uint32_t flags;
163
+ uint32_t txbsa;
164
+ uint32_t status_and_length;
165
+ uint32_t ntxdsa;
166
+};
167
+
168
+struct NPCM7xxEMCRxDesc {
169
+ uint32_t status_and_length;
170
+ uint32_t rxbsa;
171
+ uint32_t reserved;
172
+ uint32_t nrxdsa;
173
+};
174
+
175
+/* NPCM7xxEMCTxDesc.flags values */
176
+/* Owner: 0 = cpu, 1 = emc */
177
+#define TX_DESC_FLAG_OWNER_MASK (1 << 31)
178
+/* Transmit interrupt enable */
179
+#define TX_DESC_FLAG_INTEN (1 << 2)
180
+
181
+/* NPCM7xxEMCTxDesc.status_and_length values */
182
+/* Transmission complete */
183
+#define TX_DESC_STATUS_TXCP (1 << 19)
184
+/* Transmit interrupt */
185
+#define TX_DESC_STATUS_TXINTR (1 << 16)
186
+
187
+/* NPCM7xxEMCRxDesc.status_and_length values */
188
+/* Owner: 0b00 = cpu, 0b10 = emc */
189
+#define RX_DESC_STATUS_OWNER_SHIFT 30
190
+#define RX_DESC_STATUS_OWNER_MASK 0xc0000000
191
+/* Frame Reception Complete */
192
+#define RX_DESC_STATUS_RXGD (1 << 20)
193
+/* Packet too long */
194
+#define RX_DESC_STATUS_PTLE (1 << 19)
195
+/* Receive Interrupt */
196
+#define RX_DESC_STATUS_RXINTR (1 << 16)
197
+
198
+#define RX_DESC_PKT_LEN(word) ((uint32_t) (word) & 0xffff)
199
+
200
+typedef struct EMCModule {
201
+ int rx_irq;
202
+ int tx_irq;
203
+ uint64_t base_addr;
204
+} EMCModule;
205
+
206
+typedef struct TestData {
207
+ const EMCModule *module;
208
+} TestData;
209
+
210
+static const EMCModule emc_module_list[] = {
211
+ {
212
+ .rx_irq = 15,
213
+ .tx_irq = 16,
214
+ .base_addr = 0xf0825000
215
+ },
216
+ {
217
+ .rx_irq = 114,
218
+ .tx_irq = 115,
219
+ .base_addr = 0xf0826000
220
+ }
221
+};
222
+
223
+/* Returns the index of the EMC module. */
224
+static int emc_module_index(const EMCModule *mod)
225
+{
226
+ ptrdiff_t diff = mod - emc_module_list;
227
+
228
+ g_assert_true(diff >= 0 && diff < ARRAY_SIZE(emc_module_list));
229
+
230
+ return diff;
231
+}
232
+
233
+static void packet_test_clear(void *sockets)
234
+{
235
+ int *test_sockets = sockets;
236
+
237
+ close(test_sockets[0]);
238
+ g_free(test_sockets);
239
+}
240
+
241
+static int *packet_test_init(int module_num, GString *cmd_line)
242
+{
243
+ int *test_sockets = g_new(int, 2);
244
+ int ret = socketpair(PF_UNIX, SOCK_STREAM, 0, test_sockets);
245
+ g_assert_cmpint(ret, != , -1);
246
+
247
+ /*
248
+ * KISS and use -nic. We specify two nics (both emc{0,1}) because there's
249
+ * currently no way to specify only emc1: The driver implicitly relies on
250
+ * emc[i] == nd_table[i].
251
+ */
252
+ if (module_num == 0) {
253
+ g_string_append_printf(cmd_line,
254
+ " -nic socket,fd=%d,model=" TYPE_NPCM7XX_EMC " "
255
+ " -nic user,model=" TYPE_NPCM7XX_EMC " ",
256
+ test_sockets[1]);
257
+ } else {
258
+ g_string_append_printf(cmd_line,
259
+ " -nic user,model=" TYPE_NPCM7XX_EMC " "
260
+ " -nic socket,fd=%d,model=" TYPE_NPCM7XX_EMC " ",
261
+ test_sockets[1]);
262
+ }
263
+
264
+ g_test_queue_destroy(packet_test_clear, test_sockets);
265
+ return test_sockets;
266
+}
267
+
268
+static uint32_t emc_read(QTestState *qts, const EMCModule *mod,
269
+ NPCM7xxPWMRegister regno)
270
+{
271
+ return qtest_readl(qts, mod->base_addr + regno * sizeof(uint32_t));
272
+}
273
+
274
+static void emc_write(QTestState *qts, const EMCModule *mod,
275
+ NPCM7xxPWMRegister regno, uint32_t value)
276
+{
277
+ qtest_writel(qts, mod->base_addr + regno * sizeof(uint32_t), value);
278
+}
279
+
280
+static void emc_read_tx_desc(QTestState *qts, uint32_t addr,
281
+ NPCM7xxEMCTxDesc *desc)
282
+{
283
+ qtest_memread(qts, addr, desc, sizeof(*desc));
284
+ desc->flags = le32_to_cpu(desc->flags);
285
+ desc->txbsa = le32_to_cpu(desc->txbsa);
286
+ desc->status_and_length = le32_to_cpu(desc->status_and_length);
287
+ desc->ntxdsa = le32_to_cpu(desc->ntxdsa);
288
+}
289
+
290
+static void emc_write_tx_desc(QTestState *qts, const NPCM7xxEMCTxDesc *desc,
291
+ uint32_t addr)
292
+{
293
+ NPCM7xxEMCTxDesc le_desc;
294
+
295
+ le_desc.flags = cpu_to_le32(desc->flags);
296
+ le_desc.txbsa = cpu_to_le32(desc->txbsa);
297
+ le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
298
+ le_desc.ntxdsa = cpu_to_le32(desc->ntxdsa);
299
+ qtest_memwrite(qts, addr, &le_desc, sizeof(le_desc));
300
+}
301
+
302
+static void emc_read_rx_desc(QTestState *qts, uint32_t addr,
303
+ NPCM7xxEMCRxDesc *desc)
304
+{
305
+ qtest_memread(qts, addr, desc, sizeof(*desc));
306
+ desc->status_and_length = le32_to_cpu(desc->status_and_length);
307
+ desc->rxbsa = le32_to_cpu(desc->rxbsa);
308
+ desc->reserved = le32_to_cpu(desc->reserved);
309
+ desc->nrxdsa = le32_to_cpu(desc->nrxdsa);
310
+}
311
+
312
+static void emc_write_rx_desc(QTestState *qts, const NPCM7xxEMCRxDesc *desc,
313
+ uint32_t addr)
314
+{
315
+ NPCM7xxEMCRxDesc le_desc;
316
+
317
+ le_desc.status_and_length = cpu_to_le32(desc->status_and_length);
318
+ le_desc.rxbsa = cpu_to_le32(desc->rxbsa);
319
+ le_desc.reserved = cpu_to_le32(desc->reserved);
320
+ le_desc.nrxdsa = cpu_to_le32(desc->nrxdsa);
321
+ qtest_memwrite(qts, addr, &le_desc, sizeof(le_desc));
322
+}
323
+
324
+/*
325
+ * Reset the EMC module.
326
+ * The module must be reset before, e.g., TXDLSA,RXDLSA are changed.
327
+ */
328
+static bool emc_soft_reset(QTestState *qts, const EMCModule *mod)
329
+{
330
+ uint32_t val;
331
+ uint64_t end_time;
332
+
333
+ emc_write(qts, mod, REG_MCMDR, REG_MCMDR_SWR);
334
+
335
+ /*
336
+ * Wait for device to reset as the linux driver does.
337
+ * During reset the AHB reads 0 for all registers. So first wait for
338
+ * something that resets to non-zero, and then wait for SWR becoming 0.
339
+ */
340
+ end_time = g_get_monotonic_time() + TIMEOUT_SECONDS * G_TIME_SPAN_SECOND;
341
+
342
+ do {
343
+ qtest_clock_step(qts, 100);
344
+ val = emc_read(qts, mod, REG_FFTCR);
345
+ } while (val == 0 && g_get_monotonic_time() < end_time);
346
+ if (val != 0) {
347
+ do {
348
+ qtest_clock_step(qts, 100);
349
+ val = emc_read(qts, mod, REG_MCMDR);
350
+ if ((val & REG_MCMDR_SWR) == 0) {
351
+ /*
352
+ * N.B. The CAMs have been reset here, so macaddr matching of
353
+ * incoming packets will not work.
354
+ */
355
+ return true;
356
+ }
357
+ } while (g_get_monotonic_time() < end_time);
358
+ }
359
+
360
+ g_message("%s: Timeout expired", __func__);
361
+ return false;
362
+}
363
+
364
+/* Check emc registers are reset to default value. */
365
+static void test_init(gconstpointer test_data)
366
+{
367
+ const TestData *td = test_data;
368
+ const EMCModule *mod = td->module;
369
+ QTestState *qts = qtest_init("-machine quanta-gsj");
370
+ int i;
371
+
372
+#define CHECK_REG(regno, value) \
373
+ do { \
374
+ g_assert_cmphex(emc_read(qts, mod, (regno)), ==, (value)); \
375
+ } while (0)
376
+
377
+ CHECK_REG(REG_CAMCMR, 0);
378
+ CHECK_REG(REG_CAMEN, 0);
379
+ CHECK_REG(REG_TXDLSA, 0xfffffffc);
380
+ CHECK_REG(REG_RXDLSA, 0xfffffffc);
381
+ CHECK_REG(REG_MCMDR, 0);
382
+ CHECK_REG(REG_MIID, 0);
383
+ CHECK_REG(REG_MIIDA, 0x00900000);
384
+ CHECK_REG(REG_FFTCR, 0x0101);
385
+ CHECK_REG(REG_DMARFC, 0x0800);
386
+ CHECK_REG(REG_MIEN, 0);
387
+ CHECK_REG(REG_MISTA, 0);
388
+ CHECK_REG(REG_MGSTA, 0);
389
+ CHECK_REG(REG_MPCNT, 0x7fff);
390
+ CHECK_REG(REG_MRPC, 0);
391
+ CHECK_REG(REG_MRPCC, 0);
392
+ CHECK_REG(REG_MREPC, 0);
393
+ CHECK_REG(REG_DMARFS, 0);
394
+ CHECK_REG(REG_CTXDSA, 0);
395
+ CHECK_REG(REG_CTXBSA, 0);
396
+ CHECK_REG(REG_CRXDSA, 0);
397
+ CHECK_REG(REG_CRXBSA, 0);
398
+
399
+#undef CHECK_REG
400
+
401
+ for (i = 0; i < NUM_CAMML_REGS; ++i) {
402
+ g_assert_cmpuint(emc_read(qts, mod, REG_CAMM_BASE + i * 2), ==,
403
+ 0);
404
+ g_assert_cmpuint(emc_read(qts, mod, REG_CAML_BASE + i * 2), ==,
405
+ 0);
406
+ }
407
+
408
+ qtest_quit(qts);
409
+}
410
+
411
+static bool emc_wait_irq(QTestState *qts, const EMCModule *mod, int step,
412
+ bool is_tx)
413
+{
414
+ uint64_t end_time =
415
+ g_get_monotonic_time() + TIMEOUT_SECONDS * G_TIME_SPAN_SECOND;
416
+
417
+ do {
418
+ if (qtest_get_irq(qts, is_tx ? mod->tx_irq : mod->rx_irq)) {
419
+ return true;
420
+ }
421
+ qtest_clock_step(qts, step);
422
+ } while (g_get_monotonic_time() < end_time);
423
+
424
+ g_message("%s: Timeout expired", __func__);
425
+ return false;
426
+}
427
+
428
+static bool emc_wait_mista(QTestState *qts, const EMCModule *mod, int step,
429
+ uint32_t flag)
430
+{
431
+ uint64_t end_time =
432
+ g_get_monotonic_time() + TIMEOUT_SECONDS * G_TIME_SPAN_SECOND;
433
+
434
+ do {
435
+ uint32_t mista = emc_read(qts, mod, REG_MISTA);
436
+ if (mista & flag) {
437
+ return true;
438
+ }
439
+ qtest_clock_step(qts, step);
440
+ } while (g_get_monotonic_time() < end_time);
441
+
442
+ g_message("%s: Timeout expired", __func__);
443
+ return false;
444
+}
445
+
446
+static bool wait_socket_readable(int fd)
447
+{
448
+ fd_set read_fds;
449
+ struct timeval tv;
450
+ int rv;
451
+
452
+ FD_ZERO(&read_fds);
453
+ FD_SET(fd, &read_fds);
454
+ tv.tv_sec = TIMEOUT_SECONDS;
455
+ tv.tv_usec = 0;
456
+ rv = select(fd + 1, &read_fds, NULL, NULL, &tv);
457
+ if (rv == -1) {
458
+ perror("select");
459
+ } else if (rv == 0) {
460
+ g_message("%s: Timeout expired", __func__);
461
+ }
462
+ return rv == 1;
463
+}
464
+
465
+/* Initialize *desc (in host endian format). */
466
+static void init_tx_desc(NPCM7xxEMCTxDesc *desc, size_t count,
467
+ uint32_t desc_addr)
468
+{
469
+ g_assert(count >= 2);
470
+ memset(&desc[0], 0, sizeof(*desc) * count);
471
+ /* Leave the last one alone, owned by the cpu -> stops transmission. */
472
+ for (size_t i = 0; i < count - 1; ++i) {
473
+ desc[i].flags =
474
+ (TX_DESC_FLAG_OWNER_MASK | /* owner = 1: emc */
475
+ TX_DESC_FLAG_INTEN |
476
+ 0 | /* crc append = 0 */
477
+ 0 /* padding enable = 0 */);
478
+ desc[i].status_and_length =
479
+ (0 | /* collision count = 0 */
480
+ 0 | /* SQE = 0 */
481
+ 0 | /* PAU = 0 */
482
+ 0 | /* TXHA = 0 */
483
+ 0 | /* LC = 0 */
484
+ 0 | /* TXABT = 0 */
485
+ 0 | /* NCS = 0 */
486
+ 0 | /* EXDEF = 0 */
487
+ 0 | /* TXCP = 0 */
488
+ 0 | /* DEF = 0 */
489
+ 0 | /* TXINTR = 0 */
490
+ 0 /* length filled in later */);
491
+ desc[i].ntxdsa = desc_addr + (i + 1) * sizeof(*desc);
492
+ }
493
+}
494
+
495
+static void enable_tx(QTestState *qts, const EMCModule *mod,
496
+ const NPCM7xxEMCTxDesc *desc, size_t count,
497
+ uint32_t desc_addr, uint32_t mien_flags)
498
+{
499
+ /* Write the descriptors to guest memory. */
500
+ for (size_t i = 0; i < count; ++i) {
501
+ emc_write_tx_desc(qts, desc + i, desc_addr + i * sizeof(*desc));
502
+ }
503
+
504
+ /* Trigger sending the packet. */
505
+ /* The module must be reset before changing TXDLSA. */
506
+ g_assert(emc_soft_reset(qts, mod));
507
+ emc_write(qts, mod, REG_TXDLSA, desc_addr);
508
+ emc_write(qts, mod, REG_CTXDSA, ~0);
509
+ emc_write(qts, mod, REG_MIEN, REG_MIEN_ENTXCP | mien_flags);
510
+ {
511
+ uint32_t mcmdr = emc_read(qts, mod, REG_MCMDR);
512
+ mcmdr |= REG_MCMDR_TXON;
513
+ emc_write(qts, mod, REG_MCMDR, mcmdr);
514
+ }
515
+
516
+ /* Prod the device to send the packet. */
517
+ emc_write(qts, mod, REG_TSDR, 1);
518
+}
519
+
520
+static void emc_send_verify1(QTestState *qts, const EMCModule *mod, int fd,
521
+ bool with_irq, uint32_t desc_addr,
522
+ uint32_t next_desc_addr,
523
+ const char *test_data, int test_size)
524
+{
525
+ NPCM7xxEMCTxDesc result_desc;
526
+ uint32_t expected_mask, expected_value, recv_len;
527
+ int ret;
528
+ char buffer[TX_DATA_LEN];
529
+
530
+ g_assert(wait_socket_readable(fd));
531
+
532
+ /* Read the descriptor back. */
533
+ emc_read_tx_desc(qts, desc_addr, &result_desc);
534
+ /* Descriptor should be owned by cpu now. */
535
+ g_assert((result_desc.flags & TX_DESC_FLAG_OWNER_MASK) == 0);
536
+ /* Test the status bits, ignoring the length field. */
537
+ expected_mask = 0xffff << 16;
538
+ expected_value = TX_DESC_STATUS_TXCP;
539
+ if (with_irq) {
540
+ expected_value |= TX_DESC_STATUS_TXINTR;
541
+ }
542
+ g_assert_cmphex((result_desc.status_and_length & expected_mask), ==,
543
+ expected_value);
544
+
545
+ /* Check data sent to the backend. */
546
+ recv_len = ~0;
547
+ ret = qemu_recv(fd, &recv_len, sizeof(recv_len), MSG_DONTWAIT);
548
+ g_assert_cmpint(ret, == , sizeof(recv_len));
549
+
550
+ g_assert(wait_socket_readable(fd));
551
+ memset(buffer, 0xff, sizeof(buffer));
552
+ ret = qemu_recv(fd, buffer, test_size, MSG_DONTWAIT);
553
+ g_assert_cmpmem(buffer, ret, test_data, test_size);
554
+}
555
+
556
+static void emc_send_verify(QTestState *qts, const EMCModule *mod, int fd,
557
+ bool with_irq)
558
+{
559
+ NPCM7xxEMCTxDesc desc[NUM_TX_DESCRIPTORS];
560
+ uint32_t desc_addr = DESC_ADDR;
561
+ static const char test1_data[] = "TEST1";
562
+ static const char test2_data[] = "Testing 1 2 3 ...";
563
+ uint32_t data1_addr = DATA_ADDR;
564
+ uint32_t data2_addr = data1_addr + sizeof(test1_data);
565
+ bool got_tdu;
566
+ uint32_t end_desc_addr;
567
+
568
+ /* Prepare test data buffer. */
569
+ qtest_memwrite(qts, data1_addr, test1_data, sizeof(test1_data));
570
+ qtest_memwrite(qts, data2_addr, test2_data, sizeof(test2_data));
571
+
572
+ init_tx_desc(&desc[0], NUM_TX_DESCRIPTORS, desc_addr);
573
+ desc[0].txbsa = data1_addr;
574
+ desc[0].status_and_length |= sizeof(test1_data);
575
+ desc[1].txbsa = data2_addr;
576
+ desc[1].status_and_length |= sizeof(test2_data);
577
+
578
+ enable_tx(qts, mod, &desc[0], NUM_TX_DESCRIPTORS, desc_addr,
579
+ with_irq ? REG_MIEN_ENTXINTR : 0);
580
+
581
+ /*
582
+ * It's problematic to observe the interrupt for each packet.
583
+ * Instead just wait until all the packets go out.
584
+ */
585
+ got_tdu = false;
586
+ while (!got_tdu) {
587
+ if (with_irq) {
588
+ g_assert_true(emc_wait_irq(qts, mod, TX_STEP_COUNT,
589
+ /*is_tx=*/true));
590
+ } else {
591
+ g_assert_true(emc_wait_mista(qts, mod, TX_STEP_COUNT,
592
+ REG_MISTA_TXINTR));
593
+ }
594
+ got_tdu = !!(emc_read(qts, mod, REG_MISTA) & REG_MISTA_TDU);
595
+ /* If we don't have TDU yet, reset the interrupt. */
596
+ if (!got_tdu) {
597
+ emc_write(qts, mod, REG_MISTA,
598
+ emc_read(qts, mod, REG_MISTA) & 0xffff0000);
599
+ }
600
+ }
601
+
602
+ end_desc_addr = desc_addr + 2 * sizeof(desc[0]);
603
+ g_assert_cmphex(emc_read(qts, mod, REG_CTXDSA), ==, end_desc_addr);
604
+ g_assert_cmphex(emc_read(qts, mod, REG_MISTA), ==,
605
+ REG_MISTA_TXCP | REG_MISTA_TXINTR | REG_MISTA_TDU);
606
+
607
+ emc_send_verify1(qts, mod, fd, with_irq,
608
+ desc_addr, end_desc_addr,
609
+ test1_data, sizeof(test1_data));
610
+ emc_send_verify1(qts, mod, fd, with_irq,
611
+ desc_addr + sizeof(desc[0]), end_desc_addr,
612
+ test2_data, sizeof(test2_data));
613
+}
614
+
615
+/* Initialize *desc (in host endian format). */
616
+static void init_rx_desc(NPCM7xxEMCRxDesc *desc, size_t count,
617
+ uint32_t desc_addr, uint32_t data_addr)
618
+{
619
+ g_assert_true(count >= 2);
620
+ memset(desc, 0, sizeof(*desc) * count);
621
+ desc[0].rxbsa = data_addr;
622
+ desc[0].status_and_length =
623
+ (0b10 << RX_DESC_STATUS_OWNER_SHIFT | /* owner = 10: emc */
624
+ 0 | /* RP = 0 */
625
+ 0 | /* ALIE = 0 */
626
+ 0 | /* RXGD = 0 */
627
+ 0 | /* PTLE = 0 */
628
+ 0 | /* CRCE = 0 */
629
+ 0 | /* RXINTR = 0 */
630
+ 0 /* length (filled in later) */);
631
+ /* Leave the last one alone, owned by the cpu -> stops transmission. */
632
+ desc[0].nrxdsa = desc_addr + sizeof(*desc);
633
+}
634
+
635
+static void enable_rx(QTestState *qts, const EMCModule *mod,
636
+ const NPCM7xxEMCRxDesc *desc, size_t count,
637
+ uint32_t desc_addr, uint32_t mien_flags,
638
+ uint32_t mcmdr_flags)
639
+{
640
+ /*
641
+ * Write the descriptor to guest memory.
642
+ * FWIW, IWBN if the docs said the buffer needs to be at least DMARFC
643
+ * bytes.
644
+ */
645
+ for (size_t i = 0; i < count; ++i) {
646
+ emc_write_rx_desc(qts, desc + i, desc_addr + i * sizeof(*desc));
647
+ }
648
+
649
+ /* Trigger receiving the packet. */
650
+ /* The module must be reset before changing RXDLSA. */
651
+ g_assert(emc_soft_reset(qts, mod));
652
+ emc_write(qts, mod, REG_RXDLSA, desc_addr);
653
+ emc_write(qts, mod, REG_MIEN, REG_MIEN_ENRXGD | mien_flags);
654
+
655
+ /*
656
+ * We don't know what the device's macaddr is, so just accept all
657
+ * unicast packets (AUP).
658
+ */
659
+ emc_write(qts, mod, REG_CAMCMR, REG_CAMCMR_AUP);
660
+ emc_write(qts, mod, REG_CAMEN, 1 << 0);
661
+ {
662
+ uint32_t mcmdr = emc_read(qts, mod, REG_MCMDR);
663
+ mcmdr |= REG_MCMDR_RXON | mcmdr_flags;
664
+ emc_write(qts, mod, REG_MCMDR, mcmdr);
665
+ }
666
+
667
+ /* Prod the device to accept a packet. */
668
+ emc_write(qts, mod, REG_RSDR, 1);
669
+}
670
+
671
+static void emc_recv_verify(QTestState *qts, const EMCModule *mod, int fd,
672
+ bool with_irq)
673
+{
674
+ NPCM7xxEMCRxDesc desc[NUM_RX_DESCRIPTORS];
675
+ uint32_t desc_addr = DESC_ADDR;
676
+ uint32_t data_addr = DATA_ADDR;
677
+ int ret;
678
+ uint32_t expected_mask, expected_value;
679
+ NPCM7xxEMCRxDesc result_desc;
680
+
681
+ /* Prepare test data buffer. */
682
+ const char test[RX_DATA_LEN] = "TEST";
683
+ int len = htonl(sizeof(test));
684
+ const struct iovec iov[] = {
685
+ {
686
+ .iov_base = &len,
687
+ .iov_len = sizeof(len),
688
+ },{
689
+ .iov_base = (char *) test,
690
+ .iov_len = sizeof(test),
691
+ },
692
+ };
693
+
694
+ /*
695
+ * Reset the device BEFORE sending a test packet, otherwise the packet
696
+ * may get swallowed by an active device of an earlier test.
697
+ */
698
+ init_rx_desc(&desc[0], NUM_RX_DESCRIPTORS, desc_addr, data_addr);
699
+ enable_rx(qts, mod, &desc[0], NUM_RX_DESCRIPTORS, desc_addr,
700
+ with_irq ? REG_MIEN_ENRXINTR : 0, 0);
701
+
702
+ /* Send test packet to device's socket. */
703
+ ret = iov_send(fd, iov, 2, 0, sizeof(len) + sizeof(test));
704
+ g_assert_cmpint(ret, == , sizeof(test) + sizeof(len));
705
+
706
+ /* Wait for RX interrupt. */
707
+ if (with_irq) {
708
+ g_assert_true(emc_wait_irq(qts, mod, RX_STEP_COUNT, /*is_tx=*/false));
709
+ } else {
710
+ g_assert_true(emc_wait_mista(qts, mod, RX_STEP_COUNT, REG_MISTA_RXGD));
711
+ }
712
+
713
+ g_assert_cmphex(emc_read(qts, mod, REG_CRXDSA), ==,
714
+ desc_addr + sizeof(desc[0]));
715
+
716
+ expected_mask = 0xffff;
717
+ expected_value = (REG_MISTA_DENI |
718
+ REG_MISTA_RXGD |
719
+ REG_MISTA_RXINTR);
720
+ g_assert_cmphex((emc_read(qts, mod, REG_MISTA) & expected_mask),
721
+ ==, expected_value);
722
+
723
+ /* Read the descriptor back. */
724
+ emc_read_rx_desc(qts, desc_addr, &result_desc);
725
+ /* Descriptor should be owned by cpu now. */
726
+ g_assert((result_desc.status_and_length & RX_DESC_STATUS_OWNER_MASK) == 0);
727
+ /* Test the status bits, ignoring the length field. */
728
+ expected_mask = 0xffff << 16;
729
+ expected_value = RX_DESC_STATUS_RXGD;
730
+ if (with_irq) {
731
+ expected_value |= RX_DESC_STATUS_RXINTR;
732
+ }
733
+ g_assert_cmphex((result_desc.status_and_length & expected_mask), ==,
734
+ expected_value);
735
+ g_assert_cmpint(RX_DESC_PKT_LEN(result_desc.status_and_length), ==,
736
+ RX_DATA_LEN + CRC_LENGTH);
737
+
738
+ {
739
+ char buffer[RX_DATA_LEN];
740
+ qtest_memread(qts, data_addr, buffer, sizeof(buffer));
741
+ g_assert_cmpstr(buffer, == , "TEST");
742
+ }
743
+}
744
+
745
+static void emc_test_ptle(QTestState *qts, const EMCModule *mod, int fd)
746
+{
747
+ NPCM7xxEMCRxDesc desc[NUM_RX_DESCRIPTORS];
748
+ uint32_t desc_addr = DESC_ADDR;
749
+ uint32_t data_addr = DATA_ADDR;
750
+ int ret;
751
+ NPCM7xxEMCRxDesc result_desc;
752
+ uint32_t expected_mask, expected_value;
753
+
754
+ /* Prepare test data buffer. */
755
+#define PTLE_DATA_LEN 1600
756
+ char test_data[PTLE_DATA_LEN];
757
+ int len = htonl(sizeof(test_data));
758
+ const struct iovec iov[] = {
759
+ {
760
+ .iov_base = &len,
761
+ .iov_len = sizeof(len),
762
+ },{
763
+ .iov_base = (char *) test_data,
764
+ .iov_len = sizeof(test_data),
765
+ },
766
+ };
767
+ memset(test_data, 42, sizeof(test_data));
768
+
769
+ /*
770
+ * Reset the device BEFORE sending a test packet, otherwise the packet
771
+ * may get swallowed by an active device of an earlier test.
772
+ */
773
+ init_rx_desc(&desc[0], NUM_RX_DESCRIPTORS, desc_addr, data_addr);
774
+ enable_rx(qts, mod, &desc[0], NUM_RX_DESCRIPTORS, desc_addr,
775
+ REG_MIEN_ENRXINTR, REG_MCMDR_ALP);
776
+
777
+ /* Send test packet to device's socket. */
778
+ ret = iov_send(fd, iov, 2, 0, sizeof(len) + sizeof(test_data));
779
+ g_assert_cmpint(ret, == , sizeof(test_data) + sizeof(len));
780
+
781
+ /* Wait for RX interrupt. */
782
+ g_assert_true(emc_wait_irq(qts, mod, RX_STEP_COUNT, /*is_tx=*/false));
783
+
784
+ /* Read the descriptor back. */
785
+ emc_read_rx_desc(qts, desc_addr, &result_desc);
786
+ /* Descriptor should be owned by cpu now. */
787
+ g_assert((result_desc.status_and_length & RX_DESC_STATUS_OWNER_MASK) == 0);
788
+ /* Test the status bits, ignoring the length field. */
789
+ expected_mask = 0xffff << 16;
790
+ expected_value = (RX_DESC_STATUS_RXGD |
791
+ RX_DESC_STATUS_PTLE |
792
+ RX_DESC_STATUS_RXINTR);
793
+ g_assert_cmphex((result_desc.status_and_length & expected_mask), ==,
794
+ expected_value);
795
+ g_assert_cmpint(RX_DESC_PKT_LEN(result_desc.status_and_length), ==,
796
+ PTLE_DATA_LEN + CRC_LENGTH);
797
+
798
+ {
799
+ char buffer[PTLE_DATA_LEN];
800
+ qtest_memread(qts, data_addr, buffer, sizeof(buffer));
801
+ g_assert(memcmp(buffer, test_data, PTLE_DATA_LEN) == 0);
802
+ }
803
+}
804
+
805
+static void test_tx(gconstpointer test_data)
806
+{
807
+ const TestData *td = test_data;
808
+ GString *cmd_line = g_string_new("-machine quanta-gsj");
809
+ int *test_sockets = packet_test_init(emc_module_index(td->module),
810
+ cmd_line);
811
+ QTestState *qts = qtest_init(cmd_line->str);
812
+
813
+ /*
814
+ * TODO: For pedantic correctness test_sockets[0] should be closed after
815
+ * the fork and before the exec, but that will require some harness
816
+ * improvements.
817
+ */
818
+ close(test_sockets[1]);
819
+ /* Defensive programming */
820
+ test_sockets[1] = -1;
821
+
822
+ qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
823
+
824
+ emc_send_verify(qts, td->module, test_sockets[0], /*with_irq=*/false);
825
+ emc_send_verify(qts, td->module, test_sockets[0], /*with_irq=*/true);
826
+
827
+ qtest_quit(qts);
828
+}
829
+
830
+static void test_rx(gconstpointer test_data)
831
+{
832
+ const TestData *td = test_data;
833
+ GString *cmd_line = g_string_new("-machine quanta-gsj");
834
+ int *test_sockets = packet_test_init(emc_module_index(td->module),
835
+ cmd_line);
836
+ QTestState *qts = qtest_init(cmd_line->str);
837
+
838
+ /*
839
+ * TODO: For pedantic correctness test_sockets[0] should be closed after
840
+ * the fork and before the exec, but that will require some harness
841
+ * improvements.
842
+ */
843
+ close(test_sockets[1]);
844
+ /* Defensive programming */
845
+ test_sockets[1] = -1;
846
+
847
+ qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
848
+
849
+ emc_recv_verify(qts, td->module, test_sockets[0], /*with_irq=*/false);
850
+ emc_recv_verify(qts, td->module, test_sockets[0], /*with_irq=*/true);
851
+ emc_test_ptle(qts, td->module, test_sockets[0]);
852
+
853
+ qtest_quit(qts);
854
+}
855
+
856
+static void emc_add_test(const char *name, const TestData* td,
857
+ GTestDataFunc fn)
858
+{
859
+ g_autofree char *full_name = g_strdup_printf(
860
+ "npcm7xx_emc/emc[%d]/%s", emc_module_index(td->module), name);
861
+ qtest_add_data_func(full_name, td, fn);
862
+}
863
+#define add_test(name, td) emc_add_test(#name, td, test_##name)
864
+
865
+int main(int argc, char **argv)
866
+{
867
+ TestData test_data_list[ARRAY_SIZE(emc_module_list)];
868
+
869
+ g_test_init(&argc, &argv, NULL);
870
+
871
+ for (int i = 0; i < ARRAY_SIZE(emc_module_list); ++i) {
872
+ TestData *td = &test_data_list[i];
873
+
874
+ td->module = &emc_module_list[i];
875
+
876
+ add_test(init, td);
877
+ add_test(tx, td);
878
+ add_test(rx, td);
879
+ }
880
+
881
+ return g_test_run();
882
+}
883
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
15
index XXXXXXX..XXXXXXX 100644
884
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
885
--- a/tests/qtest/meson.build
17
+++ b/target/arm/translate-a64.c
886
+++ b/tests/qtest/meson.build
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
887
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
19
case 0xf: /* FMAXP */
888
'npcm7xx_rng-test',
20
case 0x2c: /* FMINNMP */
889
'npcm7xx_smbus-test',
21
case 0x2f: /* FMINP */
890
'npcm7xx_timer-test',
22
- /* FP op, size[0] is 32 or 64 bit */
891
- 'npcm7xx_watchdog_timer-test']
23
+ /* FP op, size[0] is 32 or 64 bit*/
892
+ 'npcm7xx_watchdog_timer-test'] + \
24
if (!u) {
893
+ (slirp.found() ? ['npcm7xx_emc-test'] : [])
25
- unallocated_encoding(s);
894
qtests_arm = \
26
- return;
895
(config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
27
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
896
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
28
+ unallocated_encoding(s);
29
+ return;
30
+ } else {
31
+ size = MO_16;
32
+ }
33
+ } else {
34
+ size = extract32(size, 0, 1) ? MO_64 : MO_32;
35
}
36
+
37
if (!fp_access_check(s)) {
38
return;
39
}
40
41
- size = extract32(size, 0, 1) ? 3 : 2;
42
- fpst = get_fpstatus_ptr(false);
43
+ fpst = get_fpstatus_ptr(size == MO_16);
44
break;
45
default:
46
unallocated_encoding(s);
47
return;
48
}
49
50
- if (size == 3) {
51
+ if (size == MO_64) {
52
TCGv_i64 tcg_op1 = tcg_temp_new_i64();
53
TCGv_i64 tcg_op2 = tcg_temp_new_i64();
54
TCGv_i64 tcg_res = tcg_temp_new_i64();
55
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_pairwise(DisasContext *s, uint32_t insn)
56
TCGv_i32 tcg_op2 = tcg_temp_new_i32();
57
TCGv_i32 tcg_res = tcg_temp_new_i32();
58
59
- read_vec_element_i32(s, tcg_op1, rn, 0, MO_32);
60
- read_vec_element_i32(s, tcg_op2, rn, 1, MO_32);
61
+ read_vec_element_i32(s, tcg_op1, rn, 0, size);
62
+ read_vec_element_i32(s, tcg_op2, rn, 1, size);
63
64
- switch (opcode) {
65
- case 0xc: /* FMAXNMP */
66
- gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst);
67
- break;
68
- case 0xd: /* FADDP */
69
- gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst);
70
- break;
71
- case 0xf: /* FMAXP */
72
- gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst);
73
- break;
74
- case 0x2c: /* FMINNMP */
75
- gen_helper_vfp_minnums(tcg_res, tcg_op1, tcg_op2, fpst);
76
- break;
77
- case 0x2f: /* FMINP */
78
- gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst);
79
- break;
80
- default:
81
- g_assert_not_reached();
82
+ if (size == MO_16) {
83
+ switch (opcode) {
84
+ case 0xc: /* FMAXNMP */
85
+ gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
86
+ break;
87
+ case 0xd: /* FADDP */
88
+ gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
89
+ break;
90
+ case 0xf: /* FMAXP */
91
+ gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
92
+ break;
93
+ case 0x2c: /* FMINNMP */
94
+ gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
95
+ break;
96
+ case 0x2f: /* FMINP */
97
+ gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
98
+ break;
99
+ default:
100
+ g_assert_not_reached();
101
+ }
102
+ } else {
103
+ switch (opcode) {
104
+ case 0xc: /* FMAXNMP */
105
+ gen_helper_vfp_maxnums(tcg_res, tcg_op1, tcg_op2, fpst);
106
+ break;
107
+ case 0xd: /* FADDP */
108
+ gen_helper_vfp_adds(tcg_res, tcg_op1, tcg_op2, fpst);
109
+ break;
110
+ case 0xf: /* FMAXP */
111
+ gen_helper_vfp_maxs(tcg_res, tcg_op1, tcg_op2, fpst);
112
+ break;
113
+ case 0x2c: /* FMINNMP */
114
+ gen_helper_vfp_minnums(tcg_res, tcg_op1, tcg_op2, fpst);
115
+ break;
116
+ case 0x2f: /* FMINP */
117
+ gen_helper_vfp_mins(tcg_res, tcg_op1, tcg_op2, fpst);
118
+ break;
119
+ default:
120
+ g_assert_not_reached();
121
+ }
122
}
123
124
write_fp_sreg(s, rd, tcg_res);
125
--
897
--
126
2.16.2
898
2.20.1
127
899
128
900
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Only one half-precision instruction has been added to this group.
3
We hint the 'has_rpu' property is no longer required since commit
4
6908ec448b4 ("xlnx-zynqmp: Properly support the smp command line
5
option") which was released in QEMU v2.11.0.
4
6
5
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Beside, this device is marked 'user_creatable = false', so the
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
only thing that could be setting the property is the board code
7
Message-id: 20180227143852.11175-29-alex.bennee@linaro.org
9
that creates the device.
10
11
Since the property is not user-facing, we can remove it without
12
going through the deprecation process.
13
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20210219144350.1979905-1-f4bug@amsat.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
18
---
10
target/arm/translate-a64.c | 35 +++++++++++++++++++++++++----------
19
include/hw/arm/xlnx-zynqmp.h | 2 --
11
1 file changed, 25 insertions(+), 10 deletions(-)
20
hw/arm/xlnx-zynqmp.c | 6 ------
21
2 files changed, 8 deletions(-)
12
22
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
23
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
14
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
25
--- a/include/hw/arm/xlnx-zynqmp.h
16
+++ b/target/arm/translate-a64.c
26
+++ b/include/hw/arm/xlnx-zynqmp.h
17
@@ -XXX,XX +XXX,XX @@ static void disas_simd_copy(DisasContext *s, uint32_t insn)
27
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
18
* MVNI - move inverted (shifted) imm into register
28
bool secure;
19
* ORR - bitwise OR of (shifted) imm with register
29
/* Has the ARM Virtualization extensions? */
20
* BIC - bitwise clear of (shifted) imm with register
30
bool virt;
21
+ * With ARMv8.2 we also have:
31
- /* Has the RPU subsystem? */
22
+ * FMOV half-precision
32
- bool has_rpu;
23
*/
33
24
static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
34
/* CAN bus. */
25
{
35
CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
26
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
36
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
27
uint64_t imm = 0;
37
index XXXXXXX..XXXXXXX 100644
28
38
--- a/hw/arm/xlnx-zynqmp.c
29
if (o2 != 0 || ((cmode == 0xf) && is_neg && !is_q)) {
39
+++ b/hw/arm/xlnx-zynqmp.c
30
- unallocated_encoding(s);
40
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
31
- return;
41
}
32
+ /* Check for FMOV (vector, immediate) - half-precision */
33
+ if (!(arm_dc_feature(s, ARM_FEATURE_V8_FP16) && o2 && cmode == 0xf)) {
34
+ unallocated_encoding(s);
35
+ return;
36
+ }
37
}
42
}
38
43
39
if (!fp_access_check(s)) {
44
- if (s->has_rpu) {
40
@@ -XXX,XX +XXX,XX @@ static void disas_simd_mod_imm(DisasContext *s, uint32_t insn)
45
- info_report("The 'has_rpu' property is no longer required, to use the "
41
imm |= 0x4000000000000000ULL;
46
- "RPUs just use -smp 6.");
42
}
47
- }
43
} else {
48
-
44
- imm = (abcdefgh & 0x3f) << 19;
49
xlnx_zynqmp_create_rpu(ms, s, boot_cpu, &err);
45
- if (abcdefgh & 0x80) {
50
if (err) {
46
- imm |= 0x80000000;
51
error_propagate(errp, err);
47
- }
52
@@ -XXX,XX +XXX,XX @@ static Property xlnx_zynqmp_props[] = {
48
- if (abcdefgh & 0x40) {
53
DEFINE_PROP_STRING("boot-cpu", XlnxZynqMPState, boot_cpu),
49
- imm |= 0x3e000000;
54
DEFINE_PROP_BOOL("secure", XlnxZynqMPState, secure, false),
50
+ if (o2) {
55
DEFINE_PROP_BOOL("virtualization", XlnxZynqMPState, virt, false),
51
+ /* FMOV (vector, immediate) - half-precision */
56
- DEFINE_PROP_BOOL("has_rpu", XlnxZynqMPState, has_rpu, false),
52
+ imm = vfp_expand_imm(MO_16, abcdefgh);
57
DEFINE_PROP_LINK("ddr-ram", XlnxZynqMPState, ddr_ram, TYPE_MEMORY_REGION,
53
+ /* now duplicate across the lanes */
58
MemoryRegion *),
54
+ imm = bitfield_replicate(imm, 16);
59
DEFINE_PROP_LINK("canbus0", XlnxZynqMPState, canbus[0], TYPE_CAN_BUS,
55
} else {
56
- imm |= 0x40000000;
57
+ imm = (abcdefgh & 0x3f) << 19;
58
+ if (abcdefgh & 0x80) {
59
+ imm |= 0x80000000;
60
+ }
61
+ if (abcdefgh & 0x40) {
62
+ imm |= 0x3e000000;
63
+ } else {
64
+ imm |= 0x40000000;
65
+ }
66
+ imm |= (imm << 32);
67
}
68
- imm |= (imm << 32);
69
}
70
}
71
break;
72
+ default:
73
+ fprintf(stderr, "%s: cmode_3_1: %x\n", __func__, cmode_3_1);
74
+ g_assert_not_reached();
75
}
76
77
if (cmode_3_1 != 7 && is_neg) {
78
--
60
--
79
2.16.2
61
2.20.1
80
62
81
63
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This adds the full range of half-precision floating point to integral
3
Always perform one call instead of two for 16-byte operands.
4
instructions.
4
Use byte loads/stores directly into the vector register file
5
5
instead of extractions and deposits to a 64-bit local variable.
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
In order to easily receive pointers into the vector register file,
8
Message-id: 20180227143852.11175-18-alex.bennee@linaro.org
8
convert the helper to the gvec out-of-line signature. Move the
9
helper into vec_helper.c, where it can make use of H1 and clear_tail.
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Tested-by: Alex Bennée <alex.bennee@linaro.org>
14
Message-id: 20210224230532.276878-1-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
16
---
11
target/arm/helper-a64.h | 2 +
17
target/arm/helper-a64.h | 2 +-
12
target/arm/helper-a64.c | 22 ++++++++
18
target/arm/helper-a64.c | 32 ---------------------
13
target/arm/translate-a64.c | 123 +++++++++++++++++++++++++++++++++++++++++++--
19
target/arm/translate-a64.c | 58 +++++---------------------------------
14
3 files changed, 142 insertions(+), 5 deletions(-)
20
target/arm/vec_helper.c | 48 +++++++++++++++++++++++++++++++
21
4 files changed, 56 insertions(+), 84 deletions(-)
15
22
16
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
23
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
17
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-a64.h
25
--- a/target/arm/helper-a64.h
19
+++ b/target/arm/helper-a64.h
26
+++ b/target/arm/helper-a64.h
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(advsimd_maxnum2h, i32, i32, i32, ptr)
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
21
DEF_HELPER_3(advsimd_minnum2h, i32, i32, i32, ptr)
28
DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr)
22
DEF_HELPER_3(advsimd_mulx2h, i32, i32, i32, ptr)
29
DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr)
23
DEF_HELPER_4(advsimd_muladd2h, i32, i32, i32, i32, ptr)
30
DEF_HELPER_3(vfp_cmped_a64, i64, f64, f64, ptr)
24
+DEF_HELPER_2(advsimd_rinth_exact, f16, f16, ptr)
31
-DEF_HELPER_FLAGS_5(simd_tbl, TCG_CALL_NO_RWG_SE, i64, env, i64, i64, i32, i32)
25
+DEF_HELPER_2(advsimd_rinth, f16, f16, ptr)
32
+DEF_HELPER_FLAGS_4(simd_tblx, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
DEF_HELPER_FLAGS_3(vfp_mulxs, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
34
DEF_HELPER_FLAGS_3(vfp_mulxd, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
35
DEF_HELPER_FLAGS_3(neon_ceq_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
26
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
36
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
27
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/helper-a64.c
38
--- a/target/arm/helper-a64.c
29
+++ b/target/arm/helper-a64.c
39
+++ b/target/arm/helper-a64.c
30
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
40
@@ -XXX,XX +XXX,XX @@ float64 HELPER(vfp_mulxd)(float64 a, float64 b, void *fpstp)
31
int compare = float16_compare(f0, f1, fpst);
41
return float64_mul(a, b, fpst);
32
return ADVSIMD_CMPRES(compare == float_relation_greater);
33
}
42
}
34
+
43
35
+/* round to integral */
44
-uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices,
36
+float16 HELPER(advsimd_rinth_exact)(float16 x, void *fp_status)
45
- uint32_t rn, uint32_t numregs)
37
+{
46
-{
38
+ return float16_round_to_int(x, fp_status);
47
- /* Helper function for SIMD TBL and TBX. We have to do the table
39
+}
48
- * lookup part for the 64 bits worth of indices we're passed in.
40
+
49
- * result is the initial results vector (either zeroes for TBL
41
+float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
50
- * or some guest values for TBX), rn the register number where
42
+{
51
- * the table starts, and numregs the number of registers in the table.
43
+ int old_flags = get_float_exception_flags(fp_status), new_flags;
52
- * We return the results of the lookups.
44
+ float16 ret;
53
- */
45
+
54
- int shift;
46
+ ret = float16_round_to_int(x, fp_status);
55
-
47
+
56
- for (shift = 0; shift < 64; shift += 8) {
48
+ /* Suppress any inexact exceptions the conversion produced */
57
- int index = extract64(indices, shift, 8);
49
+ if (!(old_flags & float_flag_inexact)) {
58
- if (index < 16 * numregs) {
50
+ new_flags = get_float_exception_flags(fp_status);
59
- /* Convert index (a byte offset into the virtual table
51
+ set_float_exception_flags(new_flags & ~float_flag_inexact, fp_status);
60
- * which is a series of 128-bit vectors concatenated)
52
+ }
61
- * into the correct register element plus a bit offset
53
+
62
- * into that element, bearing in mind that the table
54
+ return ret;
63
- * can wrap around from V31 to V0.
55
+}
64
- */
65
- int elt = (rn * 2 + (index >> 3)) % 64;
66
- int bitidx = (index & 7) * 8;
67
- uint64_t *q = aa64_vfp_qreg(env, elt >> 1);
68
- uint64_t val = extract64(q[elt & 1], bitidx, 8);
69
-
70
- result = deposit64(result, shift, 8, val);
71
- }
72
- }
73
- return result;
74
-}
75
-
76
/* 64bit/double versions of the neon float compare functions */
77
uint64_t HELPER(neon_ceq_f64)(float64 a, float64 b, void *fpstp)
78
{
56
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
79
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
57
index XXXXXXX..XXXXXXX 100644
80
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-a64.c
81
--- a/target/arm/translate-a64.c
59
+++ b/target/arm/translate-a64.c
82
+++ b/target/arm/translate-a64.c
60
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
83
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
61
*/
84
int rm = extract32(insn, 16, 5);
62
static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
85
int rn = extract32(insn, 5, 5);
63
{
86
int rd = extract32(insn, 0, 5);
64
- int fpop, opcode, a;
87
- int is_tblx = extract32(insn, 12, 1);
65
+ int fpop, opcode, a, u;
88
- int len = extract32(insn, 13, 2);
66
+ int rn, rd;
89
- TCGv_i64 tcg_resl, tcg_resh, tcg_idx;
67
+ bool is_q;
90
- TCGv_i32 tcg_regno, tcg_numregs;
68
+ bool is_scalar;
91
+ int is_tbx = extract32(insn, 12, 1);
69
+ bool only_in_vector = false;
92
+ int len = (extract32(insn, 13, 2) + 1) * 16;
70
+
93
71
+ int pass;
94
if (op2 != 0) {
72
+ TCGv_i32 tcg_rmode = NULL;
73
+ TCGv_ptr tcg_fpstatus = NULL;
74
+ bool need_rmode = false;
75
+ int rmode;
76
77
if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
78
unallocated_encoding(s);
95
unallocated_encoding(s);
96
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
79
return;
97
return;
80
}
98
}
81
99
82
- if (!fp_access_check(s)) {
100
- /* This does a table lookup: for every byte element in the input
83
- return;
101
- * we index into a table formed from up to four vector registers,
84
- }
102
- * and then the output is the result of the lookups. Our helper
85
+ rd = extract32(insn, 0, 5);
103
- * function does the lookup operation for a single 64 bit part of
86
+ rn = extract32(insn, 5, 5);
104
- * the input.
87
105
- */
88
- opcode = extract32(insn, 12, 4);
106
- tcg_resl = tcg_temp_new_i64();
89
a = extract32(insn, 23, 1);
107
- tcg_resh = NULL;
90
+ u = extract32(insn, 29, 1);
108
-
91
+ is_scalar = extract32(insn, 28, 1);
109
- if (is_tblx) {
92
+ is_q = extract32(insn, 30, 1);
110
- read_vec_element(s, tcg_resl, rd, 0, MO_64);
93
+
111
- } else {
94
+ opcode = extract32(insn, 12, 5);
112
- tcg_gen_movi_i64(tcg_resl, 0);
95
fpop = deposit32(opcode, 5, 1, a);
113
- }
96
+ fpop = deposit32(fpop, 6, 1, u);
114
-
97
115
- if (is_q) {
98
switch (fpop) {
116
- tcg_resh = tcg_temp_new_i64();
99
+ case 0x18: /* FRINTN */
117
- if (is_tblx) {
100
+ need_rmode = true;
118
- read_vec_element(s, tcg_resh, rd, 1, MO_64);
101
+ only_in_vector = true;
119
- } else {
102
+ rmode = FPROUNDING_TIEEVEN;
120
- tcg_gen_movi_i64(tcg_resh, 0);
103
+ break;
121
- }
104
+ case 0x19: /* FRINTM */
122
- }
105
+ need_rmode = true;
123
-
106
+ only_in_vector = true;
124
- tcg_idx = tcg_temp_new_i64();
107
+ rmode = FPROUNDING_NEGINF;
125
- tcg_regno = tcg_const_i32(rn);
108
+ break;
126
- tcg_numregs = tcg_const_i32(len + 1);
109
+ case 0x38: /* FRINTP */
127
- read_vec_element(s, tcg_idx, rm, 0, MO_64);
110
+ need_rmode = true;
128
- gen_helper_simd_tbl(tcg_resl, cpu_env, tcg_resl, tcg_idx,
111
+ only_in_vector = true;
129
- tcg_regno, tcg_numregs);
112
+ rmode = FPROUNDING_POSINF;
130
- if (is_q) {
113
+ break;
131
- read_vec_element(s, tcg_idx, rm, 1, MO_64);
114
+ case 0x39: /* FRINTZ */
132
- gen_helper_simd_tbl(tcg_resh, cpu_env, tcg_resh, tcg_idx,
115
+ need_rmode = true;
133
- tcg_regno, tcg_numregs);
116
+ only_in_vector = true;
134
- }
117
+ rmode = FPROUNDING_ZERO;
135
- tcg_temp_free_i64(tcg_idx);
118
+ break;
136
- tcg_temp_free_i32(tcg_regno);
119
+ case 0x58: /* FRINTA */
137
- tcg_temp_free_i32(tcg_numregs);
120
+ need_rmode = true;
138
-
121
+ only_in_vector = true;
139
- write_vec_element(s, tcg_resl, rd, 0, MO_64);
122
+ rmode = FPROUNDING_TIEAWAY;
140
- tcg_temp_free_i64(tcg_resl);
123
+ break;
141
-
124
+ case 0x59: /* FRINTX */
142
- if (is_q) {
125
+ case 0x79: /* FRINTI */
143
- write_vec_element(s, tcg_resh, rd, 1, MO_64);
126
+ only_in_vector = true;
144
- tcg_temp_free_i64(tcg_resh);
127
+ /* current rounding mode */
145
- }
128
+ break;
146
- clear_vec_high(s, is_q, rd);
129
default:
147
+ tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd),
130
fprintf(stderr, "%s: insn %#04x fpop %#2x\n", __func__, insn, fpop);
148
+ vec_full_reg_offset(s, rm), cpu_env,
131
g_assert_not_reached();
149
+ is_q ? 16 : 8, vec_full_reg_size(s),
132
}
150
+ (len << 6) | (is_tbx << 5) | rn,
133
151
+ gen_helper_simd_tblx);
134
+
152
}
135
+ /* Check additional constraints for the scalar encoding */
153
136
+ if (is_scalar) {
154
/* ZIP/UZP/TRN
137
+ if (!is_q) {
155
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
138
+ unallocated_encoding(s);
156
index XXXXXXX..XXXXXXX 100644
139
+ return;
157
--- a/target/arm/vec_helper.c
140
+ }
158
+++ b/target/arm/vec_helper.c
141
+ /* FRINTxx is only in the vector form */
159
@@ -XXX,XX +XXX,XX @@ DO_VRINT_RMODE(gvec_vrint_rm_h, helper_rinth, uint16_t)
142
+ if (only_in_vector) {
160
DO_VRINT_RMODE(gvec_vrint_rm_s, helper_rints, uint32_t)
143
+ unallocated_encoding(s);
161
144
+ return;
162
#undef DO_VRINT_RMODE
163
+
164
+#ifdef TARGET_AARCH64
165
+void HELPER(simd_tblx)(void *vd, void *vm, void *venv, uint32_t desc)
166
+{
167
+ const uint8_t *indices = vm;
168
+ CPUARMState *env = venv;
169
+ size_t oprsz = simd_oprsz(desc);
170
+ uint32_t rn = extract32(desc, SIMD_DATA_SHIFT, 5);
171
+ bool is_tbx = extract32(desc, SIMD_DATA_SHIFT + 5, 1);
172
+ uint32_t table_len = desc >> (SIMD_DATA_SHIFT + 6);
173
+ union {
174
+ uint8_t b[16];
175
+ uint64_t d[2];
176
+ } result;
177
+
178
+ /*
179
+ * We must construct the final result in a temp, lest the output
180
+ * overlaps the input table. For TBL, begin with zero; for TBX,
181
+ * begin with the original register contents. Note that we always
182
+ * copy 16 bytes here to avoid an extra branch; clearing the high
183
+ * bits of the register for oprsz == 8 is handled below.
184
+ */
185
+ if (is_tbx) {
186
+ memcpy(&result, vd, 16);
187
+ } else {
188
+ memset(&result, 0, 16);
189
+ }
190
+
191
+ for (size_t i = 0; i < oprsz; ++i) {
192
+ uint32_t index = indices[H1(i)];
193
+
194
+ if (index < table_len) {
195
+ /*
196
+ * Convert index (a byte offset into the virtual table
197
+ * which is a series of 128-bit vectors concatenated)
198
+ * into the correct register element, bearing in mind
199
+ * that the table can wrap around from V31 to V0.
200
+ */
201
+ const uint8_t *table = (const uint8_t *)
202
+ aa64_vfp_qreg(env, (rn + (index >> 4)) % 32);
203
+ result.b[H1(i)] = table[H1(index % 16)];
145
+ }
204
+ }
146
+ }
205
+ }
147
+
206
+
148
+ if (!fp_access_check(s)) {
207
+ memcpy(vd, &result, 16);
149
+ return;
208
+ clear_tail(vd, oprsz, simd_maxsz(desc));
150
+ }
209
+}
151
+
210
+#endif
152
+ if (need_rmode) {
153
+ tcg_fpstatus = get_fpstatus_ptr(true);
154
+ }
155
+
156
+ if (need_rmode) {
157
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
158
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
159
+ }
160
+
161
+ if (is_scalar) {
162
+ /* no operations yet */
163
+ } else {
164
+ for (pass = 0; pass < (is_q ? 8 : 4); pass++) {
165
+ TCGv_i32 tcg_op = tcg_temp_new_i32();
166
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
167
+
168
+ read_vec_element_i32(s, tcg_op, rn, pass, MO_16);
169
+
170
+ switch (fpop) {
171
+ case 0x18: /* FRINTN */
172
+ case 0x19: /* FRINTM */
173
+ case 0x38: /* FRINTP */
174
+ case 0x39: /* FRINTZ */
175
+ case 0x58: /* FRINTA */
176
+ case 0x79: /* FRINTI */
177
+ gen_helper_advsimd_rinth(tcg_res, tcg_op, tcg_fpstatus);
178
+ break;
179
+ case 0x59: /* FRINTX */
180
+ gen_helper_advsimd_rinth_exact(tcg_res, tcg_op, tcg_fpstatus);
181
+ break;
182
+ default:
183
+ g_assert_not_reached();
184
+ }
185
+
186
+ write_vec_element_i32(s, tcg_res, rd, pass, MO_16);
187
+
188
+ tcg_temp_free_i32(tcg_res);
189
+ tcg_temp_free_i32(tcg_op);
190
+ }
191
+
192
+ clear_vec_high(s, is_q, rd);
193
+ }
194
+
195
+ if (tcg_rmode) {
196
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
197
+ tcg_temp_free_i32(tcg_rmode);
198
+ }
199
+
200
+ if (tcg_fpstatus) {
201
+ tcg_temp_free_ptr(tcg_fpstatus);
202
+ }
203
}
204
205
/* AdvSIMD scalar x indexed element
206
--
211
--
207
2.16.2
212
2.20.1
208
213
209
214
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Now we have added f16 during the re-factoring we can simply call the
3
The STATUS register will be reset to IDLE in
4
helper.
4
cnpcm7xx_smbus_enter_reset(), no need to preset
5
it in instance_init().
5
6
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
Message-id: 20180227143852.11175-24-alex.bennee@linaro.org
9
Message-id: 20210228224813.312532-1-f4bug@amsat.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
target/arm/translate-a64.c | 8 ++++++++
12
hw/i2c/npcm7xx_smbus.c | 1 -
12
1 file changed, 8 insertions(+)
13
1 file changed, 1 deletion(-)
13
14
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
--- a/hw/i2c/npcm7xx_smbus.c
17
+++ b/target/arm/translate-a64.c
18
+++ b/hw/i2c/npcm7xx_smbus.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_init(Object *obj)
19
case 0x6d: /* FCMLE (zero) */
20
sysbus_init_mmio(sbd, &s->iomem);
20
handle_2misc_fcmp_zero(s, fpop, is_scalar, 0, is_q, MO_16, rn, rd);
21
21
return;
22
s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
22
+ case 0x3d: /* FRECPE */
23
- s->status = NPCM7XX_SMBUS_STATUS_IDLE;
23
+ break;
24
}
24
case 0x18: /* FRINTN */
25
25
need_rmode = true;
26
static const VMStateDescription vmstate_npcm7xx_smbus = {
26
only_in_vector = true;
27
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
28
case 0x3b: /* FCVTZS */
29
gen_helper_advsimd_f16tosinth(tcg_res, tcg_op, tcg_fpstatus);
30
break;
31
+ case 0x3d: /* FRECPE */
32
+ gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus);
33
+ break;
34
case 0x5a: /* FCVTNU */
35
case 0x5b: /* FCVTMU */
36
case 0x5c: /* FCVTAU */
37
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
38
case 0x3b: /* FCVTZS */
39
gen_helper_advsimd_f16tosinth(tcg_res, tcg_op, tcg_fpstatus);
40
break;
41
+ case 0x3d: /* FRECPE */
42
+ gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus);
43
+ break;
44
case 0x5a: /* FCVTNU */
45
case 0x5b: /* FCVTMU */
46
case 0x5c: /* FCVTAU */
47
--
27
--
48
2.16.2
28
2.20.1
49
29
50
30
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: schspa <schspa@gmail.com>
2
2
3
Neither of these operations alter the floating point status registers
3
At the moment the following QEMU command line triggers an assertion
4
so we can do a pure bitwise operation, either squashing any sign
4
failure On xlnx-versal SOC:
5
bit (ABS) or inverting it (NEG).
5
qemu-system-aarch64 \
6
-machine xlnx-versal-virt -nographic -smp 2 -m 128 \
7
-fsdev local,id=shareid,path=${HOME}/work,security_model=none \
8
-device virtio-9p-device,fsdev=shareid,mount_tag=share \
9
-fsdev local,id=shareid1,path=${HOME}/Music,security_model=none \
10
-device virtio-9p-device,fsdev=shareid1,mount_tag=share1
6
11
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
12
qemu-system-aarch64: ../migration/savevm.c:860:
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
vmstate_register_with_alias_id:
9
Message-id: 20180227143852.11175-22-alex.bennee@linaro.org
14
Assertion `!se->compat || se->instance_id == 0' failed.
15
16
This problem was fixed on arm virt platform in commit f58b39d2d5b
17
("virtio-mmio: format transport base address in BusClass.get_dev_path")
18
19
It works perfectly on arm virt platform. but there is still there on
20
xlnx-versal SOC.
21
22
The main difference between arm virt and xlnx-versal is they use
23
different way to create virtio-mmio qdev. on arm virt, it calls
24
sysbus_create_simple("virtio-mmio", base, pic[irq]); which will call
25
sysbus_mmio_map internally and assign base address to subsys device
26
mmio correctly. but xlnx-versal's implements won't do this.
27
28
However, xlnx-versal can't switch to sysbus_create_simple() to create
29
virtio-mmio device. It's because xlnx-versal's cpu use
30
VersalVirt.soc.fpd.apu.mr as it's memory. which is subregion of
31
system_memory. sysbus_create_simple will add virtio to system_memory,
32
which can't be accessed by cpu.
33
34
Besides, xlnx-versal can't add sysbus_mmio_map api call too, because
35
this will add memory region to system_memory, and it can't be added
36
to VersalVirt.soc.fpd.apu.mr again.
37
38
We can solve this by assign correct base address offset on dev_path.
39
40
This path was test on aarch64 virt & xlnx-versal platform.
41
42
Signed-off-by: schspa <schspa@gmail.com>
43
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
45
---
12
target/arm/translate-a64.c | 16 +++++++++++++++-
46
hw/virtio/virtio-mmio.c | 13 +++++++------
13
1 file changed, 15 insertions(+), 1 deletion(-)
47
1 file changed, 7 insertions(+), 6 deletions(-)
14
48
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
49
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
16
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
51
--- a/hw/virtio/virtio-mmio.c
18
+++ b/target/arm/translate-a64.c
52
+++ b/hw/virtio/virtio-mmio.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
53
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
20
TCGv_i32 tcg_rmode = NULL;
54
BusState *virtio_mmio_bus;
21
TCGv_ptr tcg_fpstatus = NULL;
55
VirtIOMMIOProxy *virtio_mmio_proxy;
22
bool need_rmode = false;
56
char *proxy_path;
23
+ bool need_fpst = true;
57
- SysBusDevice *proxy_sbd;
24
int rmode;
58
char *path;
25
59
+ MemoryRegionSection section;
26
if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
60
27
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
61
virtio_mmio_bus = qdev_get_parent_bus(dev);
28
need_rmode = true;
62
virtio_mmio_proxy = VIRTIO_MMIO(virtio_mmio_bus->parent);
29
rmode = FPROUNDING_ZERO;
63
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
30
break;
31
+ case 0x2f: /* FABS */
32
+ case 0x6f: /* FNEG */
33
+ need_fpst = false;
34
+ break;
35
default:
36
fprintf(stderr, "%s: insn %#04x fpop %#2x\n", __func__, insn, fpop);
37
g_assert_not_reached();
38
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
39
return;
40
}
64
}
41
65
42
- if (need_rmode) {
66
/* Otherwise, we append the base address of the transport. */
43
+ if (need_rmode || need_fpst) {
67
- proxy_sbd = SYS_BUS_DEVICE(virtio_mmio_proxy);
44
tcg_fpstatus = get_fpstatus_ptr(true);
68
- assert(proxy_sbd->num_mmio == 1);
69
- assert(proxy_sbd->mmio[0].memory == &virtio_mmio_proxy->iomem);
70
+ section = memory_region_find(&virtio_mmio_proxy->iomem, 0, 0x200);
71
+ assert(section.mr);
72
73
if (proxy_path) {
74
path = g_strdup_printf("%s/virtio-mmio@" TARGET_FMT_plx, proxy_path,
75
- proxy_sbd->mmio[0].addr);
76
+ section.offset_within_address_space);
77
} else {
78
path = g_strdup_printf("virtio-mmio@" TARGET_FMT_plx,
79
- proxy_sbd->mmio[0].addr);
80
+ section.offset_within_address_space);
45
}
81
}
46
82
+ memory_region_unref(section.mr);
47
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
83
+
48
case 0x7b: /* FCVTZU */
84
g_free(proxy_path);
49
gen_helper_advsimd_f16touinth(tcg_res, tcg_op, tcg_fpstatus);
85
return path;
50
break;
86
}
51
+ case 0x6f: /* FNEG */
52
+ tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
53
+ break;
54
default:
55
g_assert_not_reached();
56
}
57
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
58
case 0x59: /* FRINTX */
59
gen_helper_advsimd_rinth_exact(tcg_res, tcg_op, tcg_fpstatus);
60
break;
61
+ case 0x2f: /* FABS */
62
+ tcg_gen_andi_i32(tcg_res, tcg_op, 0x7fff);
63
+ break;
64
+ case 0x6f: /* FNEG */
65
+ tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
66
+ break;
67
default:
68
g_assert_not_reached();
69
}
70
--
87
--
71
2.16.2
88
2.20.1
72
89
73
90
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Peter Collingbourne <pcc@google.com>
2
2
3
I've re-factored the handle_simd_intfp_conv helper to properly handle
3
Section D6.7 of the ARM ARM states:
4
half-precision as well as call plain conversion helpers when we are
5
not doing fixed point conversion.
6
4
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
5
For the purpose of determining Tag Check Fault handling, unprivileged
6
load and store instructions are treated as if executed at EL0 when
7
executed at either:
8
- EL1, when the Effective value of PSTATE.UAO is 0.
9
- EL2, when both the Effective value of HCR_EL2.{E2H, TGE} is {1, 1}
10
and the Effective value of PSTATE.UAO is 0.
11
12
ARM has confirmed a defect in the pseudocode function
13
AArch64.TagCheckFault that makes it inconsistent with the above
14
wording. The remedy is to adjust references to PSTATE.EL in that
15
function to instead refer to AArch64.AccessUsesEL(acctype), so
16
that unprivileged instructions use SCTLR_EL1.TCF0 and TFSRE0_EL1.
17
The exception type for synchronous tag check faults remains unchanged.
18
19
This patch implements the described change by partially reverting
20
commits 50244cc76abc and cc97b0019bb5.
21
22
Signed-off-by: Peter Collingbourne <pcc@google.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180227143852.11175-21-alex.bennee@linaro.org
24
Message-id: 20210219201820.2672077-1-pcc@google.com
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
27
---
12
target/arm/helper.h | 10 ++++
28
target/arm/helper.c | 2 +-
13
target/arm/helper.c | 4 ++
29
target/arm/mte_helper.c | 13 +++++++++----
14
target/arm/translate-a64.c | 122 ++++++++++++++++++++++++++++++++++-----------
30
2 files changed, 10 insertions(+), 5 deletions(-)
15
3 files changed, 108 insertions(+), 28 deletions(-)
16
31
17
diff --git a/target/arm/helper.h b/target/arm/helper.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.h
20
+++ b/target/arm/helper.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmped, void, f64, f64, env)
22
DEF_HELPER_2(vfp_fcvtds, f64, f32, env)
23
DEF_HELPER_2(vfp_fcvtsd, f32, f64, env)
24
25
+DEF_HELPER_2(vfp_uitoh, f16, i32, ptr)
26
DEF_HELPER_2(vfp_uitos, f32, i32, ptr)
27
DEF_HELPER_2(vfp_uitod, f64, i32, ptr)
28
+DEF_HELPER_2(vfp_sitoh, f16, i32, ptr)
29
DEF_HELPER_2(vfp_sitos, f32, i32, ptr)
30
DEF_HELPER_2(vfp_sitod, f64, i32, ptr)
31
32
+DEF_HELPER_2(vfp_touih, i32, f16, ptr)
33
DEF_HELPER_2(vfp_touis, i32, f32, ptr)
34
DEF_HELPER_2(vfp_touid, i32, f64, ptr)
35
+DEF_HELPER_2(vfp_touizh, i32, f16, ptr)
36
DEF_HELPER_2(vfp_touizs, i32, f32, ptr)
37
DEF_HELPER_2(vfp_touizd, i32, f64, ptr)
38
+DEF_HELPER_2(vfp_tosih, i32, f16, ptr)
39
DEF_HELPER_2(vfp_tosis, i32, f32, ptr)
40
DEF_HELPER_2(vfp_tosid, i32, f64, ptr)
41
+DEF_HELPER_2(vfp_tosizh, i32, f16, ptr)
42
DEF_HELPER_2(vfp_tosizs, i32, f32, ptr)
43
DEF_HELPER_2(vfp_tosizd, i32, f64, ptr)
44
45
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_toshd_round_to_zero, i64, f64, i32, ptr)
46
DEF_HELPER_3(vfp_tosld_round_to_zero, i64, f64, i32, ptr)
47
DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, ptr)
48
DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr)
49
+DEF_HELPER_3(vfp_toulh, i32, f16, i32, ptr)
50
+DEF_HELPER_3(vfp_toslh, i32, f16, i32, ptr)
51
DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr)
52
DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr)
53
DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr)
54
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_sqtod, f64, i64, i32, ptr)
55
DEF_HELPER_3(vfp_uhtod, f64, i64, i32, ptr)
56
DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr)
57
DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr)
58
+DEF_HELPER_3(vfp_sltoh, f16, i32, i32, ptr)
59
+DEF_HELPER_3(vfp_ultoh, f16, i32, i32, ptr)
60
61
DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr)
62
DEF_HELPER_FLAGS_2(set_neon_rmode, TCG_CALL_NO_RWG, i32, i32, env)
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
64
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/helper.c
34
--- a/target/arm/helper.c
66
+++ b/target/arm/helper.c
35
+++ b/target/arm/helper.c
67
@@ -XXX,XX +XXX,XX @@ CONV_ITOF(vfp_##name##to##p, fsz, sign) \
36
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
68
CONV_FTOI(vfp_to##name##p, fsz, sign, ) \
37
if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
69
CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero)
38
&& tbid
70
39
&& !(env->pstate & PSTATE_TCO)
71
+FLOAT_CONVS(si, h, 16, )
40
- && (sctlr & SCTLR_TCF)
72
FLOAT_CONVS(si, s, 32, )
41
+ && (sctlr & SCTLR_TCF0)
73
FLOAT_CONVS(si, d, 64, )
42
&& allocation_tag_access_enabled(env, 0, sctlr)) {
74
+FLOAT_CONVS(ui, h, 16, u)
43
flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
75
FLOAT_CONVS(ui, s, 32, u)
44
}
76
FLOAT_CONVS(ui, d, 64, u)
45
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
77
78
@@ -XXX,XX +XXX,XX @@ VFP_CONV_FIX_A64(sq, s, 32, 64, int64)
79
VFP_CONV_FIX(uh, s, 32, 32, uint16)
80
VFP_CONV_FIX(ul, s, 32, 32, uint32)
81
VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
82
+VFP_CONV_FIX_A64(sl, h, 16, 32, int32)
83
+VFP_CONV_FIX_A64(ul, h, 16, 32, uint32)
84
#undef VFP_CONV_FIX
85
#undef VFP_CONV_FIX_FLOAT
86
#undef VFP_CONV_FLOAT_FIX_ROUND
87
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
88
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
89
--- a/target/arm/translate-a64.c
47
--- a/target/arm/mte_helper.c
90
+++ b/target/arm/translate-a64.c
48
+++ b/target/arm/mte_helper.c
91
@@ -XXX,XX +XXX,XX @@ static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn,
49
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
92
int elements, int is_signed,
50
reg_el = regime_el(env, arm_mmu_idx);
93
int fracbits, int size)
51
sctlr = env->cp15.sctlr_el[reg_el];
94
{
52
95
- bool is_double = size == 3 ? true : false;
53
- el = arm_current_el(env);
96
- TCGv_ptr tcg_fpst = get_fpstatus_ptr(false);
54
- if (el == 0) {
97
- TCGv_i32 tcg_shift = tcg_const_i32(fracbits);
55
+ switch (arm_mmu_idx) {
98
- TCGv_i64 tcg_int = tcg_temp_new_i64();
56
+ case ARMMMUIdx_E10_0:
99
+ TCGv_ptr tcg_fpst = get_fpstatus_ptr(size == MO_16);
57
+ case ARMMMUIdx_E20_0:
100
+ TCGv_i32 tcg_shift = NULL;
58
+ el = 0;
101
+
59
tcf = extract64(sctlr, 38, 2);
102
TCGMemOp mop = size | (is_signed ? MO_SIGN : 0);
60
- } else {
103
int pass;
61
+ break;
104
62
+ default:
105
- for (pass = 0; pass < elements; pass++) {
63
+ el = reg_el;
106
- read_vec_element(s, tcg_int, rn, pass, mop);
64
tcf = extract64(sctlr, 40, 2);
107
+ if (fracbits || size == MO_64) {
108
+ tcg_shift = tcg_const_i32(fracbits);
109
+ }
110
+
111
+ if (size == MO_64) {
112
+ TCGv_i64 tcg_int64 = tcg_temp_new_i64();
113
+ TCGv_i64 tcg_double = tcg_temp_new_i64();
114
+
115
+ for (pass = 0; pass < elements; pass++) {
116
+ read_vec_element(s, tcg_int64, rn, pass, mop);
117
118
- if (is_double) {
119
- TCGv_i64 tcg_double = tcg_temp_new_i64();
120
if (is_signed) {
121
- gen_helper_vfp_sqtod(tcg_double, tcg_int,
122
+ gen_helper_vfp_sqtod(tcg_double, tcg_int64,
123
tcg_shift, tcg_fpst);
124
} else {
125
- gen_helper_vfp_uqtod(tcg_double, tcg_int,
126
+ gen_helper_vfp_uqtod(tcg_double, tcg_int64,
127
tcg_shift, tcg_fpst);
128
}
129
if (elements == 1) {
130
@@ -XXX,XX +XXX,XX @@ static void handle_simd_intfp_conv(DisasContext *s, int rd, int rn,
131
} else {
132
write_vec_element(s, tcg_double, rd, pass, MO_64);
133
}
134
- tcg_temp_free_i64(tcg_double);
135
- } else {
136
- TCGv_i32 tcg_single = tcg_temp_new_i32();
137
- if (is_signed) {
138
- gen_helper_vfp_sqtos(tcg_single, tcg_int,
139
- tcg_shift, tcg_fpst);
140
- } else {
141
- gen_helper_vfp_uqtos(tcg_single, tcg_int,
142
- tcg_shift, tcg_fpst);
143
- }
144
- if (elements == 1) {
145
- write_fp_sreg(s, rd, tcg_single);
146
- } else {
147
- write_vec_element_i32(s, tcg_single, rd, pass, MO_32);
148
- }
149
- tcg_temp_free_i32(tcg_single);
150
}
151
+
152
+ tcg_temp_free_i64(tcg_int64);
153
+ tcg_temp_free_i64(tcg_double);
154
+
155
+ } else {
156
+ TCGv_i32 tcg_int32 = tcg_temp_new_i32();
157
+ TCGv_i32 tcg_float = tcg_temp_new_i32();
158
+
159
+ for (pass = 0; pass < elements; pass++) {
160
+ read_vec_element_i32(s, tcg_int32, rn, pass, mop);
161
+
162
+ switch (size) {
163
+ case MO_32:
164
+ if (fracbits) {
165
+ if (is_signed) {
166
+ gen_helper_vfp_sltos(tcg_float, tcg_int32,
167
+ tcg_shift, tcg_fpst);
168
+ } else {
169
+ gen_helper_vfp_ultos(tcg_float, tcg_int32,
170
+ tcg_shift, tcg_fpst);
171
+ }
172
+ } else {
173
+ if (is_signed) {
174
+ gen_helper_vfp_sitos(tcg_float, tcg_int32, tcg_fpst);
175
+ } else {
176
+ gen_helper_vfp_uitos(tcg_float, tcg_int32, tcg_fpst);
177
+ }
178
+ }
179
+ break;
180
+ case MO_16:
181
+ if (fracbits) {
182
+ if (is_signed) {
183
+ gen_helper_vfp_sltoh(tcg_float, tcg_int32,
184
+ tcg_shift, tcg_fpst);
185
+ } else {
186
+ gen_helper_vfp_ultoh(tcg_float, tcg_int32,
187
+ tcg_shift, tcg_fpst);
188
+ }
189
+ } else {
190
+ if (is_signed) {
191
+ gen_helper_vfp_sitoh(tcg_float, tcg_int32, tcg_fpst);
192
+ } else {
193
+ gen_helper_vfp_uitoh(tcg_float, tcg_int32, tcg_fpst);
194
+ }
195
+ }
196
+ break;
197
+ default:
198
+ g_assert_not_reached();
199
+ }
200
+
201
+ if (elements == 1) {
202
+ write_fp_sreg(s, rd, tcg_float);
203
+ } else {
204
+ write_vec_element_i32(s, tcg_float, rd, pass, size);
205
+ }
206
+ }
207
+
208
+ tcg_temp_free_i32(tcg_int32);
209
+ tcg_temp_free_i32(tcg_float);
210
}
65
}
211
66
212
- tcg_temp_free_i64(tcg_int);
67
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
213
tcg_temp_free_ptr(tcg_fpst);
68
env->exception.vaddress = dirty_ptr;
214
- tcg_temp_free_i32(tcg_shift);
69
215
+ if (tcg_shift) {
70
is_write = FIELD_EX32(desc, MTEDESC, WRITE);
216
+ tcg_temp_free_i32(tcg_shift);
71
- syn = syn_data_abort_no_iss(el != 0, 0, 0, 0, 0, is_write, 0x11);
217
+ }
72
+ syn = syn_data_abort_no_iss(arm_current_el(env) != 0, 0, 0, 0, 0,
218
73
+ is_write, 0x11);
219
clear_vec_high(s, elements << size == 16, rd);
74
raise_exception(env, EXCP_DATA_ABORT, syn, exception_target_el(env));
220
}
75
/* noreturn, but fall through to the assert anyway */
221
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
76
222
rn = extract32(insn, 5, 5);
223
224
switch (fpop) {
225
+ case 0x1d: /* SCVTF */
226
+ case 0x5d: /* UCVTF */
227
+ {
228
+ int elements;
229
+
230
+ if (is_scalar) {
231
+ elements = 1;
232
+ } else {
233
+ elements = (is_q ? 8 : 4);
234
+ }
235
+
236
+ if (!fp_access_check(s)) {
237
+ return;
238
+ }
239
+ handle_simd_intfp_conv(s, rd, rn, elements, !u, 0, MO_16);
240
+ return;
241
+ }
242
break;
243
case 0x2c: /* FCMGT (zero) */
244
case 0x2d: /* FCMEQ (zero) */
245
--
77
--
246
2.16.2
78
2.20.1
247
79
248
80
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Use 8 dummy cycles (4 dummy bytes) with the QIOR/QIOR4 commands in legacy mode
3
IDAU is specific to M-profile. KVM only supports A-profile.
4
for matching what is expected by Micron (Numonyx) flashes (the default target
4
Restrict this interface to TCG, as it is pointless (and
5
flash type of the QSPI).
5
confusing) on a KVM-only build.
6
6
7
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Alistair Francis <alistair.francis@xilinx.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20180223232233.31482-3-frasse.iglesias@gmail.com
10
Message-id: 20210221222617.2579610-2-f4bug@amsat.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
hw/ssi/xilinx_spips.c | 2 +-
13
target/arm/cpu.c | 7 -------
14
1 file changed, 1 insertion(+), 1 deletion(-)
14
target/arm/cpu_tcg.c | 8 ++++++++
15
2 files changed, 8 insertions(+), 7 deletions(-)
15
16
16
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ssi/xilinx_spips.c
19
--- a/target/arm/cpu.c
19
+++ b/hw/ssi/xilinx_spips.c
20
+++ b/target/arm/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static int xilinx_spips_num_dummies(XilinxQSPIPS *qs, uint8_t command)
21
@@ -XXX,XX +XXX,XX @@ static const TypeInfo arm_cpu_type_info = {
21
return 2;
22
.class_init = arm_cpu_class_init,
22
case QIOR:
23
};
23
case QIOR_4:
24
24
- return 5;
25
-static const TypeInfo idau_interface_type_info = {
25
+ return 4;
26
- .name = TYPE_IDAU_INTERFACE,
26
default:
27
- .parent = TYPE_INTERFACE,
27
return -1;
28
- .class_size = sizeof(IDAUInterfaceClass),
29
-};
30
-
31
static void arm_cpu_register_types(void)
32
{
33
const size_t cpu_count = ARRAY_SIZE(arm_cpus);
34
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_register_types(void)
35
if (cpu_count) {
36
size_t i;
37
38
- type_register_static(&idau_interface_type_info);
39
for (i = 0; i < cpu_count; ++i) {
40
arm_cpu_register(&arm_cpus[i]);
41
}
42
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/cpu_tcg.c
45
+++ b/target/arm/cpu_tcg.c
46
@@ -XXX,XX +XXX,XX @@
47
#include "hw/core/tcg-cpu-ops.h"
48
#endif /* CONFIG_TCG */
49
#include "internals.h"
50
+#include "target/arm/idau.h"
51
52
/* CPU models. These are not needed for the AArch64 linux-user build. */
53
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
54
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
55
{ .name = "pxa270-c5", .initfn = pxa270c5_initfn },
56
};
57
58
+static const TypeInfo idau_interface_type_info = {
59
+ .name = TYPE_IDAU_INTERFACE,
60
+ .parent = TYPE_INTERFACE,
61
+ .class_size = sizeof(IDAUInterfaceClass),
62
+};
63
+
64
static void arm_tcg_cpu_register_types(void)
65
{
66
size_t i;
67
68
+ type_register_static(&idau_interface_type_info);
69
for (i = 0; i < ARRAY_SIZE(arm_tcg_cpus); ++i) {
70
arm_cpu_register(&arm_tcg_cpus[i]);
28
}
71
}
29
--
72
--
30
2.16.2
73
2.20.1
31
74
32
75
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
This covers all the floating point convert operations.
3
We will move this code in the next commit. Clean it up
4
first to avoid checkpatch.pl errors.
4
5
5
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210221222617.2579610-3-f4bug@amsat.org
7
Message-id: 20180227143852.11175-19-alex.bennee@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/helper-a64.h | 2 ++
11
target/arm/cpu.c | 12 ++++++++----
11
target/arm/helper-a64.c | 32 +++++++++++++++++
12
1 file changed, 8 insertions(+), 4 deletions(-)
12
target/arm/translate-a64.c | 85 +++++++++++++++++++++++++++++++++++++++++++++-
13
3 files changed, 118 insertions(+), 1 deletion(-)
14
13
15
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-a64.h
16
--- a/target/arm/cpu.c
18
+++ b/target/arm/helper-a64.h
17
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(advsimd_mulx2h, i32, i32, i32, ptr)
18
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
20
DEF_HELPER_4(advsimd_muladd2h, i32, i32, i32, i32, ptr)
21
DEF_HELPER_2(advsimd_rinth_exact, f16, f16, ptr)
22
DEF_HELPER_2(advsimd_rinth, f16, f16, ptr)
23
+DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
24
+DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
25
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/helper-a64.c
28
+++ b/target/arm/helper-a64.c
29
@@ -XXX,XX +XXX,XX @@ float16 HELPER(advsimd_rinth)(float16 x, void *fp_status)
30
31
return ret;
32
}
19
}
33
+
20
34
+/*
21
static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
35
+ * Half-precision floating point conversion functions
22
- /* power_control should be set to maximum latency. Again,
36
+ *
23
+ /*
37
+ * There are a multitude of conversion functions with various
24
+ * power_control should be set to maximum latency. Again,
38
+ * different rounding modes. This is dealt with by the calling code
25
* default to 0 and set by private hook
39
+ * setting the mode appropriately before calling the helper.
26
*/
40
+ */
27
{ .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
41
+
28
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
42
+uint32_t HELPER(advsimd_f16tosinth)(float16 a, void *fpstp)
29
set_feature(&cpu->env, ARM_FEATURE_NEON);
43
+{
30
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
44
+ float_status *fpst = fpstp;
31
set_feature(&cpu->env, ARM_FEATURE_EL3);
45
+
32
- /* Note that A9 supports the MP extensions even for
46
+ /* Invalid if we are passed a NaN */
33
+ /*
47
+ if (float16_is_any_nan(a)) {
34
+ * Note that A9 supports the MP extensions even for
48
+ float_raise(float_flag_invalid, fpst);
35
* A9UP and single-core A9MP (which are both different
49
+ return 0;
36
* and valid configurations; we don't model A9UP).
50
+ }
37
*/
51
+ return float16_to_int16(a, fpst);
38
@@ -XXX,XX +XXX,XX @@ static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
52
+}
39
{
53
+
40
MachineState *ms = MACHINE(qdev_get_machine());
54
+uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
41
55
+{
42
- /* Linux wants the number of processors from here.
56
+ float_status *fpst = fpstp;
43
+ /*
57
+
44
+ * Linux wants the number of processors from here.
58
+ /* Invalid if we are passed a NaN */
45
* Might as well set the interrupt-controller bit too.
59
+ if (float16_is_any_nan(a)) {
46
*/
60
+ float_raise(float_flag_invalid, fpst);
47
return ((ms->smp.cpus - 1) << 24) | (1 << 23);
61
+ return 0;
48
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
62
+ }
49
cpu->isar.id_mmfr1 = 0x40000000;
63
+ return float16_to_uint16(a, fpst);
50
cpu->isar.id_mmfr2 = 0x01240000;
64
+}
51
cpu->isar.id_mmfr3 = 0x02102211;
65
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
52
- /* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
66
index XXXXXXX..XXXXXXX 100644
53
+ /*
67
--- a/target/arm/translate-a64.c
54
+ * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
68
+++ b/target/arm/translate-a64.c
55
* table 4-41 gives 0x02101110, which includes the arm div insns.
69
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
56
*/
70
only_in_vector = true;
57
cpu->isar.id_isar0 = 0x02101110;
71
/* current rounding mode */
72
break;
73
+ case 0x1a: /* FCVTNS */
74
+ need_rmode = true;
75
+ rmode = FPROUNDING_TIEEVEN;
76
+ break;
77
+ case 0x1b: /* FCVTMS */
78
+ need_rmode = true;
79
+ rmode = FPROUNDING_NEGINF;
80
+ break;
81
+ case 0x1c: /* FCVTAS */
82
+ need_rmode = true;
83
+ rmode = FPROUNDING_TIEAWAY;
84
+ break;
85
+ case 0x3a: /* FCVTPS */
86
+ need_rmode = true;
87
+ rmode = FPROUNDING_POSINF;
88
+ break;
89
+ case 0x3b: /* FCVTZS */
90
+ need_rmode = true;
91
+ rmode = FPROUNDING_ZERO;
92
+ break;
93
+ case 0x5a: /* FCVTNU */
94
+ need_rmode = true;
95
+ rmode = FPROUNDING_TIEEVEN;
96
+ break;
97
+ case 0x5b: /* FCVTMU */
98
+ need_rmode = true;
99
+ rmode = FPROUNDING_NEGINF;
100
+ break;
101
+ case 0x5c: /* FCVTAU */
102
+ need_rmode = true;
103
+ rmode = FPROUNDING_TIEAWAY;
104
+ break;
105
+ case 0x7a: /* FCVTPU */
106
+ need_rmode = true;
107
+ rmode = FPROUNDING_POSINF;
108
+ break;
109
+ case 0x7b: /* FCVTZU */
110
+ need_rmode = true;
111
+ rmode = FPROUNDING_ZERO;
112
+ break;
113
default:
114
fprintf(stderr, "%s: insn %#04x fpop %#2x\n", __func__, insn, fpop);
115
g_assert_not_reached();
116
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
117
}
118
119
if (is_scalar) {
120
- /* no operations yet */
121
+ TCGv_i32 tcg_op = tcg_temp_new_i32();
122
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
123
+
124
+ read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
125
+
126
+ switch (fpop) {
127
+ case 0x1a: /* FCVTNS */
128
+ case 0x1b: /* FCVTMS */
129
+ case 0x1c: /* FCVTAS */
130
+ case 0x3a: /* FCVTPS */
131
+ case 0x3b: /* FCVTZS */
132
+ gen_helper_advsimd_f16tosinth(tcg_res, tcg_op, tcg_fpstatus);
133
+ break;
134
+ case 0x5a: /* FCVTNU */
135
+ case 0x5b: /* FCVTMU */
136
+ case 0x5c: /* FCVTAU */
137
+ case 0x7a: /* FCVTPU */
138
+ case 0x7b: /* FCVTZU */
139
+ gen_helper_advsimd_f16touinth(tcg_res, tcg_op, tcg_fpstatus);
140
+ break;
141
+ default:
142
+ g_assert_not_reached();
143
+ }
144
+
145
+ /* limit any sign extension going on */
146
+ tcg_gen_andi_i32(tcg_res, tcg_res, 0xffff);
147
+ write_fp_sreg(s, rd, tcg_res);
148
+
149
+ tcg_temp_free_i32(tcg_res);
150
+ tcg_temp_free_i32(tcg_op);
151
} else {
152
for (pass = 0; pass < (is_q ? 8 : 4); pass++) {
153
TCGv_i32 tcg_op = tcg_temp_new_i32();
154
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
155
read_vec_element_i32(s, tcg_op, rn, pass, MO_16);
156
157
switch (fpop) {
158
+ case 0x1a: /* FCVTNS */
159
+ case 0x1b: /* FCVTMS */
160
+ case 0x1c: /* FCVTAS */
161
+ case 0x3a: /* FCVTPS */
162
+ case 0x3b: /* FCVTZS */
163
+ gen_helper_advsimd_f16tosinth(tcg_res, tcg_op, tcg_fpstatus);
164
+ break;
165
+ case 0x5a: /* FCVTNU */
166
+ case 0x5b: /* FCVTMU */
167
+ case 0x5c: /* FCVTAU */
168
+ case 0x7a: /* FCVTPU */
169
+ case 0x7b: /* FCVTZU */
170
+ gen_helper_advsimd_f16touinth(tcg_res, tcg_op, tcg_fpstatus);
171
+ break;
172
case 0x18: /* FRINTN */
173
case 0x19: /* FRINTM */
174
case 0x38: /* FRINTP */
175
--
58
--
176
2.16.2
59
2.20.1
177
60
178
61
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
For a long time now the UI layer has guaranteed that the console
2
surface is always 32 bits per pixel RGB. Remove the legacy dead
3
code from the milkymist display device which was handling the
4
possibility that the console surface was some other format.
2
5
3
This includes FMAXNMP, FADDP, FMAXP, FMINNMP, FMINP.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215103215.4944-2-peter.maydell@linaro.org
9
---
10
hw/arm/musicpal.c | 64 ++++++++++++++++++-----------------------------
11
1 file changed, 24 insertions(+), 40 deletions(-)
4
12
5
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
13
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180227143852.11175-14-alex.bennee@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 208 +++++++++++++++++++++++++++++----------------
11
1 file changed, 133 insertions(+), 75 deletions(-)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
15
--- a/hw/arm/musicpal.c
16
+++ b/target/arm/translate-a64.c
16
+++ b/hw/arm/musicpal.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
17
@@ -XXX,XX +XXX,XX @@ static uint8_t scale_lcd_color(musicpal_lcd_state *s, uint8_t col)
18
int datasize, elements;
18
}
19
int pass;
19
}
20
TCGv_ptr fpst;
20
21
+ bool pairwise = false;
21
-#define SET_LCD_PIXEL(depth, type) \
22
22
-static inline void glue(set_lcd_pixel, depth) \
23
if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
23
- (musicpal_lcd_state *s, int x, int y, type col) \
24
unallocated_encoding(s);
24
-{ \
25
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
25
- int dx, dy; \
26
datasize = is_q ? 128 : 64;
26
- DisplaySurface *surface = qemu_console_surface(s->con); \
27
elements = datasize / 16;
27
- type *pixel = &((type *) surface_data(surface))[(y * 128 * 3 + x) * 3]; \
28
28
-\
29
+ switch (fpopcode) {
29
- for (dy = 0; dy < 3; dy++, pixel += 127 * 3) \
30
+ case 0x10: /* FMAXNMP */
30
- for (dx = 0; dx < 3; dx++, pixel++) \
31
+ case 0x12: /* FADDP */
31
- *pixel = col; \
32
+ case 0x16: /* FMAXP */
32
+static inline void set_lcd_pixel32(musicpal_lcd_state *s,
33
+ case 0x18: /* FMINNMP */
33
+ int x, int y, uint32_t col)
34
+ case 0x1e: /* FMINP */
34
+{
35
+ pairwise = true;
35
+ int dx, dy;
36
+ break;
36
+ DisplaySurface *surface = qemu_console_surface(s->con);
37
+ uint32_t *pixel =
38
+ &((uint32_t *) surface_data(surface))[(y * 128 * 3 + x) * 3];
39
+
40
+ for (dy = 0; dy < 3; dy++, pixel += 127 * 3) {
41
+ for (dx = 0; dx < 3; dx++, pixel++) {
42
+ *pixel = col;
43
+ }
37
+ }
44
+ }
38
+
45
}
39
fpst = get_fpstatus_ptr(true);
46
-SET_LCD_PIXEL(8, uint8_t)
40
47
-SET_LCD_PIXEL(16, uint16_t)
41
- for (pass = 0; pass < elements; pass++) {
48
-SET_LCD_PIXEL(32, uint32_t)
42
+ if (pairwise) {
49
43
+ int maxpass = is_q ? 8 : 4;
50
static void lcd_refresh(void *opaque)
44
TCGv_i32 tcg_op1 = tcg_temp_new_i32();
51
{
45
TCGv_i32 tcg_op2 = tcg_temp_new_i32();
52
musicpal_lcd_state *s = opaque;
46
- TCGv_i32 tcg_res = tcg_temp_new_i32();
53
- DisplaySurface *surface = qemu_console_surface(s->con);
47
+ TCGv_i32 tcg_res[8];
54
int x, y, col;
48
55
49
- read_vec_element_i32(s, tcg_op1, rn, pass, MO_16);
56
- switch (surface_bits_per_pixel(surface)) {
50
- read_vec_element_i32(s, tcg_op2, rm, pass, MO_16);
57
- case 0:
51
+ for (pass = 0; pass < maxpass; pass++) {
58
- return;
52
+ int passreg = pass < (maxpass / 2) ? rn : rm;
59
-#define LCD_REFRESH(depth, func) \
53
+ int passelt = (pass << 1) & (maxpass - 1);
60
- case depth: \
54
61
- col = func(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff), \
55
- switch (fpopcode) {
62
- scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff), \
56
- case 0x0: /* FMAXNM */
63
- scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff)); \
57
- gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
64
- for (x = 0; x < 128; x++) { \
58
- break;
65
- for (y = 0; y < 64; y++) { \
59
- case 0x1: /* FMLA */
66
- if (s->video_ram[x + (y/8)*128] & (1 << (y % 8))) { \
60
- read_vec_element_i32(s, tcg_res, rd, pass, MO_16);
67
- glue(set_lcd_pixel, depth)(s, x, y, col); \
61
- gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_res,
68
- } else { \
62
- fpst);
69
- glue(set_lcd_pixel, depth)(s, x, y, 0); \
63
- break;
70
- } \
64
- case 0x2: /* FADD */
71
- } \
65
- gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
72
- } \
66
- break;
73
- break;
67
- case 0x3: /* FMULX */
74
- LCD_REFRESH(8, rgb_to_pixel8)
68
- gen_helper_advsimd_mulxh(tcg_res, tcg_op1, tcg_op2, fpst);
75
- LCD_REFRESH(16, rgb_to_pixel16)
69
- break;
76
- LCD_REFRESH(32, (is_surface_bgr(surface) ?
70
- case 0x4: /* FCMEQ */
77
- rgb_to_pixel32bgr : rgb_to_pixel32))
71
- gen_helper_advsimd_ceq_f16(tcg_res, tcg_op1, tcg_op2, fpst);
78
- default:
72
- break;
79
- hw_error("unsupported colour depth %i\n",
73
- case 0x6: /* FMAX */
80
- surface_bits_per_pixel(surface));
74
- gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
81
+ col = rgb_to_pixel32(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff),
75
- break;
82
+ scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff),
76
- case 0x7: /* FRECPS */
83
+ scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff));
77
- gen_helper_recpsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
84
+ for (x = 0; x < 128; x++) {
78
- break;
85
+ for (y = 0; y < 64; y++) {
79
- case 0x8: /* FMINNM */
86
+ if (s->video_ram[x + (y / 8) * 128] & (1 << (y % 8))) {
80
- gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
87
+ set_lcd_pixel32(s, x, y, col);
81
- break;
88
+ } else {
82
- case 0x9: /* FMLS */
89
+ set_lcd_pixel32(s, x, y, 0);
83
- /* As usual for ARM, separate negation for fused multiply-add */
84
- tcg_gen_xori_i32(tcg_op1, tcg_op1, 0x8000);
85
- read_vec_element_i32(s, tcg_res, rd, pass, MO_16);
86
- gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_res,
87
- fpst);
88
- break;
89
- case 0xa: /* FSUB */
90
- gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
91
- break;
92
- case 0xe: /* FMIN */
93
- gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
94
- break;
95
- case 0xf: /* FRSQRTS */
96
- gen_helper_rsqrtsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
97
- break;
98
- case 0x13: /* FMUL */
99
- gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
100
- break;
101
- case 0x14: /* FCMGE */
102
- gen_helper_advsimd_cge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
103
- break;
104
- case 0x15: /* FACGE */
105
- gen_helper_advsimd_acge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
106
- break;
107
- case 0x17: /* FDIV */
108
- gen_helper_advsimd_divh(tcg_res, tcg_op1, tcg_op2, fpst);
109
- break;
110
- case 0x1a: /* FABD */
111
- gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
112
- tcg_gen_andi_i32(tcg_res, tcg_res, 0x7fff);
113
- break;
114
- case 0x1c: /* FCMGT */
115
- gen_helper_advsimd_cgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
116
- break;
117
- case 0x1d: /* FACGT */
118
- gen_helper_advsimd_acgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
119
- break;
120
- default:
121
- fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
122
- __func__, insn, fpopcode, s->pc);
123
- g_assert_not_reached();
124
+ read_vec_element_i32(s, tcg_op1, passreg, passelt, MO_16);
125
+ read_vec_element_i32(s, tcg_op2, passreg, passelt + 1, MO_16);
126
+ tcg_res[pass] = tcg_temp_new_i32();
127
+
128
+ switch (fpopcode) {
129
+ case 0x10: /* FMAXNMP */
130
+ gen_helper_advsimd_maxnumh(tcg_res[pass], tcg_op1, tcg_op2,
131
+ fpst);
132
+ break;
133
+ case 0x12: /* FADDP */
134
+ gen_helper_advsimd_addh(tcg_res[pass], tcg_op1, tcg_op2, fpst);
135
+ break;
136
+ case 0x16: /* FMAXP */
137
+ gen_helper_advsimd_maxh(tcg_res[pass], tcg_op1, tcg_op2, fpst);
138
+ break;
139
+ case 0x18: /* FMINNMP */
140
+ gen_helper_advsimd_minnumh(tcg_res[pass], tcg_op1, tcg_op2,
141
+ fpst);
142
+ break;
143
+ case 0x1e: /* FMINP */
144
+ gen_helper_advsimd_minh(tcg_res[pass], tcg_op1, tcg_op2, fpst);
145
+ break;
146
+ default:
147
+ g_assert_not_reached();
148
+ }
90
+ }
149
+ }
91
+ }
150
+
151
+ for (pass = 0; pass < maxpass; pass++) {
152
+ write_vec_element_i32(s, tcg_res[pass], rd, pass, MO_16);
153
+ tcg_temp_free_i32(tcg_res[pass]);
154
}
155
156
- write_vec_element_i32(s, tcg_res, rd, pass, MO_16);
157
- tcg_temp_free_i32(tcg_res);
158
tcg_temp_free_i32(tcg_op1);
159
tcg_temp_free_i32(tcg_op2);
160
+
161
+ } else {
162
+ for (pass = 0; pass < elements; pass++) {
163
+ TCGv_i32 tcg_op1 = tcg_temp_new_i32();
164
+ TCGv_i32 tcg_op2 = tcg_temp_new_i32();
165
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
166
+
167
+ read_vec_element_i32(s, tcg_op1, rn, pass, MO_16);
168
+ read_vec_element_i32(s, tcg_op2, rm, pass, MO_16);
169
+
170
+ switch (fpopcode) {
171
+ case 0x0: /* FMAXNM */
172
+ gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
173
+ break;
174
+ case 0x1: /* FMLA */
175
+ read_vec_element_i32(s, tcg_res, rd, pass, MO_16);
176
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_res,
177
+ fpst);
178
+ break;
179
+ case 0x2: /* FADD */
180
+ gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
181
+ break;
182
+ case 0x3: /* FMULX */
183
+ gen_helper_advsimd_mulxh(tcg_res, tcg_op1, tcg_op2, fpst);
184
+ break;
185
+ case 0x4: /* FCMEQ */
186
+ gen_helper_advsimd_ceq_f16(tcg_res, tcg_op1, tcg_op2, fpst);
187
+ break;
188
+ case 0x6: /* FMAX */
189
+ gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
190
+ break;
191
+ case 0x7: /* FRECPS */
192
+ gen_helper_recpsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
193
+ break;
194
+ case 0x8: /* FMINNM */
195
+ gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
196
+ break;
197
+ case 0x9: /* FMLS */
198
+ /* As usual for ARM, separate negation for fused multiply-add */
199
+ tcg_gen_xori_i32(tcg_op1, tcg_op1, 0x8000);
200
+ read_vec_element_i32(s, tcg_res, rd, pass, MO_16);
201
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_res,
202
+ fpst);
203
+ break;
204
+ case 0xa: /* FSUB */
205
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
206
+ break;
207
+ case 0xe: /* FMIN */
208
+ gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
209
+ break;
210
+ case 0xf: /* FRSQRTS */
211
+ gen_helper_rsqrtsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
212
+ break;
213
+ case 0x13: /* FMUL */
214
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
215
+ break;
216
+ case 0x14: /* FCMGE */
217
+ gen_helper_advsimd_cge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
218
+ break;
219
+ case 0x15: /* FACGE */
220
+ gen_helper_advsimd_acge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
221
+ break;
222
+ case 0x17: /* FDIV */
223
+ gen_helper_advsimd_divh(tcg_res, tcg_op1, tcg_op2, fpst);
224
+ break;
225
+ case 0x1a: /* FABD */
226
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
227
+ tcg_gen_andi_i32(tcg_res, tcg_res, 0x7fff);
228
+ break;
229
+ case 0x1c: /* FCMGT */
230
+ gen_helper_advsimd_cgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
231
+ break;
232
+ case 0x1d: /* FACGT */
233
+ gen_helper_advsimd_acgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
234
+ break;
235
+ default:
236
+ fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
237
+ __func__, insn, fpopcode, s->pc);
238
+ g_assert_not_reached();
239
+ }
240
+
241
+ write_vec_element_i32(s, tcg_res, rd, pass, MO_16);
242
+ tcg_temp_free_i32(tcg_res);
243
+ tcg_temp_free_i32(tcg_op1);
244
+ tcg_temp_free_i32(tcg_op2);
245
+ }
246
}
92
}
247
93
248
tcg_temp_free_ptr(fpst);
94
dpy_gfx_update(s->con, 0, 0, 128*3, 64*3);
249
--
95
--
250
2.16.2
96
2.20.1
251
97
252
98
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
For a long time now the UI layer has guaranteed that the console
2
surface is always 32 bits per pixel RGB. Remove the legacy dead
3
code from the tc6393xb display device which was handling the
4
possibility that the console surface was some other format.
2
5
3
I re-use the existing handle_2misc_fcmp_zero handler and tweak it
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
slightly to deal with the half-precision case.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215103215.4944-3-peter.maydell@linaro.org
9
---
10
include/ui/console.h | 10 ----------
11
hw/display/tc6393xb.c | 33 +--------------------------------
12
2 files changed, 1 insertion(+), 42 deletions(-)
5
13
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
14
diff --git a/include/ui/console.h b/include/ui/console.h
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180227143852.11175-20-alex.bennee@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-a64.c | 80 +++++++++++++++++++++++++++++++++-------------
12
1 file changed, 57 insertions(+), 23 deletions(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
16
--- a/include/ui/console.h
17
+++ b/target/arm/translate-a64.c
17
+++ b/include/ui/console.h
18
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
18
@@ -XXX,XX +XXX,XX @@ PixelFormat qemu_default_pixelformat(int bpp);
19
bool is_scalar, bool is_u, bool is_q,
19
DisplaySurface *qemu_create_displaysurface(int width, int height);
20
int size, int rn, int rd)
20
void qemu_free_displaysurface(DisplaySurface *surface);
21
22
-static inline int is_surface_bgr(DisplaySurface *surface)
23
-{
24
- if (PIXMAN_FORMAT_BPP(surface->format) == 32 &&
25
- PIXMAN_FORMAT_TYPE(surface->format) == PIXMAN_TYPE_ABGR) {
26
- return 1;
27
- } else {
28
- return 0;
29
- }
30
-}
31
-
32
static inline int is_buffer_shared(DisplaySurface *surface)
21
{
33
{
22
- bool is_double = (size == 3);
34
return !(surface->flags & QEMU_ALLOCATED_FLAG);
23
+ bool is_double = (size == MO_64);
35
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
24
TCGv_ptr fpst;
36
index XXXXXXX..XXXXXXX 100644
25
37
--- a/hw/display/tc6393xb.c
26
if (!fp_access_check(s)) {
38
+++ b/hw/display/tc6393xb.c
27
return;
39
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
28
}
40
(uint32_t) addr, value & 0xff);
29
41
}
30
- fpst = get_fpstatus_ptr(false);
42
31
+ fpst = get_fpstatus_ptr(size == MO_16);
43
-#define BITS 8
32
44
-#include "tc6393xb_template.h"
33
if (is_double) {
45
-#define BITS 15
34
TCGv_i64 tcg_op = tcg_temp_new_i64();
46
-#include "tc6393xb_template.h"
35
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
47
-#define BITS 16
36
bool swap = false;
48
-#include "tc6393xb_template.h"
37
int pass, maxpasses;
49
-#define BITS 24
38
50
-#include "tc6393xb_template.h"
39
- switch (opcode) {
51
#define BITS 32
40
- case 0x2e: /* FCMLT (zero) */
52
#include "tc6393xb_template.h"
41
- swap = true;
53
42
- /* fall through */
54
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
43
- case 0x2c: /* FCMGT (zero) */
55
{
44
- genfn = gen_helper_neon_cgt_f32;
56
- DisplaySurface *surface = qemu_console_surface(s->con);
57
-
58
- switch (surface_bits_per_pixel(surface)) {
59
- case 8:
60
- tc6393xb_draw_graphic8(s);
45
- break;
61
- break;
46
- case 0x2d: /* FCMEQ (zero) */
62
- case 15:
47
- genfn = gen_helper_neon_ceq_f32;
63
- tc6393xb_draw_graphic15(s);
48
- break;
64
- break;
49
- case 0x6d: /* FCMLE (zero) */
65
- case 16:
50
- swap = true;
66
- tc6393xb_draw_graphic16(s);
51
- /* fall through */
67
- break;
52
- case 0x6c: /* FCMGE (zero) */
68
- case 24:
53
- genfn = gen_helper_neon_cge_f32;
69
- tc6393xb_draw_graphic24(s);
70
- break;
71
- case 32:
72
- tc6393xb_draw_graphic32(s);
54
- break;
73
- break;
55
- default:
74
- default:
56
- g_assert_not_reached();
75
- printf("tc6393xb: unknown depth %d\n",
57
+ if (size == MO_16) {
76
- surface_bits_per_pixel(surface));
58
+ switch (opcode) {
77
- return;
59
+ case 0x2e: /* FCMLT (zero) */
78
- }
60
+ swap = true;
79
-
61
+ /* fall through */
80
+ tc6393xb_draw_graphic32(s);
62
+ case 0x2c: /* FCMGT (zero) */
81
dpy_gfx_update_full(s->con);
63
+ genfn = gen_helper_advsimd_cgt_f16;
82
}
64
+ break;
83
65
+ case 0x2d: /* FCMEQ (zero) */
66
+ genfn = gen_helper_advsimd_ceq_f16;
67
+ break;
68
+ case 0x6d: /* FCMLE (zero) */
69
+ swap = true;
70
+ /* fall through */
71
+ case 0x6c: /* FCMGE (zero) */
72
+ genfn = gen_helper_advsimd_cge_f16;
73
+ break;
74
+ default:
75
+ g_assert_not_reached();
76
+ }
77
+ } else {
78
+ switch (opcode) {
79
+ case 0x2e: /* FCMLT (zero) */
80
+ swap = true;
81
+ /* fall through */
82
+ case 0x2c: /* FCMGT (zero) */
83
+ genfn = gen_helper_neon_cgt_f32;
84
+ break;
85
+ case 0x2d: /* FCMEQ (zero) */
86
+ genfn = gen_helper_neon_ceq_f32;
87
+ break;
88
+ case 0x6d: /* FCMLE (zero) */
89
+ swap = true;
90
+ /* fall through */
91
+ case 0x6c: /* FCMGE (zero) */
92
+ genfn = gen_helper_neon_cge_f32;
93
+ break;
94
+ default:
95
+ g_assert_not_reached();
96
+ }
97
}
98
99
if (is_scalar) {
100
maxpasses = 1;
101
} else {
102
- maxpasses = is_q ? 4 : 2;
103
+ int vector_size = 8 << is_q;
104
+ maxpasses = vector_size >> size;
105
}
106
107
for (pass = 0; pass < maxpasses; pass++) {
108
- read_vec_element_i32(s, tcg_op, rn, pass, MO_32);
109
+ read_vec_element_i32(s, tcg_op, rn, pass, size);
110
if (swap) {
111
genfn(tcg_res, tcg_zero, tcg_op, fpst);
112
} else {
113
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
114
if (is_scalar) {
115
write_fp_sreg(s, rd, tcg_res);
116
} else {
117
- write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
118
+ write_vec_element_i32(s, tcg_res, rd, pass, size);
119
}
120
}
121
tcg_temp_free_i32(tcg_res);
122
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
123
fpop = deposit32(opcode, 5, 1, a);
124
fpop = deposit32(fpop, 6, 1, u);
125
126
+ rd = extract32(insn, 0, 5);
127
+ rn = extract32(insn, 5, 5);
128
+
129
switch (fpop) {
130
+ break;
131
+ case 0x2c: /* FCMGT (zero) */
132
+ case 0x2d: /* FCMEQ (zero) */
133
+ case 0x2e: /* FCMLT (zero) */
134
+ case 0x6c: /* FCMGE (zero) */
135
+ case 0x6d: /* FCMLE (zero) */
136
+ handle_2misc_fcmp_zero(s, fpop, is_scalar, 0, is_q, MO_16, rn, rd);
137
+ return;
138
case 0x18: /* FRINTN */
139
need_rmode = true;
140
only_in_vector = true;
141
--
84
--
142
2.16.2
85
2.20.1
143
86
144
87
diff view generated by jsdifflib
New patch
1
Now the template header is included only for BITS==32, expand
2
out all the macros that depended on the BITS setting.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215103215.4944-4-peter.maydell@linaro.org
7
---
8
hw/display/tc6393xb_template.h | 35 ++++------------------------------
9
1 file changed, 4 insertions(+), 31 deletions(-)
10
11
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/display/tc6393xb_template.h
14
+++ b/hw/display/tc6393xb_template.h
15
@@ -XXX,XX +XXX,XX @@
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
-#if BITS == 8
20
-# define SET_PIXEL(addr, color) (*(uint8_t *)addr = color)
21
-#elif BITS == 15 || BITS == 16
22
-# define SET_PIXEL(addr, color) (*(uint16_t *)addr = color)
23
-#elif BITS == 24
24
-# define SET_PIXEL(addr, color) \
25
- do { \
26
- addr[0] = color; \
27
- addr[1] = (color) >> 8; \
28
- addr[2] = (color) >> 16; \
29
- } while (0)
30
-#elif BITS == 32
31
-# define SET_PIXEL(addr, color) (*(uint32_t *)addr = color)
32
-#else
33
-# error unknown bit depth
34
-#endif
35
-
36
-
37
-static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
38
+static void tc6393xb_draw_graphic32(TC6393xbState *s)
39
{
40
DisplaySurface *surface = qemu_console_surface(s->con);
41
int i;
42
@@ -XXX,XX +XXX,XX @@ static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
43
data_buffer = s->vram_ptr;
44
data_display = surface_data(surface);
45
for(i = 0; i < s->scr_height; i++) {
46
-#if (BITS == 16)
47
- memcpy(data_display, data_buffer, s->scr_width * 2);
48
- data_buffer += s->scr_width;
49
- data_display += surface_stride(surface);
50
-#else
51
int j;
52
- for (j = 0; j < s->scr_width; j++, data_display += BITS / 8, data_buffer++) {
53
+ for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
54
uint16_t color = *data_buffer;
55
- uint32_t dest_color = glue(rgb_to_pixel, BITS)(
56
+ uint32_t dest_color = rgb_to_pixel32(
57
((color & 0xf800) * 0x108) >> 11,
58
((color & 0x7e0) * 0x41) >> 9,
59
((color & 0x1f) * 0x21) >> 2
60
);
61
- SET_PIXEL(data_display, dest_color);
62
+ *(uint32_t *)data_display = dest_color;
63
}
64
-#endif
65
}
66
}
67
-
68
-#undef BITS
69
-#undef SET_PIXEL
70
--
71
2.20.1
72
73
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The function tc6393xb_draw_graphic32() is called in exactly one place,
2
so just inline the function body at its callsite. This allows us to
3
drop the template header entirely.
2
4
3
The helpers use the new re-factored muladd support in SoftFloat for
5
The code move includes a single added space after 'for' to fix
4
the float16 work.
6
the coding style.
5
7
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20180227143852.11175-15-alex.bennee@linaro.org
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20210215103215.4944-5-peter.maydell@linaro.org
10
---
12
---
11
target/arm/translate-a64.c | 82 +++++++++++++++++++++++++++++++++++++---------
13
hw/display/tc6393xb_template.h | 45 ----------------------------------
12
1 file changed, 66 insertions(+), 16 deletions(-)
14
hw/display/tc6393xb.c | 23 ++++++++++++++---
15
2 files changed, 19 insertions(+), 49 deletions(-)
16
delete mode 100644 hw/display/tc6393xb_template.h
13
17
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
19
deleted file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- a/hw/display/tc6393xb_template.h
22
+++ /dev/null
23
@@ -XXX,XX +XXX,XX @@
24
-/*
25
- * Toshiba TC6393XB I/O Controller.
26
- * Found in Sharp Zaurus SL-6000 (tosa) or some
27
- * Toshiba e-Series PDAs.
28
- *
29
- * FB support code. Based on G364 fb emulator
30
- *
31
- * Copyright (c) 2007 Hervé Poussineau
32
- *
33
- * This program is free software; you can redistribute it and/or
34
- * modify it under the terms of the GNU General Public License as
35
- * published by the Free Software Foundation; either version 2 of
36
- * the License, or (at your option) any later version.
37
- *
38
- * This program is distributed in the hope that it will be useful,
39
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
40
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41
- * GNU General Public License for more details.
42
- *
43
- * You should have received a copy of the GNU General Public License along
44
- * with this program; if not, see <http://www.gnu.org/licenses/>.
45
- */
46
-
47
-static void tc6393xb_draw_graphic32(TC6393xbState *s)
48
-{
49
- DisplaySurface *surface = qemu_console_surface(s->con);
50
- int i;
51
- uint16_t *data_buffer;
52
- uint8_t *data_display;
53
-
54
- data_buffer = s->vram_ptr;
55
- data_display = surface_data(surface);
56
- for(i = 0; i < s->scr_height; i++) {
57
- int j;
58
- for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
59
- uint16_t color = *data_buffer;
60
- uint32_t dest_color = rgb_to_pixel32(
61
- ((color & 0xf800) * 0x108) >> 11,
62
- ((color & 0x7e0) * 0x41) >> 9,
63
- ((color & 0x1f) * 0x21) >> 2
64
- );
65
- *(uint32_t *)data_display = dest_color;
66
- }
67
- }
68
-}
69
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
15
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
71
--- a/hw/display/tc6393xb.c
17
+++ b/target/arm/translate-a64.c
72
+++ b/hw/display/tc6393xb.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
73
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
19
int rd = extract32(insn, 0, 5);
74
(uint32_t) addr, value & 0xff);
20
bool is_long = false;
75
}
21
bool is_fp = false;
76
22
+ bool is_fp16 = false;
77
-#define BITS 32
23
int index;
78
-#include "tc6393xb_template.h"
24
TCGv_ptr fpst;
79
-
25
80
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
26
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
81
{
27
}
82
- tc6393xb_draw_graphic32(s);
28
/* fall through */
83
+ DisplaySurface *surface = qemu_console_surface(s->con);
29
case 0x9: /* FMUL, FMULX */
84
+ int i;
30
- if (!extract32(size, 1, 1)) {
85
+ uint16_t *data_buffer;
31
+ if (size == 1) {
86
+ uint8_t *data_display;
32
unallocated_encoding(s);
87
+
33
return;
88
+ data_buffer = s->vram_ptr;
34
}
89
+ data_display = surface_data(surface);
35
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
90
+ for (i = 0; i < s->scr_height; i++) {
36
}
91
+ int j;
37
92
+ for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
38
if (is_fp) {
93
+ uint16_t color = *data_buffer;
39
- /* low bit of size indicates single/double */
94
+ uint32_t dest_color = rgb_to_pixel32(
40
- size = extract32(size, 0, 1) ? 3 : 2;
95
+ ((color & 0xf800) * 0x108) >> 11,
41
- if (size == 2) {
96
+ ((color & 0x7e0) * 0x41) >> 9,
42
+ /* convert insn encoded size to TCGMemOp size */
97
+ ((color & 0x1f) * 0x21) >> 2
43
+ switch (size) {
98
+ );
44
+ case 2: /* single precision */
99
+ *(uint32_t *)data_display = dest_color;
45
+ size = MO_32;
100
+ }
46
index = h << 1 | l;
101
+ }
47
- } else {
102
dpy_gfx_update_full(s->con);
48
+ rm |= (m << 4);
103
}
49
+ break;
104
50
+ case 3: /* double precision */
51
+ size = MO_64;
52
if (l || !is_q) {
53
unallocated_encoding(s);
54
return;
55
}
56
index = h;
57
+ rm |= (m << 4);
58
+ break;
59
+ case 0: /* half precision */
60
+ size = MO_16;
61
+ index = h << 2 | l << 1 | m;
62
+ is_fp16 = true;
63
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
64
+ break;
65
+ }
66
+ /* fallthru */
67
+ default: /* unallocated */
68
+ unallocated_encoding(s);
69
+ return;
70
}
71
- rm |= (m << 4);
72
} else {
73
switch (size) {
74
case 1:
75
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
76
}
77
78
if (is_fp) {
79
- fpst = get_fpstatus_ptr(false);
80
+ fpst = get_fpstatus_ptr(is_fp16);
81
} else {
82
fpst = NULL;
83
}
84
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
85
break;
86
}
87
case 0x5: /* FMLS */
88
- /* As usual for ARM, separate negation for fused multiply-add */
89
- gen_helper_vfp_negs(tcg_op, tcg_op);
90
- /* fall through */
91
case 0x1: /* FMLA */
92
- read_vec_element_i32(s, tcg_res, rd, pass, MO_32);
93
- gen_helper_vfp_muladds(tcg_res, tcg_op, tcg_idx, tcg_res, fpst);
94
+ read_vec_element_i32(s, tcg_res, rd, pass,
95
+ is_scalar ? size : MO_32);
96
+ switch (size) {
97
+ case 1:
98
+ if (opcode == 0x5) {
99
+ /* As usual for ARM, separate negation for fused
100
+ * multiply-add */
101
+ tcg_gen_xori_i32(tcg_op, tcg_op, 0x80008000);
102
+ }
103
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op, tcg_idx,
104
+ tcg_res, fpst);
105
+ break;
106
+ case 2:
107
+ if (opcode == 0x5) {
108
+ /* As usual for ARM, separate negation for
109
+ * fused multiply-add */
110
+ tcg_gen_xori_i32(tcg_op, tcg_op, 0x80000000);
111
+ }
112
+ gen_helper_vfp_muladds(tcg_res, tcg_op, tcg_idx,
113
+ tcg_res, fpst);
114
+ break;
115
+ default:
116
+ g_assert_not_reached();
117
+ }
118
break;
119
case 0x9: /* FMUL, FMULX */
120
- if (u) {
121
- gen_helper_vfp_mulxs(tcg_res, tcg_op, tcg_idx, fpst);
122
- } else {
123
- gen_helper_vfp_muls(tcg_res, tcg_op, tcg_idx, fpst);
124
+ switch (size) {
125
+ case 1:
126
+ if (u) {
127
+ gen_helper_advsimd_mulxh(tcg_res, tcg_op, tcg_idx,
128
+ fpst);
129
+ } else {
130
+ g_assert_not_reached();
131
+ }
132
+ break;
133
+ case 2:
134
+ if (u) {
135
+ gen_helper_vfp_mulxs(tcg_res, tcg_op, tcg_idx, fpst);
136
+ } else {
137
+ gen_helper_vfp_muls(tcg_res, tcg_op, tcg_idx, fpst);
138
+ }
139
+ break;
140
+ default:
141
+ g_assert_not_reached();
142
}
143
break;
144
case 0xc: /* SQDMULH */
145
--
105
--
146
2.16.2
106
2.20.1
147
107
148
108
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
The omap_lcdc template header is already only included once, for
2
DEPTH==32, but it still has all the macro-driven parameterization
3
for other depths. Expand out all the macros in the header.
2
4
3
Ensure that the post write hook is called during reset. This allows us
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
to rely on the post write functions instead of having to call them from
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
the reset() function.
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210215103215.4944-6-peter.maydell@linaro.org
9
---
10
hw/display/omap_lcd_template.h | 67 ++++++++++++++--------------------
11
1 file changed, 28 insertions(+), 39 deletions(-)
6
12
7
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
13
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: d131e24b911653a945e46ca2d8f90f572469e1dd.1517856214.git.alistair.francis@xilinx.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/register.h | 6 +++---
13
hw/core/register.c | 8 ++++++++
14
2 files changed, 11 insertions(+), 3 deletions(-)
15
16
diff --git a/include/hw/register.h b/include/hw/register.h
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/register.h
15
--- a/hw/display/omap_lcd_template.h
19
+++ b/include/hw/register.h
16
+++ b/hw/display/omap_lcd_template.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct RegisterInfoArray RegisterInfoArray;
17
@@ -XXX,XX +XXX,XX @@
21
* immediately before the actual write. The returned value is what is written,
18
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
* giving the handler a chance to modify the written value.
23
* @post_write: Post write callback. Passed the written value. Most write side
24
- * effects should be implemented here.
25
+ * effects should be implemented here. This is called during device reset.
26
*
27
* @post_read: Post read callback. Passes the value that is about to be returned
28
* for a read. The return value from this function is what is ultimately read,
29
@@ -XXX,XX +XXX,XX @@ uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix,
30
bool debug);
31
32
/**
33
- * reset a register
34
- * @reg: register to reset
35
+ * Resets a register. This will also call the post_write hook if it exists.
36
+ * @reg: The register to reset.
37
*/
19
*/
38
20
39
void register_reset(RegisterInfo *reg);
21
-#if DEPTH == 32
40
diff --git a/hw/core/register.c b/hw/core/register.c
22
-# define BPP 4
41
index XXXXXXX..XXXXXXX 100644
23
-# define PIXEL_TYPE uint32_t
42
--- a/hw/core/register.c
24
-#else
43
+++ b/hw/core/register.c
25
-# error unsupport depth
44
@@ -XXX,XX +XXX,XX @@ uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix,
26
-#endif
45
27
-
46
void register_reset(RegisterInfo *reg)
28
/*
29
* 2-bit colour
30
*/
31
-static void glue(draw_line2_, DEPTH)(void *opaque,
32
- uint8_t *d, const uint8_t *s, int width, int deststep)
33
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
34
+ int width, int deststep)
47
{
35
{
48
+ const RegisterAccessInfo *ac;
36
uint16_t *pal = opaque;
49
+
37
uint8_t v, r, g, b;
50
g_assert(reg);
38
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line2_, DEPTH)(void *opaque,
51
39
r = (pal[v & 3] >> 4) & 0xf0;
52
if (!reg->data || !reg->access) {
40
g = pal[v & 3] & 0xf0;
53
return;
41
b = (pal[v & 3] << 4) & 0xf0;
54
}
42
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
55
43
- d += BPP;
56
+ ac = reg->access;
44
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
57
+
45
+ d += 4;
58
register_write_val(reg, reg->access->reset);
46
v >>= 2;
59
+
47
r = (pal[v & 3] >> 4) & 0xf0;
60
+ if (ac->post_write) {
48
g = pal[v & 3] & 0xf0;
61
+ ac->post_write(reg, reg->access->reset);
49
b = (pal[v & 3] << 4) & 0xf0;
62
+ }
50
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
51
- d += BPP;
52
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
53
+ d += 4;
54
v >>= 2;
55
r = (pal[v & 3] >> 4) & 0xf0;
56
g = pal[v & 3] & 0xf0;
57
b = (pal[v & 3] << 4) & 0xf0;
58
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
59
- d += BPP;
60
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
61
+ d += 4;
62
v >>= 2;
63
r = (pal[v & 3] >> 4) & 0xf0;
64
g = pal[v & 3] & 0xf0;
65
b = (pal[v & 3] << 4) & 0xf0;
66
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
67
- d += BPP;
68
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
69
+ d += 4;
70
s ++;
71
width -= 4;
72
} while (width > 0);
73
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line2_, DEPTH)(void *opaque,
74
/*
75
* 4-bit colour
76
*/
77
-static void glue(draw_line4_, DEPTH)(void *opaque,
78
- uint8_t *d, const uint8_t *s, int width, int deststep)
79
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
80
+ int width, int deststep)
81
{
82
uint16_t *pal = opaque;
83
uint8_t v, r, g, b;
84
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line4_, DEPTH)(void *opaque,
85
r = (pal[v & 0xf] >> 4) & 0xf0;
86
g = pal[v & 0xf] & 0xf0;
87
b = (pal[v & 0xf] << 4) & 0xf0;
88
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
89
- d += BPP;
90
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
91
+ d += 4;
92
v >>= 4;
93
r = (pal[v & 0xf] >> 4) & 0xf0;
94
g = pal[v & 0xf] & 0xf0;
95
b = (pal[v & 0xf] << 4) & 0xf0;
96
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
97
- d += BPP;
98
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
99
+ d += 4;
100
s ++;
101
width -= 2;
102
} while (width > 0);
103
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line4_, DEPTH)(void *opaque,
104
/*
105
* 8-bit colour
106
*/
107
-static void glue(draw_line8_, DEPTH)(void *opaque,
108
- uint8_t *d, const uint8_t *s, int width, int deststep)
109
+static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
110
+ int width, int deststep)
111
{
112
uint16_t *pal = opaque;
113
uint8_t v, r, g, b;
114
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line8_, DEPTH)(void *opaque,
115
r = (pal[v] >> 4) & 0xf0;
116
g = pal[v] & 0xf0;
117
b = (pal[v] << 4) & 0xf0;
118
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
119
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
120
s ++;
121
- d += BPP;
122
+ d += 4;
123
} while (-- width != 0);
63
}
124
}
64
125
65
void register_init(RegisterInfo *reg)
126
/*
127
* 12-bit colour
128
*/
129
-static void glue(draw_line12_, DEPTH)(void *opaque,
130
- uint8_t *d, const uint8_t *s, int width, int deststep)
131
+static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
132
+ int width, int deststep)
133
{
134
uint16_t v;
135
uint8_t r, g, b;
136
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line12_, DEPTH)(void *opaque,
137
r = (v >> 4) & 0xf0;
138
g = v & 0xf0;
139
b = (v << 4) & 0xf0;
140
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
141
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
142
s += 2;
143
- d += BPP;
144
+ d += 4;
145
} while (-- width != 0);
146
}
147
148
/*
149
* 16-bit colour
150
*/
151
-static void glue(draw_line16_, DEPTH)(void *opaque,
152
- uint8_t *d, const uint8_t *s, int width, int deststep)
153
+static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
154
+ int width, int deststep)
155
{
156
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
157
memcpy(d, s, width * 2);
158
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line16_, DEPTH)(void *opaque,
159
r = (v >> 8) & 0xf8;
160
g = (v >> 3) & 0xfc;
161
b = (v << 3) & 0xf8;
162
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
163
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
164
s += 2;
165
- d += BPP;
166
+ d += 4;
167
} while (-- width != 0);
168
#endif
169
}
170
-
171
-#undef DEPTH
172
-#undef BPP
173
-#undef PIXEL_TYPE
66
--
174
--
67
2.16.2
175
2.20.1
68
176
69
177
diff view generated by jsdifflib
New patch
1
The draw_line16_32() function in the omap_lcdc template header
2
includes an ifdef for the case where HOST_WORDS_BIGENDIAN matches
3
TARGET_WORDS_BIGENDIAN. This is trying to optimise for "source
4
bitmap and destination bitmap format match", but it is broken,
5
because in this function the formats don't match: the source is
6
16-bit colour and the destination is 32-bit colour, so a memcpy()
7
will produce corrupted graphics output. Drop the bogus ifdef.
1
8
9
This bug was introduced in commit ea644cf343129, when we dropped
10
support for DEPTH values other than 32 from the template header.
11
The old #if line was
12
#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
13
and this was mistakenly changed to
14
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
15
rather than deleting the #if as now having an always-false condition.
16
17
Fixes: ea644cf343129
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20210215103215.4944-7-peter.maydell@linaro.org
22
---
23
hw/display/omap_lcd_template.h | 4 ----
24
1 file changed, 4 deletions(-)
25
26
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/display/omap_lcd_template.h
29
+++ b/hw/display/omap_lcd_template.h
30
@@ -XXX,XX +XXX,XX @@ static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
31
static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
32
int width, int deststep)
33
{
34
-#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
35
- memcpy(d, s, width * 2);
36
-#else
37
uint16_t v;
38
uint8_t r, g, b;
39
40
@@ -XXX,XX +XXX,XX @@ static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
41
s += 2;
42
d += 4;
43
} while (-- width != 0);
44
-#endif
45
}
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
New patch
1
Fix some minor coding style issues in the template header,
2
so checkpatch doesn't complain when we move the code.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215103215.4944-8-peter.maydell@linaro.org
8
---
9
hw/display/omap_lcd_template.h | 6 +++---
10
1 file changed, 3 insertions(+), 3 deletions(-)
11
12
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/display/omap_lcd_template.h
15
+++ b/hw/display/omap_lcd_template.h
16
@@ -XXX,XX +XXX,XX @@ static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
17
b = (pal[v & 3] << 4) & 0xf0;
18
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
19
d += 4;
20
- s ++;
21
+ s++;
22
width -= 4;
23
} while (width > 0);
24
}
25
@@ -XXX,XX +XXX,XX @@ static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
26
b = (pal[v & 0xf] << 4) & 0xf0;
27
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
28
d += 4;
29
- s ++;
30
+ s++;
31
width -= 2;
32
} while (width > 0);
33
}
34
@@ -XXX,XX +XXX,XX @@ static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
35
g = pal[v] & 0xf0;
36
b = (pal[v] << 4) & 0xf0;
37
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
38
- s ++;
39
+ s++;
40
d += 4;
41
} while (-- width != 0);
42
}
43
--
44
2.20.1
45
46
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
We only include the template header once, so just inline it into the
2
source file for the device.
2
3
3
This allows us to explicitly pass float16 to helpers rather than
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
assuming uint32_t and dealing with the result. Of course they will be
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
passed in i32 sized registers by default.
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215103215.4944-9-peter.maydell@linaro.org
8
---
9
hw/display/omap_lcd_template.h | 154 ---------------------------------
10
hw/display/omap_lcdc.c | 127 ++++++++++++++++++++++++++-
11
2 files changed, 125 insertions(+), 156 deletions(-)
12
delete mode 100644 hw/display/omap_lcd_template.h
6
13
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
14
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
deleted file mode 100644
9
Message-id: 20180227143852.11175-2-alex.bennee@linaro.org
16
index XXXXXXX..XXXXXXX
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
--- a/hw/display/omap_lcd_template.h
11
---
18
+++ /dev/null
12
include/exec/helper-head.h | 3 +++
19
@@ -XXX,XX +XXX,XX @@
13
1 file changed, 3 insertions(+)
20
-/*
14
21
- * QEMU OMAP LCD Emulator templates
15
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
22
- *
23
- * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
24
- *
25
- * Redistribution and use in source and binary forms, with or without
26
- * modification, are permitted provided that the following conditions
27
- * are met:
28
- *
29
- * 1. Redistributions of source code must retain the above copyright
30
- * notice, this list of conditions and the following disclaimer.
31
- * 2. Redistributions in binary form must reproduce the above copyright
32
- * notice, this list of conditions and the following disclaimer in
33
- * the documentation and/or other materials provided with the
34
- * distribution.
35
- *
36
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
37
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
38
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
40
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
41
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
42
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
43
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
44
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
- */
48
-
49
-/*
50
- * 2-bit colour
51
- */
52
-static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
53
- int width, int deststep)
54
-{
55
- uint16_t *pal = opaque;
56
- uint8_t v, r, g, b;
57
-
58
- do {
59
- v = ldub_p((void *) s);
60
- r = (pal[v & 3] >> 4) & 0xf0;
61
- g = pal[v & 3] & 0xf0;
62
- b = (pal[v & 3] << 4) & 0xf0;
63
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
64
- d += 4;
65
- v >>= 2;
66
- r = (pal[v & 3] >> 4) & 0xf0;
67
- g = pal[v & 3] & 0xf0;
68
- b = (pal[v & 3] << 4) & 0xf0;
69
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
70
- d += 4;
71
- v >>= 2;
72
- r = (pal[v & 3] >> 4) & 0xf0;
73
- g = pal[v & 3] & 0xf0;
74
- b = (pal[v & 3] << 4) & 0xf0;
75
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
76
- d += 4;
77
- v >>= 2;
78
- r = (pal[v & 3] >> 4) & 0xf0;
79
- g = pal[v & 3] & 0xf0;
80
- b = (pal[v & 3] << 4) & 0xf0;
81
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
82
- d += 4;
83
- s++;
84
- width -= 4;
85
- } while (width > 0);
86
-}
87
-
88
-/*
89
- * 4-bit colour
90
- */
91
-static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
92
- int width, int deststep)
93
-{
94
- uint16_t *pal = opaque;
95
- uint8_t v, r, g, b;
96
-
97
- do {
98
- v = ldub_p((void *) s);
99
- r = (pal[v & 0xf] >> 4) & 0xf0;
100
- g = pal[v & 0xf] & 0xf0;
101
- b = (pal[v & 0xf] << 4) & 0xf0;
102
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
103
- d += 4;
104
- v >>= 4;
105
- r = (pal[v & 0xf] >> 4) & 0xf0;
106
- g = pal[v & 0xf] & 0xf0;
107
- b = (pal[v & 0xf] << 4) & 0xf0;
108
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
109
- d += 4;
110
- s++;
111
- width -= 2;
112
- } while (width > 0);
113
-}
114
-
115
-/*
116
- * 8-bit colour
117
- */
118
-static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
119
- int width, int deststep)
120
-{
121
- uint16_t *pal = opaque;
122
- uint8_t v, r, g, b;
123
-
124
- do {
125
- v = ldub_p((void *) s);
126
- r = (pal[v] >> 4) & 0xf0;
127
- g = pal[v] & 0xf0;
128
- b = (pal[v] << 4) & 0xf0;
129
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
130
- s++;
131
- d += 4;
132
- } while (-- width != 0);
133
-}
134
-
135
-/*
136
- * 12-bit colour
137
- */
138
-static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
139
- int width, int deststep)
140
-{
141
- uint16_t v;
142
- uint8_t r, g, b;
143
-
144
- do {
145
- v = lduw_le_p((void *) s);
146
- r = (v >> 4) & 0xf0;
147
- g = v & 0xf0;
148
- b = (v << 4) & 0xf0;
149
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
150
- s += 2;
151
- d += 4;
152
- } while (-- width != 0);
153
-}
154
-
155
-/*
156
- * 16-bit colour
157
- */
158
-static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
159
- int width, int deststep)
160
-{
161
- uint16_t v;
162
- uint8_t r, g, b;
163
-
164
- do {
165
- v = lduw_le_p((void *) s);
166
- r = (v >> 8) & 0xf8;
167
- g = (v >> 3) & 0xfc;
168
- b = (v << 3) & 0xf8;
169
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
170
- s += 2;
171
- d += 4;
172
- } while (-- width != 0);
173
-}
174
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
16
index XXXXXXX..XXXXXXX 100644
175
index XXXXXXX..XXXXXXX 100644
17
--- a/include/exec/helper-head.h
176
--- a/hw/display/omap_lcdc.c
18
+++ b/include/exec/helper-head.h
177
+++ b/hw/display/omap_lcdc.c
19
@@ -XXX,XX +XXX,XX @@
178
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
20
#define dh_alias_int i32
179
21
#define dh_alias_i64 i64
180
#define draw_line_func drawfn
22
#define dh_alias_s64 i64
181
23
+#define dh_alias_f16 i32
182
-#define DEPTH 32
24
#define dh_alias_f32 i32
183
-#include "omap_lcd_template.h"
25
#define dh_alias_f64 i64
184
+/*
26
#define dh_alias_ptr ptr
185
+ * 2-bit colour
27
@@ -XXX,XX +XXX,XX @@
186
+ */
28
#define dh_ctype_int int
187
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
29
#define dh_ctype_i64 uint64_t
188
+ int width, int deststep)
30
#define dh_ctype_s64 int64_t
189
+{
31
+#define dh_ctype_f16 float16
190
+ uint16_t *pal = opaque;
32
#define dh_ctype_f32 float32
191
+ uint8_t v, r, g, b;
33
#define dh_ctype_f64 float64
192
+
34
#define dh_ctype_ptr void *
193
+ do {
35
@@ -XXX,XX +XXX,XX @@
194
+ v = ldub_p((void *) s);
36
#define dh_is_signed_s32 1
195
+ r = (pal[v & 3] >> 4) & 0xf0;
37
#define dh_is_signed_i64 0
196
+ g = pal[v & 3] & 0xf0;
38
#define dh_is_signed_s64 1
197
+ b = (pal[v & 3] << 4) & 0xf0;
39
+#define dh_is_signed_f16 0
198
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
40
#define dh_is_signed_f32 0
199
+ d += 4;
41
#define dh_is_signed_f64 0
200
+ v >>= 2;
42
#define dh_is_signed_tl 0
201
+ r = (pal[v & 3] >> 4) & 0xf0;
202
+ g = pal[v & 3] & 0xf0;
203
+ b = (pal[v & 3] << 4) & 0xf0;
204
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
205
+ d += 4;
206
+ v >>= 2;
207
+ r = (pal[v & 3] >> 4) & 0xf0;
208
+ g = pal[v & 3] & 0xf0;
209
+ b = (pal[v & 3] << 4) & 0xf0;
210
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
211
+ d += 4;
212
+ v >>= 2;
213
+ r = (pal[v & 3] >> 4) & 0xf0;
214
+ g = pal[v & 3] & 0xf0;
215
+ b = (pal[v & 3] << 4) & 0xf0;
216
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
217
+ d += 4;
218
+ s++;
219
+ width -= 4;
220
+ } while (width > 0);
221
+}
222
+
223
+/*
224
+ * 4-bit colour
225
+ */
226
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
227
+ int width, int deststep)
228
+{
229
+ uint16_t *pal = opaque;
230
+ uint8_t v, r, g, b;
231
+
232
+ do {
233
+ v = ldub_p((void *) s);
234
+ r = (pal[v & 0xf] >> 4) & 0xf0;
235
+ g = pal[v & 0xf] & 0xf0;
236
+ b = (pal[v & 0xf] << 4) & 0xf0;
237
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
238
+ d += 4;
239
+ v >>= 4;
240
+ r = (pal[v & 0xf] >> 4) & 0xf0;
241
+ g = pal[v & 0xf] & 0xf0;
242
+ b = (pal[v & 0xf] << 4) & 0xf0;
243
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
244
+ d += 4;
245
+ s++;
246
+ width -= 2;
247
+ } while (width > 0);
248
+}
249
+
250
+/*
251
+ * 8-bit colour
252
+ */
253
+static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
254
+ int width, int deststep)
255
+{
256
+ uint16_t *pal = opaque;
257
+ uint8_t v, r, g, b;
258
+
259
+ do {
260
+ v = ldub_p((void *) s);
261
+ r = (pal[v] >> 4) & 0xf0;
262
+ g = pal[v] & 0xf0;
263
+ b = (pal[v] << 4) & 0xf0;
264
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
265
+ s++;
266
+ d += 4;
267
+ } while (-- width != 0);
268
+}
269
+
270
+/*
271
+ * 12-bit colour
272
+ */
273
+static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
274
+ int width, int deststep)
275
+{
276
+ uint16_t v;
277
+ uint8_t r, g, b;
278
+
279
+ do {
280
+ v = lduw_le_p((void *) s);
281
+ r = (v >> 4) & 0xf0;
282
+ g = v & 0xf0;
283
+ b = (v << 4) & 0xf0;
284
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
285
+ s += 2;
286
+ d += 4;
287
+ } while (-- width != 0);
288
+}
289
+
290
+/*
291
+ * 16-bit colour
292
+ */
293
+static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
294
+ int width, int deststep)
295
+{
296
+ uint16_t v;
297
+ uint8_t r, g, b;
298
+
299
+ do {
300
+ v = lduw_le_p((void *) s);
301
+ r = (v >> 8) & 0xf8;
302
+ g = (v >> 3) & 0xfc;
303
+ b = (v << 3) & 0xf8;
304
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
305
+ s += 2;
306
+ d += 4;
307
+ } while (-- width != 0);
308
+}
309
310
static void omap_update_display(void *opaque)
311
{
43
--
312
--
44
2.16.2
313
2.20.1
45
314
46
315
diff view generated by jsdifflib
New patch
1
The macro draw_line_func is used only once; just expand it.
1
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210215103215.4944-10-peter.maydell@linaro.org
7
---
8
hw/display/omap_lcdc.c | 4 +---
9
1 file changed, 1 insertion(+), 3 deletions(-)
10
11
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/display/omap_lcdc.c
14
+++ b/hw/display/omap_lcdc.c
15
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
16
qemu_irq_lower(s->irq);
17
}
18
19
-#define draw_line_func drawfn
20
-
21
/*
22
* 2-bit colour
23
*/
24
@@ -XXX,XX +XXX,XX @@ static void omap_update_display(void *opaque)
25
{
26
struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
27
DisplaySurface *surface;
28
- draw_line_func draw_line;
29
+ drawfn draw_line;
30
int size, height, first, last;
31
int width, linesize, step, bpp, frame_offset;
32
hwaddr frame_base;
33
--
34
2.20.1
35
36
diff view generated by jsdifflib
1
From: Linus Walleij <linus.walleij@linaro.org>
1
For a long time now the UI layer has guaranteed that the console
2
surface is always 32 bits per pixel, RGB. The TCX code already
3
assumes 32bpp, but it still has some checks of is_surface_bgr()
4
in an attempt to support 32bpp BGR. is_surface_bgr() will always
5
return false for the qemu_console_surface(), unless the display
6
device itself has deliberately created an alternate-format
7
surface via a function like qemu_create_displaysurface_from().
2
8
3
This adds the SiI9022 (and implicitly EDID I2C) device to the ARM
9
Drop the never-used BGR-handling code, and assert that we have
4
Versatile Express machine, and selects the two I2C devices necessary
10
a 32-bit surface rather than just doing nothing if it isn't.
5
in the arm-softmmu.mak configuration so everything will build
6
smoothly.
7
11
8
I am implementing proper handling of the graphics in the Linux
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
kernel and adding proper emulation of SiI9022 and EDID makes the
13
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
10
driver probe as nicely as before, retrieving the resolutions
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
supported by the "QEMU monitor" and overall just working nice.
15
Message-id: 20210215102149.20513-1-peter.maydell@linaro.org
16
---
17
hw/display/tcx.c | 31 ++++++++-----------------------
18
1 file changed, 8 insertions(+), 23 deletions(-)
12
19
13
Cc: Peter Maydell <peter.maydell@linaro.org>
20
diff --git a/hw/display/tcx.c b/hw/display/tcx.c
14
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
15
Message-id: 20180227104903.21353-6-linus.walleij@linaro.org
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
hw/arm/vexpress.c | 6 +++++-
21
default-configs/arm-softmmu.mak | 2 ++
22
2 files changed, 7 insertions(+), 1 deletion(-)
23
24
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
25
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/vexpress.c
22
--- a/hw/display/tcx.c
27
+++ b/hw/arm/vexpress.c
23
+++ b/hw/display/tcx.c
28
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ static int tcx_check_dirty(TCXState *s, DirtyBitmapSnapshot *snap,
29
#include "hw/arm/arm.h"
25
30
#include "hw/arm/primecell.h"
26
static void update_palette_entries(TCXState *s, int start, int end)
31
#include "hw/devices.h"
27
{
32
+#include "hw/i2c/i2c.h"
28
- DisplaySurface *surface = qemu_console_surface(s->con);
33
#include "net/net.h"
29
int i;
34
#include "sysemu/sysemu.h"
30
35
#include "hw/boards.h"
31
for (i = start; i < end; i++) {
36
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
32
- if (is_surface_bgr(surface)) {
37
uint32_t sys_id;
33
- s->palette[i] = rgb_to_pixel32bgr(s->r[i], s->g[i], s->b[i]);
38
DriveInfo *dinfo;
34
- } else {
39
pflash_t *pflash0;
35
- s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
40
+ I2CBus *i2c;
36
- }
41
ram_addr_t vram_size, sram_size;
37
+ s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
42
MemoryRegion *sysmem = get_system_memory();
38
}
43
MemoryRegion *vram = g_new(MemoryRegion, 1);
39
tcx_set_dirty(s, 0, memory_region_size(&s->vram_mem));
44
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
40
}
45
sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]);
41
@@ -XXX,XX +XXX,XX @@ static void tcx_draw_cursor32(TCXState *s1, uint8_t *d,
46
sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]);
42
}
47
43
48
- /* VE_SERIALDVI: not modelled */
44
/*
49
+ dev = sysbus_create_simple("versatile_i2c", map[VE_SERIALDVI], NULL);
45
- XXX Could be much more optimal:
50
+ i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
46
- * detect if line/page/whole screen is in 24 bit mode
51
+ i2c_create_slave(i2c, "sii9022", 0x39);
47
- * if destination is also BGR, use memcpy
52
48
- */
53
sysbus_create_simple("pl031", map[VE_RTC], pic[4]); /* RTC */
49
+ * XXX Could be much more optimal:
54
50
+ * detect if line/page/whole screen is in 24 bit mode
55
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
51
+ */
56
index XXXXXXX..XXXXXXX 100644
52
static inline void tcx24_draw_line32(TCXState *s1, uint8_t *d,
57
--- a/default-configs/arm-softmmu.mak
53
const uint8_t *s, int width,
58
+++ b/default-configs/arm-softmmu.mak
54
const uint32_t *cplane,
59
@@ -XXX,XX +XXX,XX @@ CONFIG_STELLARIS_INPUT=y
55
const uint32_t *s24)
60
CONFIG_STELLARIS_ENET=y
56
{
61
CONFIG_SSD0303=y
57
- DisplaySurface *surface = qemu_console_surface(s1->con);
62
CONFIG_SSD0323=y
58
- int x, bgr, r, g, b;
63
+CONFIG_DDC=y
59
+ int x, r, g, b;
64
+CONFIG_SII9022=y
60
uint8_t val, *p8;
65
CONFIG_ADS7846=y
61
uint32_t *p = (uint32_t *)d;
66
CONFIG_MAX111X=y
62
uint32_t dval;
67
CONFIG_SSI=y
63
- bgr = is_surface_bgr(surface);
64
for(x = 0; x < width; x++, s++, s24++) {
65
if (be32_to_cpu(*cplane) & 0x03000000) {
66
/* 24-bit direct, BGR order */
67
@@ -XXX,XX +XXX,XX @@ static inline void tcx24_draw_line32(TCXState *s1, uint8_t *d,
68
b = *p8++;
69
g = *p8++;
70
r = *p8;
71
- if (bgr)
72
- dval = rgb_to_pixel32bgr(r, g, b);
73
- else
74
- dval = rgb_to_pixel32(r, g, b);
75
+ dval = rgb_to_pixel32(r, g, b);
76
} else {
77
/* 8-bit pseudocolor */
78
val = *s;
79
@@ -XXX,XX +XXX,XX @@ static void tcx_update_display(void *opaque)
80
int y, y_start, dd, ds;
81
uint8_t *d, *s;
82
83
- if (surface_bits_per_pixel(surface) != 32) {
84
- return;
85
- }
86
+ assert(surface_bits_per_pixel(surface) == 32);
87
88
page = 0;
89
y_start = -1;
90
@@ -XXX,XX +XXX,XX @@ static void tcx24_update_display(void *opaque)
91
uint8_t *d, *s;
92
uint32_t *cptr, *s24;
93
94
- if (surface_bits_per_pixel(surface) != 32) {
95
- return;
96
- }
97
+ assert(surface_bits_per_pixel(surface) == 32);
98
99
page = 0;
100
y_start = -1;
68
--
101
--
69
2.16.2
102
2.20.1
70
103
71
104
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The AN524 has a different SYSCLK frequency from the AN505 and AN521;
2
make the SYSCLK frequency a field in the MPS2TZMachineClass rather
3
than a compile-time constant so we can support the AN524.
2
4
3
The fprintf is only there for debugging as the skeleton is added to,
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
it will be removed once the skeleton is complete.
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-2-peter.maydell@linaro.org
9
---
10
hw/arm/mps2-tz.c | 10 ++++++----
11
1 file changed, 6 insertions(+), 4 deletions(-)
5
12
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180227143852.11175-10-alex.bennee@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/helper-a64.h | 4 ++++
12
target/arm/helper-a64.c | 4 ++++
13
target/arm/translate-a64.c | 28 ++++++++++++++++++++++++++++
14
3 files changed, 36 insertions(+)
15
16
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-a64.h
15
--- a/hw/arm/mps2-tz.c
19
+++ b/target/arm/helper-a64.h
16
+++ b/hw/arm/mps2-tz.c
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(advsimd_maxh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
21
DEF_HELPER_FLAGS_3(advsimd_minh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
18
MachineClass parent;
22
DEF_HELPER_FLAGS_3(advsimd_maxnumh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
19
MPS2TZFPGAType fpga_type;
23
DEF_HELPER_FLAGS_3(advsimd_minnumh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
20
uint32_t scc_id;
24
+DEF_HELPER_3(advsimd_addh, f16, f16, f16, ptr)
21
+ uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
25
+DEF_HELPER_3(advsimd_subh, f16, f16, f16, ptr)
22
const char *armsse_type;
26
+DEF_HELPER_3(advsimd_mulh, f16, f16, f16, ptr)
23
};
27
+DEF_HELPER_3(advsimd_divh, f16, f16, f16, ptr)
24
28
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
25
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
29
index XXXXXXX..XXXXXXX 100644
26
30
--- a/target/arm/helper-a64.c
27
OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
31
+++ b/target/arm/helper-a64.c
28
32
@@ -XXX,XX +XXX,XX @@ float16 ADVSIMD_HELPER(name, h)(float16 a, float16 b, void *fpstp) \
29
-/* Main SYSCLK frequency in Hz */
33
return float16_ ## name(a, b, fpst); \
30
-#define SYSCLK_FRQ 20000000
31
/* Slow 32Khz S32KCLK frequency in Hz */
32
#define S32KCLK_FRQ (32 * 1000)
33
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
35
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
36
const char *name, hwaddr size)
37
{
38
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
39
CMSDKAPBUART *uart = opaque;
40
int i = uart - &mms->uart[0];
41
int rxirqno = i * 2;
42
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
43
44
object_initialize_child(OBJECT(mms), name, uart, TYPE_CMSDK_APB_UART);
45
qdev_prop_set_chr(DEVICE(uart), "chardev", serial_hd(i));
46
- qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", SYSCLK_FRQ);
47
+ qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
48
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
49
s = SYS_BUS_DEVICE(uart);
50
sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
51
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
52
53
/* These clocks don't need migration because they are fixed-frequency */
54
mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
55
- clock_set_hz(mms->sysclk, SYSCLK_FRQ);
56
+ clock_set_hz(mms->sysclk, mmc->sysclk_frq);
57
mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
58
clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
59
60
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
61
mmc->fpga_type = FPGA_AN505;
62
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
63
mmc->scc_id = 0x41045050;
64
+ mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
65
mmc->armsse_type = TYPE_IOTKIT;
34
}
66
}
35
67
36
+ADVSIMD_HALFOP(add)
68
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
37
+ADVSIMD_HALFOP(sub)
69
mmc->fpga_type = FPGA_AN521;
38
+ADVSIMD_HALFOP(mul)
70
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
39
+ADVSIMD_HALFOP(div)
71
mmc->scc_id = 0x41045210;
40
ADVSIMD_HALFOP(min)
72
+ mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
41
ADVSIMD_HALFOP(max)
73
mmc->armsse_type = TYPE_SSE200;
42
ADVSIMD_HALFOP(minnum)
74
}
43
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
75
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/translate-a64.c
46
+++ b/target/arm/translate-a64.c
47
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
48
read_vec_element_i32(s, tcg_op2, rm, pass, MO_16);
49
50
switch (fpopcode) {
51
+ case 0x0: /* FMAXNM */
52
+ gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
53
+ break;
54
+ case 0x2: /* FADD */
55
+ gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
56
+ break;
57
+ case 0x6: /* FMAX */
58
+ gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
59
+ break;
60
+ case 0x8: /* FMINNM */
61
+ gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
62
+ break;
63
+ case 0xa: /* FSUB */
64
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
65
+ break;
66
+ case 0xe: /* FMIN */
67
+ gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
68
+ break;
69
+ case 0x13: /* FMUL */
70
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
71
+ break;
72
+ case 0x17: /* FDIV */
73
+ gen_helper_advsimd_divh(tcg_res, tcg_op1, tcg_op2, fpst);
74
+ break;
75
+ case 0x1a: /* FABD */
76
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
77
+ tcg_gen_andi_i32(tcg_res, tcg_res, 0x7fff);
78
+ break;
79
default:
80
fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
81
__func__, insn, fpopcode, s->pc);
82
--
76
--
83
2.16.2
77
2.20.1
84
78
85
79
diff view generated by jsdifflib
1
From: Corey Minyard <cminyard@mvista.com>
1
Currently the MPS2 SCC device implements a fixed number of OSCCLK
2
values (3). The variant of this device in the MPS3 AN524 board has 6
3
OSCCLK values. Switch to using a PROP_ARRAY, which allows board code
4
to specify how large the OSCCLK array should be as well as its
5
values.
2
6
3
Some devices need access to it.
7
With a variable-length property array, the SCC no longer specifies
8
default values for the OSCCLKs, so we must set them explicitly in the
9
board code. This defaults are actually incorrect for the an521 and
10
an505; we will correct this bug in a following patch.
4
11
5
Signed-off-by: Corey Minyard <cminyard@mvista.com>
12
This is a migration compatibility break for all the mps boards.
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
7
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
8
Message-id: 20180227104903.21353-3-linus.walleij@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20210215115138.20465-3-peter.maydell@linaro.org
10
---
18
---
11
include/hw/i2c/i2c.h | 17 +++++++++++++++++
19
include/hw/misc/mps2-scc.h | 7 +++----
12
hw/i2c/core.c | 17 -----------------
20
hw/arm/mps2-tz.c | 5 +++++
13
2 files changed, 17 insertions(+), 17 deletions(-)
21
hw/arm/mps2.c | 5 +++++
22
hw/misc/mps2-scc.c | 24 +++++++++++++-----------
23
4 files changed, 26 insertions(+), 15 deletions(-)
14
24
15
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
25
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
16
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/i2c/i2c.h
27
--- a/include/hw/misc/mps2-scc.h
18
+++ b/include/hw/i2c/i2c.h
28
+++ b/include/hw/misc/mps2-scc.h
19
@@ -XXX,XX +XXX,XX @@ struct I2CSlave {
29
@@ -XXX,XX +XXX,XX @@
20
uint8_t address;
30
#define TYPE_MPS2_SCC "mps2-scc"
31
OBJECT_DECLARE_SIMPLE_TYPE(MPS2SCC, MPS2_SCC)
32
33
-#define NUM_OSCCLK 3
34
-
35
struct MPS2SCC {
36
/*< private >*/
37
SysBusDevice parent_obj;
38
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
39
uint32_t dll;
40
uint32_t aid;
41
uint32_t id;
42
- uint32_t oscclk[NUM_OSCCLK];
43
- uint32_t oscclk_reset[NUM_OSCCLK];
44
+ uint32_t num_oscclk;
45
+ uint32_t *oscclk;
46
+ uint32_t *oscclk_reset;
21
};
47
};
22
48
23
+#define TYPE_I2C_BUS "i2c-bus"
49
#endif
24
+#define I2C_BUS(obj) OBJECT_CHECK(I2CBus, (obj), TYPE_I2C_BUS)
50
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/arm/mps2-tz.c
53
+++ b/hw/arm/mps2-tz.c
54
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
55
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
56
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
57
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
58
+ /* This will need to be per-FPGA image eventually */
59
+ qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
60
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
61
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
62
+ qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
63
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
64
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
65
}
66
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/mps2.c
69
+++ b/hw/arm/mps2.c
70
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
71
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
72
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
73
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
74
+ /* All these FPGA images have the same OSCCLK configuration */
75
+ qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
76
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
77
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
78
+ qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
79
sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
80
sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
81
object_initialize_child(OBJECT(mms), "fpgaio",
82
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/misc/mps2-scc.c
85
+++ b/hw/misc/mps2-scc.c
86
@@ -XXX,XX +XXX,XX @@ static bool scc_cfg_write(MPS2SCC *s, unsigned function,
87
{
88
trace_mps2_scc_cfg_write(function, device, value);
89
90
- if (function != 1 || device >= NUM_OSCCLK) {
91
+ if (function != 1 || device >= s->num_oscclk) {
92
qemu_log_mask(LOG_GUEST_ERROR,
93
"MPS2 SCC config write: bad function %d device %d\n",
94
function, device);
95
@@ -XXX,XX +XXX,XX @@ static bool scc_cfg_write(MPS2SCC *s, unsigned function,
96
static bool scc_cfg_read(MPS2SCC *s, unsigned function,
97
unsigned device, uint32_t *value)
98
{
99
- if (function != 1 || device >= NUM_OSCCLK) {
100
+ if (function != 1 || device >= s->num_oscclk) {
101
qemu_log_mask(LOG_GUEST_ERROR,
102
"MPS2 SCC config read: bad function %d device %d\n",
103
function, device);
104
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_reset(DeviceState *dev)
105
s->cfgctrl = 0x100000;
106
s->cfgstat = 0;
107
s->dll = 0xffff0001;
108
- for (i = 0; i < NUM_OSCCLK; i++) {
109
+ for (i = 0; i < s->num_oscclk; i++) {
110
s->oscclk[i] = s->oscclk_reset[i];
111
}
112
for (i = 0; i < ARRAY_SIZE(s->led); i++) {
113
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_realize(DeviceState *dev, Error **errp)
114
LED_COLOR_GREEN, name);
115
g_free(name);
116
}
25
+
117
+
26
+typedef struct I2CNode I2CNode;
118
+ s->oscclk = g_new0(uint32_t, s->num_oscclk);
27
+
119
}
28
+struct I2CNode {
120
29
+ I2CSlave *elt;
121
static const VMStateDescription mps2_scc_vmstate = {
30
+ QLIST_ENTRY(I2CNode) next;
122
.name = "mps2-scc",
31
+};
123
- .version_id = 1,
32
+
124
- .minimum_version_id = 1,
33
+struct I2CBus {
125
+ .version_id = 2,
34
+ BusState qbus;
126
+ .minimum_version_id = 2,
35
+ QLIST_HEAD(, I2CNode) current_devs;
127
.fields = (VMStateField[]) {
36
+ uint8_t saved_address;
128
VMSTATE_UINT32(cfg0, MPS2SCC),
37
+ bool broadcast;
129
VMSTATE_UINT32(cfg1, MPS2SCC),
38
+};
130
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
39
+
131
VMSTATE_UINT32(cfgctrl, MPS2SCC),
40
I2CBus *i2c_init_bus(DeviceState *parent, const char *name);
132
VMSTATE_UINT32(cfgstat, MPS2SCC),
41
void i2c_set_slave_address(I2CSlave *dev, uint8_t address);
133
VMSTATE_UINT32(dll, MPS2SCC),
42
int i2c_bus_busy(I2CBus *bus);
134
- VMSTATE_UINT32_ARRAY(oscclk, MPS2SCC, NUM_OSCCLK),
43
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
135
+ VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
44
index XXXXXXX..XXXXXXX 100644
136
+ 0, vmstate_info_uint32, uint32_t),
45
--- a/hw/i2c/core.c
137
VMSTATE_END_OF_LIST()
46
+++ b/hw/i2c/core.c
138
}
47
@@ -XXX,XX +XXX,XX @@
139
};
48
#include "qemu/osdep.h"
140
@@ -XXX,XX +XXX,XX @@ static Property mps2_scc_properties[] = {
49
#include "hw/i2c/i2c.h"
141
DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0),
50
142
DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
51
-typedef struct I2CNode I2CNode;
143
DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0),
52
-
144
- /* These are the initial settings for the source clocks on the board.
53
-struct I2CNode {
145
+ /*
54
- I2CSlave *elt;
146
+ * These are the initial settings for the source clocks on the board.
55
- QLIST_ENTRY(I2CNode) next;
147
* In hardware they can be configured via a config file read by the
56
-};
148
* motherboard configuration controller to suit the FPGA image.
57
-
149
- * These default values are used by most of the standard FPGA images.
58
#define I2C_BROADCAST 0x00
150
*/
59
151
- DEFINE_PROP_UINT32("oscclk0", MPS2SCC, oscclk_reset[0], 50000000),
60
-struct I2CBus {
152
- DEFINE_PROP_UINT32("oscclk1", MPS2SCC, oscclk_reset[1], 24576000),
61
- BusState qbus;
153
- DEFINE_PROP_UINT32("oscclk2", MPS2SCC, oscclk_reset[2], 25000000),
62
- QLIST_HEAD(, I2CNode) current_devs;
154
+ DEFINE_PROP_ARRAY("oscclk", MPS2SCC, num_oscclk, oscclk_reset,
63
- uint8_t saved_address;
155
+ qdev_prop_uint32, uint32_t),
64
- bool broadcast;
65
-};
66
-
67
static Property i2c_props[] = {
68
DEFINE_PROP_UINT8("address", struct I2CSlave, address, 0),
69
DEFINE_PROP_END_OF_LIST(),
156
DEFINE_PROP_END_OF_LIST(),
70
};
157
};
71
158
72
-#define TYPE_I2C_BUS "i2c-bus"
73
-#define I2C_BUS(obj) OBJECT_CHECK(I2CBus, (obj), TYPE_I2C_BUS)
74
-
75
static const TypeInfo i2c_bus_info = {
76
.name = TYPE_I2C_BUS,
77
.parent = TYPE_BUS,
78
--
159
--
79
2.16.2
160
2.20.1
80
161
81
162
diff view generated by jsdifflib
New patch
1
We were previously using the default OSCCLK settings, which are
2
correct for the older MPS2 boards (mps2-an385, mps2-an386,
3
mps2-an500, mps2-an511), but wrong for the mps2-an505 and mps2-511
4
implemented in mps2-tz.c. Now we're setting the values explicitly we
5
can fix them to be correct.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210215115138.20465-4-peter.maydell@linaro.org
11
---
12
hw/arm/mps2-tz.c | 4 ++--
13
1 file changed, 2 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
18
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
20
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
21
/* This will need to be per-FPGA image eventually */
22
qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
23
- qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
24
- qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
25
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 40000000);
26
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24580000);
27
qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
28
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
29
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The AN505 and AN511 happen to share the same OSCCLK values, but the
2
AN524 will have a different set (and more of them), so split the
3
settings out to be per-board.
2
4
3
We do implement all the opcodes.
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-5-peter.maydell@linaro.org
9
---
10
hw/arm/mps2-tz.c | 23 ++++++++++++++++++-----
11
1 file changed, 18 insertions(+), 5 deletions(-)
4
12
5
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180227143852.11175-8-alex.bennee@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 3 +--
11
1 file changed, 1 insertion(+), 2 deletions(-)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
15
--- a/hw/arm/mps2-tz.c
16
+++ b/target/arm/translate-a64.c
16
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ static void handle_3same_64(DisasContext *s, int opcode, bool u,
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
18
/* Handle 64x64->64 opcodes which are shared between the scalar
18
MPS2TZFPGAType fpga_type;
19
* and vector 3-same groups. We cover every opcode where size == 3
19
uint32_t scc_id;
20
* is valid in either the three-reg-same (integer, not pairwise)
20
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
21
- * or scalar-three-reg-same groups. (Some opcodes are not yet
21
+ uint32_t len_oscclk;
22
- * implemented.)
22
+ const uint32_t *oscclk;
23
+ * or scalar-three-reg-same groups.
23
const char *armsse_type;
24
*/
24
};
25
TCGCond cond;
25
26
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
27
/* Slow 32Khz S32KCLK frequency in Hz */
28
#define S32KCLK_FRQ (32 * 1000)
29
30
+static const uint32_t an505_oscclk[] = {
31
+ 40000000,
32
+ 24580000,
33
+ 25000000,
34
+};
35
+
36
/* Create an alias of an entire original MemoryRegion @orig
37
* located at @base in the memory map.
38
*/
39
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
40
MPS2SCC *scc = opaque;
41
DeviceState *sccdev;
42
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
43
+ uint32_t i;
44
45
object_initialize_child(OBJECT(mms), "scc", scc, TYPE_MPS2_SCC);
46
sccdev = DEVICE(scc);
47
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
48
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
49
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
50
- /* This will need to be per-FPGA image eventually */
51
- qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
52
- qdev_prop_set_uint32(sccdev, "oscclk[0]", 40000000);
53
- qdev_prop_set_uint32(sccdev, "oscclk[1]", 24580000);
54
- qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
55
+ qdev_prop_set_uint32(sccdev, "len-oscclk", mmc->len_oscclk);
56
+ for (i = 0; i < mmc->len_oscclk; i++) {
57
+ g_autofree char *propname = g_strdup_printf("oscclk[%u]", i);
58
+ qdev_prop_set_uint32(sccdev, propname, mmc->oscclk[i]);
59
+ }
60
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
61
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
62
}
63
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
64
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
65
mmc->scc_id = 0x41045050;
66
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
67
+ mmc->oscclk = an505_oscclk;
68
+ mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
69
mmc->armsse_type = TYPE_IOTKIT;
70
}
71
72
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
73
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
74
mmc->scc_id = 0x41045210;
75
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
76
+ mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
77
+ mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
78
mmc->armsse_type = TYPE_SSE200;
79
}
26
80
27
--
81
--
28
2.16.2
82
2.20.1
29
83
30
84
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The MPS2 board has 2 LEDs, but the MPS3 board has 10 LEDs. The
2
FPGAIO device is similar on both sets of boards, but the LED0
3
register has correspondingly more bits that have an effect. Add a
4
device property for number of LEDs.
2
5
3
This actually covers two different sections of the encoding table:
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210215115138.20465-6-peter.maydell@linaro.org
10
---
11
include/hw/misc/mps2-fpgaio.h | 5 ++++-
12
hw/misc/mps2-fpgaio.c | 31 +++++++++++++++++++++++--------
13
2 files changed, 27 insertions(+), 9 deletions(-)
4
14
5
Advanced SIMD scalar two-register miscellaneous FP16
15
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
6
Advanced SIMD two-register miscellaneous (FP16)
7
8
The difference between the two is covered by a combination of Q (bit
9
30) and S (bit 28). Notably the FRINTx instructions are only
10
available in the vector form.
11
12
This is just the decode skeleton which will be filled out by later
13
patches.
14
15
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20180227143852.11175-17-alex.bennee@linaro.org
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
target/arm/translate-a64.c | 40 ++++++++++++++++++++++++++++++++++++++++
21
1 file changed, 40 insertions(+)
22
23
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate-a64.c
17
--- a/include/hw/misc/mps2-fpgaio.h
26
+++ b/target/arm/translate-a64.c
18
+++ b/include/hw/misc/mps2-fpgaio.h
27
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
19
@@ -XXX,XX +XXX,XX @@
20
#define TYPE_MPS2_FPGAIO "mps2-fpgaio"
21
OBJECT_DECLARE_SIMPLE_TYPE(MPS2FPGAIO, MPS2_FPGAIO)
22
23
+#define MPS2FPGAIO_MAX_LEDS 32
24
+
25
struct MPS2FPGAIO {
26
/*< private >*/
27
SysBusDevice parent_obj;
28
29
/*< public >*/
30
MemoryRegion iomem;
31
- LEDState *led[2];
32
+ LEDState *led[MPS2FPGAIO_MAX_LEDS];
33
+ uint32_t num_leds;
34
35
uint32_t led0;
36
uint32_t prescale;
37
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/misc/mps2-fpgaio.c
40
+++ b/hw/misc/mps2-fpgaio.c
41
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
42
43
switch (offset) {
44
case A_LED0:
45
- s->led0 = value & 0x3;
46
- led_set_state(s->led[0], value & 0x01);
47
- led_set_state(s->led[1], value & 0x02);
48
+ if (s->num_leds != 0) {
49
+ uint32_t i;
50
+
51
+ s->led0 = value & MAKE_64BIT_MASK(0, s->num_leds);
52
+ for (i = 0; i < s->num_leds; i++) {
53
+ led_set_state(s->led[i], value & (1 << i));
54
+ }
55
+ }
56
break;
57
case A_PRESCALE:
58
resync_counter(s);
59
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_reset(DeviceState *dev)
60
s->pscntr = 0;
61
s->pscntr_sync_ticks = now;
62
63
- for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
64
+ for (size_t i = 0; i < s->num_leds; i++) {
65
device_cold_reset(DEVICE(s->led[i]));
28
}
66
}
29
}
67
}
30
68
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_init(Object *obj)
31
+/* AdvSIMD [scalar] two register miscellaneous (FP16)
69
static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
32
+ *
70
{
33
+ * 31 30 29 28 27 24 23 22 21 17 16 12 11 10 9 5 4 0
71
MPS2FPGAIO *s = MPS2_FPGAIO(dev);
34
+ * +---+---+---+---+---------+---+-------------+--------+-----+------+------+
72
+ uint32_t i;
35
+ * | 0 | Q | U | S | 1 1 1 0 | a | 1 1 1 1 0 0 | opcode | 1 0 | Rn | Rd |
73
36
+ * +---+---+---+---+---------+---+-------------+--------+-----+------+------+
74
- s->led[0] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
37
+ * mask: 1000 1111 0111 1110 0000 1100 0000 0000 0x8f7e 0c00
75
- LED_COLOR_GREEN, "USERLED0");
38
+ * val: 0000 1110 0111 1000 0000 1000 0000 0000 0x0e78 0800
76
- s->led[1] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
39
+ *
77
- LED_COLOR_GREEN, "USERLED1");
40
+ * This actually covers two groups where scalar access is governed by
78
+ if (s->num_leds > MPS2FPGAIO_MAX_LEDS) {
41
+ * bit 28. A bunch of the instructions (float to integral) only exist
79
+ error_setg(errp, "num-leds cannot be greater than %d",
42
+ * in the vector form and are un-allocated for the scalar decode. Also
80
+ MPS2FPGAIO_MAX_LEDS);
43
+ * in the scalar decode Q is always 1.
44
+ */
45
+static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
46
+{
47
+ int fpop, opcode, a;
48
+
49
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
50
+ unallocated_encoding(s);
51
+ return;
81
+ return;
52
+ }
82
+ }
53
+
83
+
54
+ if (!fp_access_check(s)) {
84
+ for (i = 0; i < s->num_leds; i++) {
55
+ return;
85
+ g_autofree char *ledname = g_strdup_printf("USERLED%d", i);
86
+ s->led[i] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
87
+ LED_COLOR_GREEN, ledname);
56
+ }
88
+ }
57
+
89
}
58
+ opcode = extract32(insn, 12, 4);
90
59
+ a = extract32(insn, 23, 1);
91
static bool mps2_fpgaio_counters_needed(void *opaque)
60
+ fpop = deposit32(opcode, 5, 1, a);
92
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_fpgaio_vmstate = {
61
+
93
static Property mps2_fpgaio_properties[] = {
62
+ switch (fpop) {
94
/* Frequency of the prescale counter */
63
+ default:
95
DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000),
64
+ fprintf(stderr, "%s: insn %#04x fpop %#2x\n", __func__, insn, fpop);
96
+ /* Number of LEDs controlled by LED0 register */
65
+ g_assert_not_reached();
97
+ DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
66
+ }
98
DEFINE_PROP_END_OF_LIST(),
67
+
68
+}
69
+
70
/* AdvSIMD scalar x indexed element
71
* 31 30 29 28 24 23 22 21 20 19 16 15 12 11 10 9 5 4 0
72
* +-----+---+-----------+------+---+---+------+-----+---+---+------+------+
73
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
74
{ 0xce800000, 0xffe00000, disas_crypto_xar },
75
{ 0xce408000, 0xffe0c000, disas_crypto_three_reg_imm2 },
76
{ 0x0e400400, 0x9f60c400, disas_simd_three_reg_same_fp16 },
77
+ { 0x0e780800, 0x8f7e0c00, disas_simd_two_reg_misc_fp16 },
78
{ 0x00000000, 0x00000000, NULL }
79
};
99
};
80
100
81
--
101
--
82
2.16.2
102
2.20.1
83
103
84
104
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
MPS3 boards have an extra SWITCH register in the FPGAIO block which
2
reports the value of some switches. Implement this, governed by a
3
property the board code can use to specify whether whether it exists.
2
4
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180227143852.11175-26-alex.bennee@linaro.org
8
Message-id: 20210215115138.20465-7-peter.maydell@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
9
---
8
target/arm/helper-a64.h | 1 +
10
include/hw/misc/mps2-fpgaio.h | 1 +
9
target/arm/helper-a64.c | 13 +++++++++++++
11
hw/misc/mps2-fpgaio.c | 10 ++++++++++
10
target/arm/translate-a64.c | 5 +++++
12
2 files changed, 11 insertions(+)
11
3 files changed, 19 insertions(+)
12
13
13
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
14
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper-a64.h
16
--- a/include/hw/misc/mps2-fpgaio.h
16
+++ b/target/arm/helper-a64.h
17
+++ b/include/hw/misc/mps2-fpgaio.h
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_rinth_exact, f16, f16, ptr)
18
@@ -XXX,XX +XXX,XX @@ struct MPS2FPGAIO {
18
DEF_HELPER_2(advsimd_rinth, f16, f16, ptr)
19
MemoryRegion iomem;
19
DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
20
LEDState *led[MPS2FPGAIO_MAX_LEDS];
20
DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
21
uint32_t num_leds;
21
+DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
22
+ bool has_switches;
22
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
23
24
uint32_t led0;
25
uint32_t prescale;
26
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
23
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/helper-a64.c
28
--- a/hw/misc/mps2-fpgaio.c
25
+++ b/target/arm/helper-a64.c
29
+++ b/hw/misc/mps2-fpgaio.c
26
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_f16touinth)(float16 a, void *fpstp)
30
@@ -XXX,XX +XXX,XX @@ REG32(CLK100HZ, 0x14)
27
}
31
REG32(COUNTER, 0x18)
28
return float16_to_uint16(a, fpst);
32
REG32(PRESCALE, 0x1c)
29
}
33
REG32(PSCNTR, 0x20)
30
+
34
+REG32(SWITCH, 0x28)
31
+/*
35
REG32(MISC, 0x4c)
32
+ * Square Root and Reciprocal square root
36
33
+ */
37
static uint32_t counter_from_tickoff(int64_t now, int64_t tick_offset, int frq)
34
+
38
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
35
+float16 HELPER(sqrt_f16)(float16 a, void *fpstp)
39
resync_counter(s);
36
+{
40
r = s->pscntr;
37
+ float_status *s = fpstp;
38
+
39
+ return float16_sqrt(a, s);
40
+}
41
+
42
+
43
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/translate-a64.c
46
+++ b/target/arm/translate-a64.c
47
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
48
case 0x6f: /* FNEG */
49
need_fpst = false;
50
break;
41
break;
51
+ case 0x7f: /* FSQRT (vector) */
42
+ case A_SWITCH:
43
+ if (!s->has_switches) {
44
+ goto bad_offset;
45
+ }
46
+ /* User-togglable board switches. We don't model that, so report 0. */
47
+ r = 0;
52
+ break;
48
+ break;
53
default:
49
default:
54
fprintf(stderr, "%s: insn %#04x fpop %#2x\n", __func__, insn, fpop);
50
+ bad_offset:
55
g_assert_not_reached();
51
qemu_log_mask(LOG_GUEST_ERROR,
56
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
52
"MPS2 FPGAIO read: bad offset %x\n", (int) offset);
57
case 0x6f: /* FNEG */
53
r = 0;
58
tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
54
@@ -XXX,XX +XXX,XX @@ static Property mps2_fpgaio_properties[] = {
59
break;
55
DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000),
60
+ case 0x7f: /* FSQRT */
56
/* Number of LEDs controlled by LED0 register */
61
+ gen_helper_sqrt_f16(tcg_res, tcg_op, tcg_fpstatus);
57
DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
62
+ break;
58
+ DEFINE_PROP_BOOL("has-switches", MPS2FPGAIO, has_switches, false),
63
default:
59
DEFINE_PROP_END_OF_LIST(),
64
g_assert_not_reached();
60
};
65
}
61
66
--
62
--
67
2.16.2
63
2.20.1
68
64
69
65
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Set the FPGAIO num-leds and have-switches properties explicitly
2
per-board, rather than relying on the defaults. The AN505 and AN521
3
both have the same settings as the default values, but the AN524 will
4
be different.
2
5
3
This implements the half-precision variants of the across vector
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
reduction operations. This involves a re-factor of the reduction code
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
which more closely matches the ARM ARM order (and handles 8 element
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
reductions).
9
Message-id: 20210215115138.20465-8-peter.maydell@linaro.org
10
---
11
hw/arm/mps2-tz.c | 9 +++++++++
12
1 file changed, 9 insertions(+)
7
13
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
14
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180227143852.11175-7-alex.bennee@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/helper-a64.h | 4 ++
14
target/arm/helper-a64.c | 18 ++++++
15
target/arm/translate-a64.c | 140 ++++++++++++++++++++++++++++-----------------
16
3 files changed, 109 insertions(+), 53 deletions(-)
17
18
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper-a64.h
16
--- a/hw/arm/mps2-tz.c
21
+++ b/target/arm/helper-a64.h
17
+++ b/hw/arm/mps2-tz.c
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(paired_cmpxchg64_le_parallel, TCG_CALL_NO_WG,
18
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
23
DEF_HELPER_FLAGS_4(paired_cmpxchg64_be, TCG_CALL_NO_WG, i64, env, i64, i64, i64)
19
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
24
DEF_HELPER_FLAGS_4(paired_cmpxchg64_be_parallel, TCG_CALL_NO_WG,
20
uint32_t len_oscclk;
25
i64, env, i64, i64, i64)
21
const uint32_t *oscclk;
26
+DEF_HELPER_FLAGS_3(advsimd_maxh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
22
+ uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
27
+DEF_HELPER_FLAGS_3(advsimd_minh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
23
+ bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
28
+DEF_HELPER_FLAGS_3(advsimd_maxnumh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
24
const char *armsse_type;
29
+DEF_HELPER_FLAGS_3(advsimd_minnumh, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
25
};
30
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
26
31
index XXXXXXX..XXXXXXX 100644
27
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
32
--- a/target/arm/helper-a64.c
28
const char *name, hwaddr size)
33
+++ b/target/arm/helper-a64.c
34
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(paired_cmpxchg64_be_parallel)(CPUARMState *env, uint64_t addr,
35
{
29
{
36
return do_paired_cmpxchg64_be(env, addr, new_lo, new_hi, true, GETPC());
30
MPS2FPGAIO *fpgaio = opaque;
31
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
32
33
object_initialize_child(OBJECT(mms), "fpgaio", fpgaio, TYPE_MPS2_FPGAIO);
34
+ qdev_prop_set_uint32(DEVICE(fpgaio), "num-leds", mmc->fpgaio_num_leds);
35
+ qdev_prop_set_bit(DEVICE(fpgaio), "has-switches", mmc->fpgaio_has_switches);
36
sysbus_realize(SYS_BUS_DEVICE(fpgaio), &error_fatal);
37
return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
37
}
38
}
38
+
39
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
39
+/*
40
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
40
+ * AdvSIMD half-precision
41
mmc->oscclk = an505_oscclk;
41
+ */
42
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
42
+
43
+ mmc->fpgaio_num_leds = 2;
43
+#define ADVSIMD_HELPER(name, suffix) HELPER(glue(glue(advsimd_, name), suffix))
44
+ mmc->fpgaio_has_switches = false;
44
+
45
mmc->armsse_type = TYPE_IOTKIT;
45
+#define ADVSIMD_HALFOP(name) \
46
+float16 ADVSIMD_HELPER(name, h)(float16 a, float16 b, void *fpstp) \
47
+{ \
48
+ float_status *fpst = fpstp; \
49
+ return float16_ ## name(a, b, fpst); \
50
+}
51
+
52
+ADVSIMD_HALFOP(min)
53
+ADVSIMD_HALFOP(max)
54
+ADVSIMD_HALFOP(minnum)
55
+ADVSIMD_HALFOP(maxnum)
56
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-a64.c
59
+++ b/target/arm/translate-a64.c
60
@@ -XXX,XX +XXX,XX @@ static void disas_simd_zip_trn(DisasContext *s, uint32_t insn)
61
tcg_temp_free_i64(tcg_resh);
62
}
46
}
63
47
64
-static void do_minmaxop(DisasContext *s, TCGv_i32 tcg_elt1, TCGv_i32 tcg_elt2,
48
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
65
- int opc, bool is_min, TCGv_ptr fpst)
49
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
66
+/*
50
mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
67
+ * do_reduction_op helper
51
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
68
+ *
52
+ mmc->fpgaio_num_leds = 2;
69
+ * This mirrors the Reduce() pseudocode in the ARM ARM. It is
53
+ mmc->fpgaio_has_switches = false;
70
+ * important for correct NaN propagation that we do these
54
mmc->armsse_type = TYPE_SSE200;
71
+ * operations in exactly the order specified by the pseudocode.
72
+ *
73
+ * This is a recursive function, TCG temps should be freed by the
74
+ * calling function once it is done with the values.
75
+ */
76
+static TCGv_i32 do_reduction_op(DisasContext *s, int fpopcode, int rn,
77
+ int esize, int size, int vmap, TCGv_ptr fpst)
78
{
79
- /* Helper function for disas_simd_across_lanes: do a single precision
80
- * min/max operation on the specified two inputs,
81
- * and return the result in tcg_elt1.
82
- */
83
- if (opc == 0xc) {
84
- if (is_min) {
85
- gen_helper_vfp_minnums(tcg_elt1, tcg_elt1, tcg_elt2, fpst);
86
- } else {
87
- gen_helper_vfp_maxnums(tcg_elt1, tcg_elt1, tcg_elt2, fpst);
88
- }
89
+ if (esize == size) {
90
+ int element;
91
+ TCGMemOp msize = esize == 16 ? MO_16 : MO_32;
92
+ TCGv_i32 tcg_elem;
93
+
94
+ /* We should have one register left here */
95
+ assert(ctpop8(vmap) == 1);
96
+ element = ctz32(vmap);
97
+ assert(element < 8);
98
+
99
+ tcg_elem = tcg_temp_new_i32();
100
+ read_vec_element_i32(s, tcg_elem, rn, element, msize);
101
+ return tcg_elem;
102
} else {
103
- assert(opc == 0xf);
104
- if (is_min) {
105
- gen_helper_vfp_mins(tcg_elt1, tcg_elt1, tcg_elt2, fpst);
106
- } else {
107
- gen_helper_vfp_maxs(tcg_elt1, tcg_elt1, tcg_elt2, fpst);
108
+ int bits = size / 2;
109
+ int shift = ctpop8(vmap) / 2;
110
+ int vmap_lo = (vmap >> shift) & vmap;
111
+ int vmap_hi = (vmap & ~vmap_lo);
112
+ TCGv_i32 tcg_hi, tcg_lo, tcg_res;
113
+
114
+ tcg_hi = do_reduction_op(s, fpopcode, rn, esize, bits, vmap_hi, fpst);
115
+ tcg_lo = do_reduction_op(s, fpopcode, rn, esize, bits, vmap_lo, fpst);
116
+ tcg_res = tcg_temp_new_i32();
117
+
118
+ switch (fpopcode) {
119
+ case 0x0c: /* fmaxnmv half-precision */
120
+ gen_helper_advsimd_maxnumh(tcg_res, tcg_lo, tcg_hi, fpst);
121
+ break;
122
+ case 0x0f: /* fmaxv half-precision */
123
+ gen_helper_advsimd_maxh(tcg_res, tcg_lo, tcg_hi, fpst);
124
+ break;
125
+ case 0x1c: /* fminnmv half-precision */
126
+ gen_helper_advsimd_minnumh(tcg_res, tcg_lo, tcg_hi, fpst);
127
+ break;
128
+ case 0x1f: /* fminv half-precision */
129
+ gen_helper_advsimd_minh(tcg_res, tcg_lo, tcg_hi, fpst);
130
+ break;
131
+ case 0x2c: /* fmaxnmv */
132
+ gen_helper_vfp_maxnums(tcg_res, tcg_lo, tcg_hi, fpst);
133
+ break;
134
+ case 0x2f: /* fmaxv */
135
+ gen_helper_vfp_maxs(tcg_res, tcg_lo, tcg_hi, fpst);
136
+ break;
137
+ case 0x3c: /* fminnmv */
138
+ gen_helper_vfp_minnums(tcg_res, tcg_lo, tcg_hi, fpst);
139
+ break;
140
+ case 0x3f: /* fminv */
141
+ gen_helper_vfp_mins(tcg_res, tcg_lo, tcg_hi, fpst);
142
+ break;
143
+ default:
144
+ g_assert_not_reached();
145
}
146
+
147
+ tcg_temp_free_i32(tcg_hi);
148
+ tcg_temp_free_i32(tcg_lo);
149
+ return tcg_res;
150
}
151
}
55
}
152
56
153
@@ -XXX,XX +XXX,XX @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
154
break;
155
case 0xc: /* FMAXNMV, FMINNMV */
156
case 0xf: /* FMAXV, FMINV */
157
- if (!is_u || !is_q || extract32(size, 0, 1)) {
158
- unallocated_encoding(s);
159
- return;
160
- }
161
- /* Bit 1 of size field encodes min vs max, and actual size is always
162
- * 32 bits: adjust the size variable so following code can rely on it
163
+ /* Bit 1 of size field encodes min vs max and the actual size
164
+ * depends on the encoding of the U bit. If not set (and FP16
165
+ * enabled) then we do half-precision float instead of single
166
+ * precision.
167
*/
168
is_min = extract32(size, 1, 1);
169
is_fp = true;
170
- size = 2;
171
+ if (!is_u && arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
172
+ size = 1;
173
+ } else if (!is_u || !is_q || extract32(size, 0, 1)) {
174
+ unallocated_encoding(s);
175
+ return;
176
+ } else {
177
+ size = 2;
178
+ }
179
break;
180
default:
181
unallocated_encoding(s);
182
@@ -XXX,XX +XXX,XX @@ static void disas_simd_across_lanes(DisasContext *s, uint32_t insn)
183
184
}
185
} else {
186
- /* Floating point ops which work on 32 bit (single) intermediates.
187
+ /* Floating point vector reduction ops which work across 32
188
+ * bit (single) or 16 bit (half-precision) intermediates.
189
* Note that correct NaN propagation requires that we do these
190
* operations in exactly the order specified by the pseudocode.
191
*/
192
- TCGv_i32 tcg_elt1 = tcg_temp_new_i32();
193
- TCGv_i32 tcg_elt2 = tcg_temp_new_i32();
194
- TCGv_i32 tcg_elt3 = tcg_temp_new_i32();
195
- TCGv_ptr fpst = get_fpstatus_ptr(false);
196
-
197
- assert(esize == 32);
198
- assert(elements == 4);
199
-
200
- read_vec_element(s, tcg_elt, rn, 0, MO_32);
201
- tcg_gen_extrl_i64_i32(tcg_elt1, tcg_elt);
202
- read_vec_element(s, tcg_elt, rn, 1, MO_32);
203
- tcg_gen_extrl_i64_i32(tcg_elt2, tcg_elt);
204
-
205
- do_minmaxop(s, tcg_elt1, tcg_elt2, opcode, is_min, fpst);
206
-
207
- read_vec_element(s, tcg_elt, rn, 2, MO_32);
208
- tcg_gen_extrl_i64_i32(tcg_elt2, tcg_elt);
209
- read_vec_element(s, tcg_elt, rn, 3, MO_32);
210
- tcg_gen_extrl_i64_i32(tcg_elt3, tcg_elt);
211
-
212
- do_minmaxop(s, tcg_elt2, tcg_elt3, opcode, is_min, fpst);
213
-
214
- do_minmaxop(s, tcg_elt1, tcg_elt2, opcode, is_min, fpst);
215
-
216
- tcg_gen_extu_i32_i64(tcg_res, tcg_elt1);
217
- tcg_temp_free_i32(tcg_elt1);
218
- tcg_temp_free_i32(tcg_elt2);
219
- tcg_temp_free_i32(tcg_elt3);
220
+ TCGv_ptr fpst = get_fpstatus_ptr(size == MO_16);
221
+ int fpopcode = opcode | is_min << 4 | is_u << 5;
222
+ int vmap = (1 << elements) - 1;
223
+ TCGv_i32 tcg_res32 = do_reduction_op(s, fpopcode, rn, esize,
224
+ (is_q ? 128 : 64), vmap, fpst);
225
+ tcg_gen_extu_i32_i64(tcg_res, tcg_res32);
226
+ tcg_temp_free_i32(tcg_res32);
227
tcg_temp_free_ptr(fpst);
228
}
229
230
--
57
--
231
2.16.2
58
2.20.1
232
59
233
60
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
In the mps2-tz board code, we handle devices whose interrupt lines
2
must be wired to all CPUs by creating IRQ splitter devices for the
3
AN521, because it has 2 CPUs, but wiring the device IRQ directly to
4
the SSE/IoTKit input for the AN505, which has only 1 CPU.
2
5
3
Assert only the lower cs on bus 0 and upper cs on bus 1 when both buses and
6
We can avoid making an explicit check on the board type constant by
4
chip selects are enabled (e.g reading/writing with stripe).
7
instead creating and using the IRQ splitters for any board with more
8
than 1 CPU. This avoids having to add extra cases to the
9
conditionals every time we add new boards.
5
10
6
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
8
Tested-by: Alistair Francis <alistair.francis@xilinx.com>
9
Message-id: 20180223232233.31482-2-frasse.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210215115138.20465-9-peter.maydell@linaro.org
11
---
15
---
12
hw/ssi/xilinx_spips.c | 41 +++++++++++++++++++++++++++++++++++++----
16
hw/arm/mps2-tz.c | 19 +++++++++----------
13
1 file changed, 37 insertions(+), 4 deletions(-)
17
1 file changed, 9 insertions(+), 10 deletions(-)
14
18
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
19
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
21
--- a/hw/arm/mps2-tz.c
18
+++ b/hw/ssi/xilinx_spips.c
22
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_cs(XilinxSPIPS *s, int field)
23
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
24
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
20
{
25
{
21
int i;
26
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
22
27
- MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
23
- for (i = 0; i < s->num_cs; i++) {
28
+ MachineClass *mc = MACHINE_GET_CLASS(mms);
24
+ for (i = 0; i < s->num_cs * s->num_busses; i++) {
29
25
bool old_state = s->cs_lines_state[i];
30
assert(irqno < MPS2TZ_NUMIRQ);
26
bool new_state = field & (1 << i);
31
27
32
- switch (mmc->fpga_type) {
28
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_cs(XilinxSPIPS *s, int field)
33
- case FPGA_AN505:
29
}
34
- return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
30
qemu_set_irq(s->cs_lines[i], !new_state);
35
- case FPGA_AN521:
31
}
36
+ if (mc->max_cpus > 1) {
32
- if (!(field & ((1 << s->num_cs) - 1))) {
37
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
33
+ if (!(field & ((1 << (s->num_cs * s->num_busses)) - 1))) {
38
- default:
34
s->snoop_state = SNOOP_CHECKING;
39
- g_assert_not_reached();
35
s->cmd_dummies = 0;
40
+ } else {
36
s->link_state = 1;
41
+ return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
37
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_update_cs_lines(XlnxZynqMPQSPIPS *s)
38
{
39
if (s->regs[R_GQSPI_GF_SNAPSHOT]) {
40
int field = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, CHIP_SELECT);
41
- xilinx_spips_update_cs(XILINX_SPIPS(s), field);
42
+ bool upper_cs_sel = field & (1 << 1);
43
+ bool lower_cs_sel = field & 1;
44
+ bool bus0_enabled;
45
+ bool bus1_enabled;
46
+ uint8_t buses;
47
+ int cs = 0;
48
+
49
+ buses = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_BUS_SELECT);
50
+ bus0_enabled = buses & 1;
51
+ bus1_enabled = buses & (1 << 1);
52
+
53
+ if (bus0_enabled && bus1_enabled) {
54
+ if (lower_cs_sel) {
55
+ cs |= 1;
56
+ }
57
+ if (upper_cs_sel) {
58
+ cs |= 1 << 3;
59
+ }
60
+ } else if (bus0_enabled) {
61
+ if (lower_cs_sel) {
62
+ cs |= 1;
63
+ }
64
+ if (upper_cs_sel) {
65
+ cs |= 1 << 1;
66
+ }
67
+ } else if (bus1_enabled) {
68
+ if (lower_cs_sel) {
69
+ cs |= 1 << 2;
70
+ }
71
+ if (upper_cs_sel) {
72
+ cs |= 1 << 3;
73
+ }
74
+ }
75
+ xilinx_spips_update_cs(XILINX_SPIPS(s), cs);
76
}
42
}
77
}
43
}
78
44
79
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
45
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
80
if (num_effective_busses(s) == 2) {
46
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
81
/* Single bit chip-select for qspi */
47
82
field &= 0x1;
48
/*
83
- field |= field << 1;
49
- * The AN521 needs us to create splitters to feed the IRQ inputs
84
+ field |= field << 3;
50
- * for each CPU in the SSE-200 from each device in the board.
85
/* Dual stack U-Page */
51
+ * If this board has more than one CPU, then we need to create splitters
86
} else if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_TWO_MEM &&
52
+ * to feed the IRQ inputs for each CPU in the SSE from each device in the
87
s->regs[R_LQSPI_STS] & LQSPI_CFG_U_PAGE) {
53
+ * board. If there is only one CPU, we can just wire the device IRQ
54
+ * directly to the SSE's IRQ input.
55
*/
56
- if (mmc->fpga_type == FPGA_AN521) {
57
+ if (mc->max_cpus > 1) {
58
for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
59
char *name = g_strdup_printf("mps2-irq-splitter%d", i);
60
SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
88
--
61
--
89
2.16.2
62
2.20.1
90
63
91
64
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The AN524 has more interrupt lines than the AN505 and AN521; make
2
numirq board-specific rather than a compile-time constant.
2
3
3
A bunch of the vectorised bitwise operations just operate on larger
4
Since the difference is small (92 on the current boards and 95 on the
4
chunks at a time. We can do the same for the new half-precision
5
new one) we don't dynamically allocate the cpu_irq_splitter[] array
5
operations by introducing some TWOHALFOP helpers which work on each
6
but leave it as a fixed length array whose size is the maximum needed
6
half of a pair of half-precision operations at once.
7
for any of the boards.
7
8
8
Hopefully all this hoop jumping will get simpler once we have
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
generically vectorised helpers here.
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-10-peter.maydell@linaro.org
13
---
14
hw/arm/mps2-tz.c | 15 ++++++++++-----
15
1 file changed, 10 insertions(+), 5 deletions(-)
10
16
11
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20180227143852.11175-16-alex.bennee@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/helper-a64.h | 10 ++++++++++
17
target/arm/helper-a64.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
18
target/arm/translate-a64.c | 26 +++++++++++++++++++++-----
19
3 files changed, 76 insertions(+), 6 deletions(-)
20
21
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
22
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper-a64.h
19
--- a/hw/arm/mps2-tz.c
24
+++ b/target/arm/helper-a64.h
20
+++ b/hw/arm/mps2-tz.c
25
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(advsimd_acge_f16, i32, f16, f16, ptr)
21
@@ -XXX,XX +XXX,XX @@
26
DEF_HELPER_3(advsimd_acgt_f16, i32, f16, f16, ptr)
22
#include "hw/qdev-clock.h"
27
DEF_HELPER_3(advsimd_mulxh, f16, f16, f16, ptr)
23
#include "qom/object.h"
28
DEF_HELPER_4(advsimd_muladdh, f16, f16, f16, f16, ptr)
24
29
+DEF_HELPER_3(advsimd_add2h, i32, i32, i32, ptr)
25
-#define MPS2TZ_NUMIRQ 92
30
+DEF_HELPER_3(advsimd_sub2h, i32, i32, i32, ptr)
26
+#define MPS2TZ_NUMIRQ_MAX 92
31
+DEF_HELPER_3(advsimd_mul2h, i32, i32, i32, ptr)
27
32
+DEF_HELPER_3(advsimd_div2h, i32, i32, i32, ptr)
28
typedef enum MPS2TZFPGAType {
33
+DEF_HELPER_3(advsimd_max2h, i32, i32, i32, ptr)
29
FPGA_AN505,
34
+DEF_HELPER_3(advsimd_min2h, i32, i32, i32, ptr)
30
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
35
+DEF_HELPER_3(advsimd_maxnum2h, i32, i32, i32, ptr)
31
const uint32_t *oscclk;
36
+DEF_HELPER_3(advsimd_minnum2h, i32, i32, i32, ptr)
32
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
37
+DEF_HELPER_3(advsimd_mulx2h, i32, i32, i32, ptr)
33
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
38
+DEF_HELPER_4(advsimd_muladd2h, i32, i32, i32, i32, ptr)
34
+ int numirq; /* Number of external interrupts */
39
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
35
const char *armsse_type;
40
index XXXXXXX..XXXXXXX 100644
36
};
41
--- a/target/arm/helper-a64.c
37
42
+++ b/target/arm/helper-a64.c
38
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
43
@@ -XXX,XX +XXX,XX @@ ADVSIMD_HALFOP(max)
39
SplitIRQ sec_resp_splitter;
44
ADVSIMD_HALFOP(minnum)
40
qemu_or_irq uart_irq_orgate;
45
ADVSIMD_HALFOP(maxnum)
41
DeviceState *lan9118;
46
42
- SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
47
+#define ADVSIMD_TWOHALFOP(name) \
43
+ SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
48
+uint32_t ADVSIMD_HELPER(name, 2h)(uint32_t two_a, uint32_t two_b, void *fpstp) \
44
Clock *sysclk;
49
+{ \
45
Clock *s32kclk;
50
+ float16 a1, a2, b1, b2; \
46
};
51
+ uint32_t r1, r2; \
47
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
52
+ float_status *fpst = fpstp; \
53
+ a1 = extract32(two_a, 0, 16); \
54
+ a2 = extract32(two_a, 16, 16); \
55
+ b1 = extract32(two_b, 0, 16); \
56
+ b2 = extract32(two_b, 16, 16); \
57
+ r1 = float16_ ## name(a1, b1, fpst); \
58
+ r2 = float16_ ## name(a2, b2, fpst); \
59
+ return deposit32(r1, 16, 16, r2); \
60
+}
61
+
62
+ADVSIMD_TWOHALFOP(add)
63
+ADVSIMD_TWOHALFOP(sub)
64
+ADVSIMD_TWOHALFOP(mul)
65
+ADVSIMD_TWOHALFOP(div)
66
+ADVSIMD_TWOHALFOP(min)
67
+ADVSIMD_TWOHALFOP(max)
68
+ADVSIMD_TWOHALFOP(minnum)
69
+ADVSIMD_TWOHALFOP(maxnum)
70
+
71
/* Data processing - scalar floating-point and advanced SIMD */
72
-float16 HELPER(advsimd_mulxh)(float16 a, float16 b, void *fpstp)
73
+static float16 float16_mulx(float16 a, float16 b, void *fpstp)
74
{
48
{
75
float_status *fpst = fpstp;
49
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
76
50
MachineClass *mc = MACHINE_GET_CLASS(mms);
77
@@ -XXX,XX +XXX,XX @@ float16 HELPER(advsimd_mulxh)(float16 a, float16 b, void *fpstp)
51
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
78
return float16_mul(a, b, fpst);
52
53
- assert(irqno < MPS2TZ_NUMIRQ);
54
+ assert(irqno < mmc->numirq);
55
56
if (mc->max_cpus > 1) {
57
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
58
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
59
iotkitdev = DEVICE(&mms->iotkit);
60
object_property_set_link(OBJECT(&mms->iotkit), "memory",
61
OBJECT(system_memory), &error_abort);
62
- qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
63
+ qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
64
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
65
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
66
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
67
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
68
* board. If there is only one CPU, we can just wire the device IRQ
69
* directly to the SSE's IRQ input.
70
*/
71
+ assert(mmc->numirq <= MPS2TZ_NUMIRQ_MAX);
72
if (mc->max_cpus > 1) {
73
- for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
74
+ for (i = 0; i < mmc->numirq; i++) {
75
char *name = g_strdup_printf("mps2-irq-splitter%d", i);
76
SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
77
78
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
79
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
80
mmc->fpgaio_num_leds = 2;
81
mmc->fpgaio_has_switches = false;
82
+ mmc->numirq = 92;
83
mmc->armsse_type = TYPE_IOTKIT;
79
}
84
}
80
85
81
+ADVSIMD_HALFOP(mulx)
86
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
82
+ADVSIMD_TWOHALFOP(mulx)
87
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
83
+
88
mmc->fpgaio_num_leds = 2;
84
/* fused multiply-accumulate */
89
mmc->fpgaio_has_switches = false;
85
float16 HELPER(advsimd_muladdh)(float16 a, float16 b, float16 c, void *fpstp)
90
+ mmc->numirq = 92;
86
{
91
mmc->armsse_type = TYPE_SSE200;
87
@@ -XXX,XX +XXX,XX @@ float16 HELPER(advsimd_muladdh)(float16 a, float16 b, float16 c, void *fpstp)
88
return float16_muladd(a, b, c, 0, fpst);
89
}
92
}
90
93
91
+uint32_t HELPER(advsimd_muladd2h)(uint32_t two_a, uint32_t two_b,
92
+ uint32_t two_c, void *fpstp)
93
+{
94
+ float_status *fpst = fpstp;
95
+ float16 a1, a2, b1, b2, c1, c2;
96
+ uint32_t r1, r2;
97
+ a1 = extract32(two_a, 0, 16);
98
+ a2 = extract32(two_a, 16, 16);
99
+ b1 = extract32(two_b, 0, 16);
100
+ b2 = extract32(two_b, 16, 16);
101
+ c1 = extract32(two_c, 0, 16);
102
+ c2 = extract32(two_c, 16, 16);
103
+ r1 = float16_muladd(a1, b1, c1, 0, fpst);
104
+ r2 = float16_muladd(a2, b2, c2, 0, fpst);
105
+ return deposit32(r1, 16, 16, r2);
106
+}
107
+
108
/*
109
* Floating point comparisons produce an integer result. Softfloat
110
* routines return float_relation types which we convert to the 0/-1
111
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/translate-a64.c
114
+++ b/target/arm/translate-a64.c
115
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
116
* multiply-add */
117
tcg_gen_xori_i32(tcg_op, tcg_op, 0x80008000);
118
}
119
- gen_helper_advsimd_muladdh(tcg_res, tcg_op, tcg_idx,
120
- tcg_res, fpst);
121
+ if (is_scalar) {
122
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op, tcg_idx,
123
+ tcg_res, fpst);
124
+ } else {
125
+ gen_helper_advsimd_muladd2h(tcg_res, tcg_op, tcg_idx,
126
+ tcg_res, fpst);
127
+ }
128
break;
129
case 2:
130
if (opcode == 0x5) {
131
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
132
switch (size) {
133
case 1:
134
if (u) {
135
- gen_helper_advsimd_mulxh(tcg_res, tcg_op, tcg_idx,
136
- fpst);
137
+ if (is_scalar) {
138
+ gen_helper_advsimd_mulxh(tcg_res, tcg_op,
139
+ tcg_idx, fpst);
140
+ } else {
141
+ gen_helper_advsimd_mulx2h(tcg_res, tcg_op,
142
+ tcg_idx, fpst);
143
+ }
144
} else {
145
- g_assert_not_reached();
146
+ if (is_scalar) {
147
+ gen_helper_advsimd_mulh(tcg_res, tcg_op,
148
+ tcg_idx, fpst);
149
+ } else {
150
+ gen_helper_advsimd_mul2h(tcg_res, tcg_op,
151
+ tcg_idx, fpst);
152
+ }
153
}
154
break;
155
case 2:
156
--
94
--
157
2.16.2
95
2.20.1
158
96
159
97
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The AN524 version of the SCC interface has different behaviour for
2
some of the CFG registers; implement it.
2
3
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
4
Each board in this family can have minor differences in the meaning
5
of the CFG registers, so rather than trying to specify all the
6
possible semantics via individual device properties, we make the
7
behaviour conditional on the part-number field of the SCC_ID register
8
which the board code already passes us.
9
10
For the AN524, the differences are:
11
* CFG3 is reserved rather than being board switches
12
* CFG5 is a new register ("ACLK Frequency in Hz")
13
* CFG6 is a new register ("Clock divider for BRAM")
14
15
We implement both of the new registers as reads-as-written.
16
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180227143852.11175-28-alex.bennee@linaro.org
19
Message-id: 20210215115138.20465-11-peter.maydell@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
20
---
8
target/arm/translate-a64.c | 7 +++++++
21
include/hw/misc/mps2-scc.h | 3 ++
9
1 file changed, 7 insertions(+)
22
hw/misc/mps2-scc.c | 71 ++++++++++++++++++++++++++++++++++++--
23
2 files changed, 72 insertions(+), 2 deletions(-)
10
24
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
25
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
12
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
27
--- a/include/hw/misc/mps2-scc.h
14
+++ b/target/arm/translate-a64.c
28
+++ b/include/hw/misc/mps2-scc.h
15
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
29
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
16
case 0x6f: /* FNEG */
30
17
need_fpst = false;
31
uint32_t cfg0;
32
uint32_t cfg1;
33
+ uint32_t cfg2;
34
uint32_t cfg4;
35
+ uint32_t cfg5;
36
+ uint32_t cfg6;
37
uint32_t cfgdata_rtn;
38
uint32_t cfgdata_out;
39
uint32_t cfgctrl;
40
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/misc/mps2-scc.c
43
+++ b/hw/misc/mps2-scc.c
44
@@ -XXX,XX +XXX,XX @@
45
46
REG32(CFG0, 0)
47
REG32(CFG1, 4)
48
+REG32(CFG2, 8)
49
REG32(CFG3, 0xc)
50
REG32(CFG4, 0x10)
51
+REG32(CFG5, 0x14)
52
+REG32(CFG6, 0x18)
53
REG32(CFGDATA_RTN, 0xa0)
54
REG32(CFGDATA_OUT, 0xa4)
55
REG32(CFGCTRL, 0xa8)
56
@@ -XXX,XX +XXX,XX @@ REG32(DLL, 0x100)
57
REG32(AID, 0xFF8)
58
REG32(ID, 0xFFC)
59
60
+static int scc_partno(MPS2SCC *s)
61
+{
62
+ /* Return the partno field of the SCC_ID (0x524, 0x511, etc) */
63
+ return extract32(s->id, 4, 8);
64
+}
65
+
66
/* Handle a write via the SYS_CFG channel to the specified function/device.
67
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
68
*/
69
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
70
case A_CFG1:
71
r = s->cfg1;
18
break;
72
break;
19
+ case 0x7d: /* FRSQRTE */
73
+ case A_CFG2:
20
case 0x7f: /* FSQRT (vector) */
74
+ if (scc_partno(s) != 0x524) {
75
+ /* CFG2 reserved on other boards */
76
+ goto bad_offset;
77
+ }
78
+ r = s->cfg2;
79
+ break;
80
case A_CFG3:
81
+ if (scc_partno(s) == 0x524) {
82
+ /* CFG3 reserved on AN524 */
83
+ goto bad_offset;
84
+ }
85
/* These are user-settable DIP switches on the board. We don't
86
* model that, so just return zeroes.
87
*/
88
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
89
case A_CFG4:
90
r = s->cfg4;
91
break;
92
+ case A_CFG5:
93
+ if (scc_partno(s) != 0x524) {
94
+ /* CFG5 reserved on other boards */
95
+ goto bad_offset;
96
+ }
97
+ r = s->cfg5;
98
+ break;
99
+ case A_CFG6:
100
+ if (scc_partno(s) != 0x524) {
101
+ /* CFG6 reserved on other boards */
102
+ goto bad_offset;
103
+ }
104
+ r = s->cfg6;
105
+ break;
106
case A_CFGDATA_RTN:
107
r = s->cfgdata_rtn;
108
break;
109
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
110
r = s->id;
21
break;
111
break;
22
default:
112
default:
23
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
113
+ bad_offset:
24
case 0x6f: /* FNEG */
114
qemu_log_mask(LOG_GUEST_ERROR,
25
tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
115
"MPS2 SCC read: bad offset %x\n", (int) offset);
26
break;
116
r = 0;
27
+ case 0x7d: /* FRSQRTE */
117
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
28
+ gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus);
118
led_set_state(s->led[i], extract32(value, i, 1));
29
+ break;
30
default:
31
g_assert_not_reached();
32
}
119
}
33
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
120
break;
34
case 0x6f: /* FNEG */
121
+ case A_CFG2:
35
tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
122
+ if (scc_partno(s) != 0x524) {
36
break;
123
+ /* CFG2 reserved on other boards */
37
+ case 0x7d: /* FRSQRTE */
124
+ goto bad_offset;
38
+ gen_helper_rsqrte_f16(tcg_res, tcg_op, tcg_fpstatus);
125
+ }
39
+ break;
126
+ /* AN524: QSPI Select signal */
40
case 0x7f: /* FSQRT */
127
+ s->cfg2 = value;
41
gen_helper_sqrt_f16(tcg_res, tcg_op, tcg_fpstatus);
128
+ break;
42
break;
129
+ case A_CFG5:
130
+ if (scc_partno(s) != 0x524) {
131
+ /* CFG5 reserved on other boards */
132
+ goto bad_offset;
133
+ }
134
+ /* AN524: ACLK frequency in Hz */
135
+ s->cfg5 = value;
136
+ break;
137
+ case A_CFG6:
138
+ if (scc_partno(s) != 0x524) {
139
+ /* CFG6 reserved on other boards */
140
+ goto bad_offset;
141
+ }
142
+ /* AN524: Clock divider for BRAM */
143
+ s->cfg6 = value;
144
+ break;
145
case A_CFGDATA_OUT:
146
s->cfgdata_out = value;
147
break;
148
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
149
s->dll = deposit32(s->dll, 24, 8, extract32(value, 24, 8));
150
break;
151
default:
152
+ bad_offset:
153
qemu_log_mask(LOG_GUEST_ERROR,
154
"MPS2 SCC write: bad offset 0x%x\n", (int) offset);
155
break;
156
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_reset(DeviceState *dev)
157
trace_mps2_scc_reset();
158
s->cfg0 = 0;
159
s->cfg1 = 0;
160
+ s->cfg2 = 0;
161
+ s->cfg5 = 0;
162
+ s->cfg6 = 0;
163
s->cfgdata_rtn = 0;
164
s->cfgdata_out = 0;
165
s->cfgctrl = 0x100000;
166
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_realize(DeviceState *dev, Error **errp)
167
168
static const VMStateDescription mps2_scc_vmstate = {
169
.name = "mps2-scc",
170
- .version_id = 2,
171
- .minimum_version_id = 2,
172
+ .version_id = 3,
173
+ .minimum_version_id = 3,
174
.fields = (VMStateField[]) {
175
VMSTATE_UINT32(cfg0, MPS2SCC),
176
VMSTATE_UINT32(cfg1, MPS2SCC),
177
+ VMSTATE_UINT32(cfg2, MPS2SCC),
178
+ /* cfg3, cfg4 are read-only so need not be migrated */
179
+ VMSTATE_UINT32(cfg5, MPS2SCC),
180
+ VMSTATE_UINT32(cfg6, MPS2SCC),
181
VMSTATE_UINT32(cfgdata_rtn, MPS2SCC),
182
VMSTATE_UINT32(cfgdata_out, MPS2SCC),
183
VMSTATE_UINT32(cfgctrl, MPS2SCC),
43
--
184
--
44
2.16.2
185
2.20.1
45
186
46
187
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
On the MPS2 boards, the first 32 interrupt lines are entirely
2
internal to the SSE; interrupt lines for devices outside the SSE
3
start at 32. In the application notes that document each FPGA image,
4
the interrupt wiring is documented from the point of view of the CPU,
5
so '0' is the first of the SSE's interrupts and the devices in the
6
FPGA image itself are '32' and up: so the UART 0 Receive interrupt is
7
32, the SPI #0 interrupt is 51, and so on.
2
8
3
As the rounding mode is now split between FP16 and the rest of
9
Within our implementation, because the external interrupts must be
4
floating point we need to be explicit when tweaking it. Instead of
10
connected to the EXP_IRQ[0...n] lines of the SSE object, we made the
5
passing the CPU env we now pass the appropriate fpst pointer directly.
11
get_sse_irq_in() function take an irqno whose values start at 0 for
12
the first FPGA device interrupt. In this numbering scheme the UART 0
13
Receive interrupt is 0, the SPI #0 interrupt is 19, and so on.
6
14
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
15
The result of these two different numbering schemes has been that
16
half of the devices were wired up to the wrong IRQs: the UART IRQs
17
are wired up correctly, but the DMA and SPI devices were passing
18
start-at-32 values to get_sse_irq_in() and so being mis-connected.
19
20
Fix the bug by making get_sse_irq_in() take values specified with the
21
same scheme that the hardware manuals use, to avoid confusion.
22
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180227143852.11175-6-alex.bennee@linaro.org
25
Message-id: 20210215115138.20465-12-peter.maydell@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
26
---
12
target/arm/helper.h | 2 +-
27
hw/arm/mps2-tz.c | 24 +++++++++++++++++-------
13
target/arm/helper.c | 4 ++--
28
1 file changed, 17 insertions(+), 7 deletions(-)
14
target/arm/translate-a64.c | 26 +++++++++++++-------------
15
target/arm/translate.c | 12 ++++++------
16
4 files changed, 22 insertions(+), 22 deletions(-)
17
29
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
30
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
19
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
32
--- a/hw/arm/mps2-tz.c
21
+++ b/target/arm/helper.h
33
+++ b/hw/arm/mps2-tz.c
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_uhtod, f64, i64, i32, ptr)
34
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
23
DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr)
35
24
DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr)
36
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
25
26
-DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, env)
27
+DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr)
28
DEF_HELPER_FLAGS_2(set_neon_rmode, TCG_CALL_NO_RWG, i32, i32, env)
29
30
DEF_HELPER_2(vfp_fcvt_f16_to_f32, f32, i32, env)
31
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/helper.c
34
+++ b/target/arm/helper.c
35
@@ -XXX,XX +XXX,XX @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
36
/* Set the current fp rounding mode and return the old one.
37
* The argument is a softfloat float_round_ value.
38
*/
39
-uint32_t HELPER(set_rmode)(uint32_t rmode, CPUARMState *env)
40
+uint32_t HELPER(set_rmode)(uint32_t rmode, void *fpstp)
41
{
37
{
42
- float_status *fp_status = &env->vfp.fp_status;
38
- /* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
43
+ float_status *fp_status = fpstp;
39
+ /*
44
40
+ * Return a qemu_irq which will signal IRQ n to all CPUs in the
45
uint32_t prev_rmode = get_float_rounding_mode(fp_status);
41
+ * SSE. The irqno should be as the CPU sees it, so the first
46
set_float_rounding_mode(rmode, fp_status);
42
+ * external-to-the-SSE interrupt is 32.
47
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
43
+ */
48
index XXXXXXX..XXXXXXX 100644
44
MachineClass *mc = MACHINE_GET_CLASS(mms);
49
--- a/target/arm/translate-a64.c
45
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
50
+++ b/target/arm/translate-a64.c
46
51
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
47
- assert(irqno < mmc->numirq);
52
{
48
+ assert(irqno >= 32 && irqno < (mmc->numirq + 32));
53
TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
49
+
54
50
+ /*
55
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
51
+ * Convert from "CPU irq number" (as listed in the FPGA image
56
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
52
+ * documentation) to the SSE external-interrupt number.
57
gen_helper_rints(tcg_res, tcg_op, fpst);
53
+ */
58
54
+ irqno -= 32;
59
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
55
60
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
56
if (mc->max_cpus > 1) {
61
tcg_temp_free_i32(tcg_rmode);
57
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
62
break;
58
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
63
}
59
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
64
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
60
CMSDKAPBUART *uart = opaque;
65
{
61
int i = uart - &mms->uart[0];
66
TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
62
- int rxirqno = i * 2;
67
63
- int txirqno = i * 2 + 1;
68
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
64
- int combirqno = i + 10;
69
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
65
+ int rxirqno = i * 2 + 32;
70
gen_helper_rintd(tcg_res, tcg_op, fpst);
66
+ int txirqno = i * 2 + 33;
71
67
+ int combirqno = i + 42;
72
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
68
SysBusDevice *s;
73
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
69
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
74
tcg_temp_free_i32(tcg_rmode);
70
75
break;
71
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
76
}
72
77
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
73
s = SYS_BUS_DEVICE(mms->lan9118);
78
74
sysbus_realize_and_unref(s, &error_fatal);
79
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
75
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 16));
80
76
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 48));
81
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
77
return sysbus_mmio_get_region(s, 0);
82
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
83
84
if (is_double) {
85
TCGv_i64 tcg_double = read_fp_dreg(s, rn);
86
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
87
tcg_temp_free_i32(tcg_single);
88
}
89
90
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
91
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
92
tcg_temp_free_i32(tcg_rmode);
93
94
if (!sf) {
95
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
96
assert(!(is_scalar && is_q));
97
98
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(FPROUNDING_ZERO));
99
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
100
tcg_fpstatus = get_fpstatus_ptr(false);
101
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
102
tcg_shift = tcg_const_i32(fracbits);
103
104
if (is_double) {
105
@@ -XXX,XX +XXX,XX @@ static void handle_simd_shift_fpint_conv(DisasContext *s, bool is_scalar,
106
107
tcg_temp_free_ptr(tcg_fpstatus);
108
tcg_temp_free_i32(tcg_shift);
109
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
110
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
111
tcg_temp_free_i32(tcg_rmode);
112
}
78
}
113
79
114
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
80
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
115
81
&error_fatal);
116
if (is_fcvt) {
82
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
117
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
83
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
118
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
84
- get_sse_irq_in(mms, 15));
119
tcg_fpstatus = get_fpstatus_ptr(false);
85
+ get_sse_irq_in(mms, 47));
120
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
86
121
} else {
87
/* Most of the devices in the FPGA are behind Peripheral Protection
122
tcg_rmode = NULL;
88
* Controllers. The required order for initializing things is:
123
tcg_fpstatus = NULL;
124
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_two_reg_misc(DisasContext *s, uint32_t insn)
125
}
126
127
if (is_fcvt) {
128
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
129
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
130
tcg_temp_free_i32(tcg_rmode);
131
tcg_temp_free_ptr(tcg_fpstatus);
132
}
133
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
134
return;
135
}
136
137
- if (need_fpstatus) {
138
+ if (need_fpstatus || need_rmode) {
139
tcg_fpstatus = get_fpstatus_ptr(false);
140
} else {
141
tcg_fpstatus = NULL;
142
}
143
if (need_rmode) {
144
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
145
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
146
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
147
} else {
148
tcg_rmode = NULL;
149
}
150
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
151
clear_vec_high(s, is_q, rd);
152
153
if (need_rmode) {
154
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
155
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
156
tcg_temp_free_i32(tcg_rmode);
157
}
158
if (need_fpstatus) {
159
diff --git a/target/arm/translate.c b/target/arm/translate.c
160
index XXXXXXX..XXXXXXX 100644
161
--- a/target/arm/translate.c
162
+++ b/target/arm/translate.c
163
@@ -XXX,XX +XXX,XX @@ static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
164
TCGv_i32 tcg_rmode;
165
166
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
167
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
168
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
169
170
if (dp) {
171
TCGv_i64 tcg_op;
172
@@ -XXX,XX +XXX,XX @@ static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
173
tcg_temp_free_i32(tcg_res);
174
}
175
176
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
177
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
178
tcg_temp_free_i32(tcg_rmode);
179
180
tcg_temp_free_ptr(fpst);
181
@@ -XXX,XX +XXX,XX @@ static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
182
tcg_shift = tcg_const_i32(0);
183
184
tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
185
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
186
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
187
188
if (dp) {
189
TCGv_i64 tcg_double, tcg_res;
190
@@ -XXX,XX +XXX,XX @@ static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
191
tcg_temp_free_i32(tcg_single);
192
}
193
194
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
195
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
196
tcg_temp_free_i32(tcg_rmode);
197
198
tcg_temp_free_i32(tcg_shift);
199
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
200
TCGv_ptr fpst = get_fpstatus_ptr(0);
201
TCGv_i32 tcg_rmode;
202
tcg_rmode = tcg_const_i32(float_round_to_zero);
203
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
204
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
205
if (dp) {
206
gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
207
} else {
208
gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
209
}
210
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
211
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
212
tcg_temp_free_i32(tcg_rmode);
213
tcg_temp_free_ptr(fpst);
214
break;
215
--
89
--
216
2.16.2
90
2.20.1
217
91
218
92
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The mps2-tz code uses PPCPortInfo data structures to define what
2
devices are present and how they are wired up. Currently we use
3
these to specify device types and addresses, but hard-code the
4
interrupt line wiring in each make_* helper function. This works for
5
the two boards we have at the moment, but the AN524 has some devices
6
with different interrupt assignments.
2
7
3
It looks like the ARM ARM has simplified the pseudo code for the
8
This commit adds the framework to allow PPCPortInfo structures to
4
calculation which is done on a fixed point 9 bit integer maths. So
9
specify interrupt numbers. We add an array of interrupt numbers to
5
while adding f16 we can also clean this up to be a little less heavy
10
the PPCPortInfo struct, and pass it through to the make_* helpers.
6
on the floating point and just return the fractional part and leave
11
The following commit will change the make_* helpers over to using the
7
the calle's to do the final packing of the result.
12
framework.
8
13
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180227143852.11175-23-alex.bennee@linaro.org
16
Message-id: 20210215115138.20465-13-peter.maydell@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
17
---
14
target/arm/helper.h | 1 +
18
hw/arm/mps2-tz.c | 36 ++++++++++++++++++++++++------------
15
target/arm/helper.c | 226 +++++++++++++++++++++++++++++-----------------------
19
1 file changed, 24 insertions(+), 12 deletions(-)
16
2 files changed, 129 insertions(+), 98 deletions(-)
17
20
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
21
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
19
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
23
--- a/hw/arm/mps2-tz.c
21
+++ b/target/arm/helper.h
24
+++ b/hw/arm/mps2-tz.c
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_4(vfp_muladds, f32, f32, f32, f32, ptr)
25
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
23
26
* needs to be plugged into the downstream end of the PPC port.
24
DEF_HELPER_3(recps_f32, f32, f32, f32, env)
25
DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env)
26
+DEF_HELPER_FLAGS_2(recpe_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
27
DEF_HELPER_FLAGS_2(recpe_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
28
DEF_HELPER_FLAGS_2(recpe_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
29
DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.c
33
+++ b/target/arm/helper.c
34
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrts_f32)(float32 a, float32 b, CPUARMState *env)
35
* int->float conversions at run-time. */
36
#define float64_256 make_float64(0x4070000000000000LL)
37
#define float64_512 make_float64(0x4080000000000000LL)
38
+#define float16_maxnorm make_float16(0x7bff)
39
#define float32_maxnorm make_float32(0x7f7fffff)
40
#define float64_maxnorm make_float64(0x7fefffffffffffffLL)
41
42
/* Reciprocal functions
43
*
44
* The algorithm that must be used to calculate the estimate
45
- * is specified by the ARM ARM, see FPRecipEstimate()
46
+ * is specified by the ARM ARM, see FPRecipEstimate()/RecipEstimate
47
*/
27
*/
48
28
typedef MemoryRegion *MakeDevFn(MPS2TZMachineState *mms, void *opaque,
49
-static float64 recip_estimate(float64 a, float_status *real_fp_status)
29
- const char *name, hwaddr size);
50
+/* See RecipEstimate()
30
+ const char *name, hwaddr size,
51
+ *
31
+ const int *irqs);
52
+ * input is a 9 bit fixed point number
32
53
+ * input range 256 .. 511 for a number from 0.5 <= x < 1.0.
33
typedef struct PPCPortInfo {
54
+ * result range 256 .. 511 for a number from 1.0 to 511/256.
34
const char *name;
55
+ */
35
@@ -XXX,XX +XXX,XX @@ typedef struct PPCPortInfo {
56
+
36
void *opaque;
57
+static int recip_estimate(int input)
37
hwaddr addr;
38
hwaddr size;
39
+ int irqs[3]; /* currently no device needs more IRQ lines than this */
40
} PPCPortInfo;
41
42
typedef struct PPCInfo {
43
@@ -XXX,XX +XXX,XX @@ typedef struct PPCInfo {
44
} PPCInfo;
45
46
static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
47
- void *opaque,
48
- const char *name, hwaddr size)
49
+ void *opaque,
50
+ const char *name, hwaddr size,
51
+ const int *irqs)
58
{
52
{
59
- /* These calculations mustn't set any fp exception flags,
53
/* Initialize, configure and realize a TYPE_UNIMPLEMENTED_DEVICE,
60
- * so we use a local copy of the fp_status.
54
* and return a pointer to its MemoryRegion.
61
- */
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
62
- float_status dummy_status = *real_fp_status;
63
- float_status *s = &dummy_status;
64
- /* q = (int)(a * 512.0) */
65
- float64 q = float64_mul(float64_512, a, s);
66
- int64_t q_int = float64_to_int64_round_to_zero(q, s);
67
-
68
- /* r = 1.0 / (((double)q + 0.5) / 512.0) */
69
- q = int64_to_float64(q_int, s);
70
- q = float64_add(q, float64_half, s);
71
- q = float64_div(q, float64_512, s);
72
- q = float64_div(float64_one, q, s);
73
-
74
- /* s = (int)(256.0 * r + 0.5) */
75
- q = float64_mul(q, float64_256, s);
76
- q = float64_add(q, float64_half, s);
77
- q_int = float64_to_int64_round_to_zero(q, s);
78
-
79
- /* return (double)s / 256.0 */
80
- return float64_div(int64_to_float64(q_int, s), float64_256, s);
81
+ int a, b, r;
82
+ assert(256 <= input && input < 512);
83
+ a = (input * 2) + 1;
84
+ b = (1 << 19) / a;
85
+ r = (b + 1) >> 1;
86
+ assert(256 <= r && r < 512);
87
+ return r;
88
}
56
}
89
57
90
-/* Common wrapper to call recip_estimate */
58
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
91
-static float64 call_recip_estimate(float64 num, int off, float_status *fpst)
59
- const char *name, hwaddr size)
92
-{
60
+ const char *name, hwaddr size,
93
- uint64_t val64 = float64_val(num);
61
+ const int *irqs)
94
- uint64_t frac = extract64(val64, 0, 52);
62
{
95
- int64_t exp = extract64(val64, 52, 11);
63
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
96
- uint64_t sbit;
64
CMSDKAPBUART *uart = opaque;
97
- float64 scaled, estimate;
65
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
98
+/*
99
+ * Common wrapper to call recip_estimate
100
+ *
101
+ * The parameters are exponent and 64 bit fraction (without implicit
102
+ * bit) where the binary point is nominally at bit 52. Returns a
103
+ * float64 which can then be rounded to the appropriate size by the
104
+ * callee.
105
+ */
106
107
- /* Generate the scaled number for the estimate function */
108
- if (exp == 0) {
109
+static uint64_t call_recip_estimate(int *exp, int exp_off, uint64_t frac)
110
+{
111
+ uint32_t scaled, estimate;
112
+ uint64_t result_frac;
113
+ int result_exp;
114
+
115
+ /* Handle sub-normals */
116
+ if (*exp == 0) {
117
if (extract64(frac, 51, 1) == 0) {
118
- exp = -1;
119
- frac = extract64(frac, 0, 50) << 2;
120
+ *exp = -1;
121
+ frac <<= 2;
122
} else {
123
- frac = extract64(frac, 0, 51) << 1;
124
+ frac <<= 1;
125
}
126
}
127
128
- /* scaled = '0' : '01111111110' : fraction<51:44> : Zeros(44); */
129
- scaled = make_float64((0x3feULL << 52)
130
- | extract64(frac, 44, 8) << 44);
131
+ /* scaled = UInt('1':fraction<51:44>) */
132
+ scaled = deposit32(1 << 8, 0, 8, extract64(frac, 44, 8));
133
+ estimate = recip_estimate(scaled);
134
135
- estimate = recip_estimate(scaled, fpst);
136
-
137
- /* Build new result */
138
- val64 = float64_val(estimate);
139
- sbit = 0x8000000000000000ULL & val64;
140
- exp = off - exp;
141
- frac = extract64(val64, 0, 52);
142
-
143
- if (exp == 0) {
144
- frac = 1ULL << 51 | extract64(frac, 1, 51);
145
- } else if (exp == -1) {
146
- frac = 1ULL << 50 | extract64(frac, 2, 50);
147
- exp = 0;
148
+ result_exp = exp_off - *exp;
149
+ result_frac = deposit64(0, 44, 8, estimate);
150
+ if (result_exp == 0) {
151
+ result_frac = deposit64(result_frac >> 1, 51, 1, 1);
152
+ } else if (result_exp == -1) {
153
+ result_frac = deposit64(result_frac >> 2, 50, 2, 1);
154
+ result_exp = 0;
155
}
156
157
- return make_float64(sbit | (exp << 52) | frac);
158
+ *exp = result_exp;
159
+
160
+ return result_frac;
161
}
66
}
162
67
163
static bool round_to_inf(float_status *fpst, bool sign_bit)
68
static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
164
@@ -XXX,XX +XXX,XX @@ static bool round_to_inf(float_status *fpst, bool sign_bit)
69
- const char *name, hwaddr size)
165
g_assert_not_reached();
70
+ const char *name, hwaddr size,
71
+ const int *irqs)
72
{
73
MPS2SCC *scc = opaque;
74
DeviceState *sccdev;
75
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
166
}
76
}
167
77
168
+float16 HELPER(recpe_f16)(float16 input, void *fpstp)
78
static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
169
+{
79
- const char *name, hwaddr size)
170
+ float_status *fpst = fpstp;
80
+ const char *name, hwaddr size,
171
+ float16 f16 = float16_squash_input_denormal(input, fpst);
81
+ const int *irqs)
172
+ uint32_t f16_val = float16_val(f16);
173
+ uint32_t f16_sign = float16_is_neg(f16);
174
+ int f16_exp = extract32(f16_val, 10, 5);
175
+ uint32_t f16_frac = extract32(f16_val, 0, 10);
176
+ uint64_t f64_frac;
177
+
178
+ if (float16_is_any_nan(f16)) {
179
+ float16 nan = f16;
180
+ if (float16_is_signaling_nan(f16, fpst)) {
181
+ float_raise(float_flag_invalid, fpst);
182
+ nan = float16_maybe_silence_nan(f16, fpst);
183
+ }
184
+ if (fpst->default_nan_mode) {
185
+ nan = float16_default_nan(fpst);
186
+ }
187
+ return nan;
188
+ } else if (float16_is_infinity(f16)) {
189
+ return float16_set_sign(float16_zero, float16_is_neg(f16));
190
+ } else if (float16_is_zero(f16)) {
191
+ float_raise(float_flag_divbyzero, fpst);
192
+ return float16_set_sign(float16_infinity, float16_is_neg(f16));
193
+ } else if (float16_abs(f16) < (1 << 8)) {
194
+ /* Abs(value) < 2.0^-16 */
195
+ float_raise(float_flag_overflow | float_flag_inexact, fpst);
196
+ if (round_to_inf(fpst, f16_sign)) {
197
+ return float16_set_sign(float16_infinity, f16_sign);
198
+ } else {
199
+ return float16_set_sign(float16_maxnorm, f16_sign);
200
+ }
201
+ } else if (f16_exp >= 29 && fpst->flush_to_zero) {
202
+ float_raise(float_flag_underflow, fpst);
203
+ return float16_set_sign(float16_zero, float16_is_neg(f16));
204
+ }
205
+
206
+ f64_frac = call_recip_estimate(&f16_exp, 29,
207
+ ((uint64_t) f16_frac) << (52 - 10));
208
+
209
+ /* result = sign : result_exp<4:0> : fraction<51:42> */
210
+ f16_val = deposit32(0, 15, 1, f16_sign);
211
+ f16_val = deposit32(f16_val, 10, 5, f16_exp);
212
+ f16_val = deposit32(f16_val, 0, 10, extract64(f64_frac, 52 - 10, 10));
213
+ return make_float16(f16_val);
214
+}
215
+
216
float32 HELPER(recpe_f32)(float32 input, void *fpstp)
217
{
82
{
218
float_status *fpst = fpstp;
83
MPS2FPGAIO *fpgaio = opaque;
219
float32 f32 = float32_squash_input_denormal(input, fpst);
84
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
220
uint32_t f32_val = float32_val(f32);
85
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
221
- uint32_t f32_sbit = 0x80000000ULL & f32_val;
222
- int32_t f32_exp = extract32(f32_val, 23, 8);
223
+ bool f32_sign = float32_is_neg(f32);
224
+ int f32_exp = extract32(f32_val, 23, 8);
225
uint32_t f32_frac = extract32(f32_val, 0, 23);
226
- float64 f64, r64;
227
- uint64_t r64_val;
228
- int64_t r64_exp;
229
- uint64_t r64_frac;
230
+ uint64_t f64_frac;
231
232
if (float32_is_any_nan(f32)) {
233
float32 nan = f32;
234
@@ -XXX,XX +XXX,XX @@ float32 HELPER(recpe_f32)(float32 input, void *fpstp)
235
} else if (float32_is_zero(f32)) {
236
float_raise(float_flag_divbyzero, fpst);
237
return float32_set_sign(float32_infinity, float32_is_neg(f32));
238
- } else if ((f32_val & ~(1ULL << 31)) < (1ULL << 21)) {
239
+ } else if (float32_abs(f32) < (1ULL << 21)) {
240
/* Abs(value) < 2.0^-128 */
241
float_raise(float_flag_overflow | float_flag_inexact, fpst);
242
- if (round_to_inf(fpst, f32_sbit)) {
243
- return float32_set_sign(float32_infinity, float32_is_neg(f32));
244
+ if (round_to_inf(fpst, f32_sign)) {
245
+ return float32_set_sign(float32_infinity, f32_sign);
246
} else {
247
- return float32_set_sign(float32_maxnorm, float32_is_neg(f32));
248
+ return float32_set_sign(float32_maxnorm, f32_sign);
249
}
250
} else if (f32_exp >= 253 && fpst->flush_to_zero) {
251
float_raise(float_flag_underflow, fpst);
252
return float32_set_sign(float32_zero, float32_is_neg(f32));
253
}
254
255
+ f64_frac = call_recip_estimate(&f32_exp, 253,
256
+ ((uint64_t) f32_frac) << (52 - 23));
257
258
- f64 = make_float64(((int64_t)(f32_exp) << 52) | (int64_t)(f32_frac) << 29);
259
- r64 = call_recip_estimate(f64, 253, fpst);
260
- r64_val = float64_val(r64);
261
- r64_exp = extract64(r64_val, 52, 11);
262
- r64_frac = extract64(r64_val, 0, 52);
263
-
264
- /* result = sign : result_exp<7:0> : fraction<51:29>; */
265
- return make_float32(f32_sbit |
266
- (r64_exp & 0xff) << 23 |
267
- extract64(r64_frac, 29, 24));
268
+ /* result = sign : result_exp<7:0> : fraction<51:29> */
269
+ f32_val = deposit32(0, 31, 1, f32_sign);
270
+ f32_val = deposit32(f32_val, 23, 8, f32_exp);
271
+ f32_val = deposit32(f32_val, 0, 23, extract64(f64_frac, 52 - 23, 23));
272
+ return make_float32(f32_val);
273
}
86
}
274
87
275
float64 HELPER(recpe_f64)(float64 input, void *fpstp)
88
static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
276
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
89
- const char *name, hwaddr size)
277
float_status *fpst = fpstp;
90
+ const char *name, hwaddr size,
278
float64 f64 = float64_squash_input_denormal(input, fpst);
91
+ const int *irqs)
279
uint64_t f64_val = float64_val(f64);
92
{
280
- uint64_t f64_sbit = 0x8000000000000000ULL & f64_val;
93
SysBusDevice *s;
281
- int64_t f64_exp = extract64(f64_val, 52, 11);
94
NICInfo *nd = &nd_table[0];
282
- float64 r64;
95
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
283
- uint64_t r64_val;
284
- int64_t r64_exp;
285
- uint64_t r64_frac;
286
+ bool f64_sign = float64_is_neg(f64);
287
+ int f64_exp = extract64(f64_val, 52, 11);
288
+ uint64_t f64_frac = extract64(f64_val, 0, 52);
289
290
/* Deal with any special cases */
291
if (float64_is_any_nan(f64)) {
292
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
293
} else if ((f64_val & ~(1ULL << 63)) < (1ULL << 50)) {
294
/* Abs(value) < 2.0^-1024 */
295
float_raise(float_flag_overflow | float_flag_inexact, fpst);
296
- if (round_to_inf(fpst, f64_sbit)) {
297
- return float64_set_sign(float64_infinity, float64_is_neg(f64));
298
+ if (round_to_inf(fpst, f64_sign)) {
299
+ return float64_set_sign(float64_infinity, f64_sign);
300
} else {
301
- return float64_set_sign(float64_maxnorm, float64_is_neg(f64));
302
+ return float64_set_sign(float64_maxnorm, f64_sign);
303
}
304
} else if (f64_exp >= 2045 && fpst->flush_to_zero) {
305
float_raise(float_flag_underflow, fpst);
306
return float64_set_sign(float64_zero, float64_is_neg(f64));
307
}
308
309
- r64 = call_recip_estimate(f64, 2045, fpst);
310
- r64_val = float64_val(r64);
311
- r64_exp = extract64(r64_val, 52, 11);
312
- r64_frac = extract64(r64_val, 0, 52);
313
+ f64_frac = call_recip_estimate(&f64_exp, 2045, f64_frac);
314
315
- /* result = sign : result_exp<10:0> : fraction<51:0> */
316
- return make_float64(f64_sbit |
317
- ((r64_exp & 0x7ff) << 52) |
318
- r64_frac);
319
+ /* result = sign : result_exp<10:0> : fraction<51:0>; */
320
+ f64_val = deposit64(0, 63, 1, f64_sign);
321
+ f64_val = deposit64(f64_val, 52, 11, f64_exp);
322
+ f64_val = deposit64(f64_val, 0, 52, f64_frac);
323
+ return make_float64(f64_val);
324
}
96
}
325
97
326
/* The algorithm that must be used to calculate the estimate
98
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
327
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
99
- const char *name, hwaddr size)
328
100
+ const char *name, hwaddr size,
329
uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp)
101
+ const int *irqs)
330
{
102
{
331
- float_status *s = fpstp;
103
TZMPC *mpc = opaque;
332
- float64 f64;
104
int i = mpc - &mms->ssram_mpc[0];
333
+ /* float_status *s = fpstp; */
105
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
334
+ int input, estimate;
335
336
if ((a & 0x80000000) == 0) {
337
return 0xffffffff;
338
}
339
340
- f64 = make_float64((0x3feULL << 52)
341
- | ((int64_t)(a & 0x7fffffff) << 21));
342
+ input = extract32(a, 23, 9);
343
+ estimate = recip_estimate(input);
344
345
- f64 = recip_estimate(f64, s);
346
-
347
- return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff);
348
+ return deposit32(0, (32 - 9), 9, estimate);
349
}
106
}
350
107
351
uint32_t HELPER(rsqrte_u32)(uint32_t a, void *fpstp)
108
static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
109
- const char *name, hwaddr size)
110
+ const char *name, hwaddr size,
111
+ const int *irqs)
112
{
113
PL080State *dma = opaque;
114
int i = dma - &mms->dma[0];
115
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
116
}
117
118
static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
119
- const char *name, hwaddr size)
120
+ const char *name, hwaddr size,
121
+ const int *irqs)
122
{
123
/*
124
* The AN505 has five PL022 SPI controllers.
125
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
126
}
127
128
static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
129
- const char *name, hwaddr size)
130
+ const char *name, hwaddr size,
131
+ const int *irqs)
132
{
133
ArmSbconI2CState *i2c = opaque;
134
SysBusDevice *s;
135
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
136
continue;
137
}
138
139
- mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size);
140
+ mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size,
141
+ pinfo->irqs);
142
portname = g_strdup_printf("port[%d]", port);
143
object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
144
&error_fatal);
352
--
145
--
353
2.16.2
146
2.20.1
354
147
355
148
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Move the specification of the IRQ information for the uart, ethernet,
2
dma and spi devices to the data structures. (The other devices
3
handled by the PPCPortInfo structures don't have any interrupt lines
4
we need to wire up.)
2
5
3
As some of the constants here will also be needed
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
elsewhere (specifically for the upcoming SVE support) we move them out
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
to softfloat.h.
8
Message-id: 20210215115138.20465-14-peter.maydell@linaro.org
9
---
10
hw/arm/mps2-tz.c | 52 +++++++++++++++++++++++-------------------------
11
1 file changed, 25 insertions(+), 27 deletions(-)
6
12
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180227143852.11175-13-alex.bennee@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/fpu/softfloat.h | 18 +++++++++++++-----
13
target/arm/helper-a64.h | 2 ++
14
target/arm/helper-a64.c | 34 ++++++++++++++++++++++++++++++++++
15
target/arm/translate-a64.c | 6 ++++++
16
4 files changed, 55 insertions(+), 5 deletions(-)
17
18
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/include/fpu/softfloat.h
15
--- a/hw/arm/mps2-tz.c
21
+++ b/include/fpu/softfloat.h
16
+++ b/hw/arm/mps2-tz.c
22
@@ -XXX,XX +XXX,XX @@ static inline float16 float16_set_sign(float16 a, int sign)
17
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
18
const char *name, hwaddr size,
19
const int *irqs)
20
{
21
+ /* The irq[] array is tx, rx, combined, in that order */
22
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
23
CMSDKAPBUART *uart = opaque;
24
int i = uart - &mms->uart[0];
25
- int rxirqno = i * 2 + 32;
26
- int txirqno = i * 2 + 33;
27
- int combirqno = i + 42;
28
SysBusDevice *s;
29
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
30
31
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
32
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
33
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
34
s = SYS_BUS_DEVICE(uart);
35
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
36
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, rxirqno));
37
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
38
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
39
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
40
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
41
- sysbus_connect_irq(s, 4, get_sse_irq_in(mms, combirqno));
42
+ sysbus_connect_irq(s, 4, get_sse_irq_in(mms, irqs[2]));
43
return sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0);
23
}
44
}
24
45
25
#define float16_zero make_float16(0)
46
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
26
-#define float16_one make_float16(0x3c00)
47
27
#define float16_half make_float16(0x3800)
48
s = SYS_BUS_DEVICE(mms->lan9118);
28
+#define float16_one make_float16(0x3c00)
49
sysbus_realize_and_unref(s, &error_fatal);
29
+#define float16_one_point_five make_float16(0x3e00)
50
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 48));
30
+#define float16_two make_float16(0x4000)
51
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
31
+#define float16_three make_float16(0x4200)
52
return sysbus_mmio_get_region(s, 0);
32
#define float16_infinity make_float16(0x7c00)
33
34
/*----------------------------------------------------------------------------
35
@@ -XXX,XX +XXX,XX @@ static inline float32 float32_set_sign(float32 a, int sign)
36
}
53
}
37
54
38
#define float32_zero make_float32(0)
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
39
-#define float32_one make_float32(0x3f800000)
56
const char *name, hwaddr size,
40
#define float32_half make_float32(0x3f000000)
57
const int *irqs)
41
+#define float32_one make_float32(0x3f800000)
58
{
42
+#define float32_one_point_five make_float32(0x3fc00000)
59
+ /* The irq[] array is DMACINTR, DMACINTERR, DMACINTTC, in that order */
43
+#define float32_two make_float32(0x40000000)
60
PL080State *dma = opaque;
44
+#define float32_three make_float32(0x40400000)
61
int i = dma - &mms->dma[0];
45
#define float32_infinity make_float32(0x7f800000)
62
SysBusDevice *s;
46
63
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
47
-
64
48
/*----------------------------------------------------------------------------
65
s = SYS_BUS_DEVICE(dma);
49
| The pattern for a default generated single-precision NaN.
66
/* Wire up DMACINTR, DMACINTERR, DMACINTTC */
50
*----------------------------------------------------------------------------*/
67
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 58 + i * 3));
51
@@ -XXX,XX +XXX,XX @@ static inline float64 float64_set_sign(float64 a, int sign)
68
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, 56 + i * 3));
69
- sysbus_connect_irq(s, 2, get_sse_irq_in(mms, 57 + i * 3));
70
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
71
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
72
+ sysbus_connect_irq(s, 2, get_sse_irq_in(mms, irqs[2]));
73
74
g_free(mscname);
75
return sysbus_mmio_get_region(s, 0);
76
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
77
* lines are set via the "MISC" register in the MPS2 FPGAIO device.
78
*/
79
PL022State *spi = opaque;
80
- int i = spi - &mms->spi[0];
81
SysBusDevice *s;
82
83
object_initialize_child(OBJECT(mms), name, spi, TYPE_PL022);
84
sysbus_realize(SYS_BUS_DEVICE(spi), &error_fatal);
85
s = SYS_BUS_DEVICE(spi);
86
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 51 + i));
87
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
88
return sysbus_mmio_get_region(s, 0);
52
}
89
}
53
90
54
#define float64_zero make_float64(0)
91
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
55
-#define float64_one make_float64(0x3ff0000000000000LL)
92
}, {
56
-#define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
93
.name = "apb_ppcexp1",
57
#define float64_half make_float64(0x3fe0000000000000LL)
94
.ports = {
58
+#define float64_one make_float64(0x3ff0000000000000LL)
95
- { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000 },
59
+#define float64_one_point_five make_float64(0x3FF8000000000000ULL)
96
- { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000 },
60
+#define float64_two make_float64(0x4000000000000000ULL)
97
- { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000 },
61
+#define float64_three make_float64(0x4008000000000000ULL)
98
- { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000 },
62
+#define float64_ln2 make_float64(0x3fe62e42fefa39efLL)
99
- { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000 },
63
#define float64_infinity make_float64(0x7ff0000000000000LL)
100
- { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000 },
64
101
- { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000 },
65
/*----------------------------------------------------------------------------
102
- { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
66
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
103
- { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
67
index XXXXXXX..XXXXXXX 100644
104
- { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
68
--- a/target/arm/helper-a64.h
105
+ { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000, { 51 } },
69
+++ b/target/arm/helper-a64.h
106
+ { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000, { 52 } },
70
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(vfp_mulxd, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
107
+ { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000, { 53 } },
71
DEF_HELPER_FLAGS_3(neon_ceq_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
108
+ { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000, { 54 } },
72
DEF_HELPER_FLAGS_3(neon_cge_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
109
+ { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000, { 55 } },
73
DEF_HELPER_FLAGS_3(neon_cgt_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
110
+ { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000, { 32, 33, 42 } },
74
+DEF_HELPER_FLAGS_3(recpsf_f16, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
111
+ { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000, { 34, 35, 43 } },
75
DEF_HELPER_FLAGS_3(recpsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
112
+ { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000, { 36, 37, 44 } },
76
DEF_HELPER_FLAGS_3(recpsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
113
+ { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000, { 38, 39, 45 } },
77
+DEF_HELPER_FLAGS_3(rsqrtsf_f16, TCG_CALL_NO_RWG, f16, f16, f16, ptr)
114
+ { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000, { 40, 41, 46 } },
78
DEF_HELPER_FLAGS_3(rsqrtsf_f32, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
115
{ "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
79
DEF_HELPER_FLAGS_3(rsqrtsf_f64, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
116
{ "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
80
DEF_HELPER_FLAGS_1(neon_addlp_s8, TCG_CALL_NO_RWG_SE, i64, i64)
117
{ "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
81
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
118
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
82
index XXXXXXX..XXXXXXX 100644
119
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x40101000, 0x1000 },
83
--- a/target/arm/helper-a64.c
120
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x40102000, 0x1000 },
84
+++ b/target/arm/helper-a64.c
121
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x40103000, 0x1000 },
85
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
122
- { "eth", make_eth_dev, NULL, 0x42000000, 0x100000 },
86
* versions, these do a fully fused multiply-add or
123
+ { "eth", make_eth_dev, NULL, 0x42000000, 0x100000, { 48 } },
87
* multiply-add-and-halve.
124
},
88
*/
125
}, {
89
+#define float16_two make_float16(0x4000)
126
.name = "ahb_ppcexp1",
90
+#define float16_three make_float16(0x4200)
127
.ports = {
91
+#define float16_one_point_five make_float16(0x3e00)
128
- { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000 },
92
+
129
- { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000 },
93
#define float32_two make_float32(0x40000000)
130
- { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000 },
94
#define float32_three make_float32(0x40400000)
131
- { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000 },
95
#define float32_one_point_five make_float32(0x3fc00000)
132
+ { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000, { 58, 56, 57 } },
96
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_cgt_f64)(float64 a, float64 b, void *fpstp)
133
+ { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000, { 61, 59, 60 } },
97
#define float64_three make_float64(0x4008000000000000ULL)
134
+ { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000, { 64, 62, 63 } },
98
#define float64_one_point_five make_float64(0x3FF8000000000000ULL)
135
+ { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000, { 67, 65, 66 } },
99
136
},
100
+float16 HELPER(recpsf_f16)(float16 a, float16 b, void *fpstp)
137
},
101
+{
138
};
102
+ float_status *fpst = fpstp;
103
+
104
+ a = float16_squash_input_denormal(a, fpst);
105
+ b = float16_squash_input_denormal(b, fpst);
106
+
107
+ a = float16_chs(a);
108
+ if ((float16_is_infinity(a) && float16_is_zero(b)) ||
109
+ (float16_is_infinity(b) && float16_is_zero(a))) {
110
+ return float16_two;
111
+ }
112
+ return float16_muladd(a, b, float16_two, 0, fpst);
113
+}
114
+
115
float32 HELPER(recpsf_f32)(float32 a, float32 b, void *fpstp)
116
{
117
float_status *fpst = fpstp;
118
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpsf_f64)(float64 a, float64 b, void *fpstp)
119
return float64_muladd(a, b, float64_two, 0, fpst);
120
}
121
122
+float16 HELPER(rsqrtsf_f16)(float16 a, float16 b, void *fpstp)
123
+{
124
+ float_status *fpst = fpstp;
125
+
126
+ a = float16_squash_input_denormal(a, fpst);
127
+ b = float16_squash_input_denormal(b, fpst);
128
+
129
+ a = float16_chs(a);
130
+ if ((float16_is_infinity(a) && float16_is_zero(b)) ||
131
+ (float16_is_infinity(b) && float16_is_zero(a))) {
132
+ return float16_one_point_five;
133
+ }
134
+ return float16_muladd(a, b, float16_three, float_muladd_halve_result, fpst);
135
+}
136
+
137
float32 HELPER(rsqrtsf_f32)(float32 a, float32 b, void *fpstp)
138
{
139
float_status *fpst = fpstp;
140
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
141
index XXXXXXX..XXXXXXX 100644
142
--- a/target/arm/translate-a64.c
143
+++ b/target/arm/translate-a64.c
144
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
145
case 0x6: /* FMAX */
146
gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
147
break;
148
+ case 0x7: /* FRECPS */
149
+ gen_helper_recpsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
150
+ break;
151
case 0x8: /* FMINNM */
152
gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
153
break;
154
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
155
case 0xe: /* FMIN */
156
gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
157
break;
158
+ case 0xf: /* FRSQRTS */
159
+ gen_helper_rsqrtsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
160
+ break;
161
case 0x13: /* FMUL */
162
gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
163
break;
164
--
139
--
165
2.16.2
140
2.20.1
166
141
167
142
diff view generated by jsdifflib
1
Set the appropriate Linux hwcap bits to tell the guest binary if we
1
We create an OR gate to wire together the overflow IRQs for all the
2
have implemented half-precision floating point support.
2
UARTs on the board; this has to have twice the number of inputs as
3
there are UARTs, since each UART feeds it a TX overflow and an RX
4
overflow interrupt line. Replace the hardcoded '10' with a
5
calculation based on the size of the uart[] array in the
6
MPS2TZMachineState. (We rely on OR gate inputs that are never wired
7
up or asserted being treated as always-zero.)
3
8
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210215115138.20465-15-peter.maydell@linaro.org
6
---
12
---
7
linux-user/elfload.c | 2 ++
13
hw/arm/mps2-tz.c | 11 ++++++++---
8
1 file changed, 2 insertions(+)
14
1 file changed, 8 insertions(+), 3 deletions(-)
9
15
10
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
16
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
11
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
12
--- a/linux-user/elfload.c
18
--- a/hw/arm/mps2-tz.c
13
+++ b/linux-user/elfload.c
19
+++ b/hw/arm/mps2-tz.c
14
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
20
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
15
GET_FEATURE(ARM_FEATURE_V8_SM3, ARM_HWCAP_A64_SM3);
21
*/
16
GET_FEATURE(ARM_FEATURE_V8_SM4, ARM_HWCAP_A64_SM4);
22
memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
17
GET_FEATURE(ARM_FEATURE_V8_SHA512, ARM_HWCAP_A64_SHA512);
23
18
+ GET_FEATURE(ARM_FEATURE_V8_FP16,
24
- /* The overflow IRQs for all UARTs are ORed together.
19
+ ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
25
+ /*
20
#undef GET_FEATURE
26
+ * The overflow IRQs for all UARTs are ORed together.
21
27
* Tx, Rx and "combined" IRQs are sent to the NVIC separately.
22
return hwcaps;
28
- * Create the OR gate for this.
29
+ * Create the OR gate for this: it has one input for the TX overflow
30
+ * and one for the RX overflow for each UART we might have.
31
+ * (If the board has fewer than the maximum possible number of UARTs
32
+ * those inputs are never wired up and are treated as always-zero.)
33
*/
34
object_initialize_child(OBJECT(mms), "uart-irq-orgate",
35
&mms->uart_irq_orgate, TYPE_OR_IRQ);
36
- object_property_set_int(OBJECT(&mms->uart_irq_orgate), "num-lines", 10,
37
+ object_property_set_int(OBJECT(&mms->uart_irq_orgate), "num-lines",
38
+ 2 * ARRAY_SIZE(mms->uart),
39
&error_fatal);
40
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
41
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
23
--
42
--
24
2.16.2
43
2.20.1
25
44
26
45
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The AN505 and AN521 have the same device layout, but the AN524 is
2
somewhat different. Allow for more than one PPCInfo array, which can
3
be selected based on the board type.
2
4
3
This covers the encoding group:
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210215115138.20465-16-peter.maydell@linaro.org
8
---
9
hw/arm/mps2-tz.c | 16 ++++++++++++++--
10
1 file changed, 14 insertions(+), 2 deletions(-)
4
11
5
Advanced SIMD scalar three same FP16
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
6
7
As all the helpers are already there it is simply a case of calling the
8
existing helpers in the scalar context.
9
10
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20180227143852.11175-31-alex.bennee@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
target/arm/translate-a64.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++
16
1 file changed, 99 insertions(+)
17
18
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
19
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-a64.c
14
--- a/hw/arm/mps2-tz.c
21
+++ b/target/arm/translate-a64.c
15
+++ b/hw/arm/mps2-tz.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_same(DisasContext *s, uint32_t insn)
16
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
23
tcg_temp_free_i64(tcg_rd);
17
MemoryRegion *system_memory = get_system_memory();
24
}
18
DeviceState *iotkitdev;
25
19
DeviceState *dev_splitter;
26
+/* AdvSIMD scalar three same FP16
20
+ const PPCInfo *ppcs;
27
+ * 31 30 29 28 24 23 22 21 20 16 15 14 13 11 10 9 5 4 0
21
+ int num_ppcs;
28
+ * +-----+---+-----------+---+-----+------+-----+--------+---+----+----+
22
int i;
29
+ * | 0 1 | U | 1 1 1 1 0 | a | 1 0 | Rm | 0 0 | opcode | 1 | Rn | Rd |
23
30
+ * +-----+---+-----------+---+-----+------+-----+--------+---+----+----+
24
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
31
+ * v: 0101 1110 0100 0000 0000 0100 0000 0000 => 5e400400
25
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
32
+ * m: 1101 1111 0110 0000 1100 0100 0000 0000 => df60c400
26
* + wire up the PPC's control lines to the IoTKit object
33
+ */
27
*/
34
+static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s,
28
35
+ uint32_t insn)
29
- const PPCInfo ppcs[] = { {
36
+{
30
+ const PPCInfo an505_ppcs[] = { {
37
+ int rd = extract32(insn, 0, 5);
31
.name = "apb_ppcexp0",
38
+ int rn = extract32(insn, 5, 5);
32
.ports = {
39
+ int opcode = extract32(insn, 11, 3);
33
{ "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
40
+ int rm = extract32(insn, 16, 5);
34
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
41
+ bool u = extract32(insn, 29, 1);
35
},
42
+ bool a = extract32(insn, 23, 1);
36
};
43
+ int fpopcode = opcode | (a << 3) | (u << 4);
37
44
+ TCGv_ptr fpst;
38
- for (i = 0; i < ARRAY_SIZE(ppcs); i++) {
45
+ TCGv_i32 tcg_op1;
39
+ switch (mmc->fpga_type) {
46
+ TCGv_i32 tcg_op2;
40
+ case FPGA_AN505:
47
+ TCGv_i32 tcg_res;
41
+ case FPGA_AN521:
48
+
42
+ ppcs = an505_ppcs;
49
+ switch (fpopcode) {
43
+ num_ppcs = ARRAY_SIZE(an505_ppcs);
50
+ case 0x03: /* FMULX */
51
+ case 0x04: /* FCMEQ (reg) */
52
+ case 0x07: /* FRECPS */
53
+ case 0x0f: /* FRSQRTS */
54
+ case 0x14: /* FCMGE (reg) */
55
+ case 0x15: /* FACGE */
56
+ case 0x1a: /* FABD */
57
+ case 0x1c: /* FCMGT (reg) */
58
+ case 0x1d: /* FACGT */
59
+ break;
60
+ default:
61
+ unallocated_encoding(s);
62
+ return;
63
+ }
64
+
65
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
66
+ unallocated_encoding(s);
67
+ }
68
+
69
+ if (!fp_access_check(s)) {
70
+ return;
71
+ }
72
+
73
+ fpst = get_fpstatus_ptr(true);
74
+
75
+ tcg_op1 = tcg_temp_new_i32();
76
+ tcg_op2 = tcg_temp_new_i32();
77
+ tcg_res = tcg_temp_new_i32();
78
+
79
+ read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
80
+ read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
81
+
82
+ switch (fpopcode) {
83
+ case 0x03: /* FMULX */
84
+ gen_helper_advsimd_mulxh(tcg_res, tcg_op1, tcg_op2, fpst);
85
+ break;
86
+ case 0x04: /* FCMEQ (reg) */
87
+ gen_helper_advsimd_ceq_f16(tcg_res, tcg_op1, tcg_op2, fpst);
88
+ break;
89
+ case 0x07: /* FRECPS */
90
+ gen_helper_recpsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
91
+ break;
92
+ case 0x0f: /* FRSQRTS */
93
+ gen_helper_rsqrtsf_f16(tcg_res, tcg_op1, tcg_op2, fpst);
94
+ break;
95
+ case 0x14: /* FCMGE (reg) */
96
+ gen_helper_advsimd_cge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
97
+ break;
98
+ case 0x15: /* FACGE */
99
+ gen_helper_advsimd_acge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
100
+ break;
101
+ case 0x1a: /* FABD */
102
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
103
+ tcg_gen_andi_i32(tcg_res, tcg_res, 0x7fff);
104
+ break;
105
+ case 0x1c: /* FCMGT (reg) */
106
+ gen_helper_advsimd_cgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
107
+ break;
108
+ case 0x1d: /* FACGT */
109
+ gen_helper_advsimd_acgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
110
+ break;
44
+ break;
111
+ default:
45
+ default:
112
+ g_assert_not_reached();
46
+ g_assert_not_reached();
113
+ }
47
+ }
114
+
48
+
115
+ write_fp_sreg(s, rd, tcg_res);
49
+ for (i = 0; i < num_ppcs; i++) {
116
+
50
const PPCInfo *ppcinfo = &ppcs[i];
117
+
51
TZPPC *ppc = &mms->ppc[i];
118
+ tcg_temp_free_i32(tcg_res);
52
DeviceState *ppcdev;
119
+ tcg_temp_free_i32(tcg_op1);
120
+ tcg_temp_free_i32(tcg_op2);
121
+ tcg_temp_free_ptr(fpst);
122
+}
123
+
124
static void handle_2misc_64(DisasContext *s, int opcode, bool u,
125
TCGv_i64 tcg_rd, TCGv_i64 tcg_rn,
126
TCGv_i32 tcg_rmode, TCGv_ptr tcg_fpstatus)
127
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
128
{ 0xce408000, 0xffe0c000, disas_crypto_three_reg_imm2 },
129
{ 0x0e400400, 0x9f60c400, disas_simd_three_reg_same_fp16 },
130
{ 0x0e780800, 0x8f7e0c00, disas_simd_two_reg_misc_fp16 },
131
+ { 0x5e400400, 0xdf60c400, disas_simd_scalar_three_reg_same_fp16 },
132
{ 0x00000000, 0x00000000, NULL }
133
};
134
135
--
53
--
136
2.16.2
54
2.20.1
137
55
138
56
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The AN505 and AN521 have the same layout of RAM; the AN524 does not.
2
2
Replace the current hard-coding of where the RAM is and which parts
3
These use the generic float16_compare functionality which in turn uses
3
of it are behind which MPCs with a data-driven approach.
4
the common float_compare code from the softfloat re-factor.
4
5
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20180227143852.11175-11-alex.bennee@linaro.org
7
Message-id: 20210215115138.20465-17-peter.maydell@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
8
---
11
target/arm/helper-a64.h | 5 +++++
9
hw/arm/mps2-tz.c | 175 +++++++++++++++++++++++++++++++++++++----------
12
target/arm/helper-a64.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++
10
1 file changed, 138 insertions(+), 37 deletions(-)
13
target/arm/translate-a64.c | 15 ++++++++++++++
11
14
3 files changed, 69 insertions(+)
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
16
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-a64.h
14
--- a/hw/arm/mps2-tz.c
19
+++ b/target/arm/helper-a64.h
15
+++ b/hw/arm/mps2-tz.c
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(advsimd_addh, f16, f16, f16, ptr)
16
@@ -XXX,XX +XXX,XX @@
21
DEF_HELPER_3(advsimd_subh, f16, f16, f16, ptr)
17
#include "qom/object.h"
22
DEF_HELPER_3(advsimd_mulh, f16, f16, f16, ptr)
18
23
DEF_HELPER_3(advsimd_divh, f16, f16, f16, ptr)
19
#define MPS2TZ_NUMIRQ_MAX 92
24
+DEF_HELPER_3(advsimd_ceq_f16, i32, f16, f16, ptr)
20
+#define MPS2TZ_RAM_MAX 4
25
+DEF_HELPER_3(advsimd_cge_f16, i32, f16, f16, ptr)
21
26
+DEF_HELPER_3(advsimd_cgt_f16, i32, f16, f16, ptr)
22
typedef enum MPS2TZFPGAType {
27
+DEF_HELPER_3(advsimd_acge_f16, i32, f16, f16, ptr)
23
FPGA_AN505,
28
+DEF_HELPER_3(advsimd_acgt_f16, i32, f16, f16, ptr)
24
FPGA_AN521,
29
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
25
} MPS2TZFPGAType;
30
index XXXXXXX..XXXXXXX 100644
26
31
--- a/target/arm/helper-a64.c
32
+++ b/target/arm/helper-a64.c
33
@@ -XXX,XX +XXX,XX @@ ADVSIMD_HALFOP(min)
34
ADVSIMD_HALFOP(max)
35
ADVSIMD_HALFOP(minnum)
36
ADVSIMD_HALFOP(maxnum)
37
+
38
+/*
27
+/*
39
+ * Floating point comparisons produce an integer result. Softfloat
28
+ * Define the layout of RAM in a board, including which parts are
40
+ * routines return float_relation types which we convert to the 0/-1
29
+ * behind which MPCs.
41
+ * Neon requires.
30
+ * mrindex specifies the index into mms->ram[] to use for the backing RAM;
31
+ * -1 means "use the system RAM".
42
+ */
32
+ */
43
+
33
+typedef struct RAMInfo {
44
+#define ADVSIMD_CMPRES(test) (test) ? 0xffff : 0
34
+ const char *name;
45
+
35
+ uint32_t base;
46
+uint32_t HELPER(advsimd_ceq_f16)(float16 a, float16 b, void *fpstp)
36
+ uint32_t size;
37
+ int mpc; /* MPC number, -1 for "not behind an MPC" */
38
+ int mrindex;
39
+ int flags;
40
+} RAMInfo;
41
+
42
+/*
43
+ * Flag values:
44
+ * IS_ALIAS: this RAM area is an alias to the upstream end of the
45
+ * MPC specified by its .mpc value
46
+ */
47
+#define IS_ALIAS 1
48
+
49
struct MPS2TZMachineClass {
50
MachineClass parent;
51
MPS2TZFPGAType fpga_type;
52
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
53
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
54
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
55
int numirq; /* Number of external interrupts */
56
+ const RAMInfo *raminfo;
57
const char *armsse_type;
58
};
59
60
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
61
MachineState parent;
62
63
ARMSSE iotkit;
64
- MemoryRegion ssram[3];
65
- MemoryRegion ssram1_m;
66
+ MemoryRegion ram[MPS2TZ_RAM_MAX];
67
MPS2SCC scc;
68
MPS2FPGAIO fpgaio;
69
TZPPC ppc[5];
70
- TZMPC ssram_mpc[3];
71
+ TZMPC mpc[3];
72
PL022State spi[5];
73
ArmSbconI2CState i2c[4];
74
UnimplementedDeviceState i2s_audio;
75
@@ -XXX,XX +XXX,XX @@ static const uint32_t an505_oscclk[] = {
76
25000000,
77
};
78
79
+static const RAMInfo an505_raminfo[] = { {
80
+ .name = "ssram-0",
81
+ .base = 0x00000000,
82
+ .size = 0x00400000,
83
+ .mpc = 0,
84
+ .mrindex = 0,
85
+ }, {
86
+ .name = "ssram-1",
87
+ .base = 0x28000000,
88
+ .size = 0x00200000,
89
+ .mpc = 1,
90
+ .mrindex = 1,
91
+ }, {
92
+ .name = "ssram-2",
93
+ .base = 0x28200000,
94
+ .size = 0x00200000,
95
+ .mpc = 2,
96
+ .mrindex = 2,
97
+ }, {
98
+ .name = "ssram-0-alias",
99
+ .base = 0x00400000,
100
+ .size = 0x00400000,
101
+ .mpc = 0,
102
+ .mrindex = 3,
103
+ .flags = IS_ALIAS,
104
+ }, {
105
+ /* Use the largest bit of contiguous RAM as our "system memory" */
106
+ .name = "mps.ram",
107
+ .base = 0x80000000,
108
+ .size = 16 * MiB,
109
+ .mpc = -1,
110
+ .mrindex = -1,
111
+ }, {
112
+ .name = NULL,
113
+ },
114
+};
115
+
116
+static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
47
+{
117
+{
48
+ float_status *fpst = fpstp;
118
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
49
+ int compare = float16_compare_quiet(a, b, fpst);
119
+ const RAMInfo *p;
50
+ return ADVSIMD_CMPRES(compare == float_relation_equal);
120
+
121
+ for (p = mmc->raminfo; p->name; p++) {
122
+ if (p->mpc == mpc && !(p->flags & IS_ALIAS)) {
123
+ return p;
124
+ }
125
+ }
126
+ /* if raminfo array doesn't have an entry for each MPC this is a bug */
127
+ g_assert_not_reached();
51
+}
128
+}
52
+
129
+
53
+uint32_t HELPER(advsimd_cge_f16)(float16 a, float16 b, void *fpstp)
130
+static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
131
+ const RAMInfo *raminfo)
54
+{
132
+{
55
+ float_status *fpst = fpstp;
133
+ /* Return an initialized MemoryRegion for the RAMInfo. */
56
+ int compare = float16_compare(a, b, fpst);
134
+ MemoryRegion *ram;
57
+ return ADVSIMD_CMPRES(compare == float_relation_greater ||
135
+
58
+ compare == float_relation_equal);
136
+ if (raminfo->mrindex < 0) {
137
+ /* Means this RAMInfo is for QEMU's "system memory" */
138
+ MachineState *machine = MACHINE(mms);
139
+ return machine->ram;
140
+ }
141
+
142
+ assert(raminfo->mrindex < MPS2TZ_RAM_MAX);
143
+ ram = &mms->ram[raminfo->mrindex];
144
+
145
+ memory_region_init_ram(ram, NULL, raminfo->name,
146
+ raminfo->size, &error_fatal);
147
+ return ram;
59
+}
148
+}
60
+
149
+
61
+uint32_t HELPER(advsimd_cgt_f16)(float16 a, float16 b, void *fpstp)
150
/* Create an alias of an entire original MemoryRegion @orig
151
* located at @base in the memory map.
152
*/
153
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
154
const int *irqs)
155
{
156
TZMPC *mpc = opaque;
157
- int i = mpc - &mms->ssram_mpc[0];
158
- MemoryRegion *ssram = &mms->ssram[i];
159
+ int i = mpc - &mms->mpc[0];
160
MemoryRegion *upstream;
161
- char *mpcname = g_strdup_printf("%s-mpc", name);
162
- static uint32_t ramsize[] = { 0x00400000, 0x00200000, 0x00200000 };
163
- static uint32_t rambase[] = { 0x00000000, 0x28000000, 0x28200000 };
164
+ const RAMInfo *raminfo = find_raminfo_for_mpc(mms, i);
165
+ MemoryRegion *ram = mr_for_raminfo(mms, raminfo);
166
167
- memory_region_init_ram(ssram, NULL, name, ramsize[i], &error_fatal);
168
-
169
- object_initialize_child(OBJECT(mms), mpcname, mpc, TYPE_TZ_MPC);
170
- object_property_set_link(OBJECT(mpc), "downstream", OBJECT(ssram),
171
+ object_initialize_child(OBJECT(mms), name, mpc, TYPE_TZ_MPC);
172
+ object_property_set_link(OBJECT(mpc), "downstream", OBJECT(ram),
173
&error_fatal);
174
sysbus_realize(SYS_BUS_DEVICE(mpc), &error_fatal);
175
/* Map the upstream end of the MPC into system memory */
176
upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
177
- memory_region_add_subregion(get_system_memory(), rambase[i], upstream);
178
+ memory_region_add_subregion(get_system_memory(), raminfo->base, upstream);
179
/* and connect its interrupt to the IoTKit */
180
qdev_connect_gpio_out_named(DEVICE(mpc), "irq", 0,
181
qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
182
"mpcexp_status", i));
183
184
- /* The first SSRAM is a special case as it has an alias; accesses to
185
- * the alias region at 0x00400000 must also go to the MPC upstream.
186
- */
187
- if (i == 0) {
188
- make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", upstream, 0x00400000);
189
- }
190
-
191
- g_free(mpcname);
192
/* Return the register interface MR for our caller to map behind the PPC */
193
return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
194
}
195
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
196
return sysbus_mmio_get_region(s, 0);
197
}
198
199
+static void create_non_mpc_ram(MPS2TZMachineState *mms)
62
+{
200
+{
63
+ float_status *fpst = fpstp;
201
+ /*
64
+ int compare = float16_compare(a, b, fpst);
202
+ * Handle the RAMs which are either not behind MPCs or which are
65
+ return ADVSIMD_CMPRES(compare == float_relation_greater);
203
+ * aliases to another MPC.
204
+ */
205
+ const RAMInfo *p;
206
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
207
+
208
+ for (p = mmc->raminfo; p->name; p++) {
209
+ if (p->flags & IS_ALIAS) {
210
+ SysBusDevice *mpc_sbd = SYS_BUS_DEVICE(&mms->mpc[p->mpc]);
211
+ MemoryRegion *upstream = sysbus_mmio_get_region(mpc_sbd, 1);
212
+ make_ram_alias(&mms->ram[p->mrindex], p->name, upstream, p->base);
213
+ } else if (p->mpc == -1) {
214
+ /* RAM not behind an MPC */
215
+ MemoryRegion *mr = mr_for_raminfo(mms, p);
216
+ memory_region_add_subregion(get_system_memory(), p->base, mr);
217
+ }
218
+ }
66
+}
219
+}
67
+
220
+
68
+uint32_t HELPER(advsimd_acge_f16)(float16 a, float16 b, void *fpstp)
221
static void mps2tz_common_init(MachineState *machine)
69
+{
222
{
70
+ float_status *fpst = fpstp;
223
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
71
+ float16 f0 = float16_abs(a);
224
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
72
+ float16 f1 = float16_abs(b);
225
qdev_connect_gpio_out_named(iotkitdev, "sec_resp_cfg", 0,
73
+ int compare = float16_compare(f0, f1, fpst);
226
qdev_get_gpio_in(dev_splitter, 0));
74
+ return ADVSIMD_CMPRES(compare == float_relation_greater ||
227
75
+ compare == float_relation_equal);
228
- /* The IoTKit sets up much of the memory layout, including
76
+}
229
+ /*
77
+
230
+ * The IoTKit sets up much of the memory layout, including
78
+uint32_t HELPER(advsimd_acgt_f16)(float16 a, float16 b, void *fpstp)
231
* the aliases between secure and non-secure regions in the
79
+{
232
- * address space. The FPGA itself contains:
80
+ float_status *fpst = fpstp;
233
- *
81
+ float16 f0 = float16_abs(a);
234
- * 0x00000000..0x003fffff SSRAM1
82
+ float16 f1 = float16_abs(b);
235
- * 0x00400000..0x007fffff alias of SSRAM1
83
+ int compare = float16_compare(f0, f1, fpst);
236
- * 0x28000000..0x283fffff 4MB SSRAM2 + SSRAM3
84
+ return ADVSIMD_CMPRES(compare == float_relation_greater);
237
- * 0x40100000..0x4fffffff AHB Master Expansion 1 interface devices
85
+}
238
- * 0x80000000..0x80ffffff 16MB PSRAM
86
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
239
- */
87
index XXXXXXX..XXXXXXX 100644
240
-
88
--- a/target/arm/translate-a64.c
241
- /* The FPGA images have an odd combination of different RAMs,
89
+++ b/target/arm/translate-a64.c
242
+ * address space, and also most of the devices in the system.
90
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
243
+ * The FPGA itself contains various RAMs and some additional devices.
91
case 0x2: /* FADD */
244
+ * The FPGA images have an odd combination of different RAMs,
92
gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
245
* because in hardware they are different implementations and
93
break;
246
* connected to different buses, giving varying performance/size
94
+ case 0x4: /* FCMEQ */
247
* tradeoffs. For QEMU they're all just RAM, though. We arbitrarily
95
+ gen_helper_advsimd_ceq_f16(tcg_res, tcg_op1, tcg_op2, fpst);
248
- * call the 16MB our "system memory", as it's the largest lump.
96
+ break;
249
+ * call the largest lump our "system memory".
97
case 0x6: /* FMAX */
250
*/
98
gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
251
- memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
99
break;
252
100
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
253
/*
101
case 0x13: /* FMUL */
254
* The overflow IRQs for all UARTs are ORed together.
102
gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
255
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
103
break;
256
const PPCInfo an505_ppcs[] = { {
104
+ case 0x14: /* FCMGE */
257
.name = "apb_ppcexp0",
105
+ gen_helper_advsimd_cge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
258
.ports = {
106
+ break;
259
- { "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
107
+ case 0x15: /* FACGE */
260
- { "ssram-1", make_mpc, &mms->ssram_mpc[1], 0x58008000, 0x1000 },
108
+ gen_helper_advsimd_acge_f16(tcg_res, tcg_op1, tcg_op2, fpst);
261
- { "ssram-2", make_mpc, &mms->ssram_mpc[2], 0x58009000, 0x1000 },
109
+ break;
262
+ { "ssram-0-mpc", make_mpc, &mms->mpc[0], 0x58007000, 0x1000 },
110
case 0x17: /* FDIV */
263
+ { "ssram-1-mpc", make_mpc, &mms->mpc[1], 0x58008000, 0x1000 },
111
gen_helper_advsimd_divh(tcg_res, tcg_op1, tcg_op2, fpst);
264
+ { "ssram-2-mpc", make_mpc, &mms->mpc[2], 0x58009000, 0x1000 },
112
break;
265
},
113
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
266
}, {
114
gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
267
.name = "apb_ppcexp1",
115
tcg_gen_andi_i32(tcg_res, tcg_res, 0x7fff);
268
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
116
break;
269
117
+ case 0x1c: /* FCMGT */
270
create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000);
118
+ gen_helper_advsimd_cgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
271
119
+ break;
272
+ create_non_mpc_ram(mms);
120
+ case 0x1d: /* FACGT */
273
+
121
+ gen_helper_advsimd_acgt_f16(tcg_res, tcg_op1, tcg_op2, fpst);
274
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
122
+ break;
275
}
123
default:
276
124
fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
277
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
125
__func__, insn, fpopcode, s->pc);
278
mmc->fpgaio_num_leds = 2;
279
mmc->fpgaio_has_switches = false;
280
mmc->numirq = 92;
281
+ mmc->raminfo = an505_raminfo;
282
mmc->armsse_type = TYPE_IOTKIT;
283
}
284
285
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
286
mmc->fpgaio_num_leds = 2;
287
mmc->fpgaio_has_switches = false;
288
mmc->numirq = 92;
289
+ mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
290
mmc->armsse_type = TYPE_SSE200;
291
}
292
126
--
293
--
127
2.16.2
294
2.20.1
128
295
129
296
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
Instead of hardcoding the MachineClass default_ram_size and
2
default_ram_id fields, set them on class creation by finding the
3
entry in the RAMInfo array which is marked as being the QEMU system
4
RAM.
2
5
3
Much like recpe the ARM ARM has simplified the pseudo code for the
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
calculation which is done on a fixed point 9 bit integer maths. So
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
while adding f16 we can also clean this up to be a little less heavy
8
Message-id: 20210215115138.20465-18-peter.maydell@linaro.org
6
on the floating point and just return the fractional part and leave
9
---
7
the calle's to do the final packing of the result.
10
hw/arm/mps2-tz.c | 24 ++++++++++++++++++++++--
11
1 file changed, 22 insertions(+), 2 deletions(-)
8
12
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180227143852.11175-27-alex.bennee@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/helper.h | 1 +
15
target/arm/helper.c | 221 ++++++++++++++++++++++++----------------------------
16
2 files changed, 104 insertions(+), 118 deletions(-)
17
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.h
15
--- a/hw/arm/mps2-tz.c
21
+++ b/target/arm/helper.h
16
+++ b/hw/arm/mps2-tz.c
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(rsqrts_f32, f32, f32, f32, env)
17
@@ -XXX,XX +XXX,XX @@ static void mps2tz_class_init(ObjectClass *oc, void *data)
23
DEF_HELPER_FLAGS_2(recpe_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
18
24
DEF_HELPER_FLAGS_2(recpe_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
19
mc->init = mps2tz_common_init;
25
DEF_HELPER_FLAGS_2(recpe_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
20
iic->check = mps2_tz_idau_check;
26
+DEF_HELPER_FLAGS_2(rsqrte_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
21
- mc->default_ram_size = 16 * MiB;
27
DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
22
- mc->default_ram_id = "mps.ram";
28
DEF_HELPER_FLAGS_2(rsqrte_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
29
DEF_HELPER_2(recpe_u32, i32, i32, ptr)
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper.c
33
+++ b/target/arm/helper.c
34
@@ -XXX,XX +XXX,XX @@ float64 HELPER(recpe_f64)(float64 input, void *fpstp)
35
/* The algorithm that must be used to calculate the estimate
36
* is specified by the ARM ARM.
37
*/
38
-static float64 recip_sqrt_estimate(float64 a, float_status *real_fp_status)
39
+
40
+static int do_recip_sqrt_estimate(int a)
41
{
42
- /* These calculations mustn't set any fp exception flags,
43
- * so we use a local copy of the fp_status.
44
- */
45
- float_status dummy_status = *real_fp_status;
46
- float_status *s = &dummy_status;
47
- float64 q;
48
- int64_t q_int;
49
+ int b, estimate;
50
51
- if (float64_lt(a, float64_half, s)) {
52
- /* range 0.25 <= a < 0.5 */
53
-
54
- /* a in units of 1/512 rounded down */
55
- /* q0 = (int)(a * 512.0); */
56
- q = float64_mul(float64_512, a, s);
57
- q_int = float64_to_int64_round_to_zero(q, s);
58
-
59
- /* reciprocal root r */
60
- /* r = 1.0 / sqrt(((double)q0 + 0.5) / 512.0); */
61
- q = int64_to_float64(q_int, s);
62
- q = float64_add(q, float64_half, s);
63
- q = float64_div(q, float64_512, s);
64
- q = float64_sqrt(q, s);
65
- q = float64_div(float64_one, q, s);
66
+ assert(128 <= a && a < 512);
67
+ if (a < 256) {
68
+ a = a * 2 + 1;
69
} else {
70
- /* range 0.5 <= a < 1.0 */
71
-
72
- /* a in units of 1/256 rounded down */
73
- /* q1 = (int)(a * 256.0); */
74
- q = float64_mul(float64_256, a, s);
75
- int64_t q_int = float64_to_int64_round_to_zero(q, s);
76
-
77
- /* reciprocal root r */
78
- /* r = 1.0 /sqrt(((double)q1 + 0.5) / 256); */
79
- q = int64_to_float64(q_int, s);
80
- q = float64_add(q, float64_half, s);
81
- q = float64_div(q, float64_256, s);
82
- q = float64_sqrt(q, s);
83
- q = float64_div(float64_one, q, s);
84
+ a = (a >> 1) << 1;
85
+ a = (a + 1) * 2;
86
}
87
- /* r in units of 1/256 rounded to nearest */
88
- /* s = (int)(256.0 * r + 0.5); */
89
+ b = 512;
90
+ while (a * (b + 1) * (b + 1) < (1 << 28)) {
91
+ b += 1;
92
+ }
93
+ estimate = (b + 1) / 2;
94
+ assert(256 <= estimate && estimate < 512);
95
96
- q = float64_mul(q, float64_256,s );
97
- q = float64_add(q, float64_half, s);
98
- q_int = float64_to_int64_round_to_zero(q, s);
99
+ return estimate;
100
+}
101
102
- /* return (double)s / 256.0;*/
103
- return float64_div(int64_to_float64(q_int, s), float64_256, s);
104
+
105
+static uint64_t recip_sqrt_estimate(int *exp , int exp_off, uint64_t frac)
106
+{
107
+ int estimate;
108
+ uint32_t scaled;
109
+
110
+ if (*exp == 0) {
111
+ while (extract64(frac, 51, 1) == 0) {
112
+ frac = frac << 1;
113
+ *exp -= 1;
114
+ }
115
+ frac = extract64(frac, 0, 51) << 1;
116
+ }
117
+
118
+ if (*exp & 1) {
119
+ /* scaled = UInt('01':fraction<51:45>) */
120
+ scaled = deposit32(1 << 7, 0, 7, extract64(frac, 45, 7));
121
+ } else {
122
+ /* scaled = UInt('1':fraction<51:44>) */
123
+ scaled = deposit32(1 << 8, 0, 8, extract64(frac, 44, 8));
124
+ }
125
+ estimate = do_recip_sqrt_estimate(scaled);
126
+
127
+ *exp = (exp_off - *exp) / 2;
128
+ return extract64(estimate, 0, 8) << 44;
129
+}
23
+}
130
+
24
+
131
+float16 HELPER(rsqrte_f16)(float16 input, void *fpstp)
25
+static void mps2tz_set_default_ram_info(MPS2TZMachineClass *mmc)
132
+{
26
+{
133
+ float_status *s = fpstp;
27
+ /*
134
+ float16 f16 = float16_squash_input_denormal(input, s);
28
+ * Set mc->default_ram_size and default_ram_id from the
135
+ uint16_t val = float16_val(f16);
29
+ * information in mmc->raminfo.
136
+ bool f16_sign = float16_is_neg(f16);
30
+ */
137
+ int f16_exp = extract32(val, 10, 5);
31
+ MachineClass *mc = MACHINE_CLASS(mmc);
138
+ uint16_t f16_frac = extract32(val, 0, 10);
32
+ const RAMInfo *p;
139
+ uint64_t f64_frac;
140
+
33
+
141
+ if (float16_is_any_nan(f16)) {
34
+ for (p = mmc->raminfo; p->name; p++) {
142
+ float16 nan = f16;
35
+ if (p->mrindex < 0) {
143
+ if (float16_is_signaling_nan(f16, s)) {
36
+ /* Found the entry for "system memory" */
144
+ float_raise(float_flag_invalid, s);
37
+ mc->default_ram_size = p->size;
145
+ nan = float16_maybe_silence_nan(f16, s);
38
+ mc->default_ram_id = p->name;
39
+ return;
146
+ }
40
+ }
147
+ if (s->default_nan_mode) {
148
+ nan = float16_default_nan(s);
149
+ }
150
+ return nan;
151
+ } else if (float16_is_zero(f16)) {
152
+ float_raise(float_flag_divbyzero, s);
153
+ return float16_set_sign(float16_infinity, f16_sign);
154
+ } else if (f16_sign) {
155
+ float_raise(float_flag_invalid, s);
156
+ return float16_default_nan(s);
157
+ } else if (float16_is_infinity(f16)) {
158
+ return float16_zero;
159
+ }
41
+ }
160
+
42
+ g_assert_not_reached();
161
+ /* Scale and normalize to a double-precision value between 0.25 and 1.0,
162
+ * preserving the parity of the exponent. */
163
+
164
+ f64_frac = ((uint64_t) f16_frac) << (52 - 10);
165
+
166
+ f64_frac = recip_sqrt_estimate(&f16_exp, 44, f64_frac);
167
+
168
+ /* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(2) */
169
+ val = deposit32(0, 15, 1, f16_sign);
170
+ val = deposit32(val, 10, 5, f16_exp);
171
+ val = deposit32(val, 2, 8, extract64(f64_frac, 52 - 8, 8));
172
+ return make_float16(val);
173
}
43
}
174
44
175
float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
45
static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
176
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
46
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
177
float_status *s = fpstp;
47
mmc->numirq = 92;
178
float32 f32 = float32_squash_input_denormal(input, s);
48
mmc->raminfo = an505_raminfo;
179
uint32_t val = float32_val(f32);
49
mmc->armsse_type = TYPE_IOTKIT;
180
- uint32_t f32_sbit = 0x80000000 & val;
50
+ mps2tz_set_default_ram_info(mmc);
181
- int32_t f32_exp = extract32(val, 23, 8);
182
+ uint32_t f32_sign = float32_is_neg(f32);
183
+ int f32_exp = extract32(val, 23, 8);
184
uint32_t f32_frac = extract32(val, 0, 23);
185
uint64_t f64_frac;
186
- uint64_t val64;
187
- int result_exp;
188
- float64 f64;
189
190
if (float32_is_any_nan(f32)) {
191
float32 nan = f32;
192
@@ -XXX,XX +XXX,XX @@ float32 HELPER(rsqrte_f32)(float32 input, void *fpstp)
193
* preserving the parity of the exponent. */
194
195
f64_frac = ((uint64_t) f32_frac) << 29;
196
- if (f32_exp == 0) {
197
- while (extract64(f64_frac, 51, 1) == 0) {
198
- f64_frac = f64_frac << 1;
199
- f32_exp = f32_exp-1;
200
- }
201
- f64_frac = extract64(f64_frac, 0, 51) << 1;
202
- }
203
204
- if (extract64(f32_exp, 0, 1) == 0) {
205
- f64 = make_float64(((uint64_t) f32_sbit) << 32
206
- | (0x3feULL << 52)
207
- | f64_frac);
208
- } else {
209
- f64 = make_float64(((uint64_t) f32_sbit) << 32
210
- | (0x3fdULL << 52)
211
- | f64_frac);
212
- }
213
+ f64_frac = recip_sqrt_estimate(&f32_exp, 380, f64_frac);
214
215
- result_exp = (380 - f32_exp) / 2;
216
-
217
- f64 = recip_sqrt_estimate(f64, s);
218
-
219
- val64 = float64_val(f64);
220
-
221
- val = ((result_exp & 0xff) << 23)
222
- | ((val64 >> 29) & 0x7fffff);
223
+ /* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(15) */
224
+ val = deposit32(0, 31, 1, f32_sign);
225
+ val = deposit32(val, 23, 8, f32_exp);
226
+ val = deposit32(val, 15, 8, extract64(f64_frac, 52 - 8, 8));
227
return make_float32(val);
228
}
51
}
229
52
230
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
53
static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
231
float_status *s = fpstp;
54
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
232
float64 f64 = float64_squash_input_denormal(input, s);
55
mmc->numirq = 92;
233
uint64_t val = float64_val(f64);
56
mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
234
- uint64_t f64_sbit = 0x8000000000000000ULL & val;
57
mmc->armsse_type = TYPE_SSE200;
235
- int64_t f64_exp = extract64(val, 52, 11);
58
+ mps2tz_set_default_ram_info(mmc);
236
+ bool f64_sign = float64_is_neg(f64);
237
+ int f64_exp = extract64(val, 52, 11);
238
uint64_t f64_frac = extract64(val, 0, 52);
239
- int64_t result_exp;
240
- uint64_t result_frac;
241
242
if (float64_is_any_nan(f64)) {
243
float64 nan = f64;
244
@@ -XXX,XX +XXX,XX @@ float64 HELPER(rsqrte_f64)(float64 input, void *fpstp)
245
return float64_zero;
246
}
247
248
- /* Scale and normalize to a double-precision value between 0.25 and 1.0,
249
- * preserving the parity of the exponent. */
250
+ f64_frac = recip_sqrt_estimate(&f64_exp, 3068, f64_frac);
251
252
- if (f64_exp == 0) {
253
- while (extract64(f64_frac, 51, 1) == 0) {
254
- f64_frac = f64_frac << 1;
255
- f64_exp = f64_exp - 1;
256
- }
257
- f64_frac = extract64(f64_frac, 0, 51) << 1;
258
- }
259
-
260
- if (extract64(f64_exp, 0, 1) == 0) {
261
- f64 = make_float64(f64_sbit
262
- | (0x3feULL << 52)
263
- | f64_frac);
264
- } else {
265
- f64 = make_float64(f64_sbit
266
- | (0x3fdULL << 52)
267
- | f64_frac);
268
- }
269
-
270
- result_exp = (3068 - f64_exp) / 2;
271
-
272
- f64 = recip_sqrt_estimate(f64, s);
273
-
274
- result_frac = extract64(float64_val(f64), 0, 52);
275
-
276
- return make_float64(f64_sbit |
277
- ((result_exp & 0x7ff) << 52) |
278
- result_frac);
279
+ /* result = sign : result_exp<4:0> : estimate<7:0> : Zeros(44) */
280
+ val = deposit64(0, 61, 1, f64_sign);
281
+ val = deposit64(val, 52, 11, f64_exp);
282
+ val = deposit64(val, 44, 8, extract64(f64_frac, 52 - 8, 8));
283
+ return make_float64(val);
284
}
59
}
285
60
286
uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp)
61
static const TypeInfo mps2tz_info = {
287
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(recpe_u32)(uint32_t a, void *fpstp)
288
289
uint32_t HELPER(rsqrte_u32)(uint32_t a, void *fpstp)
290
{
291
- float_status *fpst = fpstp;
292
- float64 f64;
293
+ int estimate;
294
295
if ((a & 0xc0000000) == 0) {
296
return 0xffffffff;
297
}
298
299
- if (a & 0x80000000) {
300
- f64 = make_float64((0x3feULL << 52)
301
- | ((uint64_t)(a & 0x7fffffff) << 21));
302
- } else { /* bits 31-30 == '01' */
303
- f64 = make_float64((0x3fdULL << 52)
304
- | ((uint64_t)(a & 0x3fffffff) << 22));
305
- }
306
+ estimate = do_recip_sqrt_estimate(extract32(a, 23, 9));
307
308
- f64 = recip_sqrt_estimate(f64, fpst);
309
-
310
- return 0x80000000 | ((float64_val(f64) >> 21) & 0x7fffffff);
311
+ return deposit32(0, 23, 9, estimate);
312
}
313
314
/* VFPv4 fused multiply-accumulate */
315
--
62
--
316
2.16.2
63
2.20.1
317
64
318
65
diff view generated by jsdifflib
1
From: Linus Walleij <linus.walleij@linaro.org>
1
The AN505 and AN521 don't have any read-only memory, but the AN524
2
does; add a flag to ROMInfo to mark a region as ROM.
2
3
3
The tx function of the DDC I2C slave emulation was returning 1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
on all writes resulting in NACK in the I2C bus. Changing it to
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
0 makes the DDC I2C work fine with bit-banged I2C such as the
6
Message-id: 20210215115138.20465-19-peter.maydell@linaro.org
6
versatile I2C.
7
---
8
hw/arm/mps2-tz.c | 6 ++++++
9
1 file changed, 6 insertions(+)
7
10
8
I guess it was not affecting whatever I2C controller this was
11
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
9
used with until now, but with the Versatile I2C it surely
10
does not work.
11
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
14
Message-id: 20180227104903.21353-4-linus.walleij@linaro.org
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
hw/i2c/i2c-ddc.c | 4 ++--
19
1 file changed, 2 insertions(+), 2 deletions(-)
20
21
diff --git a/hw/i2c/i2c-ddc.c b/hw/i2c/i2c-ddc.c
22
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/i2c/i2c-ddc.c
13
--- a/hw/arm/mps2-tz.c
24
+++ b/hw/i2c/i2c-ddc.c
14
+++ b/hw/arm/mps2-tz.c
25
@@ -XXX,XX +XXX,XX @@ static int i2c_ddc_tx(I2CSlave *i2c, uint8_t data)
15
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
26
s->reg = data;
16
* Flag values:
27
s->firstbyte = false;
17
* IS_ALIAS: this RAM area is an alias to the upstream end of the
28
DPRINTF("[EDID] Written new pointer: %u\n", data);
18
* MPC specified by its .mpc value
29
- return 1;
19
+ * IS_ROM: this RAM area is read-only
30
+ return 0;
20
*/
21
#define IS_ALIAS 1
22
+#define IS_ROM 2
23
24
struct MPS2TZMachineClass {
25
MachineClass parent;
26
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
27
if (raminfo->mrindex < 0) {
28
/* Means this RAMInfo is for QEMU's "system memory" */
29
MachineState *machine = MACHINE(mms);
30
+ assert(!(raminfo->flags & IS_ROM));
31
return machine->ram;
31
}
32
}
32
33
33
/* Ignore all writes */
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
34
s->reg++;
35
35
- return 1;
36
memory_region_init_ram(ram, NULL, raminfo->name,
36
+ return 0;
37
raminfo->size, &error_fatal);
38
+ if (raminfo->flags & IS_ROM) {
39
+ memory_region_set_readonly(ram, true);
40
+ }
41
return ram;
37
}
42
}
38
43
39
static void i2c_ddc_init(Object *obj)
40
--
44
--
41
2.16.2
45
2.20.1
42
46
43
47
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The armv7m_load_kernel() function takes a mem_size argument which it
2
expects to be the size of the memory region at guest address 0. (It
3
uses this argument only as a limit on how large a raw image file it
4
can load at address zero).
2
5
3
This is the initial decode skeleton for the Advanced SIMD three same
6
Instead of hardcoding this value, find the RAMInfo corresponding to
4
instruction group.
7
the 0 address and extract its size.
5
8
6
The fprintf is purely to aid debugging as the additional instructions
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
are added. It will be removed once the group is complete.
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-20-peter.maydell@linaro.org
13
---
14
hw/arm/mps2-tz.c | 17 ++++++++++++++++-
15
1 file changed, 16 insertions(+), 1 deletion(-)
8
16
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180227143852.11175-9-alex.bennee@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/translate-a64.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++
15
1 file changed, 73 insertions(+)
16
17
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate-a64.c
19
--- a/hw/arm/mps2-tz.c
20
+++ b/target/arm/translate-a64.c
20
+++ b/hw/arm/mps2-tz.c
21
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same(DisasContext *s, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@ static void create_non_mpc_ram(MPS2TZMachineState *mms)
22
}
22
}
23
}
23
}
24
24
25
+/*
25
+static uint32_t boot_ram_size(MPS2TZMachineState *mms)
26
+ * Advanced SIMD three same (ARMv8.2 FP16 variants)
27
+ *
28
+ * 31 30 29 28 24 23 22 21 20 16 15 14 13 11 10 9 5 4 0
29
+ * +---+---+---+-----------+---------+------+-----+--------+---+------+------+
30
+ * | 0 | Q | U | 0 1 1 1 0 | a | 1 0 | Rm | 0 0 | opcode | 1 | Rn | Rd |
31
+ * +---+---+---+-----------+---------+------+-----+--------+---+------+------+
32
+ *
33
+ * This includes FMULX, FCMEQ (register), FRECPS, FRSQRTS, FCMGE
34
+ * (register), FACGE, FABD, FCMGT (register) and FACGT.
35
+ *
36
+ */
37
+static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
38
+{
26
+{
39
+ int opcode, fpopcode;
27
+ /* Return the size of the RAM block at guest address zero */
40
+ int is_q, u, a, rm, rn, rd;
28
+ const RAMInfo *p;
41
+ int datasize, elements;
29
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
42
+ int pass;
43
+ TCGv_ptr fpst;
44
+
30
+
45
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
31
+ for (p = mmc->raminfo; p->name; p++) {
46
+ unallocated_encoding(s);
32
+ if (p->base == 0) {
47
+ return;
33
+ return p->size;
34
+ }
48
+ }
35
+ }
49
+
36
+ g_assert_not_reached();
50
+ if (!fp_access_check(s)) {
51
+ return;
52
+ }
53
+
54
+ /* For these floating point ops, the U, a and opcode bits
55
+ * together indicate the operation.
56
+ */
57
+ opcode = extract32(insn, 11, 3);
58
+ u = extract32(insn, 29, 1);
59
+ a = extract32(insn, 23, 1);
60
+ is_q = extract32(insn, 30, 1);
61
+ rm = extract32(insn, 16, 5);
62
+ rn = extract32(insn, 5, 5);
63
+ rd = extract32(insn, 0, 5);
64
+
65
+ fpopcode = opcode | (a << 3) | (u << 4);
66
+ datasize = is_q ? 128 : 64;
67
+ elements = datasize / 16;
68
+
69
+ fpst = get_fpstatus_ptr(true);
70
+
71
+ for (pass = 0; pass < elements; pass++) {
72
+ TCGv_i32 tcg_op1 = tcg_temp_new_i32();
73
+ TCGv_i32 tcg_op2 = tcg_temp_new_i32();
74
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
75
+
76
+ read_vec_element_i32(s, tcg_op1, rn, pass, MO_16);
77
+ read_vec_element_i32(s, tcg_op2, rm, pass, MO_16);
78
+
79
+ switch (fpopcode) {
80
+ default:
81
+ fprintf(stderr, "%s: insn %#04x, fpop %#2x @ %#" PRIx64 "\n",
82
+ __func__, insn, fpopcode, s->pc);
83
+ g_assert_not_reached();
84
+ }
85
+
86
+ write_vec_element_i32(s, tcg_res, rd, pass, MO_16);
87
+ tcg_temp_free_i32(tcg_res);
88
+ tcg_temp_free_i32(tcg_op1);
89
+ tcg_temp_free_i32(tcg_op2);
90
+ }
91
+
92
+ tcg_temp_free_ptr(fpst);
93
+
94
+ clear_vec_high(s, is_q, rd);
95
+}
37
+}
96
+
38
+
97
static void handle_2misc_widening(DisasContext *s, int opcode, bool is_q,
39
static void mps2tz_common_init(MachineState *machine)
98
int size, int rn, int rd)
99
{
40
{
100
@@ -XXX,XX +XXX,XX @@ static const AArch64DecodeTable data_proc_simd[] = {
41
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
101
{ 0xce000000, 0xff808000, disas_crypto_four_reg },
42
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
102
{ 0xce800000, 0xffe00000, disas_crypto_xar },
43
103
{ 0xce408000, 0xffe0c000, disas_crypto_three_reg_imm2 },
44
create_non_mpc_ram(mms);
104
+ { 0x0e400400, 0x9f60c400, disas_simd_three_reg_same_fp16 },
45
105
{ 0x00000000, 0x00000000, NULL }
46
- armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
106
};
47
+ armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
107
48
+ boot_ram_size(mms));
49
}
50
51
static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
108
--
52
--
109
2.16.2
53
2.20.1
110
54
111
55
diff view generated by jsdifflib
New patch
1
1
Add support for the mps3-an524 board; this is an SSE-200 based FPGA
2
image, like the existing mps2-an521. It has a usefully larger amount
3
of RAM, and a PL031 RTC, as well as some more minor differences.
4
5
In real hardware this image runs on a newer generation of the FPGA
6
board, the MPS3 rather than the older MPS2. Architecturally the two
7
boards are similar, so we implement the MPS3 boards in the mps2-tz.c
8
file as variations of the existing MPS2 boards.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-21-peter.maydell@linaro.org
13
---
14
hw/arm/mps2-tz.c | 139 +++++++++++++++++++++++++++++++++++++++++++++--
15
1 file changed, 135 insertions(+), 4 deletions(-)
16
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2-tz.c
20
+++ b/hw/arm/mps2-tz.c
21
@@ -XXX,XX +XXX,XX @@
22
* This source file covers the following FPGA images, for TrustZone cores:
23
* "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
24
* "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
25
+ * "mps2-an524" -- Dual Cortex-M33 as documented in Application Note AN524
26
*
27
* Links to the TRM for the board itself and to the various Application
28
* Notes which document the FPGA images can be found here:
29
@@ -XXX,XX +XXX,XX @@
30
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
31
* Application Note AN521:
32
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
33
+ * Application Note AN524:
34
+ * https://developer.arm.com/documentation/dai0524/latest/
35
*
36
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
37
* (ARM ECM0601256) for the details of some of the device layout:
38
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
39
- * Similarly, the AN521 uses the SSE-200, and the SSE-200 TRM defines
40
+ * Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
41
* most of the device layout:
42
* http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
43
*
44
@@ -XXX,XX +XXX,XX @@
45
#include "hw/qdev-clock.h"
46
#include "qom/object.h"
47
48
-#define MPS2TZ_NUMIRQ_MAX 92
49
+#define MPS2TZ_NUMIRQ_MAX 95
50
#define MPS2TZ_RAM_MAX 4
51
52
typedef enum MPS2TZFPGAType {
53
FPGA_AN505,
54
FPGA_AN521,
55
+ FPGA_AN524,
56
} MPS2TZFPGAType;
57
58
/*
59
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
60
TZPPC ppc[5];
61
TZMPC mpc[3];
62
PL022State spi[5];
63
- ArmSbconI2CState i2c[4];
64
+ ArmSbconI2CState i2c[5];
65
UnimplementedDeviceState i2s_audio;
66
UnimplementedDeviceState gpio[4];
67
UnimplementedDeviceState gfx;
68
+ UnimplementedDeviceState cldc;
69
+ UnimplementedDeviceState rtc;
70
PL080State dma[4];
71
TZMSC msc[4];
72
- CMSDKAPBUART uart[5];
73
+ CMSDKAPBUART uart[6];
74
SplitIRQ sec_resp_splitter;
75
qemu_or_irq uart_irq_orgate;
76
DeviceState *lan9118;
77
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
78
#define TYPE_MPS2TZ_MACHINE "mps2tz"
79
#define TYPE_MPS2TZ_AN505_MACHINE MACHINE_TYPE_NAME("mps2-an505")
80
#define TYPE_MPS2TZ_AN521_MACHINE MACHINE_TYPE_NAME("mps2-an521")
81
+#define TYPE_MPS3TZ_AN524_MACHINE MACHINE_TYPE_NAME("mps3-an524")
82
83
OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
84
85
@@ -XXX,XX +XXX,XX @@ static const uint32_t an505_oscclk[] = {
86
25000000,
87
};
88
89
+static const uint32_t an524_oscclk[] = {
90
+ 24000000,
91
+ 32000000,
92
+ 50000000,
93
+ 50000000,
94
+ 24576000,
95
+ 23750000,
96
+};
97
+
98
static const RAMInfo an505_raminfo[] = { {
99
.name = "ssram-0",
100
.base = 0x00000000,
101
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an505_raminfo[] = { {
102
},
103
};
104
105
+static const RAMInfo an524_raminfo[] = { {
106
+ .name = "bram",
107
+ .base = 0x00000000,
108
+ .size = 512 * KiB,
109
+ .mpc = 0,
110
+ .mrindex = 0,
111
+ }, {
112
+ .name = "sram",
113
+ .base = 0x20000000,
114
+ .size = 32 * 4 * KiB,
115
+ .mpc = 1,
116
+ .mrindex = 1,
117
+ }, {
118
+ /* We don't model QSPI flash yet; for now expose it as simple ROM */
119
+ .name = "QSPI",
120
+ .base = 0x28000000,
121
+ .size = 8 * MiB,
122
+ .mpc = 1,
123
+ .mrindex = 2,
124
+ .flags = IS_ROM,
125
+ }, {
126
+ .name = "DDR",
127
+ .base = 0x60000000,
128
+ .size = 2 * GiB,
129
+ .mpc = 2,
130
+ .mrindex = -1,
131
+ }, {
132
+ .name = NULL,
133
+ },
134
+};
135
+
136
static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
137
{
138
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
139
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
140
},
141
};
142
143
+ const PPCInfo an524_ppcs[] = { {
144
+ .name = "apb_ppcexp0",
145
+ .ports = {
146
+ { "bram-mpc", make_mpc, &mms->mpc[0], 0x58007000, 0x1000 },
147
+ { "qspi-mpc", make_mpc, &mms->mpc[1], 0x58008000, 0x1000 },
148
+ { "ddr-mpc", make_mpc, &mms->mpc[2], 0x58009000, 0x1000 },
149
+ },
150
+ }, {
151
+ .name = "apb_ppcexp1",
152
+ .ports = {
153
+ { "i2c0", make_i2c, &mms->i2c[0], 0x41200000, 0x1000 },
154
+ { "i2c1", make_i2c, &mms->i2c[1], 0x41201000, 0x1000 },
155
+ { "spi0", make_spi, &mms->spi[0], 0x41202000, 0x1000, { 52 } },
156
+ { "spi1", make_spi, &mms->spi[1], 0x41203000, 0x1000, { 53 } },
157
+ { "spi2", make_spi, &mms->spi[2], 0x41204000, 0x1000, { 54 } },
158
+ { "i2c2", make_i2c, &mms->i2c[2], 0x41205000, 0x1000 },
159
+ { "i2c3", make_i2c, &mms->i2c[3], 0x41206000, 0x1000 },
160
+ { /* port 7 reserved */ },
161
+ { "i2c4", make_i2c, &mms->i2c[4], 0x41208000, 0x1000 },
162
+ },
163
+ }, {
164
+ .name = "apb_ppcexp2",
165
+ .ports = {
166
+ { "scc", make_scc, &mms->scc, 0x41300000, 0x1000 },
167
+ { "i2s-audio", make_unimp_dev, &mms->i2s_audio,
168
+ 0x41301000, 0x1000 },
169
+ { "fpgaio", make_fpgaio, &mms->fpgaio, 0x41302000, 0x1000 },
170
+ { "uart0", make_uart, &mms->uart[0], 0x41303000, 0x1000, { 32, 33, 42 } },
171
+ { "uart1", make_uart, &mms->uart[1], 0x41304000, 0x1000, { 34, 35, 43 } },
172
+ { "uart2", make_uart, &mms->uart[2], 0x41305000, 0x1000, { 36, 37, 44 } },
173
+ { "uart3", make_uart, &mms->uart[3], 0x41306000, 0x1000, { 38, 39, 45 } },
174
+ { "uart4", make_uart, &mms->uart[4], 0x41307000, 0x1000, { 40, 41, 46 } },
175
+ { "uart5", make_uart, &mms->uart[5], 0x41308000, 0x1000, { 124, 125, 126 } },
176
+
177
+ { /* port 9 reserved */ },
178
+ { "clcd", make_unimp_dev, &mms->cldc, 0x4130a000, 0x1000 },
179
+ { "rtc", make_unimp_dev, &mms->rtc, 0x4130b000, 0x1000 },
180
+ },
181
+ }, {
182
+ .name = "ahb_ppcexp0",
183
+ .ports = {
184
+ { "gpio0", make_unimp_dev, &mms->gpio[0], 0x41100000, 0x1000 },
185
+ { "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
186
+ { "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
187
+ { "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
188
+ { "eth", make_eth_dev, NULL, 0x41400000, 0x100000, { 48 } },
189
+ },
190
+ },
191
+ };
192
+
193
switch (mmc->fpga_type) {
194
case FPGA_AN505:
195
case FPGA_AN521:
196
ppcs = an505_ppcs;
197
num_ppcs = ARRAY_SIZE(an505_ppcs);
198
break;
199
+ case FPGA_AN524:
200
+ ppcs = an524_ppcs;
201
+ num_ppcs = ARRAY_SIZE(an524_ppcs);
202
+ break;
203
default:
204
g_assert_not_reached();
205
}
206
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
207
mps2tz_set_default_ram_info(mmc);
208
}
209
210
+static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
211
+{
212
+ MachineClass *mc = MACHINE_CLASS(oc);
213
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
214
+
215
+ mc->desc = "ARM MPS3 with AN524 FPGA image for dual Cortex-M33";
216
+ mc->default_cpus = 2;
217
+ mc->min_cpus = mc->default_cpus;
218
+ mc->max_cpus = mc->default_cpus;
219
+ mmc->fpga_type = FPGA_AN524;
220
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
221
+ mmc->scc_id = 0x41045240;
222
+ mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
223
+ mmc->oscclk = an524_oscclk;
224
+ mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
225
+ mmc->fpgaio_num_leds = 10;
226
+ mmc->fpgaio_has_switches = true;
227
+ mmc->numirq = 95;
228
+ mmc->raminfo = an524_raminfo;
229
+ mmc->armsse_type = TYPE_SSE200;
230
+ mps2tz_set_default_ram_info(mmc);
231
+}
232
+
233
static const TypeInfo mps2tz_info = {
234
.name = TYPE_MPS2TZ_MACHINE,
235
.parent = TYPE_MACHINE,
236
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mps2tz_an521_info = {
237
.class_init = mps2tz_an521_class_init,
238
};
239
240
+static const TypeInfo mps3tz_an524_info = {
241
+ .name = TYPE_MPS3TZ_AN524_MACHINE,
242
+ .parent = TYPE_MPS2TZ_MACHINE,
243
+ .class_init = mps3tz_an524_class_init,
244
+};
245
+
246
static void mps2tz_machine_init(void)
247
{
248
type_register_static(&mps2tz_info);
249
type_register_static(&mps2tz_an505_info);
250
type_register_static(&mps2tz_an521_info);
251
+ type_register_static(&mps3tz_an524_info);
252
}
253
254
type_init(mps2tz_machine_init);
255
--
256
2.20.1
257
258
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The AN524 has a USB controller (an ISP1763); we don't have a model of
2
it but we should provide a stub "unimplemented-device" for it. This
3
is slightly complicated because the USB controller shares a PPC port
4
with the ethernet controller.
2
5
3
We go with the localised helper.
6
Implement a make_* function which provides creates a container
7
MemoryRegion with both the ethernet controller and an
8
unimplemented-device stub for the USB controller.
4
9
5
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180227143852.11175-25-alex.bennee@linaro.org
13
Message-id: 20210215115138.20465-22-peter.maydell@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
14
---
10
target/arm/helper-a64.h | 1 +
15
hw/arm/mps2-tz.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
11
target/arm/helper-a64.c | 29 +++++++++++++++++++++++++++++
16
1 file changed, 47 insertions(+), 1 deletion(-)
12
target/arm/translate-a64.c | 4 ++++
13
3 files changed, 34 insertions(+)
14
17
15
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
18
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-a64.h
20
--- a/hw/arm/mps2-tz.c
18
+++ b/target/arm/helper-a64.h
21
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_1(neon_addlp_s16, TCG_CALL_NO_RWG_SE, i64, i64)
22
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
20
DEF_HELPER_FLAGS_1(neon_addlp_u16, TCG_CALL_NO_RWG_SE, i64, i64)
23
21
DEF_HELPER_FLAGS_2(frecpx_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
24
ARMSSE iotkit;
22
DEF_HELPER_FLAGS_2(frecpx_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
25
MemoryRegion ram[MPS2TZ_RAM_MAX];
23
+DEF_HELPER_FLAGS_2(frecpx_f16, TCG_CALL_NO_RWG, f16, f16, ptr)
26
+ MemoryRegion eth_usb_container;
24
DEF_HELPER_FLAGS_2(fcvtx_f64_to_f32, TCG_CALL_NO_RWG, f32, f64, env)
27
+
25
DEF_HELPER_FLAGS_3(crc32_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32)
28
MPS2SCC scc;
26
DEF_HELPER_FLAGS_3(crc32c_64, TCG_CALL_NO_RWG_SE, i64, i64, i64, i32)
29
MPS2FPGAIO fpgaio;
27
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
30
TZPPC ppc[5];
28
index XXXXXXX..XXXXXXX 100644
31
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
29
--- a/target/arm/helper-a64.c
32
UnimplementedDeviceState gfx;
30
+++ b/target/arm/helper-a64.c
33
UnimplementedDeviceState cldc;
31
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_addlp_u16)(uint64_t a)
34
UnimplementedDeviceState rtc;
35
+ UnimplementedDeviceState usb;
36
PL080State dma[4];
37
TZMSC msc[4];
38
CMSDKAPBUART uart[6];
39
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
40
return sysbus_mmio_get_region(s, 0);
32
}
41
}
33
42
34
/* Floating-point reciprocal exponent - see FPRecpX in ARM ARM */
43
+static MemoryRegion *make_eth_usb(MPS2TZMachineState *mms, void *opaque,
35
+float16 HELPER(frecpx_f16)(float16 a, void *fpstp)
44
+ const char *name, hwaddr size,
45
+ const int *irqs)
36
+{
46
+{
37
+ float_status *fpst = fpstp;
47
+ /*
38
+ uint16_t val16, sbit;
48
+ * The AN524 makes the ethernet and USB share a PPC port.
39
+ int16_t exp;
49
+ * irqs[] is the ethernet IRQ.
50
+ */
51
+ SysBusDevice *s;
52
+ NICInfo *nd = &nd_table[0];
40
+
53
+
41
+ if (float16_is_any_nan(a)) {
54
+ memory_region_init(&mms->eth_usb_container, OBJECT(mms),
42
+ float16 nan = a;
55
+ "mps2-tz-eth-usb-container", 0x200000);
43
+ if (float16_is_signaling_nan(a, fpst)) {
44
+ float_raise(float_flag_invalid, fpst);
45
+ nan = float16_maybe_silence_nan(a, fpst);
46
+ }
47
+ if (fpst->default_nan_mode) {
48
+ nan = float16_default_nan(fpst);
49
+ }
50
+ return nan;
51
+ }
52
+
56
+
53
+ val16 = float16_val(a);
57
+ /*
54
+ sbit = 0x8000 & val16;
58
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
55
+ exp = extract32(val16, 10, 5);
59
+ * except that it doesn't support the checksum-offload feature.
60
+ */
61
+ qemu_check_nic_model(nd, "lan9118");
62
+ mms->lan9118 = qdev_new(TYPE_LAN9118);
63
+ qdev_set_nic_properties(mms->lan9118, nd);
56
+
64
+
57
+ if (exp == 0) {
65
+ s = SYS_BUS_DEVICE(mms->lan9118);
58
+ return make_float16(deposit32(sbit, 10, 5, 0x1e));
66
+ sysbus_realize_and_unref(s, &error_fatal);
59
+ } else {
67
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
60
+ return make_float16(deposit32(sbit, 10, 5, ~exp));
68
+
61
+ }
69
+ memory_region_add_subregion(&mms->eth_usb_container,
70
+ 0, sysbus_mmio_get_region(s, 0));
71
+
72
+ /* The USB OTG controller is an ISP1763; we don't have a model of it. */
73
+ object_initialize_child(OBJECT(mms), "usb-otg",
74
+ &mms->usb, TYPE_UNIMPLEMENTED_DEVICE);
75
+ qdev_prop_set_string(DEVICE(&mms->usb), "name", "usb-otg");
76
+ qdev_prop_set_uint64(DEVICE(&mms->usb), "size", 0x100000);
77
+ s = SYS_BUS_DEVICE(&mms->usb);
78
+ sysbus_realize(s, &error_fatal);
79
+
80
+ memory_region_add_subregion(&mms->eth_usb_container,
81
+ 0x100000, sysbus_mmio_get_region(s, 0));
82
+
83
+ return &mms->eth_usb_container;
62
+}
84
+}
63
+
85
+
64
float32 HELPER(frecpx_f32)(float32 a, void *fpstp)
86
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
65
{
87
const char *name, hwaddr size,
66
float_status *fpst = fpstp;
88
const int *irqs)
67
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
89
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
68
index XXXXXXX..XXXXXXX 100644
90
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
69
--- a/target/arm/translate-a64.c
91
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
70
+++ b/target/arm/translate-a64.c
92
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
71
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
93
- { "eth", make_eth_dev, NULL, 0x41400000, 0x100000, { 48 } },
72
handle_2misc_fcmp_zero(s, fpop, is_scalar, 0, is_q, MO_16, rn, rd);
94
+ { "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 48 } },
73
return;
95
},
74
case 0x3d: /* FRECPE */
96
},
75
+ case 0x3f: /* FRECPX */
97
};
76
break;
77
case 0x18: /* FRINTN */
78
need_rmode = true;
79
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
80
case 0x3d: /* FRECPE */
81
gen_helper_recpe_f16(tcg_res, tcg_op, tcg_fpstatus);
82
break;
83
+ case 0x3f: /* FRECPX */
84
+ gen_helper_frecpx_f16(tcg_res, tcg_op, tcg_fpstatus);
85
+ break;
86
case 0x5a: /* FCVTNU */
87
case 0x5b: /* FCVTMU */
88
case 0x5c: /* FCVTAU */
89
--
98
--
90
2.16.2
99
2.20.1
91
100
92
101
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
The AN524 has a PL031 RTC, which we have a model of; provide it
2
rather than an unimplemented-device stub.
2
3
3
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180227143852.11175-12-alex.bennee@linaro.org
7
Message-id: 20210215115138.20465-23-peter.maydell@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
---
8
target/arm/helper-a64.h | 2 ++
9
hw/arm/mps2-tz.c | 22 ++++++++++++++++++++--
9
target/arm/helper-a64.c | 24 ++++++++++++++++++++++++
10
1 file changed, 20 insertions(+), 2 deletions(-)
10
target/arm/translate-a64.c | 15 +++++++++++++++
11
3 files changed, 41 insertions(+)
12
11
13
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper-a64.h
14
--- a/hw/arm/mps2-tz.c
16
+++ b/target/arm/helper-a64.h
15
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(advsimd_cge_f16, i32, f16, f16, ptr)
16
@@ -XXX,XX +XXX,XX @@
18
DEF_HELPER_3(advsimd_cgt_f16, i32, f16, f16, ptr)
17
#include "hw/misc/tz-msc.h"
19
DEF_HELPER_3(advsimd_acge_f16, i32, f16, f16, ptr)
18
#include "hw/arm/armsse.h"
20
DEF_HELPER_3(advsimd_acgt_f16, i32, f16, f16, ptr)
19
#include "hw/dma/pl080.h"
21
+DEF_HELPER_3(advsimd_mulxh, f16, f16, f16, ptr)
20
+#include "hw/rtc/pl031.h"
22
+DEF_HELPER_4(advsimd_muladdh, f16, f16, f16, f16, ptr)
21
#include "hw/ssi/pl022.h"
23
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
22
#include "hw/i2c/arm_sbcon_i2c.h"
24
index XXXXXXX..XXXXXXX 100644
23
#include "hw/net/lan9118.h"
25
--- a/target/arm/helper-a64.c
24
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
26
+++ b/target/arm/helper-a64.c
25
UnimplementedDeviceState gpio[4];
27
@@ -XXX,XX +XXX,XX @@ ADVSIMD_HALFOP(max)
26
UnimplementedDeviceState gfx;
28
ADVSIMD_HALFOP(minnum)
27
UnimplementedDeviceState cldc;
29
ADVSIMD_HALFOP(maxnum)
28
- UnimplementedDeviceState rtc;
30
29
UnimplementedDeviceState usb;
31
+/* Data processing - scalar floating-point and advanced SIMD */
30
+ PL031State rtc;
32
+float16 HELPER(advsimd_mulxh)(float16 a, float16 b, void *fpstp)
31
PL080State dma[4];
32
TZMSC msc[4];
33
CMSDKAPBUART uart[6];
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
35
return sysbus_mmio_get_region(s, 0);
36
}
37
38
+static MemoryRegion *make_rtc(MPS2TZMachineState *mms, void *opaque,
39
+ const char *name, hwaddr size,
40
+ const int *irqs)
33
+{
41
+{
34
+ float_status *fpst = fpstp;
42
+ PL031State *pl031 = opaque;
43
+ SysBusDevice *s;
35
+
44
+
36
+ a = float16_squash_input_denormal(a, fpst);
45
+ object_initialize_child(OBJECT(mms), name, pl031, TYPE_PL031);
37
+ b = float16_squash_input_denormal(b, fpst);
46
+ s = SYS_BUS_DEVICE(pl031);
38
+
47
+ sysbus_realize(s, &error_fatal);
39
+ if ((float16_is_zero(a) && float16_is_infinity(b)) ||
48
+ /*
40
+ (float16_is_infinity(a) && float16_is_zero(b))) {
49
+ * The board docs don't give an IRQ number for the PL031, so
41
+ /* 2.0 with the sign bit set to sign(A) XOR sign(B) */
50
+ * presumably it is not connected.
42
+ return make_float16((1U << 14) |
51
+ */
43
+ ((float16_val(a) ^ float16_val(b)) & (1U << 15)));
52
+ return sysbus_mmio_get_region(s, 0);
44
+ }
45
+ return float16_mul(a, b, fpst);
46
+}
53
+}
47
+
54
+
48
+/* fused multiply-accumulate */
55
static void create_non_mpc_ram(MPS2TZMachineState *mms)
49
+float16 HELPER(advsimd_muladdh)(float16 a, float16 b, float16 c, void *fpstp)
56
{
50
+{
57
/*
51
+ float_status *fpst = fpstp;
58
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
52
+ return float16_muladd(a, b, c, 0, fpst);
59
53
+}
60
{ /* port 9 reserved */ },
54
+
61
{ "clcd", make_unimp_dev, &mms->cldc, 0x4130a000, 0x1000 },
55
/*
62
- { "rtc", make_unimp_dev, &mms->rtc, 0x4130b000, 0x1000 },
56
* Floating point comparisons produce an integer result. Softfloat
63
+ { "rtc", make_rtc, &mms->rtc, 0x4130b000, 0x1000 },
57
* routines return float_relation types which we convert to the 0/-1
64
},
58
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
65
}, {
59
index XXXXXXX..XXXXXXX 100644
66
.name = "ahb_ppcexp0",
60
--- a/target/arm/translate-a64.c
61
+++ b/target/arm/translate-a64.c
62
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
63
case 0x0: /* FMAXNM */
64
gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
65
break;
66
+ case 0x1: /* FMLA */
67
+ read_vec_element_i32(s, tcg_res, rd, pass, MO_16);
68
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_res,
69
+ fpst);
70
+ break;
71
case 0x2: /* FADD */
72
gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
73
break;
74
+ case 0x3: /* FMULX */
75
+ gen_helper_advsimd_mulxh(tcg_res, tcg_op1, tcg_op2, fpst);
76
+ break;
77
case 0x4: /* FCMEQ */
78
gen_helper_advsimd_ceq_f16(tcg_res, tcg_op1, tcg_op2, fpst);
79
break;
80
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_fp16(DisasContext *s, uint32_t insn)
81
case 0x8: /* FMINNM */
82
gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
83
break;
84
+ case 0x9: /* FMLS */
85
+ /* As usual for ARM, separate negation for fused multiply-add */
86
+ tcg_gen_xori_i32(tcg_op1, tcg_op1, 0x8000);
87
+ read_vec_element_i32(s, tcg_res, rd, pass, MO_16);
88
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_res,
89
+ fpst);
90
+ break;
91
case 0xa: /* FSUB */
92
gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
93
break;
94
--
67
--
95
2.16.2
68
2.20.1
96
69
97
70
diff view generated by jsdifflib
1
From: Corey Minyard <cminyard@mvista.com>
1
Add brief documentation of the new mps3-an524 board.
2
2
3
Signed-off-by: Corey Minyard <cminyard@mvista.com>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
6
Message-id: 20180227104903.21353-2-linus.walleij@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215115138.20465-24-peter.maydell@linaro.org
8
---
7
---
9
include/hw/i2c/i2c.h | 6 ++----
8
docs/system/arm/mps2.rst | 24 ++++++++++++++++++------
10
hw/i2c/core.c | 3 +--
9
1 file changed, 18 insertions(+), 6 deletions(-)
11
2 files changed, 3 insertions(+), 6 deletions(-)
12
10
13
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
11
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/include/hw/i2c/i2c.h
13
--- a/docs/system/arm/mps2.rst
16
+++ b/include/hw/i2c/i2c.h
14
+++ b/docs/system/arm/mps2.rst
17
@@ -XXX,XX +XXX,XX @@ typedef struct I2CSlave I2CSlave;
15
@@ -XXX,XX +XXX,XX @@
18
#define I2C_SLAVE_GET_CLASS(obj) \
16
-Arm MPS2 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``)
19
OBJECT_GET_CLASS(I2CSlaveClass, (obj), TYPE_I2C_SLAVE)
17
-================================================================================================================
20
18
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
21
-typedef struct I2CSlaveClass
19
+=========================================================================================================================================
22
-{
20
23
+typedef struct I2CSlaveClass {
21
These board models all use Arm M-profile CPUs.
24
DeviceClass parent_class;
22
25
23
-The Arm MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
26
/* Callbacks provided by the device. */
24
-FPGA but is otherwise the same as the 2). Since the CPU itself
27
@@ -XXX,XX +XXX,XX @@ typedef struct I2CSlaveClass
25
-and most of the devices are in the FPGA, the details of the board
28
int (*event)(I2CSlave *s, enum i2c_event event);
26
-as seen by the guest depend significantly on the FPGA image.
29
} I2CSlaveClass;
27
+The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
30
28
+bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
31
-struct I2CSlave
29
+FPGA again, can handle 4GB of RAM and has a USB controller and QSPI flash).
32
-{
30
+
33
+struct I2CSlave {
31
+Since the CPU itself and most of the devices are in the FPGA, the
34
DeviceState qdev;
32
+details of the board as seen by the guest depend significantly on the
35
33
+FPGA image.
36
/* Remaining fields for internal use by the I2C code. */
34
37
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
35
QEMU models the following FPGA images:
38
index XXXXXXX..XXXXXXX 100644
36
39
--- a/hw/i2c/core.c
37
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
40
+++ b/hw/i2c/core.c
38
Cortex-M3 'DesignStart' as documented in Arm Application Note AN511
41
@@ -XXX,XX +XXX,XX @@ struct I2CNode {
39
``mps2-an521``
42
40
Dual Cortex-M33 as documented in Arm Application Note AN521
43
#define I2C_BROADCAST 0x00
41
+``mps3-an524``
44
42
+ Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
45
-struct I2CBus
43
46
-{
44
Differences between QEMU and real hardware:
47
+struct I2CBus {
45
48
BusState qbus;
46
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
49
QLIST_HEAD(, I2CNode) current_devs;
47
block RAM is unimplemented (QEMU always maps this to ZBT SSRAM1, as
50
uint8_t saved_address;
48
if zbt_boot_ctrl is always zero)
49
+- AN524 remapping of low memory to either BRAM or to QSPI flash is
50
+ unimplemented (QEMU always maps this to BRAM, ignoring the
51
+ SCC CFG_REG0 memory-remap bit)
52
- QEMU provides a LAN9118 ethernet rather than LAN9220; the only guest
53
visible difference is that the LAN9118 doesn't support checksum
54
offloading
55
+- QEMU does not model the QSPI flash in MPS3 boards as real QSPI
56
+ flash, but only as simple ROM, so attempting to rewrite the flash
57
+ from the guest will fail
58
+- QEMU does not model the USB controller in MPS3 boards
51
--
59
--
52
2.16.2
60
2.20.1
53
61
54
62
diff view generated by jsdifflib
New patch
1
1
Update old infocenter.arm.com URLs to the equivalent developer.arm.com
2
ones (the old URLs should redirect, but we might as well avoid the
3
redirection notice, and the new URLs are pleasantly shorter).
4
5
This commit covers the links to the MPS2 board TRM, the various
6
Application Notes, the IoTKit and SSE-200 documents.
7
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210215115138.20465-25-peter.maydell@linaro.org
11
---
12
include/hw/arm/armsse.h | 4 ++--
13
include/hw/misc/armsse-cpuid.h | 2 +-
14
include/hw/misc/armsse-mhu.h | 2 +-
15
include/hw/misc/iotkit-secctl.h | 2 +-
16
include/hw/misc/iotkit-sysctl.h | 2 +-
17
include/hw/misc/iotkit-sysinfo.h | 2 +-
18
include/hw/misc/mps2-fpgaio.h | 2 +-
19
hw/arm/mps2-tz.c | 11 +++++------
20
hw/misc/armsse-cpuid.c | 2 +-
21
hw/misc/armsse-mhu.c | 2 +-
22
hw/misc/iotkit-sysctl.c | 2 +-
23
hw/misc/iotkit-sysinfo.c | 2 +-
24
hw/misc/mps2-fpgaio.c | 2 +-
25
hw/misc/mps2-scc.c | 2 +-
26
14 files changed, 19 insertions(+), 20 deletions(-)
27
28
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/armsse.h
31
+++ b/include/hw/arm/armsse.h
32
@@ -XXX,XX +XXX,XX @@
33
* hardware, which include the IoT Kit and the SSE-050, SSE-100 and
34
* SSE-200. Currently we model:
35
* - the Arm IoT Kit which is documented in
36
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
37
+ * https://developer.arm.com/documentation/ecm0601256/latest
38
* - the SSE-200 which is documented in
39
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
40
+ * https://developer.arm.com/documentation/101104/latest/
41
*
42
* The IoTKit contains:
43
* a Cortex-M33
44
diff --git a/include/hw/misc/armsse-cpuid.h b/include/hw/misc/armsse-cpuid.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/hw/misc/armsse-cpuid.h
47
+++ b/include/hw/misc/armsse-cpuid.h
48
@@ -XXX,XX +XXX,XX @@
49
/*
50
* This is a model of the "CPU_IDENTITY" register block which is part of the
51
* Arm SSE-200 and documented in
52
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
53
+ * https://developer.arm.com/documentation/101104/latest/
54
*
55
* QEMU interface:
56
* + QOM property "CPUID": the value to use for the CPUID register
57
diff --git a/include/hw/misc/armsse-mhu.h b/include/hw/misc/armsse-mhu.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/include/hw/misc/armsse-mhu.h
60
+++ b/include/hw/misc/armsse-mhu.h
61
@@ -XXX,XX +XXX,XX @@
62
/*
63
* This is a model of the Message Handling Unit (MHU) which is part of the
64
* Arm SSE-200 and documented in
65
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
66
+ * https://developer.arm.com/documentation/101104/latest/
67
*
68
* QEMU interface:
69
* + sysbus MMIO region 0: the system information register bank
70
diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
71
index XXXXXXX..XXXXXXX 100644
72
--- a/include/hw/misc/iotkit-secctl.h
73
+++ b/include/hw/misc/iotkit-secctl.h
74
@@ -XXX,XX +XXX,XX @@
75
76
/* This is a model of the security controller which is part of the
77
* Arm IoT Kit and documented in
78
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
79
+ * https://developer.arm.com/documentation/ecm0601256/latest
80
*
81
* QEMU interface:
82
* + sysbus MMIO region 0 is the "secure privilege control block" registers
83
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
84
index XXXXXXX..XXXXXXX 100644
85
--- a/include/hw/misc/iotkit-sysctl.h
86
+++ b/include/hw/misc/iotkit-sysctl.h
87
@@ -XXX,XX +XXX,XX @@
88
/*
89
* This is a model of the "system control element" which is part of the
90
* Arm IoTKit and documented in
91
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
92
+ * https://developer.arm.com/documentation/ecm0601256/latest
93
* Specifically, it implements the "system information block" and
94
* "system control register" blocks.
95
*
96
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
97
index XXXXXXX..XXXXXXX 100644
98
--- a/include/hw/misc/iotkit-sysinfo.h
99
+++ b/include/hw/misc/iotkit-sysinfo.h
100
@@ -XXX,XX +XXX,XX @@
101
/*
102
* This is a model of the "system information block" which is part of the
103
* Arm IoTKit and documented in
104
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
105
+ * https://developer.arm.com/documentation/ecm0601256/latest
106
* QEMU interface:
107
* + QOM property "SYS_VERSION": value to use for SYS_VERSION register
108
* + QOM property "SYS_CONFIG": value to use for SYS_CONFIG register
109
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
110
index XXXXXXX..XXXXXXX 100644
111
--- a/include/hw/misc/mps2-fpgaio.h
112
+++ b/include/hw/misc/mps2-fpgaio.h
113
@@ -XXX,XX +XXX,XX @@
114
/* This is a model of the FPGAIO register block in the AN505
115
* FPGA image for the MPS2 dev board; it is documented in the
116
* application note:
117
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
118
+ * https://developer.arm.com/documentation/dai0505/latest/
119
*
120
* QEMU interface:
121
* + sysbus MMIO region 0: the register bank
122
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/hw/arm/mps2-tz.c
125
+++ b/hw/arm/mps2-tz.c
126
@@ -XXX,XX +XXX,XX @@
127
* https://developer.arm.com/products/system-design/development-boards/fpga-prototyping-boards/mps2
128
*
129
* Board TRM:
130
- * http://infocenter.arm.com/help/topic/com.arm.doc.100112_0200_06_en/versatile_express_cortex_m_prototyping_systems_v2m_mps2_and_v2m_mps2plus_technical_reference_100112_0200_06_en.pdf
131
+ * https://developer.arm.com/documentation/100112/latest/
132
* Application Note AN505:
133
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
134
+ * https://developer.arm.com/documentation/dai0505/latest/
135
* Application Note AN521:
136
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
137
+ * https://developer.arm.com/documentation/dai0521/latest/
138
* Application Note AN524:
139
* https://developer.arm.com/documentation/dai0524/latest/
140
*
141
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
142
* (ARM ECM0601256) for the details of some of the device layout:
143
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
144
+ * https://developer.arm.com/documentation/ecm0601256/latest
145
* Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
146
* most of the device layout:
147
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
148
- *
149
+ * https://developer.arm.com/documentation/101104/latest/
150
*/
151
152
#include "qemu/osdep.h"
153
diff --git a/hw/misc/armsse-cpuid.c b/hw/misc/armsse-cpuid.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/hw/misc/armsse-cpuid.c
156
+++ b/hw/misc/armsse-cpuid.c
157
@@ -XXX,XX +XXX,XX @@
158
/*
159
* This is a model of the "CPU_IDENTITY" register block which is part of the
160
* Arm SSE-200 and documented in
161
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
162
+ * https://developer.arm.com/documentation/101104/latest/
163
*
164
* It consists of one read-only CPUID register (set by QOM property), plus the
165
* usual ID registers.
166
diff --git a/hw/misc/armsse-mhu.c b/hw/misc/armsse-mhu.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/hw/misc/armsse-mhu.c
169
+++ b/hw/misc/armsse-mhu.c
170
@@ -XXX,XX +XXX,XX @@
171
/*
172
* This is a model of the Message Handling Unit (MHU) which is part of the
173
* Arm SSE-200 and documented in
174
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
175
+ * https://developer.arm.com/documentation/101104/latest/
176
*/
177
178
#include "qemu/osdep.h"
179
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
180
index XXXXXXX..XXXXXXX 100644
181
--- a/hw/misc/iotkit-sysctl.c
182
+++ b/hw/misc/iotkit-sysctl.c
183
@@ -XXX,XX +XXX,XX @@
184
/*
185
* This is a model of the "system control element" which is part of the
186
* Arm IoTKit and documented in
187
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
188
+ * https://developer.arm.com/documentation/ecm0601256/latest
189
* Specifically, it implements the "system control register" blocks.
190
*/
191
192
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/hw/misc/iotkit-sysinfo.c
195
+++ b/hw/misc/iotkit-sysinfo.c
196
@@ -XXX,XX +XXX,XX @@
197
/*
198
* This is a model of the "system information block" which is part of the
199
* Arm IoTKit and documented in
200
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
201
+ * https://developer.arm.com/documentation/ecm0601256/latest
202
* It consists of 2 read-only version/config registers, plus the
203
* usual ID registers.
204
*/
205
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
206
index XXXXXXX..XXXXXXX 100644
207
--- a/hw/misc/mps2-fpgaio.c
208
+++ b/hw/misc/mps2-fpgaio.c
209
@@ -XXX,XX +XXX,XX @@
210
/* This is a model of the "FPGA system control and I/O" block found
211
* in the AN505 FPGA image for the MPS2 devboard.
212
* It is documented in AN505:
213
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
214
+ * https://developer.arm.com/documentation/dai0505/latest/
215
*/
216
217
#include "qemu/osdep.h"
218
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
219
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/misc/mps2-scc.c
221
+++ b/hw/misc/mps2-scc.c
222
@@ -XXX,XX +XXX,XX @@
223
* found in the FPGA images of MPS2 development boards.
224
*
225
* Documentation of it can be found in the MPS2 TRM:
226
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100112_0100_03_en/index.html
227
+ * https://developer.arm.com/documentation/100112/latest/
228
* and also in the Application Notes documenting individual FPGA images.
229
*/
230
231
--
232
2.20.1
233
234
diff view generated by jsdifflib