1
Hopefully last target-arm queue before softfreeze;
1
target-arm queue: I have a lot more still in my to-review
2
this one's largest part is the remainder of the SVE patches,
2
queue, but my rule of thumb is when I get to 50 patches or
3
but there are a selection of other minor things too.
3
so to send out what I have.
4
4
5
thanks
5
thanks
6
-- PMM
6
-- PMM
7
7
8
The following changes since commit 109b25045b3651f9c5d02c3766c0b3ff63e6d193:
8
The following changes since commit 9a7beaad3dbba982f7a461d676b55a5c3851d312:
9
9
10
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging (2018-06-29 12:30:29 +0100)
10
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20210304' into staging (2021-03-05 10:47: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-20180629
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 802abf4024d23e48d45373ac3f2b580124b54b47:
16
for you to fetch changes up to 2c669ff88ec6733420a000103a2b8b9e93df4945:
17
17
18
target/arm: Add ID_ISAR6 (2018-06-29 15:30:54 +0100)
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
* last of the SVE patches; SVE is now enabled for aarch64 linux-user
22
* sbsa-ref: add 'max' to list of allowed cpus
23
* sd: Don't trace SDRequest crc field (coverity bugfix)
23
* target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
24
* target/arm: Mark PMINTENSET accesses as possibly doing IO
24
* npcm7xx: add EMC model
25
* clean up v7VE feature bit handling
25
* xlnx-zynqmp: Remove obsolete 'has_rpu' property
26
* i.mx7d: minor cleanups
26
* target/arm: Speed up aarch64 TBL/TBX
27
* target/arm: support reading of CNT[VCT|FRQ]_EL0 from user-space
27
* virtio-mmio: improve virtio-mmio get_dev_path alog
28
* target/arm: Implement ARMv8.2-DotProd
28
* target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
29
* virt: add addresses to dt node names (which stops dtc from
29
* target/arm: Restrict v8M IDAU to TCG
30
complaining that they're not correctly named)
30
* target/arm/cpu: Update coding style to make checkpatch.pl happy
31
* cleanups: replace error_setg(&error_fatal) by error_report() + exit()
31
* musicpal, tc6393xb, omap_lcdc, tcx: drop dead code for non-32-bit-RGB surfaces
32
* Add new board: mps3-an524
32
33
33
----------------------------------------------------------------
34
----------------------------------------------------------------
34
Aaron Lindsay (3):
35
Doug Evans (3):
35
target/arm: Add ARM_FEATURE_V7VE for v7 Virtualization Extensions
36
hw/net: Add npcm7xx emc model
36
target/arm: Remove redundant DIV detection for KVM
37
hw/arm: Add npcm7xx emc model
37
target/arm: Mark PMINTENSET accesses as possibly doing IO
38
tests/qtests: Add npcm7xx emc model test
38
39
39
Alex Bennée (1):
40
Marcin Juszkiewicz (2):
40
target/arm: support reading of CNT[VCT|FRQ]_EL0 from user-space
41
sbsa-ref: remove cortex-a53 from list of supported cpus
42
sbsa-ref: add 'max' to list of allowed cpus
41
43
42
Eric Auger (3):
44
Peter Collingbourne (1):
43
device_tree: Add qemu_fdt_node_unit_path
45
target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
44
hw/arm/virt: Silence dtc /intc warnings
45
hw/arm/virt: Silence dtc /memory warning
46
46
47
Jean-Christophe Dubois (3):
47
Peter Maydell (34):
48
i.mx7d: Remove unused header files
48
hw/arm/musicpal: Remove dead code for non-32-bit-RGB surfaces
49
i.mx7d: Change SRC unimplemented device name from sdma to src
49
hw/display/tc6393xb: Remove dead code for handling non-32bpp surfaces
50
i.mx7d: Change IRQ number type from hwaddr to int
50
hw/display/tc6393xb: Expand out macros in template header
51
51
hw/display/tc6393xb: Inline tc6393xb_draw_graphic32() at its callsite
52
Peter Maydell (1):
52
hw/display/omap_lcdc: Expand out macros in template header
53
sd: Don't trace SDRequest crc field
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
54
82
55
Philippe Mathieu-Daudé (4):
83
Philippe Mathieu-Daudé (4):
56
hw/block/fdc: Replace error_setg(&error_abort) by assert()
84
hw/arm/xlnx-zynqmp: Remove obsolete 'has_rpu' property
57
hw/arm/sysbus-fdt: Replace error_setg(&error_fatal) by error_report() + exit()
85
hw/i2c/npcm7xx_smbus: Simplify npcm7xx_smbus_init()
58
device_tree: Replace error_setg(&error_fatal) by error_report() + exit()
86
target/arm: Restrict v8M IDAU to TCG
59
sdcard: Use the ldst API
87
target/arm/cpu: Update coding style to make checkpatch.pl happy
60
88
61
Richard Henderson (40):
89
Rebecca Cran (3):
62
target/arm: Implement SVE Memory Contiguous Load Group
90
target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
63
target/arm: Implement SVE Contiguous Load, first-fault and no-fault
91
target/arm: Enable FEAT_SSBS for "max" AARCH64 CPU
64
target/arm: Implement SVE Memory Contiguous Store Group
92
target/arm: Set ID_PFR2.SSBS to 1 for "max" 32-bit CPU
65
target/arm: Implement SVE load and broadcast quadword
66
target/arm: Implement SVE integer convert to floating-point
67
target/arm: Implement SVE floating-point arithmetic (predicated)
68
target/arm: Implement SVE FP Multiply-Add Group
69
target/arm: Implement SVE Floating Point Accumulating Reduction Group
70
target/arm: Implement SVE load and broadcast element
71
target/arm: Implement SVE store vector/predicate register
72
target/arm: Implement SVE scatter stores
73
target/arm: Implement SVE prefetches
74
target/arm: Implement SVE gather loads
75
target/arm: Implement SVE first-fault gather loads
76
target/arm: Implement SVE scatter store vector immediate
77
target/arm: Implement SVE floating-point compare vectors
78
target/arm: Implement SVE floating-point arithmetic with immediate
79
target/arm: Implement SVE Floating Point Multiply Indexed Group
80
target/arm: Implement SVE FP Fast Reduction Group
81
target/arm: Implement SVE Floating Point Unary Operations - Unpredicated Group
82
target/arm: Implement SVE FP Compare with Zero Group
83
target/arm: Implement SVE floating-point trig multiply-add coefficient
84
target/arm: Implement SVE floating-point convert precision
85
target/arm: Implement SVE floating-point convert to integer
86
target/arm: Implement SVE floating-point round to integral value
87
target/arm: Implement SVE floating-point unary operations
88
target/arm: Implement SVE MOVPRFX
89
target/arm: Implement SVE floating-point complex add
90
target/arm: Implement SVE fp complex multiply add
91
target/arm: Pass index to AdvSIMD FCMLA (indexed)
92
target/arm: Implement SVE fp complex multiply add (indexed)
93
target/arm: Implement SVE dot product (vectors)
94
target/arm: Implement SVE dot product (indexed)
95
target/arm: Enable SVE for aarch64-linux-user
96
target/arm: Implement ARMv8.2-DotProd
97
target/arm: Fix SVE signed division vs x86 overflow exception
98
target/arm: Fix SVE system register access checks
99
target/arm: Prune a57 features from max
100
target/arm: Prune a15 features from max
101
target/arm: Add ID_ISAR6
102
93
103
include/sysemu/device_tree.h | 16 +
94
Richard Henderson (1):
104
target/arm/cpu.h | 3 +
95
target/arm: Speed up aarch64 TBL/TBX
105
target/arm/helper-sve.h | 682 +++++++++++++++
106
target/arm/helper.h | 44 +-
107
device_tree.c | 78 +-
108
hw/arm/boot.c | 41 +-
109
hw/arm/fsl-imx7.c | 8 +-
110
hw/arm/mcimx7d-sabre.c | 2 -
111
hw/arm/sysbus-fdt.c | 53 +-
112
hw/arm/virt.c | 70 +-
113
hw/block/fdc.c | 9 +-
114
hw/sd/bcm2835_sdhost.c | 13 +-
115
hw/sd/core.c | 2 +-
116
hw/sd/milkymist-memcard.c | 3 +-
117
hw/sd/omap_mmc.c | 6 +-
118
hw/sd/pl181.c | 11 +-
119
hw/sd/sdhci.c | 15 +-
120
hw/sd/ssi-sd.c | 6 +-
121
linux-user/elfload.c | 2 +
122
target/arm/cpu.c | 36 +-
123
target/arm/cpu64.c | 13 +-
124
target/arm/helper.c | 44 +-
125
target/arm/kvm32.c | 27 +-
126
target/arm/sve_helper.c | 1875 +++++++++++++++++++++++++++++++++++++++++-
127
target/arm/translate-a64.c | 62 +-
128
target/arm/translate-sve.c | 1688 ++++++++++++++++++++++++++++++++++++-
129
target/arm/translate.c | 102 ++-
130
target/arm/vec_helper.c | 311 ++++++-
131
hw/sd/trace-events | 2 +-
132
target/arm/sve.decode | 427 ++++++++++
133
30 files changed, 5394 insertions(+), 257 deletions(-)
134
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: Richard Henderson <richard.henderson@linaro.org>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
This register was added to aa32 state by ARMv8.2.
3
Cortex-A53 supports 40bits of address space. sbsa-ref's memory starts
4
above this limit.
4
5
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20180629001538.11415-6-richard.henderson@linaro.org
8
Acked-by: Leif Lindholm <leif@nuviainc.com>
9
Message-id: 20210216150122.3830863-2-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
target/arm/cpu.c | 4 ++++
13
1 file changed, 1 deletion(-)
12
target/arm/cpu64.c | 2 ++
13
target/arm/helper.c | 5 ++---
14
4 files changed, 9 insertions(+), 3 deletions(-)
15
14
16
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
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
17
--- a/hw/arm/sbsa-ref.c
19
+++ b/target/arm/cpu.h
18
+++ b/hw/arm/sbsa-ref.c
20
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
21
uint32_t id_isar3;
20
};
22
uint32_t id_isar4;
21
23
uint32_t id_isar5;
22
static const char * const valid_cpus[] = {
24
+ uint32_t id_isar6;
23
- ARM_CPU_TYPE_NAME("cortex-a53"),
25
uint64_t id_aa64pfr0;
24
ARM_CPU_TYPE_NAME("cortex-a57"),
26
uint64_t id_aa64pfr1;
25
ARM_CPU_TYPE_NAME("cortex-a72"),
27
uint64_t id_aa64dfr0;
26
};
28
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.c
31
+++ b/target/arm/cpu.c
32
@@ -XXX,XX +XXX,XX @@ static void cortex_m3_initfn(Object *obj)
33
cpu->id_isar3 = 0x01111110;
34
cpu->id_isar4 = 0x01310102;
35
cpu->id_isar5 = 0x00000000;
36
+ cpu->id_isar6 = 0x00000000;
37
}
38
39
static void cortex_m4_initfn(Object *obj)
40
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
41
cpu->id_isar3 = 0x01111110;
42
cpu->id_isar4 = 0x01310102;
43
cpu->id_isar5 = 0x00000000;
44
+ cpu->id_isar6 = 0x00000000;
45
}
46
47
static void cortex_m33_initfn(Object *obj)
48
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
49
cpu->id_isar3 = 0x01111131;
50
cpu->id_isar4 = 0x01310132;
51
cpu->id_isar5 = 0x00000000;
52
+ cpu->id_isar6 = 0x00000000;
53
cpu->clidr = 0x00000000;
54
cpu->ctr = 0x8000c000;
55
}
56
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
57
cpu->id_isar3 = 0x01112131;
58
cpu->id_isar4 = 0x0010142;
59
cpu->id_isar5 = 0x0;
60
+ cpu->id_isar6 = 0x0;
61
cpu->mp_is_up = true;
62
cpu->pmsav7_dregion = 16;
63
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
64
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/cpu64.c
67
+++ b/target/arm/cpu64.c
68
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
69
cpu->id_isar3 = 0x01112131;
70
cpu->id_isar4 = 0x00011142;
71
cpu->id_isar5 = 0x00011121;
72
+ cpu->id_isar6 = 0;
73
cpu->id_aa64pfr0 = 0x00002222;
74
cpu->id_aa64dfr0 = 0x10305106;
75
cpu->pmceid0 = 0x00000000;
76
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
77
cpu->id_isar3 = 0x01112131;
78
cpu->id_isar4 = 0x00011142;
79
cpu->id_isar5 = 0x00011121;
80
+ cpu->id_isar6 = 0;
81
cpu->id_aa64pfr0 = 0x00002222;
82
cpu->id_aa64dfr0 = 0x10305106;
83
cpu->id_aa64isar0 = 0x00011120;
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
89
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 6,
90
.access = PL1_R, .type = ARM_CP_CONST,
91
.resetvalue = cpu->id_mmfr4 },
92
- /* 7 is as yet unallocated and must RAZ */
93
- { .name = "ID_ISAR7_RESERVED", .state = ARM_CP_STATE_BOTH,
94
+ { .name = "ID_ISAR6", .state = ARM_CP_STATE_BOTH,
95
.opc0 = 3, .opc1 = 0, .crn = 0, .crm = 2, .opc2 = 7,
96
.access = PL1_R, .type = ARM_CP_CONST,
97
- .resetvalue = 0 },
98
+ .resetvalue = cpu->id_isar6 },
99
REGINFO_SENTINEL
100
};
101
define_arm_cp_regs(cpu, v6_idregs);
102
--
27
--
103
2.17.1
28
2.20.1
104
29
105
30
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
We already check for the same condition within the normal integer
3
Let add 'max' cpu while work goes on adding newer CPU types than
4
sdiv and sdiv64 helpers. Use a slightly different formation that
4
Cortex-A72. This allows us to check SVE etc support.
5
does not require deducing the expression type.
6
5
7
Fixes: f97cfd596ed
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Acked-by: Leif Lindholm <leif@nuviainc.com>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20210216150122.3830863-3-marcin.juszkiewicz@linaro.org
11
Message-id: 20180629001538.11415-2-richard.henderson@linaro.org
12
[PMM: reworded a comment]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
target/arm/sve_helper.c | 20 +++++++++++++++-----
12
hw/arm/sbsa-ref.c | 1 +
16
1 file changed, 15 insertions(+), 5 deletions(-)
13
1 file changed, 1 insertion(+)
17
14
18
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/sve_helper.c
17
--- a/hw/arm/sbsa-ref.c
21
+++ b/target/arm/sve_helper.c
18
+++ b/hw/arm/sbsa-ref.c
22
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, uint32_t desc) \
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
23
#define DO_MIN(N, M) ((N) >= (M) ? (M) : (N))
20
static const char * const valid_cpus[] = {
24
#define DO_ABD(N, M) ((N) >= (M) ? (N) - (M) : (M) - (N))
21
ARM_CPU_TYPE_NAME("cortex-a57"),
25
#define DO_MUL(N, M) (N * M)
22
ARM_CPU_TYPE_NAME("cortex-a72"),
26
-#define DO_DIV(N, M) (M ? N / M : 0)
23
+ ARM_CPU_TYPE_NAME("max"),
27
+
24
};
28
+
25
29
+/*
26
static bool cpu_type_valid(const char *cpu)
30
+ * We must avoid the C undefined behaviour cases: division by
31
+ * zero and signed division of INT_MIN by -1. Both of these
32
+ * have architecturally defined required results for Arm.
33
+ * We special case all signed divisions by -1 to avoid having
34
+ * to deduce the minimum integer for the type involved.
35
+ */
36
+#define DO_SDIV(N, M) (unlikely(M == 0) ? 0 : unlikely(M == -1) ? -N : N / M)
37
+#define DO_UDIV(N, M) (unlikely(M == 0) ? 0 : N / M)
38
39
DO_ZPZZ(sve_and_zpzz_b, uint8_t, H1, DO_AND)
40
DO_ZPZZ(sve_and_zpzz_h, uint16_t, H1_2, DO_AND)
41
@@ -XXX,XX +XXX,XX @@ DO_ZPZZ(sve_umulh_zpzz_h, uint16_t, H1_2, do_mulh_h)
42
DO_ZPZZ(sve_umulh_zpzz_s, uint32_t, H1_4, do_mulh_s)
43
DO_ZPZZ_D(sve_umulh_zpzz_d, uint64_t, do_umulh_d)
44
45
-DO_ZPZZ(sve_sdiv_zpzz_s, int32_t, H1_4, DO_DIV)
46
-DO_ZPZZ_D(sve_sdiv_zpzz_d, int64_t, DO_DIV)
47
+DO_ZPZZ(sve_sdiv_zpzz_s, int32_t, H1_4, DO_SDIV)
48
+DO_ZPZZ_D(sve_sdiv_zpzz_d, int64_t, DO_SDIV)
49
50
-DO_ZPZZ(sve_udiv_zpzz_s, uint32_t, H1_4, DO_DIV)
51
-DO_ZPZZ_D(sve_udiv_zpzz_d, uint64_t, DO_DIV)
52
+DO_ZPZZ(sve_udiv_zpzz_s, uint32_t, H1_4, DO_UDIV)
53
+DO_ZPZZ_D(sve_udiv_zpzz_d, uint64_t, DO_UDIV)
54
55
/* Note that all bits of the shift are significant
56
and not modulo the element size. */
57
--
27
--
58
2.17.1
28
2.20.1
59
29
60
30
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Add support for FEAT_SSBS. SSBS (Speculative Store Bypass Safe) is an
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
optional feature in ARMv8.0, and mandatory in ARMv8.5.
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
6
Message-id: 20180627043328.11531-34-richard.henderson@linaro.org
6
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210216224543.16142-2-rebecca@nuviainc.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
target/arm/helper.h | 5 ++
11
target/arm/cpu.h | 15 ++++++++++++++-
10
target/arm/translate-sve.c | 18 ++++++
12
target/arm/internals.h | 6 ++++++
11
target/arm/vec_helper.c | 124 +++++++++++++++++++++++++++++++++++++
13
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++++++++
12
target/arm/sve.decode | 6 ++
14
target/arm/translate-a64.c | 12 ++++++++++++
13
4 files changed, 153 insertions(+)
15
4 files changed, 69 insertions(+), 1 deletion(-)
14
16
15
diff --git a/target/arm/helper.h b/target/arm/helper.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.h
19
--- a/target/arm/cpu.h
18
+++ b/target/arm/helper.h
20
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(gvec_udot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
20
DEF_HELPER_FLAGS_4(gvec_sdot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
22
#define SCTLR_TE (1U << 30) /* AArch32 only */
21
DEF_HELPER_FLAGS_4(gvec_udot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
#define SCTLR_EnIB (1U << 30) /* v8.3, AArch64 only */
22
24
#define SCTLR_EnIA (1U << 31) /* v8.3, AArch64 only */
23
+DEF_HELPER_FLAGS_4(gvec_sdot_idx_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
+#define SCTLR_DSSBS_32 (1U << 31) /* v8.5, AArch32 only */
24
+DEF_HELPER_FLAGS_4(gvec_udot_idx_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
#define SCTLR_BT0 (1ULL << 35) /* v8.5-BTI */
25
+DEF_HELPER_FLAGS_4(gvec_sdot_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
27
#define SCTLR_BT1 (1ULL << 36) /* v8.5-BTI */
26
+DEF_HELPER_FLAGS_4(gvec_udot_idx_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
#define SCTLR_ITFSB (1ULL << 37) /* v8.5-MemTag */
27
+
29
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
28
DEF_HELPER_FLAGS_5(gvec_fcaddh, TCG_CALL_NO_RWG,
30
#define SCTLR_TCF (3ULL << 40) /* v8.5-MemTag */
29
void, ptr, ptr, ptr, ptr, i32)
31
#define SCTLR_ATA0 (1ULL << 42) /* v8.5-MemTag */
30
DEF_HELPER_FLAGS_5(gvec_fcadds, TCG_CALL_NO_RWG,
32
#define SCTLR_ATA (1ULL << 43) /* v8.5-MemTag */
31
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
33
-#define SCTLR_DSSBS (1ULL << 44) /* v8.5 */
32
index XXXXXXX..XXXXXXX 100644
34
+#define SCTLR_DSSBS_64 (1ULL << 44) /* v8.5, AArch64 only */
33
--- a/target/arm/translate-sve.c
35
34
+++ b/target/arm/translate-sve.c
36
#define CPTR_TCPAC (1U << 31)
35
@@ -XXX,XX +XXX,XX @@ static bool trans_DOT_zzz(DisasContext *s, arg_DOT_zzz *a, uint32_t insn)
37
#define CPTR_TTA (1U << 20)
36
return true;
38
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
39
#define CPSR_IL (1U << 20)
40
#define CPSR_DIT (1U << 21)
41
#define CPSR_PAN (1U << 22)
42
+#define CPSR_SSBS (1U << 23)
43
#define CPSR_J (1U << 24)
44
#define CPSR_IT_0_1 (3U << 25)
45
#define CPSR_Q (1U << 27)
46
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
47
#define PSTATE_A (1U << 8)
48
#define PSTATE_D (1U << 9)
49
#define PSTATE_BTYPE (3U << 10)
50
+#define PSTATE_SSBS (1U << 12)
51
#define PSTATE_IL (1U << 20)
52
#define PSTATE_SS (1U << 21)
53
#define PSTATE_PAN (1U << 22)
54
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_dit(const ARMISARegisters *id)
55
return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0;
37
}
56
}
38
57
39
+static bool trans_DOT_zzx(DisasContext *s, arg_DOT_zzx *a, uint32_t insn)
58
+static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
40
+{
59
+{
41
+ static gen_helper_gvec_3 * const fns[2][2] = {
60
+ return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
42
+ { gen_helper_gvec_sdot_idx_b, gen_helper_gvec_sdot_idx_h },
43
+ { gen_helper_gvec_udot_idx_b, gen_helper_gvec_udot_idx_h }
44
+ };
45
+
46
+ if (sve_access_check(s)) {
47
+ unsigned vsz = vec_full_reg_size(s);
48
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
49
+ vec_full_reg_offset(s, a->rn),
50
+ vec_full_reg_offset(s, a->rm),
51
+ vsz, vsz, a->index, fns[a->u][a->sz]);
52
+ }
53
+ return true;
54
+}
61
+}
55
+
62
+
63
/*
64
* 64-bit feature tests via id registers.
65
*/
66
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
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
+}
56
+
74
+
57
/*
75
/*
58
*** SVE Floating Point Multiply-Add Indexed Group
76
* Feature tests for "does this exist in either 32-bit or 64-bit?"
59
*/
77
*/
60
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
78
diff --git a/target/arm/internals.h b/target/arm/internals.h
61
index XXXXXXX..XXXXXXX 100644
79
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/vec_helper.c
80
--- a/target/arm/internals.h
63
+++ b/target/arm/vec_helper.c
81
+++ b/target/arm/internals.h
64
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_udot_h)(void *vd, void *vn, void *vm, uint32_t desc)
82
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
65
clear_tail(d, opr_sz, simd_maxsz(desc));
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;
66
}
91
}
67
92
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
68
+void HELPER(gvec_sdot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
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
}
102
diff --git a/target/arm/helper.c b/target/arm/helper.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/helper.c
105
+++ b/target/arm/helper.c
106
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dit_reginfo = {
107
.readfn = aa64_dit_read, .writefn = aa64_dit_write
108
};
109
110
+static uint64_t aa64_ssbs_read(CPUARMState *env, const ARMCPRegInfo *ri)
69
+{
111
+{
70
+ intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4;
112
+ return env->pstate & PSTATE_SSBS;
71
+ intptr_t index = simd_data(desc);
72
+ uint32_t *d = vd;
73
+ int8_t *n = vn;
74
+ int8_t *m_indexed = (int8_t *)vm + index * 4;
75
+
76
+ /* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
77
+ * Otherwise opr_sz is a multiple of 16.
78
+ */
79
+ segend = MIN(4, opr_sz_4);
80
+ i = 0;
81
+ do {
82
+ int8_t m0 = m_indexed[i * 4 + 0];
83
+ int8_t m1 = m_indexed[i * 4 + 1];
84
+ int8_t m2 = m_indexed[i * 4 + 2];
85
+ int8_t m3 = m_indexed[i * 4 + 3];
86
+
87
+ do {
88
+ d[i] += n[i * 4 + 0] * m0
89
+ + n[i * 4 + 1] * m1
90
+ + n[i * 4 + 2] * m2
91
+ + n[i * 4 + 3] * m3;
92
+ } while (++i < segend);
93
+ segend = i + 4;
94
+ } while (i < opr_sz_4);
95
+
96
+ clear_tail(d, opr_sz, simd_maxsz(desc));
97
+}
113
+}
98
+
114
+
99
+void HELPER(gvec_udot_idx_b)(void *vd, void *vn, void *vm, uint32_t desc)
115
+static void aa64_ssbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
116
+ uint64_t value)
100
+{
117
+{
101
+ intptr_t i, segend, opr_sz = simd_oprsz(desc), opr_sz_4 = opr_sz / 4;
118
+ env->pstate = (env->pstate & ~PSTATE_SSBS) | (value & PSTATE_SSBS);
102
+ intptr_t index = simd_data(desc);
103
+ uint32_t *d = vd;
104
+ uint8_t *n = vn;
105
+ uint8_t *m_indexed = (uint8_t *)vm + index * 4;
106
+
107
+ /* Notice the special case of opr_sz == 8, from aa64/aa32 advsimd.
108
+ * Otherwise opr_sz is a multiple of 16.
109
+ */
110
+ segend = MIN(4, opr_sz_4);
111
+ i = 0;
112
+ do {
113
+ uint8_t m0 = m_indexed[i * 4 + 0];
114
+ uint8_t m1 = m_indexed[i * 4 + 1];
115
+ uint8_t m2 = m_indexed[i * 4 + 2];
116
+ uint8_t m3 = m_indexed[i * 4 + 3];
117
+
118
+ do {
119
+ d[i] += n[i * 4 + 0] * m0
120
+ + n[i * 4 + 1] * m1
121
+ + n[i * 4 + 2] * m2
122
+ + n[i * 4 + 3] * m3;
123
+ } while (++i < segend);
124
+ segend = i + 4;
125
+ } while (i < opr_sz_4);
126
+
127
+ clear_tail(d, opr_sz, simd_maxsz(desc));
128
+}
119
+}
129
+
120
+
130
+void HELPER(gvec_sdot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
121
+static const ARMCPRegInfo ssbs_reginfo = {
131
+{
122
+ .name = "SSBS", .state = ARM_CP_STATE_AA64,
132
+ intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8;
123
+ .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 6,
133
+ intptr_t index = simd_data(desc);
124
+ .type = ARM_CP_NO_RAW, .access = PL0_RW,
134
+ uint64_t *d = vd;
125
+ .readfn = aa64_ssbs_read, .writefn = aa64_ssbs_write
135
+ int16_t *n = vn;
126
+};
136
+ int16_t *m_indexed = (int16_t *)vm + index * 4;
137
+
127
+
138
+ /* This is supported by SVE only, so opr_sz is always a multiple of 16.
128
static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
139
+ * Process the entire segment all at once, writing back the results
129
const ARMCPRegInfo *ri,
140
+ * only after we've consumed all of the inputs.
130
bool isread)
141
+ */
131
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
142
+ for (i = 0; i < opr_sz_8 ; i += 2) {
132
if (cpu_isar_feature(aa64_dit, cpu)) {
143
+ uint64_t d0, d1;
133
define_one_arm_cp_reg(cpu, &dit_reginfo);
144
+
134
}
145
+ d0 = n[i * 4 + 0] * (int64_t)m_indexed[i * 4 + 0];
135
+ if (cpu_isar_feature(aa64_ssbs, cpu)) {
146
+ d0 += n[i * 4 + 1] * (int64_t)m_indexed[i * 4 + 1];
136
+ define_one_arm_cp_reg(cpu, &ssbs_reginfo);
147
+ d0 += n[i * 4 + 2] * (int64_t)m_indexed[i * 4 + 2];
137
+ }
148
+ d0 += n[i * 4 + 3] * (int64_t)m_indexed[i * 4 + 3];
138
149
+ d1 = n[i * 4 + 4] * (int64_t)m_indexed[i * 4 + 0];
139
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
150
+ d1 += n[i * 4 + 5] * (int64_t)m_indexed[i * 4 + 1];
140
define_arm_cp_regs(cpu, vhe_reginfo);
151
+ d1 += n[i * 4 + 6] * (int64_t)m_indexed[i * 4 + 2];
141
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
152
+ d1 += n[i * 4 + 7] * (int64_t)m_indexed[i * 4 + 3];
142
env->uncached_cpsr &= ~(CPSR_IL | CPSR_J);
153
+
143
env->daif |= mask;
154
+ d[i + 0] += d0;
144
155
+ d[i + 1] += d1;
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
+ }
156
+ }
151
+ }
157
+
152
+
158
+ clear_tail(d, opr_sz, simd_maxsz(desc));
153
if (new_mode == ARM_CPU_MODE_HYP) {
159
+}
154
env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0;
160
+
155
env->elr_el[2] = env->regs[15];
161
+void HELPER(gvec_udot_idx_h)(void *vd, void *vn, void *vm, uint32_t desc)
156
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
162
+{
157
new_mode |= PSTATE_TCO;
163
+ intptr_t i, opr_sz = simd_oprsz(desc), opr_sz_8 = opr_sz / 8;
158
}
164
+ intptr_t index = simd_data(desc);
159
165
+ uint64_t *d = vd;
160
+ if (cpu_isar_feature(aa64_ssbs, cpu)) {
166
+ uint16_t *n = vn;
161
+ if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_64) {
167
+ uint16_t *m_indexed = (uint16_t *)vm + index * 4;
162
+ new_mode |= PSTATE_SSBS;
168
+
163
+ } else {
169
+ /* This is supported by SVE only, so opr_sz is always a multiple of 16.
164
+ new_mode &= ~PSTATE_SSBS;
170
+ * Process the entire segment all at once, writing back the results
165
+ }
171
+ * only after we've consumed all of the inputs.
172
+ */
173
+ for (i = 0; i < opr_sz_8 ; i += 2) {
174
+ uint64_t d0, d1;
175
+
176
+ d0 = n[i * 4 + 0] * (uint64_t)m_indexed[i * 4 + 0];
177
+ d0 += n[i * 4 + 1] * (uint64_t)m_indexed[i * 4 + 1];
178
+ d0 += n[i * 4 + 2] * (uint64_t)m_indexed[i * 4 + 2];
179
+ d0 += n[i * 4 + 3] * (uint64_t)m_indexed[i * 4 + 3];
180
+ d1 = n[i * 4 + 4] * (uint64_t)m_indexed[i * 4 + 0];
181
+ d1 += n[i * 4 + 5] * (uint64_t)m_indexed[i * 4 + 1];
182
+ d1 += n[i * 4 + 6] * (uint64_t)m_indexed[i * 4 + 2];
183
+ d1 += n[i * 4 + 7] * (uint64_t)m_indexed[i * 4 + 3];
184
+
185
+ d[i + 0] += d0;
186
+ d[i + 1] += d1;
187
+ }
166
+ }
188
+
167
+
189
+ clear_tail(d, opr_sz, simd_maxsz(desc));
168
pstate_write(env, PSTATE_DAIF | new_mode);
190
+}
169
env->aarch64 = 1;
170
aarch64_restore_sp(env, new_el);
171
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
172
index XXXXXXX..XXXXXXX 100644
173
--- a/target/arm/translate-a64.c
174
+++ b/target/arm/translate-a64.c
175
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
176
tcg_temp_free_i32(t1);
177
break;
178
179
+ case 0x19: /* SSBS */
180
+ if (!dc_isar_feature(aa64_ssbs, s)) {
181
+ goto do_unallocated;
182
+ }
183
+ if (crm & 1) {
184
+ set_pstate_bits(PSTATE_SSBS);
185
+ } else {
186
+ clear_pstate_bits(PSTATE_SSBS);
187
+ }
188
+ /* Don't need to rebuild hflags since SSBS is a nop */
189
+ break;
191
+
190
+
192
void HELPER(gvec_fcaddh)(void *vd, void *vn, void *vm,
191
case 0x1a: /* DIT */
193
void *vfpst, uint32_t desc)
192
if (!dc_isar_feature(aa64_dit, s)) {
194
{
193
goto do_unallocated;
195
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
196
index XXXXXXX..XXXXXXX 100644
197
--- a/target/arm/sve.decode
198
+++ b/target/arm/sve.decode
199
@@ -XXX,XX +XXX,XX @@ MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
200
# SVE integer dot product (unpredicated)
201
DOT_zzz 01000100 1 sz:1 0 rm:5 00000 u:1 rn:5 rd:5 ra=%reg_movprfx
202
203
+# SVE integer dot product (indexed)
204
+DOT_zzx 01000100 101 index:2 rm:3 00000 u:1 rn:5 rd:5 \
205
+ sz=0 ra=%reg_movprfx
206
+DOT_zzx 01000100 111 index:1 rm:4 00000 u:1 rn:5 rd:5 \
207
+ sz=1 ra=%reg_movprfx
208
+
209
# SVE floating-point complex add (predicated)
210
FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
211
rn=%reg_movprfx
212
--
194
--
213
2.17.1
195
2.20.1
214
196
215
197
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
2
3
There is no need to re-set these 9 features already
3
Set ID_AA64PFR1_EL1.SSBS to 2 and ID_PFR2.SSBS to 1.
4
implied by the call to aarch64_a57_initfn.
5
4
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20210216224543.16142-3-rebecca@nuviainc.com
9
Message-id: 20180629001538.11415-4-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
target/arm/cpu64.c | 9 ---------
10
target/arm/cpu64.c | 5 +++++
13
1 file changed, 9 deletions(-)
11
1 file changed, 5 insertions(+)
14
12
15
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
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu64.c
15
--- a/target/arm/cpu64.c
18
+++ b/target/arm/cpu64.c
16
+++ b/target/arm/cpu64.c
19
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
20
* whereas the architecture requires them to be present in both if
18
21
* present in either.
19
t = cpu->isar.id_aa64pfr1;
22
*/
20
t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
23
- set_feature(&cpu->env, ARM_FEATURE_V8);
21
+ t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2);
24
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
22
/*
25
- set_feature(&cpu->env, ARM_FEATURE_NEON);
23
* Begin with full support for MTE. This will be downgraded to MTE=0
26
- set_feature(&cpu->env, ARM_FEATURE_AARCH64);
24
* during realize if the board provides no tag memory, much like
27
- set_feature(&cpu->env, ARM_FEATURE_V8_AES);
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
28
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
26
u = FIELD_DP32(u, ID_PFR0, DIT, 1);
29
- set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
27
cpu->isar.id_pfr0 = u;
30
set_feature(&cpu->env, ARM_FEATURE_V8_SHA512);
28
31
set_feature(&cpu->env, ARM_FEATURE_V8_SHA3);
29
+ u = cpu->isar.id_pfr2;
32
set_feature(&cpu->env, ARM_FEATURE_V8_SM3);
30
+ u = FIELD_DP32(u, ID_PFR2, SSBS, 1);
33
set_feature(&cpu->env, ARM_FEATURE_V8_SM4);
31
+ cpu->isar.id_pfr2 = u;
34
- set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
32
+
35
- set_feature(&cpu->env, ARM_FEATURE_CRC);
33
u = cpu->isar.id_mmfr3;
36
set_feature(&cpu->env, ARM_FEATURE_V8_ATOMICS);
34
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
37
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
35
cpu->isar.id_mmfr3 = u;
38
set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
39
--
36
--
40
2.17.1
37
2.20.1
41
38
42
39
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
2
3
There is no need to re-set these 3 features already
3
Enable FEAT_SSBS for the "max" 32-bit CPU.
4
implied by the call to aarch64_a15_initfn.
5
4
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20210216224543.16142-4-rebecca@nuviainc.com
9
Message-id: 20180629001538.11415-5-richard.henderson@linaro.org
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
target/arm/cpu.c | 3 ---
11
target/arm/cpu.c | 4 ++++
13
1 file changed, 3 deletions(-)
12
1 file changed, 4 insertions(+)
14
13
15
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
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/cpu.c
16
--- a/target/arm/cpu.c
18
+++ b/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
18
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
20
* since we don't correctly set the ID registers to advertise them,
19
t = cpu->isar.id_pfr0;
21
*/
20
t = FIELD_DP32(t, ID_PFR0, DIT, 1);
22
set_feature(&cpu->env, ARM_FEATURE_V8);
21
cpu->isar.id_pfr0 = t;
23
- set_feature(&cpu->env, ARM_FEATURE_VFP4);
22
+
24
- set_feature(&cpu->env, ARM_FEATURE_NEON);
23
+ t = cpu->isar.id_pfr2;
25
- set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
24
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
26
set_feature(&cpu->env, ARM_FEATURE_V8_AES);
25
+ cpu->isar.id_pfr2 = t;
27
set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
26
}
28
set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
27
#endif
28
}
29
--
29
--
30
2.17.1
30
2.20.1
31
31
32
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Doug Evans <dje@google.com>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
This is a 10/100 ethernet device that has several features.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Only the ones needed by the Linux driver have been implemented.
5
Message-id: 20180627043328.11531-12-richard.henderson@linaro.org
5
See npcm7xx_emc.c for a list of unimplemented features.
6
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
9
Signed-off-by: Doug Evans <dje@google.com>
10
Message-id: 20210218212453.831406-2-dje@google.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
12
---
8
target/arm/helper-sve.h | 41 +++++++++++++++++++++
13
include/hw/net/npcm7xx_emc.h | 286 ++++++++++++
9
target/arm/sve_helper.c | 61 +++++++++++++++++++++++++++++++
14
hw/net/npcm7xx_emc.c | 857 +++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 75 ++++++++++++++++++++++++++++++++++++++
15
hw/net/meson.build | 1 +
11
target/arm/sve.decode | 39 ++++++++++++++++++++
16
hw/net/trace-events | 17 +
12
4 files changed, 216 insertions(+)
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
13
20
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
21
diff --git a/include/hw/net/npcm7xx_emc.h b/include/hw/net/npcm7xx_emc.h
15
index XXXXXXX..XXXXXXX 100644
22
new file mode 100644
16
--- a/target/arm/helper-sve.h
23
index XXXXXXX..XXXXXXX
17
+++ b/target/arm/helper-sve.h
24
--- /dev/null
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_st1hs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
25
+++ b/include/hw/net/npcm7xx_emc.h
19
DEF_HELPER_FLAGS_4(sve_st1hd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
26
@@ -XXX,XX +XXX,XX @@
20
21
DEF_HELPER_FLAGS_4(sve_st1sd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
22
+
23
+DEF_HELPER_FLAGS_6(sve_stbs_zsu, TCG_CALL_NO_WG,
24
+ void, env, ptr, ptr, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_6(sve_sths_zsu, TCG_CALL_NO_WG,
26
+ void, env, ptr, ptr, ptr, tl, i32)
27
+DEF_HELPER_FLAGS_6(sve_stss_zsu, TCG_CALL_NO_WG,
28
+ void, env, ptr, ptr, ptr, tl, i32)
29
+
30
+DEF_HELPER_FLAGS_6(sve_stbs_zss, TCG_CALL_NO_WG,
31
+ void, env, ptr, ptr, ptr, tl, i32)
32
+DEF_HELPER_FLAGS_6(sve_sths_zss, TCG_CALL_NO_WG,
33
+ void, env, ptr, ptr, ptr, tl, i32)
34
+DEF_HELPER_FLAGS_6(sve_stss_zss, TCG_CALL_NO_WG,
35
+ void, env, ptr, ptr, ptr, tl, i32)
36
+
37
+DEF_HELPER_FLAGS_6(sve_stbd_zsu, TCG_CALL_NO_WG,
38
+ void, env, ptr, ptr, ptr, tl, i32)
39
+DEF_HELPER_FLAGS_6(sve_sthd_zsu, TCG_CALL_NO_WG,
40
+ void, env, ptr, ptr, ptr, tl, i32)
41
+DEF_HELPER_FLAGS_6(sve_stsd_zsu, TCG_CALL_NO_WG,
42
+ void, env, ptr, ptr, ptr, tl, i32)
43
+DEF_HELPER_FLAGS_6(sve_stdd_zsu, TCG_CALL_NO_WG,
44
+ void, env, ptr, ptr, ptr, tl, i32)
45
+
46
+DEF_HELPER_FLAGS_6(sve_stbd_zss, TCG_CALL_NO_WG,
47
+ void, env, ptr, ptr, ptr, tl, i32)
48
+DEF_HELPER_FLAGS_6(sve_sthd_zss, TCG_CALL_NO_WG,
49
+ void, env, ptr, ptr, ptr, tl, i32)
50
+DEF_HELPER_FLAGS_6(sve_stsd_zss, TCG_CALL_NO_WG,
51
+ void, env, ptr, ptr, ptr, tl, i32)
52
+DEF_HELPER_FLAGS_6(sve_stdd_zss, TCG_CALL_NO_WG,
53
+ void, env, ptr, ptr, ptr, tl, i32)
54
+
55
+DEF_HELPER_FLAGS_6(sve_stbd_zd, TCG_CALL_NO_WG,
56
+ void, env, ptr, ptr, ptr, tl, i32)
57
+DEF_HELPER_FLAGS_6(sve_sthd_zd, TCG_CALL_NO_WG,
58
+ void, env, ptr, ptr, ptr, tl, i32)
59
+DEF_HELPER_FLAGS_6(sve_stsd_zd, TCG_CALL_NO_WG,
60
+ void, env, ptr, ptr, ptr, tl, i32)
61
+DEF_HELPER_FLAGS_6(sve_stdd_zd, TCG_CALL_NO_WG,
62
+ void, env, ptr, ptr, ptr, tl, i32)
63
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/sve_helper.c
66
+++ b/target/arm/sve_helper.c
67
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_st4dd_r)(CPUARMState *env, void *vg,
68
addr += 4 * 8;
69
}
70
}
71
+
72
+/* Stores with a vector index. */
73
+
74
+#define DO_ST1_ZPZ_S(NAME, TYPEI, FN) \
75
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
76
+ target_ulong base, uint32_t desc) \
77
+{ \
78
+ intptr_t i, oprsz = simd_oprsz(desc); \
79
+ unsigned scale = simd_data(desc); \
80
+ uintptr_t ra = GETPC(); \
81
+ for (i = 0; i < oprsz; ) { \
82
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
83
+ do { \
84
+ if (likely(pg & 1)) { \
85
+ target_ulong off = *(TYPEI *)(vm + H1_4(i)); \
86
+ uint32_t d = *(uint32_t *)(vd + H1_4(i)); \
87
+ FN(env, base + (off << scale), d, ra); \
88
+ } \
89
+ i += sizeof(uint32_t), pg >>= sizeof(uint32_t); \
90
+ } while (i & 15); \
91
+ } \
92
+}
93
+
94
+#define DO_ST1_ZPZ_D(NAME, TYPEI, FN) \
95
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
96
+ target_ulong base, uint32_t desc) \
97
+{ \
98
+ intptr_t i, oprsz = simd_oprsz(desc) / 8; \
99
+ unsigned scale = simd_data(desc); \
100
+ uintptr_t ra = GETPC(); \
101
+ uint64_t *d = vd, *m = vm; uint8_t *pg = vg; \
102
+ for (i = 0; i < oprsz; i++) { \
103
+ if (likely(pg[H1(i)] & 1)) { \
104
+ target_ulong off = (target_ulong)(TYPEI)m[i] << scale; \
105
+ FN(env, base + off, d[i], ra); \
106
+ } \
107
+ } \
108
+}
109
+
110
+DO_ST1_ZPZ_S(sve_stbs_zsu, uint32_t, cpu_stb_data_ra)
111
+DO_ST1_ZPZ_S(sve_sths_zsu, uint32_t, cpu_stw_data_ra)
112
+DO_ST1_ZPZ_S(sve_stss_zsu, uint32_t, cpu_stl_data_ra)
113
+
114
+DO_ST1_ZPZ_S(sve_stbs_zss, int32_t, cpu_stb_data_ra)
115
+DO_ST1_ZPZ_S(sve_sths_zss, int32_t, cpu_stw_data_ra)
116
+DO_ST1_ZPZ_S(sve_stss_zss, int32_t, cpu_stl_data_ra)
117
+
118
+DO_ST1_ZPZ_D(sve_stbd_zsu, uint32_t, cpu_stb_data_ra)
119
+DO_ST1_ZPZ_D(sve_sthd_zsu, uint32_t, cpu_stw_data_ra)
120
+DO_ST1_ZPZ_D(sve_stsd_zsu, uint32_t, cpu_stl_data_ra)
121
+DO_ST1_ZPZ_D(sve_stdd_zsu, uint32_t, cpu_stq_data_ra)
122
+
123
+DO_ST1_ZPZ_D(sve_stbd_zss, int32_t, cpu_stb_data_ra)
124
+DO_ST1_ZPZ_D(sve_sthd_zss, int32_t, cpu_stw_data_ra)
125
+DO_ST1_ZPZ_D(sve_stsd_zss, int32_t, cpu_stl_data_ra)
126
+DO_ST1_ZPZ_D(sve_stdd_zss, int32_t, cpu_stq_data_ra)
127
+
128
+DO_ST1_ZPZ_D(sve_stbd_zd, uint64_t, cpu_stb_data_ra)
129
+DO_ST1_ZPZ_D(sve_sthd_zd, uint64_t, cpu_stw_data_ra)
130
+DO_ST1_ZPZ_D(sve_stsd_zd, uint64_t, cpu_stl_data_ra)
131
+DO_ST1_ZPZ_D(sve_stdd_zd, uint64_t, cpu_stq_data_ra)
132
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/target/arm/translate-sve.c
135
+++ b/target/arm/translate-sve.c
136
@@ -XXX,XX +XXX,XX @@ typedef void gen_helper_gvec_flags_4(TCGv_i32, TCGv_ptr, TCGv_ptr,
137
TCGv_ptr, TCGv_ptr, TCGv_i32);
138
139
typedef void gen_helper_gvec_mem(TCGv_env, TCGv_ptr, TCGv_i64, TCGv_i32);
140
+typedef void gen_helper_gvec_mem_scatter(TCGv_env, TCGv_ptr, TCGv_ptr,
141
+ TCGv_ptr, TCGv_i64, TCGv_i32);
142
143
/*
144
* Helpers for extracting complex instruction fields.
145
@@ -XXX,XX +XXX,XX @@ static bool trans_ST_zpri(DisasContext *s, arg_rpri_store *a, uint32_t insn)
146
}
147
return true;
148
}
149
+
150
+/*
27
+/*
151
+ *** SVE gather loads / scatter stores
28
+ * Nuvoton NPCM7xx EMC Module
29
+ *
30
+ * Copyright 2020 Google LLC
31
+ *
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.
36
+ *
37
+ * This program is distributed in the hope that it will be useful, but WITHOUT
38
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
39
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
40
+ * for more details.
152
+ */
41
+ */
153
+
42
+
154
+static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm, int scale,
43
+#ifndef NPCM7XX_EMC_H
155
+ TCGv_i64 scalar, gen_helper_gvec_mem_scatter *fn)
44
+#define NPCM7XX_EMC_H
156
+{
45
+
157
+ unsigned vsz = vec_full_reg_size(s);
46
+#include "hw/irq.h"
158
+ TCGv_i32 desc = tcg_const_i32(simd_desc(vsz, vsz, scale));
47
+#include "hw/sysbus.h"
159
+ TCGv_ptr t_zm = tcg_temp_new_ptr();
48
+#include "net/net.h"
160
+ TCGv_ptr t_pg = tcg_temp_new_ptr();
49
+
161
+ TCGv_ptr t_zt = tcg_temp_new_ptr();
50
+/* 32-bit register indices. */
162
+
51
+enum NPCM7xxPWMRegister {
163
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
52
+ /* Control registers. */
164
+ tcg_gen_addi_ptr(t_zm, cpu_env, vec_full_reg_offset(s, zm));
53
+ REG_CAMCMR,
165
+ tcg_gen_addi_ptr(t_zt, cpu_env, vec_full_reg_offset(s, zt));
54
+ REG_CAMEN,
166
+ fn(cpu_env, t_zt, t_pg, t_zm, scalar, desc);
55
+
167
+
56
+ /* There are 16 CAMn[ML] registers. */
168
+ tcg_temp_free_ptr(t_zt);
57
+ REG_CAMM_BASE,
169
+ tcg_temp_free_ptr(t_zm);
58
+ REG_CAML_BASE,
170
+ tcg_temp_free_ptr(t_pg);
59
+ REG_CAMML_LAST = 0x21,
171
+ tcg_temp_free_i32(desc);
60
+
172
+}
61
+ REG_TXDLSA = 0x22,
173
+
62
+ REG_RXDLSA,
174
+static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
63
+ REG_MCMDR,
175
+{
64
+ REG_MIID,
176
+ /* Indexed by [xs][msz]. */
65
+ REG_MIIDA,
177
+ static gen_helper_gvec_mem_scatter * const fn32[2][3] = {
66
+ REG_FFTCR,
178
+ { gen_helper_sve_stbs_zsu,
67
+ REG_TSDR,
179
+ gen_helper_sve_sths_zsu,
68
+ REG_RSDR,
180
+ gen_helper_sve_stss_zsu, },
69
+ REG_DMARFC,
181
+ { gen_helper_sve_stbs_zss,
70
+ REG_MIEN,
182
+ gen_helper_sve_sths_zss,
71
+
183
+ gen_helper_sve_stss_zss, },
72
+ /* Status registers. */
184
+ };
73
+ REG_MISTA,
185
+ /* Note that we overload xs=2 to indicate 64-bit offset. */
74
+ REG_MGSTA,
186
+ static gen_helper_gvec_mem_scatter * const fn64[3][4] = {
75
+ REG_MPCNT,
187
+ { gen_helper_sve_stbd_zsu,
76
+ REG_MRPC,
188
+ gen_helper_sve_sthd_zsu,
77
+ REG_MRPCC,
189
+ gen_helper_sve_stsd_zsu,
78
+ REG_MREPC,
190
+ gen_helper_sve_stdd_zsu, },
79
+ REG_DMARFS,
191
+ { gen_helper_sve_stbd_zss,
80
+ REG_CTXDSA,
192
+ gen_helper_sve_sthd_zss,
81
+ REG_CTXBSA,
193
+ gen_helper_sve_stsd_zss,
82
+ REG_CRXDSA,
194
+ gen_helper_sve_stdd_zss, },
83
+ REG_CRXBSA,
195
+ { gen_helper_sve_stbd_zd,
84
+
196
+ gen_helper_sve_sthd_zd,
85
+ NPCM7XX_NUM_EMC_REGS,
197
+ gen_helper_sve_stsd_zd,
86
+};
198
+ gen_helper_sve_stdd_zd, },
87
+
199
+ };
88
+/* REG_CAMCMR fields */
200
+ gen_helper_gvec_mem_scatter *fn;
89
+/* Enable CAM Compare */
201
+
90
+#define REG_CAMCMR_ECMP (1 << 4)
202
+ if (a->esz < a->msz || (a->msz == 0 && a->scale)) {
91
+/* Complement CAM Compare */
203
+ return false;
92
+#define REG_CAMCMR_CCAM (1 << 3)
204
+ }
93
+/* Accept Broadcast Packet */
205
+ if (!sve_access_check(s)) {
94
+#define REG_CAMCMR_ABP (1 << 2)
206
+ return true;
95
+/* Accept Multicast Packet */
207
+ }
96
+#define REG_CAMCMR_AMP (1 << 1)
208
+ switch (a->esz) {
97
+/* Accept Unicast Packet */
209
+ case MO_32:
98
+#define REG_CAMCMR_AUP (1 << 0)
210
+ fn = fn32[a->xs][a->msz];
99
+
211
+ break;
100
+/* REG_MCMDR fields */
212
+ case MO_64:
101
+/* Software Reset */
213
+ fn = fn64[a->xs][a->msz];
102
+#define REG_MCMDR_SWR (1 << 24)
214
+ break;
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
+
348
+#include "qemu/osdep.h"
349
+
350
+/* For crc32 */
351
+#include <zlib.h>
352
+
353
+#include "qemu-common.h"
354
+#include "hw/irq.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"
366
+#include "trace.h"
367
+
368
+#define CRC_LENGTH 4
369
+
370
+/*
371
+ * The maximum size of a (layer 2) ethernet frame as defined by 802.3.
372
+ * 1518 = 6(dest macaddr) + 6(src macaddr) + 2(proto) + 4(crc) + 1500(payload)
373
+ * This does not include an additional 4 for the vlan field (802.1q).
374
+ */
375
+#define MAX_ETH_FRAME_SIZE 1518
376
+
377
+static const char *emc_reg_name(int regno)
378
+{
379
+#define REG(name) case REG_ ## name: return #name;
380
+ switch (regno) {
381
+ REG(CAMCMR)
382
+ REG(CAMEN)
383
+ REG(TXDLSA)
384
+ REG(RXDLSA)
385
+ REG(MCMDR)
386
+ REG(MIID)
387
+ REG(MIIDA)
388
+ REG(FFTCR)
389
+ REG(TSDR)
390
+ REG(RSDR)
391
+ REG(DMARFC)
392
+ REG(MIEN)
393
+ REG(MISTA)
394
+ REG(MGSTA)
395
+ REG(MPCNT)
396
+ REG(MRPC)
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
+ }
215
+ default:
760
+ default:
216
+ g_assert_not_reached();
761
+ g_assert_not_reached();
217
+ }
762
+ }
218
+ do_mem_zpz(s, a->rd, a->pg, a->rm, a->scale * a->msz,
763
+}
219
+ cpu_reg_sp(s, a->rn), fn);
764
+
220
+ return true;
765
+static bool emc_receive_filter(NPCM7xxEMCState *emc, const uint8_t *buf,
221
+}
766
+ size_t len)
222
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
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,
1136
+ .fields = (VMStateField[]) {
1137
+ VMSTATE_UINT8(emc_num, NPCM7xxEMCState),
1138
+ VMSTATE_UINT32_ARRAY(regs, NPCM7xxEMCState, NPCM7XX_NUM_EMC_REGS),
1139
+ VMSTATE_BOOL(tx_active, NPCM7xxEMCState),
1140
+ VMSTATE_BOOL(rx_active, NPCM7xxEMCState),
1141
+ VMSTATE_END_OF_LIST(),
1142
+ },
1143
+};
1144
+
1145
+static Property npcm7xx_emc_properties[] = {
1146
+ DEFINE_NIC_PROPERTIES(NPCM7xxEMCState, conf),
1147
+ DEFINE_PROP_END_OF_LIST(),
1148
+};
1149
+
1150
+static void npcm7xx_emc_class_init(ObjectClass *klass, void *data)
1151
+{
1152
+ DeviceClass *dc = DEVICE_CLASS(klass);
1153
+
1154
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
1155
+ dc->desc = "NPCM7xx EMC Controller";
1156
+ dc->realize = npcm7xx_emc_realize;
1157
+ dc->unrealize = npcm7xx_emc_unrealize;
1158
+ dc->reset = npcm7xx_emc_reset;
1159
+ dc->vmsd = &vmstate_npcm7xx_emc;
1160
+ device_class_set_props(dc, npcm7xx_emc_properties);
1161
+}
1162
+
1163
+static const TypeInfo npcm7xx_emc_info = {
1164
+ .name = TYPE_NPCM7XX_EMC,
1165
+ .parent = TYPE_SYS_BUS_DEVICE,
1166
+ .instance_size = sizeof(NPCM7xxEMCState),
1167
+ .class_init = npcm7xx_emc_class_init,
1168
+};
1169
+
1170
+static void npcm7xx_emc_register_type(void)
1171
+{
1172
+ type_register_static(&npcm7xx_emc_info);
1173
+}
1174
+
1175
+type_init(npcm7xx_emc_register_type)
1176
diff --git a/hw/net/meson.build b/hw/net/meson.build
223
index XXXXXXX..XXXXXXX 100644
1177
index XXXXXXX..XXXXXXX 100644
224
--- a/target/arm/sve.decode
1178
--- a/hw/net/meson.build
225
+++ b/target/arm/sve.decode
1179
+++ b/hw/net/meson.build
226
@@ -XXX,XX +XXX,XX @@
1180
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_I82596_COMMON', if_true: files('i82596.c'))
227
&rpri_load rd pg rn imm dtype nreg
1181
softmmu_ss.add(when: 'CONFIG_SUNHME', if_true: files('sunhme.c'))
228
&rprr_store rd pg rn rm msz esz nreg
1182
softmmu_ss.add(when: 'CONFIG_FTGMAC100', if_true: files('ftgmac100.c'))
229
&rpri_store rd pg rn imm msz esz nreg
1183
softmmu_ss.add(when: 'CONFIG_SUNGEM', if_true: files('sungem.c'))
230
+&rprr_scatter_store rd pg rn rm esz msz xs scale
1184
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c'))
231
1185
232
###########################################################################
1186
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c'))
233
# Named instruction formats. These are generally used to
1187
softmmu_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
234
@@ -XXX,XX +XXX,XX @@
1188
diff --git a/hw/net/trace-events b/hw/net/trace-events
235
@rpri_store_msz ....... msz:2 .. . imm:s4 ... pg:3 rn:5 rd:5 &rpri_store
1189
index XXXXXXX..XXXXXXX 100644
236
@rprr_store_esz_n0 ....... .. esz:2 rm:5 ... pg:3 rn:5 rd:5 \
1190
--- a/hw/net/trace-events
237
&rprr_store nreg=0
1191
+++ b/hw/net/trace-events
238
+@rprr_scatter_store ....... msz:2 .. rm:5 ... pg:3 rn:5 rd:5 \
1192
@@ -XXX,XX +XXX,XX @@ imx_fec_receive_last(int last) "rx frame flags 0x%04x"
239
+ &rprr_scatter_store
1193
imx_enet_receive(size_t size) "len %zu"
240
1194
imx_enet_receive_len(uint64_t addr, int len) "rx_bd 0x%"PRIx64" length %d"
241
###########################################################################
1195
imx_enet_receive_last(int last) "rx frame flags 0x%04x"
242
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
1196
+
243
@@ -XXX,XX +XXX,XX @@ ST_zpri 1110010 .. nreg:2 1.... 111 ... ..... ..... \
1197
+# npcm7xx_emc.c
244
# SVE store multiple structures (scalar plus scalar) (nreg != 0)
1198
+npcm7xx_emc_reset(int emc_num) "Resetting emc%d"
245
ST_zprr 1110010 msz:2 nreg:2 ..... 011 ... ..... ..... \
1199
+npcm7xx_emc_update_tx_irq(int level) "Setting tx irq to %d"
246
@rprr_store esz=%size_23
1200
+npcm7xx_emc_update_rx_irq(int level) "Setting rx irq to %d"
247
+
1201
+npcm7xx_emc_set_mista(uint32_t flags) "ORing 0x%x into MISTA"
248
+# SVE 32-bit scatter store (scalar plus 32-bit scaled offsets)
1202
+npcm7xx_emc_cpu_owned_desc(uint32_t addr) "Can't process cpu-owned descriptor @0x%x"
249
+# Require msz > 0 && msz <= esz.
1203
+npcm7xx_emc_sent_packet(uint32_t len) "Sent %u byte packet"
250
+ST1_zprz 1110010 .. 11 ..... 100 ... ..... ..... \
1204
+npcm7xx_emc_tx_done(uint32_t ctxdsa) "TX done, CTXDSA=0x%x"
251
+ @rprr_scatter_store xs=0 esz=2 scale=1
1205
+npcm7xx_emc_can_receive(int can_receive) "Can receive: %d"
252
+ST1_zprz 1110010 .. 11 ..... 110 ... ..... ..... \
1206
+npcm7xx_emc_packet_filtered_out(const char* fail_reason) "Packet filtered out: %s"
253
+ @rprr_scatter_store xs=1 esz=2 scale=1
1207
+npcm7xx_emc_packet_dropped(uint32_t len) "%u byte packet dropped"
254
+
1208
+npcm7xx_emc_receiving_packet(uint32_t len) "Receiving %u byte packet"
255
+# SVE 32-bit scatter store (scalar plus 32-bit unscaled offsets)
1209
+npcm7xx_emc_received_packet(uint32_t len) "Received %u byte packet"
256
+# Require msz <= esz.
1210
+npcm7xx_emc_rx_done(uint32_t crxdsa) "RX done, CRXDSA=0x%x"
257
+ST1_zprz 1110010 .. 10 ..... 100 ... ..... ..... \
1211
+npcm7xx_emc_reg_read(int emc_num, uint32_t result, const char *name, int regno) "emc%d: 0x%x = reg[%s/%d]"
258
+ @rprr_scatter_store xs=0 esz=2 scale=0
1212
+npcm7xx_emc_reg_write(int emc_num, const char *name, int regno, uint32_t value) "emc%d: reg[%s/%d] = 0x%x"
259
+ST1_zprz 1110010 .. 10 ..... 110 ... ..... ..... \
260
+ @rprr_scatter_store xs=1 esz=2 scale=0
261
+
262
+# SVE 64-bit scatter store (scalar plus 64-bit scaled offset)
263
+# Require msz > 0
264
+ST1_zprz 1110010 .. 01 ..... 101 ... ..... ..... \
265
+ @rprr_scatter_store xs=2 esz=3 scale=1
266
+
267
+# SVE 64-bit scatter store (scalar plus 64-bit unscaled offset)
268
+ST1_zprz 1110010 .. 00 ..... 101 ... ..... ..... \
269
+ @rprr_scatter_store xs=2 esz=3 scale=0
270
+
271
+# SVE 64-bit scatter store (scalar plus unpacked 32-bit scaled offset)
272
+# Require msz > 0
273
+ST1_zprz 1110010 .. 01 ..... 100 ... ..... ..... \
274
+ @rprr_scatter_store xs=0 esz=3 scale=1
275
+ST1_zprz 1110010 .. 01 ..... 110 ... ..... ..... \
276
+ @rprr_scatter_store xs=1 esz=3 scale=1
277
+
278
+# SVE 64-bit scatter store (scalar plus unpacked 32-bit unscaled offset)
279
+ST1_zprz 1110010 .. 00 ..... 100 ... ..... ..... \
280
+ @rprr_scatter_store xs=0 esz=3 scale=0
281
+ST1_zprz 1110010 .. 00 ..... 110 ... ..... ..... \
282
+ @rprr_scatter_store xs=1 esz=3 scale=0
283
--
1213
--
284
2.17.1
1214
2.20.1
285
1215
286
1216
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Doug Evans <dje@google.com>
2
2
3
This is a 10/100 ethernet device that has several features.
4
Only the ones needed by the Linux driver have been implemented.
5
See npcm7xx_emc.c for a list of unimplemented features.
6
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Doug Evans <dje@google.com>
5
Message-id: 20180627043328.11531-9-richard.henderson@linaro.org
11
Message-id: 20210218212453.831406-3-dje@google.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
13
---
8
target/arm/helper-sve.h | 7 +++++
14
docs/system/arm/nuvoton.rst | 3 ++-
9
target/arm/sve_helper.c | 56 ++++++++++++++++++++++++++++++++++++++
15
include/hw/arm/npcm7xx.h | 2 ++
10
target/arm/translate-sve.c | 45 ++++++++++++++++++++++++++++++
16
hw/arm/npcm7xx.c | 50 +++++++++++++++++++++++++++++++++++--
11
target/arm/sve.decode | 5 ++++
17
3 files changed, 52 insertions(+), 3 deletions(-)
12
4 files changed, 113 insertions(+)
13
18
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
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/helper-sve.h
21
--- a/docs/system/arm/nuvoton.rst
17
+++ b/target/arm/helper-sve.h
22
+++ b/docs/system/arm/nuvoton.rst
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
23
@@ -XXX,XX +XXX,XX @@ Supported devices
19
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
24
* Analog to Digital Converter (ADC)
20
void, ptr, ptr, ptr, ptr, i32)
25
* Pulse Width Modulation (PWM)
21
26
* SMBus controller (SMBF)
22
+DEF_HELPER_FLAGS_5(sve_fadda_h, TCG_CALL_NO_RWG,
27
+ * Ethernet controller (EMC)
23
+ i64, i64, ptr, ptr, ptr, i32)
28
24
+DEF_HELPER_FLAGS_5(sve_fadda_s, TCG_CALL_NO_RWG,
29
Missing devices
25
+ i64, i64, ptr, ptr, ptr, i32)
30
---------------
26
+DEF_HELPER_FLAGS_5(sve_fadda_d, TCG_CALL_NO_RWG,
31
@@ -XXX,XX +XXX,XX @@ Missing devices
27
+ i64, i64, ptr, ptr, ptr, i32)
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
+};
28
+
91
+
29
DEF_HELPER_FLAGS_6(sve_fadd_h, TCG_CALL_NO_RWG,
92
static const struct {
30
void, ptr, ptr, ptr, ptr, ptr, i32)
93
hwaddr regs_addr;
31
DEF_HELPER_FLAGS_6(sve_fadd_s, TCG_CALL_NO_RWG,
94
uint32_t unconnected_pins;
32
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
95
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
33
index XXXXXXX..XXXXXXX 100644
96
for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
34
--- a/target/arm/sve_helper.c
97
object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
35
+++ b/target/arm/sve_helper.c
98
}
36
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
99
+
37
return predtest_ones(d, oprsz, esz_mask);
100
+ for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
101
+ object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
102
+ }
38
}
103
}
39
104
40
+uint64_t HELPER(sve_fadda_h)(uint64_t nn, void *vm, void *vg,
105
static void npcm7xx_realize(DeviceState *dev, Error **errp)
41
+ void *status, uint32_t desc)
106
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
42
+{
107
sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
43
+ intptr_t i = 0, opr_sz = simd_oprsz(desc);
108
}
44
+ float16 result = nn;
109
45
+
110
+ /*
46
+ do {
111
+ * EMC Modules. Cannot fail.
47
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3));
112
+ * The mapping of the device to its netdev backend works as follows:
48
+ do {
113
+ * emc[i] = nd_table[i]
49
+ if (pg & 1) {
114
+ * This works around the inability to specify the netdev property for the
50
+ float16 mm = *(float16 *)(vm + H1_2(i));
115
+ * emc device: it's not pluggable and thus the -device option can't be
51
+ result = float16_add(result, mm, status);
116
+ * used.
52
+ }
117
+ */
53
+ i += sizeof(float16), pg >>= sizeof(float16);
118
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_emc_addr) != ARRAY_SIZE(s->emc));
54
+ } while (i & 15);
119
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->emc) != 2);
55
+ } while (i < opr_sz);
120
+ for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
56
+
121
+ s->emc[i].emc_num = i;
57
+ return result;
122
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->emc[i]);
58
+}
123
+ if (nd_table[i].used) {
59
+
124
+ qemu_check_nic_model(&nd_table[i], TYPE_NPCM7XX_EMC);
60
+uint64_t HELPER(sve_fadda_s)(uint64_t nn, void *vm, void *vg,
125
+ qdev_set_nic_properties(DEVICE(sbd), &nd_table[i]);
61
+ void *status, uint32_t desc)
62
+{
63
+ intptr_t i = 0, opr_sz = simd_oprsz(desc);
64
+ float32 result = nn;
65
+
66
+ do {
67
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3));
68
+ do {
69
+ if (pg & 1) {
70
+ float32 mm = *(float32 *)(vm + H1_2(i));
71
+ result = float32_add(result, mm, status);
72
+ }
73
+ i += sizeof(float32), pg >>= sizeof(float32);
74
+ } while (i & 15);
75
+ } while (i < opr_sz);
76
+
77
+ return result;
78
+}
79
+
80
+uint64_t HELPER(sve_fadda_d)(uint64_t nn, void *vm, void *vg,
81
+ void *status, uint32_t desc)
82
+{
83
+ intptr_t i = 0, opr_sz = simd_oprsz(desc) / 8;
84
+ uint64_t *m = vm;
85
+ uint8_t *pg = vg;
86
+
87
+ for (i = 0; i < opr_sz; i++) {
88
+ if (pg[H1(i)] & 1) {
89
+ nn = float64_add(nn, m[i], status);
90
+ }
126
+ }
127
+ /*
128
+ * The device exists regardless of whether it's connected to a QEMU
129
+ * netdev backend. So always instantiate it even if there is no
130
+ * backend.
131
+ */
132
+ sysbus_realize(sbd, &error_abort);
133
+ sysbus_mmio_map(sbd, 0, npcm7xx_emc_addr[i]);
134
+ int tx_irq = i == 0 ? NPCM7XX_EMC1TX_IRQ : NPCM7XX_EMC2TX_IRQ;
135
+ int rx_irq = i == 0 ? NPCM7XX_EMC1RX_IRQ : NPCM7XX_EMC2RX_IRQ;
136
+ /*
137
+ * N.B. The values for the second argument sysbus_connect_irq are
138
+ * chosen to match the registration order in npcm7xx_emc_realize.
139
+ */
140
+ sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, tx_irq));
141
+ sysbus_connect_irq(sbd, 1, npcm7xx_irq(s, rx_irq));
91
+ }
142
+ }
92
+
143
+
93
+ return nn;
144
/*
94
+}
145
* Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
95
+
146
* specified, but this is a programming error.
96
/* Fully general three-operand expander, controlled by a predicate,
147
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
97
* With the extra float_status parameter.
148
create_unimplemented_device("npcm7xx.vcd", 0xf0810000, 64 * KiB);
98
*/
149
create_unimplemented_device("npcm7xx.ece", 0xf0820000, 8 * KiB);
99
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
150
create_unimplemented_device("npcm7xx.vdma", 0xf0822000, 8 * KiB);
100
index XXXXXXX..XXXXXXX 100644
151
- create_unimplemented_device("npcm7xx.emc1", 0xf0825000, 4 * KiB);
101
--- a/target/arm/translate-sve.c
152
- create_unimplemented_device("npcm7xx.emc2", 0xf0826000, 4 * KiB);
102
+++ b/target/arm/translate-sve.c
153
create_unimplemented_device("npcm7xx.usbd[0]", 0xf0830000, 4 * KiB);
103
@@ -XXX,XX +XXX,XX @@ DO_ZZI(UMIN, umin)
154
create_unimplemented_device("npcm7xx.usbd[1]", 0xf0831000, 4 * KiB);
104
155
create_unimplemented_device("npcm7xx.usbd[2]", 0xf0832000, 4 * KiB);
105
#undef DO_ZZI
106
107
+/*
108
+ *** SVE Floating Point Accumulating Reduction Group
109
+ */
110
+
111
+static bool trans_FADDA(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
112
+{
113
+ typedef void fadda_fn(TCGv_i64, TCGv_i64, TCGv_ptr,
114
+ TCGv_ptr, TCGv_ptr, TCGv_i32);
115
+ static fadda_fn * const fns[3] = {
116
+ gen_helper_sve_fadda_h,
117
+ gen_helper_sve_fadda_s,
118
+ gen_helper_sve_fadda_d,
119
+ };
120
+ unsigned vsz = vec_full_reg_size(s);
121
+ TCGv_ptr t_rm, t_pg, t_fpst;
122
+ TCGv_i64 t_val;
123
+ TCGv_i32 t_desc;
124
+
125
+ if (a->esz == 0) {
126
+ return false;
127
+ }
128
+ if (!sve_access_check(s)) {
129
+ return true;
130
+ }
131
+
132
+ t_val = load_esz(cpu_env, vec_reg_offset(s, a->rn, 0, a->esz), a->esz);
133
+ t_rm = tcg_temp_new_ptr();
134
+ t_pg = tcg_temp_new_ptr();
135
+ tcg_gen_addi_ptr(t_rm, cpu_env, vec_full_reg_offset(s, a->rm));
136
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, a->pg));
137
+ t_fpst = get_fpstatus_ptr(a->esz == MO_16);
138
+ t_desc = tcg_const_i32(simd_desc(vsz, vsz, 0));
139
+
140
+ fns[a->esz - 1](t_val, t_val, t_rm, t_pg, t_fpst, t_desc);
141
+
142
+ tcg_temp_free_i32(t_desc);
143
+ tcg_temp_free_ptr(t_fpst);
144
+ tcg_temp_free_ptr(t_pg);
145
+ tcg_temp_free_ptr(t_rm);
146
+
147
+ write_fp_dreg(s, a->rd, t_val);
148
+ tcg_temp_free_i64(t_val);
149
+ return true;
150
+}
151
+
152
/*
153
*** SVE Floating Point Arithmetic - Unpredicated Group
154
*/
155
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/sve.decode
158
+++ b/target/arm/sve.decode
159
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
160
# SVE integer multiply immediate (unpredicated)
161
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
162
163
+### SVE FP Accumulating Reduction Group
164
+
165
+# SVE floating-point serial reduction (predicated)
166
+FADDA 01100101 .. 011 000 001 ... ..... ..... @rdn_pg_rm
167
+
168
### SVE Floating Point Arithmetic - Unpredicated Group
169
170
# SVE floating-point arithmetic (unpredicated)
171
--
156
--
172
2.17.1
157
2.20.1
173
158
174
159
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Doug Evans <dje@google.com>
2
2
3
The load/store API will ease further code movement.
3
Reviewed-by: Hao Wu <wuhaotsh@google.com>
4
4
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
5
Per the Physical Layer Simplified Spec. "3.6 Bus Protocol":
6
7
"In the CMD line the Most Significant Bit (MSB) is transmitted
8
first, the Least Significant Bit (LSB) is the last."
9
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Doug Evans <dje@google.com>
7
Message-id: 20210218212453.831406-4-dje@google.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
9
---
14
hw/sd/bcm2835_sdhost.c | 13 +++++--------
10
tests/qtest/npcm7xx_emc-test.c | 862 +++++++++++++++++++++++++++++++++
15
hw/sd/milkymist-memcard.c | 3 +--
11
tests/qtest/meson.build | 3 +-
16
hw/sd/omap_mmc.c | 6 ++----
12
2 files changed, 864 insertions(+), 1 deletion(-)
17
hw/sd/pl181.c | 11 ++++-------
13
create mode 100644 tests/qtest/npcm7xx_emc-test.c
18
hw/sd/sdhci.c | 15 +++++----------
19
hw/sd/ssi-sd.c | 6 ++----
20
6 files changed, 19 insertions(+), 35 deletions(-)
21
14
22
diff --git a/hw/sd/bcm2835_sdhost.c b/hw/sd/bcm2835_sdhost.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
23
index XXXXXXX..XXXXXXX 100644
884
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/sd/bcm2835_sdhost.c
885
--- a/tests/qtest/meson.build
25
+++ b/hw/sd/bcm2835_sdhost.c
886
+++ b/tests/qtest/meson.build
26
@@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s)
887
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
27
goto error;
888
'npcm7xx_rng-test',
28
}
889
'npcm7xx_smbus-test',
29
if (!(s->cmd & SDCMD_NO_RESPONSE)) {
890
'npcm7xx_timer-test',
30
-#define RWORD(n) (((uint32_t)rsp[n] << 24) | (rsp[n + 1] << 16) \
891
- 'npcm7xx_watchdog_timer-test']
31
- | (rsp[n + 2] << 8) | rsp[n + 3])
892
+ 'npcm7xx_watchdog_timer-test'] + \
32
if (rlen == 0 || (rlen == 4 && (s->cmd & SDCMD_LONG_RESPONSE))) {
893
+ (slirp.found() ? ['npcm7xx_emc-test'] : [])
33
goto error;
894
qtests_arm = \
34
}
895
(config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
35
@@ -XXX,XX +XXX,XX @@ static void bcm2835_sdhost_send_command(BCM2835SDHostState *s)
896
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
36
goto error;
37
}
38
if (rlen == 4) {
39
- s->rsp[0] = RWORD(0);
40
+ s->rsp[0] = ldl_be_p(&rsp[0]);
41
s->rsp[1] = s->rsp[2] = s->rsp[3] = 0;
42
} else {
43
- s->rsp[0] = RWORD(12);
44
- s->rsp[1] = RWORD(8);
45
- s->rsp[2] = RWORD(4);
46
- s->rsp[3] = RWORD(0);
47
+ s->rsp[0] = ldl_be_p(&rsp[12]);
48
+ s->rsp[1] = ldl_be_p(&rsp[8]);
49
+ s->rsp[2] = ldl_be_p(&rsp[4]);
50
+ s->rsp[3] = ldl_be_p(&rsp[0]);
51
}
52
-#undef RWORD
53
}
54
/* We never really delay commands, so if this was a 'busywait' command
55
* then we've completed it now and can raise the interrupt.
56
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/sd/milkymist-memcard.c
59
+++ b/hw/sd/milkymist-memcard.c
60
@@ -XXX,XX +XXX,XX @@ static void memcard_sd_command(MilkymistMemcardState *s)
61
SDRequest req;
62
63
req.cmd = s->command[0] & 0x3f;
64
- req.arg = (s->command[1] << 24) | (s->command[2] << 16)
65
- | (s->command[3] << 8) | s->command[4];
66
+ req.arg = ldl_be_p(s->command + 1);
67
req.crc = s->command[5];
68
69
s->response[0] = req.cmd;
70
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/sd/omap_mmc.c
73
+++ b/hw/sd/omap_mmc.c
74
@@ -XXX,XX +XXX,XX @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
75
CID_CSD_OVERWRITE;
76
if (host->sdio & (1 << 13))
77
mask |= AKE_SEQ_ERROR;
78
- rspstatus = (response[0] << 24) | (response[1] << 16) |
79
- (response[2] << 8) | (response[3] << 0);
80
+ rspstatus = ldl_be_p(response);
81
break;
82
83
case sd_r2:
84
@@ -XXX,XX +XXX,XX @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
85
}
86
rsplen = 4;
87
88
- rspstatus = (response[0] << 24) | (response[1] << 16) |
89
- (response[2] << 8) | (response[3] << 0);
90
+ rspstatus = ldl_be_p(response);
91
if (rspstatus & 0x80000000)
92
host->status &= 0xe000;
93
else
94
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/hw/sd/pl181.c
97
+++ b/hw/sd/pl181.c
98
@@ -XXX,XX +XXX,XX @@ static void pl181_send_command(PL181State *s)
99
if (rlen < 0)
100
goto error;
101
if (s->cmd & PL181_CMD_RESPONSE) {
102
-#define RWORD(n) (((uint32_t)response[n] << 24) | (response[n + 1] << 16) \
103
- | (response[n + 2] << 8) | response[n + 3])
104
if (rlen == 0 || (rlen == 4 && (s->cmd & PL181_CMD_LONGRESP)))
105
goto error;
106
if (rlen != 4 && rlen != 16)
107
goto error;
108
- s->response[0] = RWORD(0);
109
+ s->response[0] = ldl_be_p(&response[0]);
110
if (rlen == 4) {
111
s->response[1] = s->response[2] = s->response[3] = 0;
112
} else {
113
- s->response[1] = RWORD(4);
114
- s->response[2] = RWORD(8);
115
- s->response[3] = RWORD(12) & ~1;
116
+ s->response[1] = ldl_be_p(&response[4]);
117
+ s->response[2] = ldl_be_p(&response[8]);
118
+ s->response[3] = ldl_be_p(&response[12]) & ~1;
119
}
120
DPRINTF("Response received\n");
121
s->status |= PL181_STATUS_CMDRESPEND;
122
-#undef RWORD
123
} else {
124
DPRINTF("Command sent\n");
125
s->status |= PL181_STATUS_CMDSENT;
126
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/sd/sdhci.c
129
+++ b/hw/sd/sdhci.c
130
@@ -XXX,XX +XXX,XX @@ static void sdhci_send_command(SDHCIState *s)
131
132
if (s->cmdreg & SDHC_CMD_RESPONSE) {
133
if (rlen == 4) {
134
- s->rspreg[0] = (response[0] << 24) | (response[1] << 16) |
135
- (response[2] << 8) | response[3];
136
+ s->rspreg[0] = ldl_be_p(response);
137
s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0;
138
trace_sdhci_response4(s->rspreg[0]);
139
} else if (rlen == 16) {
140
- s->rspreg[0] = (response[11] << 24) | (response[12] << 16) |
141
- (response[13] << 8) | response[14];
142
- s->rspreg[1] = (response[7] << 24) | (response[8] << 16) |
143
- (response[9] << 8) | response[10];
144
- s->rspreg[2] = (response[3] << 24) | (response[4] << 16) |
145
- (response[5] << 8) | response[6];
146
+ s->rspreg[0] = ldl_be_p(&response[11]);
147
+ s->rspreg[1] = ldl_be_p(&response[7]);
148
+ s->rspreg[2] = ldl_be_p(&response[3]);
149
s->rspreg[3] = (response[0] << 16) | (response[1] << 8) |
150
response[2];
151
trace_sdhci_response16(s->rspreg[3], s->rspreg[2],
152
@@ -XXX,XX +XXX,XX @@ static void sdhci_end_transfer(SDHCIState *s)
153
trace_sdhci_end_transfer(request.cmd, request.arg);
154
sdbus_do_command(&s->sdbus, &request, response);
155
/* Auto CMD12 response goes to the upper Response register */
156
- s->rspreg[3] = (response[0] << 24) | (response[1] << 16) |
157
- (response[2] << 8) | response[3];
158
+ s->rspreg[3] = ldl_be_p(response);
159
}
160
161
s->prnsts &= ~(SDHC_DOING_READ | SDHC_DOING_WRITE |
162
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/hw/sd/ssi-sd.c
165
+++ b/hw/sd/ssi-sd.c
166
@@ -XXX,XX +XXX,XX @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
167
uint8_t longresp[16];
168
/* FIXME: Check CRC. */
169
request.cmd = s->cmd;
170
- request.arg = (s->cmdarg[0] << 24) | (s->cmdarg[1] << 16)
171
- | (s->cmdarg[2] << 8) | s->cmdarg[3];
172
+ request.arg = ldl_be_p(s->cmdarg);
173
DPRINTF("CMD%d arg 0x%08x\n", s->cmd, request.arg);
174
s->arglen = sdbus_do_command(&s->sdbus, &request, longresp);
175
if (s->arglen <= 0) {
176
@@ -XXX,XX +XXX,XX @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val)
177
/* CMD13 returns a 2-byte statuse work. Other commands
178
only return the first byte. */
179
s->arglen = (s->cmd == 13) ? 2 : 1;
180
- cardstatus = (longresp[0] << 24) | (longresp[1] << 16)
181
- | (longresp[2] << 8) | longresp[3];
182
+ cardstatus = ldl_be_p(longresp);
183
status = 0;
184
if (((cardstatus >> 9) & 0xf) < 4)
185
status |= SSI_SDR_IDLE;
186
--
897
--
187
2.17.1
898
2.20.1
188
899
189
900
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Use error_report() + exit() instead of error_setg(&error_fatal),
3
We hint the 'has_rpu' property is no longer required since commit
4
as suggested by the "qapi/error.h" documentation:
4
6908ec448b4 ("xlnx-zynqmp: Properly support the smp command line
5
option") which was released in QEMU v2.11.0.
5
6
6
Please don't error_setg(&error_fatal, ...), use error_report() and
7
Beside, this device is marked 'user_creatable = false', so the
7
exit(), because that's more obvious.
8
only thing that could be setting the property is the board code
9
that creates the device.
8
10
9
This fixes CID 1352173:
11
Since the property is not user-facing, we can remove it without
10
"Passing null pointer dt_name to qemu_fdt_node_path, which dereferences it."
12
going through the deprecation process.
11
13
12
And this also fixes:
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
14
hw/arm/sysbus-fdt.c:322:9: warning: Array access (from variable 'node_path') results in a null pointer dereference
15
if (node_path[1]) {
16
^~~~~~~~~~~~
17
18
Fixes: Coverity CID 1352173 (Dereference after null check)
19
Suggested-by: Eric Blake <eblake@redhat.com>
20
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Reviewed-by: Eric Auger <eric.auger@redhat.com>
16
Message-id: 20210219144350.1979905-1-f4bug@amsat.org
22
Message-id: 20180625165749.3910-3-f4bug@amsat.org
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
18
---
25
hw/arm/sysbus-fdt.c | 53 +++++++++++++++++++++++++--------------------
19
include/hw/arm/xlnx-zynqmp.h | 2 --
26
1 file changed, 30 insertions(+), 23 deletions(-)
20
hw/arm/xlnx-zynqmp.c | 6 ------
21
2 files changed, 8 deletions(-)
27
22
28
diff --git a/hw/arm/sysbus-fdt.c b/hw/arm/sysbus-fdt.c
23
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
29
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/sysbus-fdt.c
25
--- a/include/hw/arm/xlnx-zynqmp.h
31
+++ b/hw/arm/sysbus-fdt.c
26
+++ b/include/hw/arm/xlnx-zynqmp.h
32
@@ -XXX,XX +XXX,XX @@ static void copy_properties_from_host(HostProperty *props, int nb_props,
27
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
33
r = qemu_fdt_getprop(host_fdt, node_path,
28
bool secure;
34
props[i].name,
29
/* Has the ARM Virtualization extensions? */
35
&prop_len,
30
bool virt;
36
- props[i].optional ? &err : &error_fatal);
31
- /* Has the RPU subsystem? */
37
+ &err);
32
- bool has_rpu;
38
if (r) {
33
39
qemu_fdt_setprop(guest_fdt, nodename,
34
/* CAN bus. */
40
props[i].name, r, prop_len);
35
CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
41
} else {
36
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
42
- if (prop_len != -FDT_ERR_NOTFOUND) {
37
index XXXXXXX..XXXXXXX 100644
43
- /* optional property not returned although property exists */
38
--- a/hw/arm/xlnx-zynqmp.c
44
- error_report_err(err);
39
+++ b/hw/arm/xlnx-zynqmp.c
45
- } else {
40
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
46
+ if (props[i].optional && prop_len == -FDT_ERR_NOTFOUND) {
47
+ /* optional property does not exist */
48
error_free(err);
49
+ } else {
50
+ error_report_err(err);
51
+ }
52
+ if (!props[i].optional) {
53
+ /* mandatory property not found: bail out */
54
+ exit(1);
55
}
56
}
41
}
57
}
42
}
58
@@ -XXX,XX +XXX,XX @@ static void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
43
59
44
- if (s->has_rpu) {
60
node_offset = fdt_node_offset_by_phandle(host_fdt, host_phandle);
45
- info_report("The 'has_rpu' property is no longer required, to use the "
61
if (node_offset <= 0) {
46
- "RPUs just use -smp 6.");
62
- error_setg(&error_fatal,
47
- }
63
- "not able to locate clock handle %d in host device tree",
48
-
64
- host_phandle);
49
xlnx_zynqmp_create_rpu(ms, s, boot_cpu, &err);
65
+ error_report("not able to locate clock handle %d in host device tree",
50
if (err) {
66
+ host_phandle);
51
error_propagate(errp, err);
67
+ exit(1);
52
@@ -XXX,XX +XXX,XX @@ static Property xlnx_zynqmp_props[] = {
68
}
53
DEFINE_PROP_STRING("boot-cpu", XlnxZynqMPState, boot_cpu),
69
node_path = g_malloc(path_len);
54
DEFINE_PROP_BOOL("secure", XlnxZynqMPState, secure, false),
70
while ((ret = fdt_get_path(host_fdt, node_offset, node_path, path_len))
55
DEFINE_PROP_BOOL("virtualization", XlnxZynqMPState, virt, false),
71
@@ -XXX,XX +XXX,XX @@ static void fdt_build_clock_node(void *host_fdt, void *guest_fdt,
56
- DEFINE_PROP_BOOL("has_rpu", XlnxZynqMPState, has_rpu, false),
72
node_path = g_realloc(node_path, path_len);
57
DEFINE_PROP_LINK("ddr-ram", XlnxZynqMPState, ddr_ram, TYPE_MEMORY_REGION,
73
}
58
MemoryRegion *),
74
if (ret < 0) {
59
DEFINE_PROP_LINK("canbus0", XlnxZynqMPState, canbus[0], TYPE_CAN_BUS,
75
- error_setg(&error_fatal,
76
- "not able to retrieve node path for clock handle %d",
77
- host_phandle);
78
+ error_report("not able to retrieve node path for clock handle %d",
79
+ host_phandle);
80
+ exit(1);
81
}
82
83
r = qemu_fdt_getprop(host_fdt, node_path, "compatible", &prop_len,
84
&error_fatal);
85
if (strcmp(r, "fixed-clock")) {
86
- error_setg(&error_fatal,
87
- "clock handle %d is not a fixed clock", host_phandle);
88
+ error_report("clock handle %d is not a fixed clock", host_phandle);
89
+ exit(1);
90
}
91
92
nodename = strrchr(node_path, '/');
93
@@ -XXX,XX +XXX,XX @@ static int add_amd_xgbe_fdt_node(SysBusDevice *sbdev, void *opaque)
94
95
dt_name = sysfs_to_dt_name(vbasedev->name);
96
if (!dt_name) {
97
- error_setg(&error_fatal, "%s incorrect sysfs device name %s",
98
- __func__, vbasedev->name);
99
+ error_report("%s incorrect sysfs device name %s",
100
+ __func__, vbasedev->name);
101
+ exit(1);
102
}
103
node_path = qemu_fdt_node_path(host_fdt, dt_name, vdev->compat,
104
&error_fatal);
105
if (!node_path || !node_path[0]) {
106
- error_setg(&error_fatal, "%s unable to retrieve node path for %s/%s",
107
- __func__, dt_name, vdev->compat);
108
+ error_report("%s unable to retrieve node path for %s/%s",
109
+ __func__, dt_name, vdev->compat);
110
+ exit(1);
111
}
112
113
if (node_path[1]) {
114
- error_setg(&error_fatal, "%s more than one node matching %s/%s!",
115
- __func__, dt_name, vdev->compat);
116
+ error_report("%s more than one node matching %s/%s!",
117
+ __func__, dt_name, vdev->compat);
118
+ exit(1);
119
}
120
121
g_free(dt_name);
122
123
if (vbasedev->num_regions != 5) {
124
- error_setg(&error_fatal, "%s Does the host dt node combine XGBE/PHY?",
125
- __func__);
126
+ error_report("%s Does the host dt node combine XGBE/PHY?", __func__);
127
+ exit(1);
128
}
129
130
/* generate nodes for DMA_CLK and PTP_CLK */
131
r = qemu_fdt_getprop(host_fdt, node_path[0], "clocks",
132
&prop_len, &error_fatal);
133
if (prop_len != 8) {
134
- error_setg(&error_fatal, "%s clocks property should contain 2 handles",
135
- __func__);
136
+ error_report("%s clocks property should contain 2 handles", __func__);
137
+ exit(1);
138
}
139
host_clock_phandles = (uint32_t *)r;
140
guest_clock_phandles[0] = qemu_fdt_alloc_phandle(guest_fdt);
141
--
60
--
142
2.17.1
61
2.20.1
143
62
144
63
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
For aa64 advsimd, we had been passing the pre-indexed vector.
3
Always perform one call instead of two for 16-byte operands.
4
However, sve applies the index to each 128-bit segment, so we
4
Use byte loads/stores directly into the vector register file
5
need to pass in the index separately.
5
instead of extractions and deposits to a 64-bit local variable.
6
6
7
For aa32 advsimd, the fp32 operation always has index 0, but
7
In order to easily receive pointers into the vector register file,
8
we failed to interpret the fp16 index correctly.
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.
9
10
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Message-id: 20180627043328.11531-31-richard.henderson@linaro.org
13
Tested-by: Alex Bennée <alex.bennee@linaro.org>
14
Message-id: 20210224230532.276878-1-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
---
16
target/arm/translate-a64.c | 21 ++++++++++++---------
17
target/arm/helper-a64.h | 2 +-
17
target/arm/translate.c | 32 +++++++++++++++++++++++---------
18
target/arm/helper-a64.c | 32 ---------------------
18
target/arm/vec_helper.c | 10 ++++++----
19
target/arm/translate-a64.c | 58 +++++---------------------------------
19
3 files changed, 41 insertions(+), 22 deletions(-)
20
target/arm/vec_helper.c | 48 +++++++++++++++++++++++++++++++
20
21
4 files changed, 56 insertions(+), 84 deletions(-)
22
23
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper-a64.h
26
+++ b/target/arm/helper-a64.h
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
28
DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr)
29
DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr)
30
DEF_HELPER_3(vfp_cmped_a64, i64, f64, f64, ptr)
31
-DEF_HELPER_FLAGS_5(simd_tbl, TCG_CALL_NO_RWG_SE, i64, env, i64, i64, i32, i32)
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)
36
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/helper-a64.c
39
+++ b/target/arm/helper-a64.c
40
@@ -XXX,XX +XXX,XX @@ float64 HELPER(vfp_mulxd)(float64 a, float64 b, void *fpstp)
41
return float64_mul(a, b, fpst);
42
}
43
44
-uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices,
45
- uint32_t rn, uint32_t numregs)
46
-{
47
- /* Helper function for SIMD TBL and TBX. We have to do the table
48
- * lookup part for the 64 bits worth of indices we're passed in.
49
- * result is the initial results vector (either zeroes for TBL
50
- * or some guest values for TBX), rn the register number where
51
- * the table starts, and numregs the number of registers in the table.
52
- * We return the results of the lookups.
53
- */
54
- int shift;
55
-
56
- for (shift = 0; shift < 64; shift += 8) {
57
- int index = extract64(indices, shift, 8);
58
- if (index < 16 * numregs) {
59
- /* Convert index (a byte offset into the virtual table
60
- * which is a series of 128-bit vectors concatenated)
61
- * into the correct register element plus a bit offset
62
- * into that element, bearing in mind that the table
63
- * can wrap around from V31 to V0.
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
{
21
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
22
index XXXXXXX..XXXXXXX 100644
80
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/translate-a64.c
81
--- a/target/arm/translate-a64.c
24
+++ b/target/arm/translate-a64.c
82
+++ b/target/arm/translate-a64.c
25
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
83
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
26
case 0x13: /* FCMLA #90 */
84
int rm = extract32(insn, 16, 5);
27
case 0x15: /* FCMLA #180 */
85
int rn = extract32(insn, 5, 5);
28
case 0x17: /* FCMLA #270 */
86
int rd = extract32(insn, 0, 5);
29
- tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
87
- int is_tblx = extract32(insn, 12, 1);
30
- vec_full_reg_offset(s, rn),
88
- int len = extract32(insn, 13, 2);
31
- vec_reg_offset(s, rm, index, size), fpst,
89
- TCGv_i64 tcg_resl, tcg_resh, tcg_idx;
32
- is_q ? 16 : 8, vec_full_reg_size(s),
90
- TCGv_i32 tcg_regno, tcg_numregs;
33
- extract32(insn, 13, 2), /* rot */
91
+ int is_tbx = extract32(insn, 12, 1);
34
- size == MO_64
92
+ int len = (extract32(insn, 13, 2) + 1) * 16;
35
- ? gen_helper_gvec_fcmlas_idx
93
36
- : gen_helper_gvec_fcmlah_idx);
94
if (op2 != 0) {
37
- tcg_temp_free_ptr(fpst);
95
unallocated_encoding(s);
38
+ {
96
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
39
+ int rot = extract32(insn, 13, 2);
40
+ int data = (index << 2) | rot;
41
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
42
+ vec_full_reg_offset(s, rn),
43
+ vec_full_reg_offset(s, rm), fpst,
44
+ is_q ? 16 : 8, vec_full_reg_size(s), data,
45
+ size == MO_64
46
+ ? gen_helper_gvec_fcmlas_idx
47
+ : gen_helper_gvec_fcmlah_idx);
48
+ tcg_temp_free_ptr(fpst);
49
+ }
50
return;
97
return;
51
}
98
}
52
99
53
diff --git a/target/arm/translate.c b/target/arm/translate.c
100
- /* This does a table lookup: for every byte element in the input
54
index XXXXXXX..XXXXXXX 100644
101
- * we index into a table formed from up to four vector registers,
55
--- a/target/arm/translate.c
102
- * and then the output is the result of the lookups. Our helper
56
+++ b/target/arm/translate.c
103
- * function does the lookup operation for a single 64 bit part of
57
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
104
- * the input.
58
105
- */
59
static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
106
- tcg_resl = tcg_temp_new_i64();
60
{
107
- tcg_resh = NULL;
61
- int rd, rn, rm, rot, size, opr_sz;
108
-
62
+ gen_helper_gvec_3_ptr *fn_gvec_ptr;
109
- if (is_tblx) {
63
+ int rd, rn, rm, opr_sz, data;
110
- read_vec_element(s, tcg_resl, rd, 0, MO_64);
64
TCGv_ptr fpst;
111
- } else {
65
bool q;
112
- tcg_gen_movi_i64(tcg_resl, 0);
66
113
- }
67
q = extract32(insn, 6, 1);
114
-
68
VFP_DREG_D(rd, insn);
115
- if (is_q) {
69
VFP_DREG_N(rn, insn);
116
- tcg_resh = tcg_temp_new_i64();
70
- VFP_DREG_M(rm, insn);
117
- if (is_tblx) {
71
if ((rd | rn) & q) {
118
- read_vec_element(s, tcg_resh, rd, 1, MO_64);
72
return 1;
119
- } else {
73
}
120
- tcg_gen_movi_i64(tcg_resh, 0);
74
121
- }
75
if ((insn & 0xff000f10) == 0xfe000800) {
122
- }
76
/* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
123
-
77
- rot = extract32(insn, 20, 2);
124
- tcg_idx = tcg_temp_new_i64();
78
- size = extract32(insn, 23, 1);
125
- tcg_regno = tcg_const_i32(rn);
79
- if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
126
- tcg_numregs = tcg_const_i32(len + 1);
80
- || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
127
- read_vec_element(s, tcg_idx, rm, 0, MO_64);
81
+ int rot = extract32(insn, 20, 2);
128
- gen_helper_simd_tbl(tcg_resl, cpu_env, tcg_resl, tcg_idx,
82
+ int size = extract32(insn, 23, 1);
129
- tcg_regno, tcg_numregs);
83
+ int index;
130
- if (is_q) {
84
+
131
- read_vec_element(s, tcg_idx, rm, 1, MO_64);
85
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)) {
132
- gen_helper_simd_tbl(tcg_resh, cpu_env, tcg_resh, tcg_idx,
86
return 1;
133
- tcg_regno, tcg_numregs);
87
}
134
- }
88
+ if (size == 0) {
135
- tcg_temp_free_i64(tcg_idx);
89
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
136
- tcg_temp_free_i32(tcg_regno);
90
+ return 1;
137
- tcg_temp_free_i32(tcg_numregs);
91
+ }
138
-
92
+ /* For fp16, rm is just Vm, and index is M. */
139
- write_vec_element(s, tcg_resl, rd, 0, MO_64);
93
+ rm = extract32(insn, 0, 4);
140
- tcg_temp_free_i64(tcg_resl);
94
+ index = extract32(insn, 5, 1);
141
-
95
+ } else {
142
- if (is_q) {
96
+ /* For fp32, rm is the usual M:Vm, and index is 0. */
143
- write_vec_element(s, tcg_resh, rd, 1, MO_64);
97
+ VFP_DREG_M(rm, insn);
144
- tcg_temp_free_i64(tcg_resh);
98
+ index = 0;
145
- }
99
+ }
146
- clear_vec_high(s, is_q, rd);
100
+ data = (index << 2) | rot;
147
+ tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd),
101
+ fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
148
+ vec_full_reg_offset(s, rm), cpu_env,
102
+ : gen_helper_gvec_fcmlah_idx);
149
+ is_q ? 16 : 8, vec_full_reg_size(s),
103
} else {
150
+ (len << 6) | (is_tbx << 5) | rn,
104
return 1;
151
+ gen_helper_simd_tblx);
105
}
106
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
107
tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
108
vfp_reg_offset(1, rn),
109
vfp_reg_offset(1, rm), fpst,
110
- opr_sz, opr_sz, rot,
111
- size ? gen_helper_gvec_fcmlas_idx
112
- : gen_helper_gvec_fcmlah_idx);
113
+ opr_sz, opr_sz, data, fn_gvec_ptr);
114
tcg_temp_free_ptr(fpst);
115
return 0;
116
}
152
}
153
154
/* ZIP/UZP/TRN
117
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
155
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
118
index XXXXXXX..XXXXXXX 100644
156
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/vec_helper.c
157
--- a/target/arm/vec_helper.c
120
+++ b/target/arm/vec_helper.c
158
+++ b/target/arm/vec_helper.c
121
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm,
159
@@ -XXX,XX +XXX,XX @@ DO_VRINT_RMODE(gvec_vrint_rm_h, helper_rinth, uint16_t)
122
float_status *fpst = vfpst;
160
DO_VRINT_RMODE(gvec_vrint_rm_s, helper_rints, uint32_t)
123
intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1);
161
124
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
162
#undef DO_VRINT_RMODE
125
+ intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
163
+
126
uint32_t neg_real = flip ^ neg_imag;
164
+#ifdef TARGET_AARCH64
127
uintptr_t i;
165
+void HELPER(simd_tblx)(void *vd, void *vm, void *venv, uint32_t desc)
128
- float16 e1 = m[H2(flip)];
166
+{
129
- float16 e3 = m[H2(1 - flip)];
167
+ const uint8_t *indices = vm;
130
+ float16 e1 = m[H2(2 * index + flip)];
168
+ CPUARMState *env = venv;
131
+ float16 e3 = m[H2(2 * index + 1 - flip)];
169
+ size_t oprsz = simd_oprsz(desc);
132
170
+ uint32_t rn = extract32(desc, SIMD_DATA_SHIFT, 5);
133
/* Shift boolean to the sign bit so we can xor to negate. */
171
+ bool is_tbx = extract32(desc, SIMD_DATA_SHIFT + 5, 1);
134
neg_real <<= 15;
172
+ uint32_t table_len = desc >> (SIMD_DATA_SHIFT + 6);
135
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm,
173
+ union {
136
float_status *fpst = vfpst;
174
+ uint8_t b[16];
137
intptr_t flip = extract32(desc, SIMD_DATA_SHIFT, 1);
175
+ uint64_t d[2];
138
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
176
+ } result;
139
+ intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
177
+
140
uint32_t neg_real = flip ^ neg_imag;
178
+ /*
141
uintptr_t i;
179
+ * We must construct the final result in a temp, lest the output
142
- float32 e1 = m[H4(flip)];
180
+ * overlaps the input table. For TBL, begin with zero; for TBX,
143
- float32 e3 = m[H4(1 - flip)];
181
+ * begin with the original register contents. Note that we always
144
+ float32 e1 = m[H4(2 * index + flip)];
182
+ * copy 16 bytes here to avoid an extra branch; clearing the high
145
+ float32 e3 = m[H4(2 * index + 1 - flip)];
183
+ * bits of the register for oprsz == 8 is handled below.
146
184
+ */
147
/* Shift boolean to the sign bit so we can xor to negate. */
185
+ if (is_tbx) {
148
neg_real <<= 31;
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)];
204
+ }
205
+ }
206
+
207
+ memcpy(vd, &result, 16);
208
+ clear_tail(vd, oprsz, simd_maxsz(desc));
209
+}
210
+#endif
149
--
211
--
150
2.17.1
212
2.20.1
151
213
152
214
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Use assert() instead of error_setg(&error_abort),
3
The STATUS register will be reset to IDLE in
4
as suggested by the "qapi/error.h" documentation:
4
cnpcm7xx_smbus_enter_reset(), no need to preset
5
5
it in instance_init().
6
Please don't error_setg(&error_fatal, ...), use error_report() and
7
exit(), because that's more obvious.
8
Likewise, don't error_setg(&error_abort, ...), use assert().
9
6
10
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Acked-by: John Snow <jsnow@redhat.com>
8
Reviewed-by: Hao Wu <wuhaotsh@google.com>
12
Message-id: 20180625165749.3910-2-f4bug@amsat.org
9
Message-id: 20210228224813.312532-1-f4bug@amsat.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
11
---
15
hw/block/fdc.c | 9 +--------
12
hw/i2c/npcm7xx_smbus.c | 1 -
16
1 file changed, 1 insertion(+), 8 deletions(-)
13
1 file changed, 1 deletion(-)
17
14
18
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
15
diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/block/fdc.c
17
--- a/hw/i2c/npcm7xx_smbus.c
21
+++ b/hw/block/fdc.c
18
+++ b/hw/i2c/npcm7xx_smbus.c
22
@@ -XXX,XX +XXX,XX @@ static int pick_geometry(FDrive *drv)
19
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_init(Object *obj)
23
nb_sectors,
20
sysbus_init_mmio(sbd, &s->iomem);
24
FloppyDriveType_str(parse->drive));
21
25
}
22
s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
26
+ assert(type_match != -1 && "misconfigured fd_format");
23
- s->status = NPCM7XX_SMBUS_STATUS_IDLE;
27
match = type_match;
24
}
28
}
25
29
-
26
static const VMStateDescription vmstate_npcm7xx_smbus = {
30
- /* No match of any kind found -- fd_format is misconfigured, abort. */
31
- if (match == -1) {
32
- error_setg(&error_abort, "No candidate geometries present in table "
33
- " for floppy drive type '%s'",
34
- FloppyDriveType_str(drv->drive));
35
- }
36
-
37
parse = &(fd_formats[match]);
38
39
out:
40
--
27
--
41
2.17.1
28
2.20.1
42
29
43
30
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: schspa <schspa@gmail.com>
2
2
3
When running dtc on the guest /proc/device-tree we get the
3
At the moment the following QEMU command line triggers an assertion
4
following warning: Warning (unit_address_vs_reg): Node /memory
4
failure On xlnx-versal SOC:
5
has a reg or ranges property, but no unit name".
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
Let's fix that by adding the unit address to the node name. We also
12
qemu-system-aarch64: ../migration/savevm.c:860:
8
don't create the /memory node anymore in create_fdt(). We directly
13
vmstate_register_with_alias_id:
9
create it in load_dtb. /chosen still needs to be created in create_fdt
14
Assertion `!se->compat || se->instance_id == 0' failed.
10
as the uart needs it. In case the user provided his own dtb, we nop
11
all memory nodes found in root and create new one(s).
12
15
13
Signed-off-by: Eric Auger <eric.auger@redhat.com>
16
This problem was fixed on arm virt platform in commit f58b39d2d5b
14
Message-id: 1530044492-24921-4-git-send-email-eric.auger@redhat.com
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>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
43
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
45
---
18
hw/arm/boot.c | 41 +++++++++++++++++++++++------------------
46
hw/virtio/virtio-mmio.c | 13 +++++++------
19
hw/arm/virt.c | 7 +------
47
1 file changed, 7 insertions(+), 6 deletions(-)
20
2 files changed, 24 insertions(+), 24 deletions(-)
21
48
22
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
49
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
23
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/arm/boot.c
51
--- a/hw/virtio/virtio-mmio.c
25
+++ b/hw/arm/boot.c
52
+++ b/hw/virtio/virtio-mmio.c
26
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
53
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
27
hwaddr addr_limit, AddressSpace *as)
54
BusState *virtio_mmio_bus;
28
{
55
VirtIOMMIOProxy *virtio_mmio_proxy;
29
void *fdt = NULL;
56
char *proxy_path;
30
- int size, rc;
57
- SysBusDevice *proxy_sbd;
31
+ int size, rc, n = 0;
58
char *path;
32
uint32_t acells, scells;
59
+ MemoryRegionSection section;
33
char *nodename;
60
34
unsigned int i;
61
virtio_mmio_bus = qdev_get_parent_bus(dev);
35
hwaddr mem_base, mem_len;
62
virtio_mmio_proxy = VIRTIO_MMIO(virtio_mmio_bus->parent);
36
+ char **node_path;
63
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
37
+ Error *err = NULL;
38
39
if (binfo->dtb_filename) {
40
char *filename;
41
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
42
goto fail;
43
}
64
}
44
65
45
+ /* nop all root nodes matching /memory or /memory@unit-address */
66
/* Otherwise, we append the base address of the transport. */
46
+ node_path = qemu_fdt_node_unit_path(fdt, "memory", &err);
67
- proxy_sbd = SYS_BUS_DEVICE(virtio_mmio_proxy);
47
+ if (err) {
68
- assert(proxy_sbd->num_mmio == 1);
48
+ error_report_err(err);
69
- assert(proxy_sbd->mmio[0].memory == &virtio_mmio_proxy->iomem);
49
+ goto fail;
70
+ section = memory_region_find(&virtio_mmio_proxy->iomem, 0, 0x200);
50
+ }
71
+ assert(section.mr);
51
+ while (node_path[n]) {
72
52
+ if (g_str_has_prefix(node_path[n], "/memory")) {
73
if (proxy_path) {
53
+ qemu_fdt_nop_node(fdt, node_path[n]);
74
path = g_strdup_printf("%s/virtio-mmio@" TARGET_FMT_plx, proxy_path,
54
+ }
75
- proxy_sbd->mmio[0].addr);
55
+ n++;
76
+ section.offset_within_address_space);
56
+ }
77
} else {
57
+ g_strfreev(node_path);
78
path = g_strdup_printf("virtio-mmio@" TARGET_FMT_plx,
79
- proxy_sbd->mmio[0].addr);
80
+ section.offset_within_address_space);
81
}
82
+ memory_region_unref(section.mr);
58
+
83
+
59
if (nb_numa_nodes > 0) {
84
g_free(proxy_path);
60
- /*
85
return path;
61
- * Turn the /memory node created before into a NOP node, then create
86
}
62
- * /memory@addr nodes for all numa nodes respectively.
63
- */
64
- qemu_fdt_nop_node(fdt, "/memory");
65
mem_base = binfo->loader_start;
66
for (i = 0; i < nb_numa_nodes; i++) {
67
mem_len = numa_info[i].node_mem;
68
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
69
g_free(nodename);
70
}
71
} else {
72
- Error *err = NULL;
73
+ nodename = g_strdup_printf("/memory@%" PRIx64, binfo->loader_start);
74
+ qemu_fdt_add_subnode(fdt, nodename);
75
+ qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
76
77
- rc = fdt_path_offset(fdt, "/memory");
78
- if (rc < 0) {
79
- qemu_fdt_add_subnode(fdt, "/memory");
80
- }
81
-
82
- if (!qemu_fdt_getprop(fdt, "/memory", "device_type", NULL, &err)) {
83
- qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
84
- }
85
-
86
- rc = qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg",
87
+ rc = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
88
acells, binfo->loader_start,
89
scells, binfo->ram_size);
90
if (rc < 0) {
91
- fprintf(stderr, "couldn't set /memory/reg\n");
92
+ fprintf(stderr, "couldn't set %s reg\n", nodename);
93
goto fail;
94
}
95
+ g_free(nodename);
96
}
97
98
rc = fdt_path_offset(fdt, "/chosen");
99
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/arm/virt.c
102
+++ b/hw/arm/virt.c
103
@@ -XXX,XX +XXX,XX @@ static void create_fdt(VirtMachineState *vms)
104
qemu_fdt_setprop_cell(fdt, "/", "#address-cells", 0x2);
105
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
106
107
- /*
108
- * /chosen and /memory nodes must exist for load_dtb
109
- * to fill in necessary properties later
110
- */
111
+ /* /chosen must exist for load_dtb to fill in necessary properties later */
112
qemu_fdt_add_subnode(fdt, "/chosen");
113
- qemu_fdt_add_subnode(fdt, "/memory");
114
- qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
115
116
/* Clock node, for the benefit of the UART. The kernel device tree
117
* binding documentation claims the PL011 node clock properties are
118
--
87
--
119
2.17.1
88
2.20.1
120
89
121
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
Since kernel commit a86bd139f2 (arm64: arch_timer: Enable CNTVCT_EL0
3
Section D6.7 of the ARM ARM states:
4
trap..), released in kernel version v4.12, user-space has been able
5
to read these system registers. As we can't use QEMUTimer's in
6
linux-user mode we just directly call cpu_get_clock().
7
4
8
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>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180625160009.17437-2-alex.bennee@linaro.org
24
Message-id: 20210219201820.2672077-1-pcc@google.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
27
---
14
target/arm/helper.c | 27 ++++++++++++++++++++++++---
28
target/arm/helper.c | 2 +-
15
1 file changed, 24 insertions(+), 3 deletions(-)
29
target/arm/mte_helper.c | 13 +++++++++----
30
2 files changed, 10 insertions(+), 5 deletions(-)
16
31
17
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
18
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
34
--- a/target/arm/helper.c
20
+++ b/target/arm/helper.c
35
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
36
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
22
};
37
if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
23
38
&& tbid
24
#else
39
&& !(env->pstate & PSTATE_TCO)
25
-/* In user-mode none of the generic timer registers are accessible,
40
- && (sctlr & SCTLR_TCF)
26
- * and their implementation depends on QEMU_CLOCK_VIRTUAL and qdev gpio outputs,
41
+ && (sctlr & SCTLR_TCF0)
27
- * so instead just don't register any of them.
42
&& allocation_tag_access_enabled(env, 0, sctlr)) {
28
+
43
flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
29
+/* In user-mode most of the generic timer registers are inaccessible
44
}
30
+ * however modern kernels (4.12+) allow access to cntvct_el0
45
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
31
*/
46
index XXXXXXX..XXXXXXX 100644
32
+
47
--- a/target/arm/mte_helper.c
33
+static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
48
+++ b/target/arm/mte_helper.c
34
+{
49
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
35
+ /* Currently we have no support for QEMUTimer in linux-user so we
50
reg_el = regime_el(env, arm_mmu_idx);
36
+ * can't call gt_get_countervalue(env), instead we directly
51
sctlr = env->cp15.sctlr_el[reg_el];
37
+ * call the lower level functions.
52
38
+ */
53
- el = arm_current_el(env);
39
+ return cpu_get_clock() / GTIMER_SCALE;
54
- if (el == 0) {
40
+}
55
+ switch (arm_mmu_idx) {
41
+
56
+ case ARMMMUIdx_E10_0:
42
static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
57
+ case ARMMMUIdx_E20_0:
43
+ { .name = "CNTFRQ_EL0", .state = ARM_CP_STATE_AA64,
58
+ el = 0;
44
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 0,
59
tcf = extract64(sctlr, 38, 2);
45
+ .type = ARM_CP_CONST, .access = PL0_R /* no PL1_RW in linux-user */,
60
- } else {
46
+ .fieldoffset = offsetof(CPUARMState, cp15.c14_cntfrq),
61
+ break;
47
+ .resetvalue = NANOSECONDS_PER_SECOND / GTIMER_SCALE,
62
+ default:
48
+ },
63
+ el = reg_el;
49
+ { .name = "CNTVCT_EL0", .state = ARM_CP_STATE_AA64,
64
tcf = extract64(sctlr, 40, 2);
50
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 2,
65
}
51
+ .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
66
52
+ .readfn = gt_virt_cnt_read,
67
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
53
+ },
68
env->exception.vaddress = dirty_ptr;
54
REGINFO_SENTINEL
69
55
};
70
is_write = FIELD_EX32(desc, MTEDESC, WRITE);
71
- syn = syn_data_abort_no_iss(el != 0, 0, 0, 0, 0, is_write, 0x11);
72
+ syn = syn_data_abort_no_iss(arm_current_el(env) != 0, 0, 0, 0, 0,
73
+ is_write, 0x11);
74
raise_exception(env, EXCP_DATA_ABORT, syn, exception_target_el(env));
75
/* noreturn, but fall through to the assert anyway */
56
76
57
--
77
--
58
2.17.1
78
2.20.1
59
79
60
80
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Enable ARM_FEATURE_SVE for the generic "max" cpu.
3
IDAU is specific to M-profile. KVM only supports A-profile.
4
Restrict this interface to TCG, as it is pointless (and
5
confusing) on a KVM-only build.
4
6
5
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20180627043328.11531-35-richard.henderson@linaro.org
10
Message-id: 20210221222617.2579610-2-f4bug@amsat.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
linux-user/elfload.c | 1 +
13
target/arm/cpu.c | 7 -------
12
target/arm/cpu.c | 7 +++++++
14
target/arm/cpu_tcg.c | 8 ++++++++
13
target/arm/cpu64.c | 1 +
15
2 files changed, 8 insertions(+), 7 deletions(-)
14
3 files changed, 9 insertions(+)
15
16
16
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/linux-user/elfload.c
19
+++ b/linux-user/elfload.c
20
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
21
GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS);
22
GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM);
23
GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA);
24
+ GET_FEATURE(ARM_FEATURE_SVE, ARM_HWCAP_A64_SVE);
25
#undef GET_FEATURE
26
27
return hwcaps;
28
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
29
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/cpu.c
19
--- a/target/arm/cpu.c
31
+++ b/target/arm/cpu.c
20
+++ b/target/arm/cpu.c
32
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
21
@@ -XXX,XX +XXX,XX @@ static const TypeInfo arm_cpu_type_info = {
33
env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
22
.class_init = arm_cpu_class_init,
34
/* and to the FP/Neon instructions */
23
};
35
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
24
36
+ /* and to the SVE instructions */
25
-static const TypeInfo idau_interface_type_info = {
37
+ env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
26
- .name = TYPE_IDAU_INTERFACE,
38
+ env->cp15.cptr_el[3] |= CPTR_EZ;
27
- .parent = TYPE_INTERFACE,
39
+ /* with maximum vector length */
28
- .class_size = sizeof(IDAUInterfaceClass),
40
+ env->vfp.zcr_el[1] = ARM_MAX_VQ - 1;
29
-};
41
+ env->vfp.zcr_el[2] = ARM_MAX_VQ - 1;
30
-
42
+ env->vfp.zcr_el[3] = ARM_MAX_VQ - 1;
31
static void arm_cpu_register_types(void)
43
#else
32
{
44
/* Reset into the highest available EL */
33
const size_t cpu_count = ARRAY_SIZE(arm_cpus);
45
if (arm_feature(env, ARM_FEATURE_EL3)) {
34
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_register_types(void)
46
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
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
47
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/cpu64.c
44
--- a/target/arm/cpu_tcg.c
49
+++ b/target/arm/cpu64.c
45
+++ b/target/arm/cpu_tcg.c
50
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
46
@@ -XXX,XX +XXX,XX @@
51
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
47
#include "hw/core/tcg-cpu-ops.h"
52
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
48
#endif /* CONFIG_TCG */
53
set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
49
#include "internals.h"
54
+ set_feature(&cpu->env, ARM_FEATURE_SVE);
50
+#include "target/arm/idau.h"
55
/* For usermode -cpu max we can use a larger and more efficient DCZ
51
56
* blocksize since we don't have to follow what the hardware does.
52
/* CPU models. These are not needed for the AArch64 linux-user build. */
57
*/
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]);
71
}
58
--
72
--
59
2.17.1
73
2.20.1
60
74
61
75
diff view generated by jsdifflib
1
From: Aaron Lindsay <alindsay@codeaurora.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
3
We will move this code in the next commit. Clean it up
4
Message-id: 1529699547-17044-5-git-send-email-alindsay@codeaurora.org
4
first to avoid checkpatch.pl errors.
5
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210221222617.2579610-3-f4bug@amsat.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
---
10
---
7
target/arm/cpu.h | 1 +
11
target/arm/cpu.c | 12 ++++++++----
8
target/arm/cpu.c | 21 ++++++++++++++-------
12
1 file changed, 8 insertions(+), 4 deletions(-)
9
target/arm/kvm32.c | 8 ++++----
10
3 files changed, 19 insertions(+), 11 deletions(-)
11
13
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
15
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ enum arm_features {
17
ARM_FEATURE_OMAPCP, /* OMAP specific CP15 ops handling. */
18
ARM_FEATURE_THUMB2EE,
19
ARM_FEATURE_V7MP, /* v7 Multiprocessing Extensions */
20
+ ARM_FEATURE_V7VE, /* v7 Virtualization Extensions (non-EL2 parts) */
21
ARM_FEATURE_V4T,
22
ARM_FEATURE_V5,
23
ARM_FEATURE_STRONGARM,
24
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/cpu.c
16
--- a/target/arm/cpu.c
27
+++ b/target/arm/cpu.c
17
+++ b/target/arm/cpu.c
28
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
29
19
}
30
/* Some features automatically imply others: */
20
31
if (arm_feature(env, ARM_FEATURE_V8)) {
21
static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
32
- set_feature(env, ARM_FEATURE_V7);
22
- /* power_control should be set to maximum latency. Again,
33
+ set_feature(env, ARM_FEATURE_V7VE);
23
+ /*
34
+ }
24
+ * power_control should be set to maximum latency. Again,
35
+ if (arm_feature(env, ARM_FEATURE_V7VE)) {
25
* default to 0 and set by private hook
36
+ /* v7 Virtualization Extensions. In real hardware this implies
26
*/
37
+ * EL2 and also the presence of the Security Extensions.
27
{ .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
38
+ * For QEMU, for backwards-compatibility we implement some
28
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
39
+ * CPUs or CPU configs which have no actual EL2 or EL3 but do
40
+ * include the various other features that V7VE implies.
41
+ * Presence of EL2 itself is ARM_FEATURE_EL2, and of the
42
+ * Security Extensions is ARM_FEATURE_EL3.
43
+ */
44
set_feature(env, ARM_FEATURE_ARM_DIV);
45
set_feature(env, ARM_FEATURE_LPAE);
46
+ set_feature(env, ARM_FEATURE_V7);
47
}
48
if (arm_feature(env, ARM_FEATURE_V7)) {
49
set_feature(env, ARM_FEATURE_VAPA);
50
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
51
ARMCPU *cpu = ARM_CPU(obj);
52
53
cpu->dtb_compatible = "arm,cortex-a7";
54
- set_feature(&cpu->env, ARM_FEATURE_V7);
55
+ set_feature(&cpu->env, ARM_FEATURE_V7VE);
56
set_feature(&cpu->env, ARM_FEATURE_VFP4);
57
set_feature(&cpu->env, ARM_FEATURE_NEON);
29
set_feature(&cpu->env, ARM_FEATURE_NEON);
58
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
30
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
59
- set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
60
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
61
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
62
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
63
- set_feature(&cpu->env, ARM_FEATURE_LPAE);
64
set_feature(&cpu->env, ARM_FEATURE_EL3);
31
set_feature(&cpu->env, ARM_FEATURE_EL3);
65
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A7;
32
- /* Note that A9 supports the MP extensions even for
66
cpu->midr = 0x410fc075;
33
+ /*
67
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
34
+ * Note that A9 supports the MP extensions even for
68
ARMCPU *cpu = ARM_CPU(obj);
35
* A9UP and single-core A9MP (which are both different
69
36
* and valid configurations; we don't model A9UP).
70
cpu->dtb_compatible = "arm,cortex-a15";
71
- set_feature(&cpu->env, ARM_FEATURE_V7);
72
+ set_feature(&cpu->env, ARM_FEATURE_V7VE);
73
set_feature(&cpu->env, ARM_FEATURE_VFP4);
74
set_feature(&cpu->env, ARM_FEATURE_NEON);
75
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
76
- set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
77
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
78
set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
79
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
80
- set_feature(&cpu->env, ARM_FEATURE_LPAE);
81
set_feature(&cpu->env, ARM_FEATURE_EL3);
82
cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
83
cpu->midr = 0x412fc0f1;
84
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/kvm32.c
87
+++ b/target/arm/kvm32.c
88
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
89
/* Now we've retrieved all the register information we can
90
* set the feature bits based on the ID register fields.
91
* We can assume any KVM supporting CPU is at least a v7
92
- * with VFPv3, LPAE and the generic timers; this in turn implies
93
- * most of the other feature bits, but a few must be tested.
94
+ * with VFPv3, virtualization extensions, and the generic
95
+ * timers; this in turn implies most of the other feature
96
+ * bits, but a few must be tested.
97
*/
37
*/
98
- set_feature(&features, ARM_FEATURE_V7);
38
@@ -XXX,XX +XXX,XX @@ static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
99
+ set_feature(&features, ARM_FEATURE_V7VE);
39
{
100
set_feature(&features, ARM_FEATURE_VFP3);
40
MachineState *ms = MACHINE(qdev_get_machine());
101
- set_feature(&features, ARM_FEATURE_LPAE);
41
102
set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
42
- /* Linux wants the number of processors from here.
103
43
+ /*
104
switch (extract32(id_isar0, 24, 4)) {
44
+ * Linux wants the number of processors from here.
45
* Might as well set the interrupt-controller bit too.
46
*/
47
return ((ms->smp.cpus - 1) << 24) | (1 << 23);
48
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
49
cpu->isar.id_mmfr1 = 0x40000000;
50
cpu->isar.id_mmfr2 = 0x01240000;
51
cpu->isar.id_mmfr3 = 0x02102211;
52
- /* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
53
+ /*
54
+ * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
55
* table 4-41 gives 0x02101110, which includes the arm div insns.
56
*/
57
cpu->isar.id_isar0 = 0x02101110;
105
--
58
--
106
2.17.1
59
2.20.1
107
60
108
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Enhance the existing helpers to support SVE, which takes the
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
index from each 128-bit segment. The change has no effect
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
for AdvSIMD, since there is only one such segment.
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(-)
6
12
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20180627043328.11531-32-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/translate-sve.c | 23 ++++++++++++++++++
14
target/arm/vec_helper.c | 50 +++++++++++++++++++++++---------------
15
target/arm/sve.decode | 6 +++++
16
3 files changed, 59 insertions(+), 20 deletions(-)
17
18
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-sve.c
15
--- a/hw/arm/musicpal.c
21
+++ b/target/arm/translate-sve.c
16
+++ b/hw/arm/musicpal.c
22
@@ -XXX,XX +XXX,XX @@ static bool trans_FCMLA_zpzzz(DisasContext *s,
17
@@ -XXX,XX +XXX,XX @@ static uint8_t scale_lcd_color(musicpal_lcd_state *s, uint8_t col)
23
return true;
18
}
24
}
19
}
25
20
26
+static bool trans_FCMLA_zzxz(DisasContext *s, arg_FCMLA_zzxz *a, uint32_t insn)
21
-#define SET_LCD_PIXEL(depth, type) \
22
-static inline void glue(set_lcd_pixel, depth) \
23
- (musicpal_lcd_state *s, int x, int y, type col) \
24
-{ \
25
- int dx, dy; \
26
- DisplaySurface *surface = qemu_console_surface(s->con); \
27
- type *pixel = &((type *) surface_data(surface))[(y * 128 * 3 + x) * 3]; \
28
-\
29
- for (dy = 0; dy < 3; dy++, pixel += 127 * 3) \
30
- for (dx = 0; dx < 3; dx++, pixel++) \
31
- *pixel = col; \
32
+static inline void set_lcd_pixel32(musicpal_lcd_state *s,
33
+ int x, int y, uint32_t col)
27
+{
34
+{
28
+ static gen_helper_gvec_3_ptr * const fns[2] = {
35
+ int dx, dy;
29
+ gen_helper_gvec_fcmlah_idx,
36
+ DisplaySurface *surface = qemu_console_surface(s->con);
30
+ gen_helper_gvec_fcmlas_idx,
37
+ uint32_t *pixel =
31
+ };
38
+ &((uint32_t *) surface_data(surface))[(y * 128 * 3 + x) * 3];
32
+
39
+
33
+ tcg_debug_assert(a->esz == 1 || a->esz == 2);
40
+ for (dy = 0; dy < 3; dy++, pixel += 127 * 3) {
34
+ tcg_debug_assert(a->rd == a->ra);
41
+ for (dx = 0; dx < 3; dx++, pixel++) {
35
+ if (sve_access_check(s)) {
42
+ *pixel = col;
36
+ unsigned vsz = vec_full_reg_size(s);
43
+ }
37
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
38
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
39
+ vec_full_reg_offset(s, a->rn),
40
+ vec_full_reg_offset(s, a->rm),
41
+ status, vsz, vsz,
42
+ a->index * 4 + a->rot,
43
+ fns[a->esz - 1]);
44
+ tcg_temp_free_ptr(status);
45
+ }
44
+ }
46
+ return true;
45
}
47
+}
46
-SET_LCD_PIXEL(8, uint8_t)
48
+
47
-SET_LCD_PIXEL(16, uint16_t)
49
/*
48
-SET_LCD_PIXEL(32, uint32_t)
50
*** SVE Floating Point Unary Operations Predicated Group
49
51
*/
50
static void lcd_refresh(void *opaque)
52
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
51
{
53
index XXXXXXX..XXXXXXX 100644
52
musicpal_lcd_state *s = opaque;
54
--- a/target/arm/vec_helper.c
53
- DisplaySurface *surface = qemu_console_surface(s->con);
55
+++ b/target/arm/vec_helper.c
54
int x, y, col;
56
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlah_idx)(void *vd, void *vn, void *vm,
55
57
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
56
- switch (surface_bits_per_pixel(surface)) {
58
intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
57
- case 0:
59
uint32_t neg_real = flip ^ neg_imag;
58
- return;
60
- uintptr_t i;
59
-#define LCD_REFRESH(depth, func) \
61
- float16 e1 = m[H2(2 * index + flip)];
60
- case depth: \
62
- float16 e3 = m[H2(2 * index + 1 - flip)];
61
- col = func(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff), \
63
+ intptr_t elements = opr_sz / sizeof(float16);
62
- scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff), \
64
+ intptr_t eltspersegment = 16 / sizeof(float16);
63
- scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff)); \
65
+ intptr_t i, j;
64
- for (x = 0; x < 128; x++) { \
66
65
- for (y = 0; y < 64; y++) { \
67
/* Shift boolean to the sign bit so we can xor to negate. */
66
- if (s->video_ram[x + (y/8)*128] & (1 << (y % 8))) { \
68
neg_real <<= 15;
67
- glue(set_lcd_pixel, depth)(s, x, y, col); \
69
neg_imag <<= 15;
68
- } else { \
70
- e1 ^= neg_real;
69
- glue(set_lcd_pixel, depth)(s, x, y, 0); \
71
- e3 ^= neg_imag;
70
- } \
72
71
- } \
73
- for (i = 0; i < opr_sz / 2; i += 2) {
72
- } \
74
- float16 e2 = n[H2(i + flip)];
73
- break;
75
- float16 e4 = e2;
74
- LCD_REFRESH(8, rgb_to_pixel8)
76
+ for (i = 0; i < elements; i += eltspersegment) {
75
- LCD_REFRESH(16, rgb_to_pixel16)
77
+ float16 mr = m[H2(i + 2 * index + 0)];
76
- LCD_REFRESH(32, (is_surface_bgr(surface) ?
78
+ float16 mi = m[H2(i + 2 * index + 1)];
77
- rgb_to_pixel32bgr : rgb_to_pixel32))
79
+ float16 e1 = neg_real ^ (flip ? mi : mr);
78
- default:
80
+ float16 e3 = neg_imag ^ (flip ? mr : mi);
79
- hw_error("unsupported colour depth %i\n",
81
80
- surface_bits_per_pixel(surface));
82
- d[H2(i)] = float16_muladd(e2, e1, d[H2(i)], 0, fpst);
81
+ col = rgb_to_pixel32(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff),
83
- d[H2(i + 1)] = float16_muladd(e4, e3, d[H2(i + 1)], 0, fpst);
82
+ scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff),
84
+ for (j = i; j < i + eltspersegment; j += 2) {
83
+ scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff));
85
+ float16 e2 = n[H2(j + flip)];
84
+ for (x = 0; x < 128; x++) {
86
+ float16 e4 = e2;
85
+ for (y = 0; y < 64; y++) {
87
+
86
+ if (s->video_ram[x + (y / 8) * 128] & (1 << (y % 8))) {
88
+ d[H2(j)] = float16_muladd(e2, e1, d[H2(j)], 0, fpst);
87
+ set_lcd_pixel32(s, x, y, col);
89
+ d[H2(j + 1)] = float16_muladd(e4, e3, d[H2(j + 1)], 0, fpst);
88
+ } else {
89
+ set_lcd_pixel32(s, x, y, 0);
90
+ }
90
+ }
91
+ }
91
}
92
}
92
clear_tail(d, opr_sz, simd_maxsz(desc));
93
93
}
94
dpy_gfx_update(s->con, 0, 0, 128*3, 64*3);
94
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlas_idx)(void *vd, void *vn, void *vm,
95
uint32_t neg_imag = extract32(desc, SIMD_DATA_SHIFT + 1, 1);
96
intptr_t index = extract32(desc, SIMD_DATA_SHIFT + 2, 2);
97
uint32_t neg_real = flip ^ neg_imag;
98
- uintptr_t i;
99
- float32 e1 = m[H4(2 * index + flip)];
100
- float32 e3 = m[H4(2 * index + 1 - flip)];
101
+ intptr_t elements = opr_sz / sizeof(float32);
102
+ intptr_t eltspersegment = 16 / sizeof(float32);
103
+ intptr_t i, j;
104
105
/* Shift boolean to the sign bit so we can xor to negate. */
106
neg_real <<= 31;
107
neg_imag <<= 31;
108
- e1 ^= neg_real;
109
- e3 ^= neg_imag;
110
111
- for (i = 0; i < opr_sz / 4; i += 2) {
112
- float32 e2 = n[H4(i + flip)];
113
- float32 e4 = e2;
114
+ for (i = 0; i < elements; i += eltspersegment) {
115
+ float32 mr = m[H4(i + 2 * index + 0)];
116
+ float32 mi = m[H4(i + 2 * index + 1)];
117
+ float32 e1 = neg_real ^ (flip ? mi : mr);
118
+ float32 e3 = neg_imag ^ (flip ? mr : mi);
119
120
- d[H4(i)] = float32_muladd(e2, e1, d[H4(i)], 0, fpst);
121
- d[H4(i + 1)] = float32_muladd(e4, e3, d[H4(i + 1)], 0, fpst);
122
+ for (j = i; j < i + eltspersegment; j += 2) {
123
+ float32 e2 = n[H4(j + flip)];
124
+ float32 e4 = e2;
125
+
126
+ d[H4(j)] = float32_muladd(e2, e1, d[H4(j)], 0, fpst);
127
+ d[H4(j + 1)] = float32_muladd(e4, e3, d[H4(j + 1)], 0, fpst);
128
+ }
129
}
130
clear_tail(d, opr_sz, simd_maxsz(desc));
131
}
132
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
133
index XXXXXXX..XXXXXXX 100644
134
--- a/target/arm/sve.decode
135
+++ b/target/arm/sve.decode
136
@@ -XXX,XX +XXX,XX @@ FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
137
FCMLA_zpzzz 01100100 esz:2 0 rm:5 0 rot:2 pg:3 rn:5 rd:5 \
138
ra=%reg_movprfx
139
140
+# SVE floating-point complex multiply-add (indexed)
141
+FCMLA_zzxz 01100100 10 1 index:2 rm:3 0001 rot:2 rn:5 rd:5 \
142
+ ra=%reg_movprfx esz=1
143
+FCMLA_zzxz 01100100 11 1 index:1 rm:4 0001 rot:2 rn:5 rd:5 \
144
+ ra=%reg_movprfx esz=2
145
+
146
### SVE FP Multiply-Add Indexed Group
147
148
# SVE floating-point multiply-add (indexed)
149
--
95
--
150
2.17.1
96
2.20.1
151
97
152
98
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-28-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215103215.4944-3-peter.maydell@linaro.org
7
---
9
---
8
target/arm/translate-sve.c | 60 +++++++++++++++++++++++++++++++++++++-
10
include/ui/console.h | 10 ----------
9
target/arm/sve.decode | 7 +++++
11
hw/display/tc6393xb.c | 33 +--------------------------------
10
2 files changed, 66 insertions(+), 1 deletion(-)
12
2 files changed, 1 insertion(+), 42 deletions(-)
11
13
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
14
diff --git a/include/ui/console.h b/include/ui/console.h
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
16
--- a/include/ui/console.h
15
+++ b/target/arm/translate-sve.c
17
+++ b/include/ui/console.h
16
@@ -XXX,XX +XXX,XX @@ static bool do_zpzz_ool(DisasContext *s, arg_rprr_esz *a, gen_helper_gvec_4 *fn)
18
@@ -XXX,XX +XXX,XX @@ PixelFormat qemu_default_pixelformat(int bpp);
17
return true;
19
DisplaySurface *qemu_create_displaysurface(int width, int height);
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)
33
{
34
return !(surface->flags & QEMU_ALLOCATED_FLAG);
35
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/display/tc6393xb.c
38
+++ b/hw/display/tc6393xb.c
39
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
40
(uint32_t) addr, value & 0xff);
18
}
41
}
19
42
20
+/* Select active elememnts from Zn and inactive elements from Zm,
43
-#define BITS 8
21
+ * storing the result in Zd.
44
-#include "tc6393xb_template.h"
22
+ */
45
-#define BITS 15
23
+static void do_sel_z(DisasContext *s, int rd, int rn, int rm, int pg, int esz)
46
-#include "tc6393xb_template.h"
24
+{
47
-#define BITS 16
25
+ static gen_helper_gvec_4 * const fns[4] = {
48
-#include "tc6393xb_template.h"
26
+ gen_helper_sve_sel_zpzz_b, gen_helper_sve_sel_zpzz_h,
49
-#define BITS 24
27
+ gen_helper_sve_sel_zpzz_s, gen_helper_sve_sel_zpzz_d
50
-#include "tc6393xb_template.h"
28
+ };
51
#define BITS 32
29
+ unsigned vsz = vec_full_reg_size(s);
52
#include "tc6393xb_template.h"
30
+ tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
53
31
+ vec_full_reg_offset(s, rn),
54
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
32
+ vec_full_reg_offset(s, rm),
55
{
33
+ pred_full_reg_offset(s, pg),
56
- DisplaySurface *surface = qemu_console_surface(s->con);
34
+ vsz, vsz, 0, fns[esz]);
57
-
35
+}
58
- switch (surface_bits_per_pixel(surface)) {
36
+
59
- case 8:
37
#define DO_ZPZZ(NAME, name) \
60
- tc6393xb_draw_graphic8(s);
38
static bool trans_##NAME##_zpzz(DisasContext *s, arg_rprr_esz *a, \
61
- break;
39
uint32_t insn) \
62
- case 15:
40
@@ -XXX,XX +XXX,XX @@ static bool trans_UDIV_zpzz(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
63
- tc6393xb_draw_graphic15(s);
41
return do_zpzz_ool(s, a, fns[a->esz]);
64
- break;
65
- case 16:
66
- tc6393xb_draw_graphic16(s);
67
- break;
68
- case 24:
69
- tc6393xb_draw_graphic24(s);
70
- break;
71
- case 32:
72
- tc6393xb_draw_graphic32(s);
73
- break;
74
- default:
75
- printf("tc6393xb: unknown depth %d\n",
76
- surface_bits_per_pixel(surface));
77
- return;
78
- }
79
-
80
+ tc6393xb_draw_graphic32(s);
81
dpy_gfx_update_full(s->con);
42
}
82
}
43
83
44
-DO_ZPZZ(SEL, sel)
45
+static bool trans_SEL_zpzz(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
46
+{
47
+ if (sve_access_check(s)) {
48
+ do_sel_z(s, a->rd, a->rn, a->rm, a->pg, a->esz);
49
+ }
50
+ return true;
51
+}
52
53
#undef DO_ZPZZ
54
55
@@ -XXX,XX +XXX,XX @@ static bool trans_PRF_rr(DisasContext *s, arg_PRF_rr *a, uint32_t insn)
56
sve_access_check(s);
57
return true;
58
}
59
+
60
+/*
61
+ * Move Prefix
62
+ *
63
+ * TODO: The implementation so far could handle predicated merging movprfx.
64
+ * The helper functions as written take an extra source register to
65
+ * use in the operation, but the result is only written when predication
66
+ * succeeds. For unpredicated movprfx, we need to rearrange the helpers
67
+ * to allow the final write back to the destination to be unconditional.
68
+ * For predicated zeroing movprfx, we need to rearrange the helpers to
69
+ * allow the final write back to zero inactives.
70
+ *
71
+ * In the meantime, just emit the moves.
72
+ */
73
+
74
+static bool trans_MOVPRFX(DisasContext *s, arg_MOVPRFX *a, uint32_t insn)
75
+{
76
+ return do_mov_z(s, a->rd, a->rn);
77
+}
78
+
79
+static bool trans_MOVPRFX_m(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
80
+{
81
+ if (sve_access_check(s)) {
82
+ do_sel_z(s, a->rd, a->rn, a->rd, a->pg, a->esz);
83
+ }
84
+ return true;
85
+}
86
+
87
+static bool trans_MOVPRFX_z(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
88
+{
89
+ if (sve_access_check(s)) {
90
+ do_movz_zpz(s, a->rd, a->rn, a->pg, a->esz);
91
+ }
92
+ return true;
93
+}
94
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
95
index XXXXXXX..XXXXXXX 100644
96
--- a/target/arm/sve.decode
97
+++ b/target/arm/sve.decode
98
@@ -XXX,XX +XXX,XX @@ ORV 00000100 .. 011 000 001 ... ..... ..... @rd_pg_rn
99
EORV 00000100 .. 011 001 001 ... ..... ..... @rd_pg_rn
100
ANDV 00000100 .. 011 010 001 ... ..... ..... @rd_pg_rn
101
102
+# SVE constructive prefix (predicated)
103
+MOVPRFX_z 00000100 .. 010 000 001 ... ..... ..... @rd_pg_rn
104
+MOVPRFX_m 00000100 .. 010 001 001 ... ..... ..... @rd_pg_rn
105
+
106
# SVE integer add reduction (predicated)
107
# Note that saddv requires size != 3.
108
UADDV 00000100 .. 000 001 001 ... ..... ..... @rd_pg_rn
109
@@ -XXX,XX +XXX,XX @@ ADR_p64 00000100 11 1 ..... 1010 .. ..... ..... @rd_rn_msz_rm
110
111
### SVE Integer Misc - Unpredicated Group
112
113
+# SVE constructive prefix (unpredicated)
114
+MOVPRFX 00000100 00 1 00000 101111 rn:5 rd:5
115
+
116
# SVE floating-point exponential accelerator
117
# Note esz != 0
118
FEXPA 00000100 .. 1 00000 101110 ..... ..... @rd_rn
119
--
84
--
120
2.17.1
85
2.20.1
121
86
122
87
diff view generated by jsdifflib
1
From: Aaron Lindsay <alindsay@codeaurora.org>
1
Now the template header is included only for BITS==32, expand
2
out all the macros that depended on the BITS setting.
2
3
3
This makes it match its AArch64 equivalent, PMINTENSET_EL1
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(-)
4
10
5
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
11
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
6
Message-id: 1529699547-17044-13-git-send-email-alindsay@codeaurora.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/helper.c | 2 +-
10
1 file changed, 1 insertion(+), 1 deletion(-)
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
13
--- a/hw/display/tc6393xb_template.h
15
+++ b/target/arm/helper.c
14
+++ b/hw/display/tc6393xb_template.h
16
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
15
@@ -XXX,XX +XXX,XX @@
17
.writefn = pmuserenr_write, .raw_writefn = raw_write },
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
18
{ .name = "PMINTENSET", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 1,
17
*/
19
.access = PL1_RW, .accessfn = access_tpm,
18
20
- .type = ARM_CP_ALIAS,
19
-#if BITS == 8
21
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
20
-# define SET_PIXEL(addr, color) (*(uint8_t *)addr = color)
22
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pminten),
21
-#elif BITS == 15 || BITS == 16
23
.resetvalue = 0,
22
-# define SET_PIXEL(addr, color) (*(uint16_t *)addr = color)
24
.writefn = pmintenset_write, .raw_writefn = raw_write },
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
25
--
70
--
26
2.17.1
71
2.20.1
27
72
28
73
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
The code move includes a single added space after 'for' to fix
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
the coding style.
5
Message-id: 20180627043328.11531-11-richard.henderson@linaro.org
7
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20210215103215.4944-5-peter.maydell@linaro.org
7
---
12
---
8
target/arm/translate-sve.c | 103 +++++++++++++++++++++++++++++++++++++
13
hw/display/tc6393xb_template.h | 45 ----------------------------------
9
target/arm/sve.decode | 6 +++
14
hw/display/tc6393xb.c | 23 ++++++++++++++---
10
2 files changed, 109 insertions(+)
15
2 files changed, 19 insertions(+), 49 deletions(-)
16
delete mode 100644 hw/display/tc6393xb_template.h
11
17
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.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
13
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
71
--- a/hw/display/tc6393xb.c
15
+++ b/target/arm/translate-sve.c
72
+++ b/hw/display/tc6393xb.c
16
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, uint32_t len,
73
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
17
tcg_temp_free_i64(t0);
74
(uint32_t) addr, value & 0xff);
18
}
75
}
19
76
20
+/* Similarly for stores. */
77
-#define BITS 32
21
+static void do_str(DisasContext *s, uint32_t vofs, uint32_t len,
78
-#include "tc6393xb_template.h"
22
+ int rn, int imm)
79
-
23
+{
80
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
24
+ uint32_t len_align = QEMU_ALIGN_DOWN(len, 8);
81
{
25
+ uint32_t len_remain = len % 8;
82
- tc6393xb_draw_graphic32(s);
26
+ uint32_t nparts = len / 8 + ctpop8(len_remain);
83
+ DisplaySurface *surface = qemu_console_surface(s->con);
27
+ int midx = get_mem_index(s);
84
+ int i;
28
+ TCGv_i64 addr, t0;
85
+ uint16_t *data_buffer;
86
+ uint8_t *data_display;
29
+
87
+
30
+ addr = tcg_temp_new_i64();
88
+ data_buffer = s->vram_ptr;
31
+ t0 = tcg_temp_new_i64();
89
+ data_display = surface_data(surface);
32
+
90
+ for (i = 0; i < s->scr_height; i++) {
33
+ /* Note that unpredicated load/store of vector/predicate registers
91
+ int j;
34
+ * are defined as a stream of bytes, which equates to little-endian
92
+ for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
35
+ * operations on larger quantities. There is no nice way to force
93
+ uint16_t color = *data_buffer;
36
+ * a little-endian store for aarch64_be-linux-user out of line.
94
+ uint32_t dest_color = rgb_to_pixel32(
37
+ *
95
+ ((color & 0xf800) * 0x108) >> 11,
38
+ * Attempt to keep code expansion to a minimum by limiting the
96
+ ((color & 0x7e0) * 0x41) >> 9,
39
+ * amount of unrolling done.
97
+ ((color & 0x1f) * 0x21) >> 2
40
+ */
98
+ );
41
+ if (nparts <= 4) {
99
+ *(uint32_t *)data_display = dest_color;
42
+ int i;
43
+
44
+ for (i = 0; i < len_align; i += 8) {
45
+ tcg_gen_ld_i64(t0, cpu_env, vofs + i);
46
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, rn), imm + i);
47
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEQ);
48
+ }
49
+ } else {
50
+ TCGLabel *loop = gen_new_label();
51
+ TCGv_ptr t2, i = tcg_const_local_ptr(0);
52
+
53
+ gen_set_label(loop);
54
+
55
+ t2 = tcg_temp_new_ptr();
56
+ tcg_gen_add_ptr(t2, cpu_env, i);
57
+ tcg_gen_ld_i64(t0, t2, vofs);
58
+
59
+ /* Minimize the number of local temps that must be re-read from
60
+ * the stack each iteration. Instead, re-compute values other
61
+ * than the loop counter.
62
+ */
63
+ tcg_gen_addi_ptr(t2, i, imm);
64
+ tcg_gen_extu_ptr_i64(addr, t2);
65
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, rn));
66
+ tcg_temp_free_ptr(t2);
67
+
68
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEQ);
69
+
70
+ tcg_gen_addi_ptr(i, i, 8);
71
+
72
+ tcg_gen_brcondi_ptr(TCG_COND_LTU, i, len_align, loop);
73
+ tcg_temp_free_ptr(i);
74
+ }
75
+
76
+ /* Predicate register stores can be any multiple of 2. */
77
+ if (len_remain) {
78
+ tcg_gen_ld_i64(t0, cpu_env, vofs + len_align);
79
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, rn), imm + len_align);
80
+
81
+ switch (len_remain) {
82
+ case 2:
83
+ case 4:
84
+ case 8:
85
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LE | ctz32(len_remain));
86
+ break;
87
+
88
+ case 6:
89
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEUL);
90
+ tcg_gen_addi_i64(addr, addr, 4);
91
+ tcg_gen_shri_i64(t0, t0, 32);
92
+ tcg_gen_qemu_st_i64(t0, addr, midx, MO_LEUW);
93
+ break;
94
+
95
+ default:
96
+ g_assert_not_reached();
97
+ }
100
+ }
98
+ }
101
+ }
99
+ tcg_temp_free_i64(addr);
102
dpy_gfx_update_full(s->con);
100
+ tcg_temp_free_i64(t0);
101
+}
102
+
103
static bool trans_LDR_zri(DisasContext *s, arg_rri *a, uint32_t insn)
104
{
105
if (sve_access_check(s)) {
106
@@ -XXX,XX +XXX,XX @@ static bool trans_LDR_pri(DisasContext *s, arg_rri *a, uint32_t insn)
107
return true;
108
}
103
}
109
104
110
+static bool trans_STR_zri(DisasContext *s, arg_rri *a, uint32_t insn)
111
+{
112
+ if (sve_access_check(s)) {
113
+ int size = vec_full_reg_size(s);
114
+ int off = vec_full_reg_offset(s, a->rd);
115
+ do_str(s, off, size, a->rn, a->imm * size);
116
+ }
117
+ return true;
118
+}
119
+
120
+static bool trans_STR_pri(DisasContext *s, arg_rri *a, uint32_t insn)
121
+{
122
+ if (sve_access_check(s)) {
123
+ int size = pred_full_reg_size(s);
124
+ int off = pred_full_reg_offset(s, a->rd);
125
+ do_str(s, off, size, a->rn, a->imm * size);
126
+ }
127
+ return true;
128
+}
129
+
130
/*
131
*** SVE Memory - Contiguous Load Group
132
*/
133
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
134
index XXXXXXX..XXXXXXX 100644
135
--- a/target/arm/sve.decode
136
+++ b/target/arm/sve.decode
137
@@ -XXX,XX +XXX,XX @@ LD1RQ_zpri 1010010 .. 00 0.... 001 ... ..... ..... \
138
139
### SVE Memory Store Group
140
141
+# SVE store predicate register
142
+STR_pri 1110010 11 0. ..... 000 ... ..... 0 .... @pd_rn_i9
143
+
144
+# SVE store vector register
145
+STR_zri 1110010 11 0. ..... 010 ... ..... ..... @rd_rn_i9
146
+
147
# SVE contiguous store (scalar plus immediate)
148
# ST1B, ST1H, ST1W, ST1D; require msz <= esz
149
ST_zpri 1110010 .. esz:2 0.... 111 ... ..... ..... \
150
--
105
--
151
2.17.1
106
2.20.1
152
107
153
108
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-7-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210215103215.4944-6-peter.maydell@linaro.org
7
---
9
---
8
target/arm/helper-sve.h | 77 +++++++++++++++++++++++++++++++++
10
hw/display/omap_lcd_template.h | 67 ++++++++++++++--------------------
9
target/arm/sve_helper.c | 89 ++++++++++++++++++++++++++++++++++++++
11
1 file changed, 28 insertions(+), 39 deletions(-)
10
target/arm/translate-sve.c | 46 ++++++++++++++++++++
11
target/arm/sve.decode | 17 ++++++++
12
4 files changed, 229 insertions(+)
13
12
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
13
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
15
--- a/hw/display/omap_lcd_template.h
17
+++ b/target/arm/helper-sve.h
16
+++ b/hw/display/omap_lcd_template.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
17
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
18
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20
void, ptr, ptr, ptr, ptr, i32)
19
*/
21
20
22
+DEF_HELPER_FLAGS_6(sve_fadd_h, TCG_CALL_NO_RWG,
21
-#if DEPTH == 32
23
+ void, ptr, ptr, ptr, ptr, ptr, i32)
22
-# define BPP 4
24
+DEF_HELPER_FLAGS_6(sve_fadd_s, TCG_CALL_NO_RWG,
23
-# define PIXEL_TYPE uint32_t
25
+ void, ptr, ptr, ptr, ptr, ptr, i32)
24
-#else
26
+DEF_HELPER_FLAGS_6(sve_fadd_d, TCG_CALL_NO_RWG,
25
-# error unsupport depth
27
+ void, ptr, ptr, ptr, ptr, ptr, i32)
26
-#endif
28
+
27
-
29
+DEF_HELPER_FLAGS_6(sve_fsub_h, TCG_CALL_NO_RWG,
28
/*
30
+ void, ptr, ptr, ptr, ptr, ptr, i32)
29
* 2-bit colour
31
+DEF_HELPER_FLAGS_6(sve_fsub_s, TCG_CALL_NO_RWG,
30
*/
32
+ void, ptr, ptr, ptr, ptr, ptr, i32)
31
-static void glue(draw_line2_, DEPTH)(void *opaque,
33
+DEF_HELPER_FLAGS_6(sve_fsub_d, TCG_CALL_NO_RWG,
32
- uint8_t *d, const uint8_t *s, int width, int deststep)
34
+ void, ptr, ptr, ptr, ptr, ptr, i32)
33
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
35
+
34
+ int width, int deststep)
36
+DEF_HELPER_FLAGS_6(sve_fmul_h, TCG_CALL_NO_RWG,
35
{
37
+ void, ptr, ptr, ptr, ptr, ptr, i32)
36
uint16_t *pal = opaque;
38
+DEF_HELPER_FLAGS_6(sve_fmul_s, TCG_CALL_NO_RWG,
37
uint8_t v, r, g, b;
39
+ void, ptr, ptr, ptr, ptr, ptr, i32)
38
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line2_, DEPTH)(void *opaque,
40
+DEF_HELPER_FLAGS_6(sve_fmul_d, TCG_CALL_NO_RWG,
39
r = (pal[v & 3] >> 4) & 0xf0;
41
+ void, ptr, ptr, ptr, ptr, ptr, i32)
40
g = pal[v & 3] & 0xf0;
42
+
41
b = (pal[v & 3] << 4) & 0xf0;
43
+DEF_HELPER_FLAGS_6(sve_fdiv_h, TCG_CALL_NO_RWG,
42
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
44
+ void, ptr, ptr, ptr, ptr, ptr, i32)
43
- d += BPP;
45
+DEF_HELPER_FLAGS_6(sve_fdiv_s, TCG_CALL_NO_RWG,
44
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
46
+ void, ptr, ptr, ptr, ptr, ptr, i32)
45
+ d += 4;
47
+DEF_HELPER_FLAGS_6(sve_fdiv_d, TCG_CALL_NO_RWG,
46
v >>= 2;
48
+ void, ptr, ptr, ptr, ptr, ptr, i32)
47
r = (pal[v & 3] >> 4) & 0xf0;
49
+
48
g = pal[v & 3] & 0xf0;
50
+DEF_HELPER_FLAGS_6(sve_fmin_h, TCG_CALL_NO_RWG,
49
b = (pal[v & 3] << 4) & 0xf0;
51
+ void, ptr, ptr, ptr, ptr, ptr, i32)
50
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
52
+DEF_HELPER_FLAGS_6(sve_fmin_s, TCG_CALL_NO_RWG,
51
- d += BPP;
53
+ void, ptr, ptr, ptr, ptr, ptr, i32)
52
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
54
+DEF_HELPER_FLAGS_6(sve_fmin_d, TCG_CALL_NO_RWG,
53
+ d += 4;
55
+ void, ptr, ptr, ptr, ptr, ptr, i32)
54
v >>= 2;
56
+
55
r = (pal[v & 3] >> 4) & 0xf0;
57
+DEF_HELPER_FLAGS_6(sve_fmax_h, TCG_CALL_NO_RWG,
56
g = pal[v & 3] & 0xf0;
58
+ void, ptr, ptr, ptr, ptr, ptr, i32)
57
b = (pal[v & 3] << 4) & 0xf0;
59
+DEF_HELPER_FLAGS_6(sve_fmax_s, TCG_CALL_NO_RWG,
58
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
60
+ void, ptr, ptr, ptr, ptr, ptr, i32)
59
- d += BPP;
61
+DEF_HELPER_FLAGS_6(sve_fmax_d, TCG_CALL_NO_RWG,
60
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
62
+ void, ptr, ptr, ptr, ptr, ptr, i32)
61
+ d += 4;
63
+
62
v >>= 2;
64
+DEF_HELPER_FLAGS_6(sve_fminnum_h, TCG_CALL_NO_RWG,
63
r = (pal[v & 3] >> 4) & 0xf0;
65
+ void, ptr, ptr, ptr, ptr, ptr, i32)
64
g = pal[v & 3] & 0xf0;
66
+DEF_HELPER_FLAGS_6(sve_fminnum_s, TCG_CALL_NO_RWG,
65
b = (pal[v & 3] << 4) & 0xf0;
67
+ void, ptr, ptr, ptr, ptr, ptr, i32)
66
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
68
+DEF_HELPER_FLAGS_6(sve_fminnum_d, TCG_CALL_NO_RWG,
67
- d += BPP;
69
+ void, ptr, ptr, ptr, ptr, ptr, i32)
68
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
70
+
69
+ d += 4;
71
+DEF_HELPER_FLAGS_6(sve_fmaxnum_h, TCG_CALL_NO_RWG,
70
s ++;
72
+ void, ptr, ptr, ptr, ptr, ptr, i32)
71
width -= 4;
73
+DEF_HELPER_FLAGS_6(sve_fmaxnum_s, TCG_CALL_NO_RWG,
72
} while (width > 0);
74
+ void, ptr, ptr, ptr, ptr, ptr, i32)
73
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line2_, DEPTH)(void *opaque,
75
+DEF_HELPER_FLAGS_6(sve_fmaxnum_d, TCG_CALL_NO_RWG,
74
/*
76
+ void, ptr, ptr, ptr, ptr, ptr, i32)
75
* 4-bit colour
77
+
76
*/
78
+DEF_HELPER_FLAGS_6(sve_fabd_h, TCG_CALL_NO_RWG,
77
-static void glue(draw_line4_, DEPTH)(void *opaque,
79
+ void, ptr, ptr, ptr, ptr, ptr, i32)
78
- uint8_t *d, const uint8_t *s, int width, int deststep)
80
+DEF_HELPER_FLAGS_6(sve_fabd_s, TCG_CALL_NO_RWG,
79
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
81
+ void, ptr, ptr, ptr, ptr, ptr, i32)
80
+ int width, int deststep)
82
+DEF_HELPER_FLAGS_6(sve_fabd_d, TCG_CALL_NO_RWG,
81
{
83
+ void, ptr, ptr, ptr, ptr, ptr, i32)
82
uint16_t *pal = opaque;
84
+
83
uint8_t v, r, g, b;
85
+DEF_HELPER_FLAGS_6(sve_fscalbn_h, TCG_CALL_NO_RWG,
84
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line4_, DEPTH)(void *opaque,
86
+ void, ptr, ptr, ptr, ptr, ptr, i32)
85
r = (pal[v & 0xf] >> 4) & 0xf0;
87
+DEF_HELPER_FLAGS_6(sve_fscalbn_s, TCG_CALL_NO_RWG,
86
g = pal[v & 0xf] & 0xf0;
88
+ void, ptr, ptr, ptr, ptr, ptr, i32)
87
b = (pal[v & 0xf] << 4) & 0xf0;
89
+DEF_HELPER_FLAGS_6(sve_fscalbn_d, TCG_CALL_NO_RWG,
88
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
90
+ void, ptr, ptr, ptr, ptr, ptr, i32)
89
- d += BPP;
91
+
90
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
92
+DEF_HELPER_FLAGS_6(sve_fmulx_h, TCG_CALL_NO_RWG,
91
+ d += 4;
93
+ void, ptr, ptr, ptr, ptr, ptr, i32)
92
v >>= 4;
94
+DEF_HELPER_FLAGS_6(sve_fmulx_s, TCG_CALL_NO_RWG,
93
r = (pal[v & 0xf] >> 4) & 0xf0;
95
+ void, ptr, ptr, ptr, ptr, ptr, i32)
94
g = pal[v & 0xf] & 0xf0;
96
+DEF_HELPER_FLAGS_6(sve_fmulx_d, TCG_CALL_NO_RWG,
95
b = (pal[v & 0xf] << 4) & 0xf0;
97
+ void, ptr, ptr, ptr, ptr, ptr, i32)
96
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
98
+
97
- d += BPP;
99
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
98
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
100
void, ptr, ptr, ptr, ptr, i32)
99
+ d += 4;
101
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
100
s ++;
102
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
101
width -= 2;
103
index XXXXXXX..XXXXXXX 100644
102
} while (width > 0);
104
--- a/target/arm/sve_helper.c
103
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line4_, DEPTH)(void *opaque,
105
+++ b/target/arm/sve_helper.c
104
/*
106
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
105
* 8-bit colour
107
return predtest_ones(d, oprsz, esz_mask);
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);
108
}
124
}
109
125
110
+/* Fully general three-operand expander, controlled by a predicate,
126
/*
111
+ * With the extra float_status parameter.
127
* 12-bit colour
112
+ */
113
+#define DO_ZPZZ_FP(NAME, TYPE, H, OP) \
114
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, \
115
+ void *status, uint32_t desc) \
116
+{ \
117
+ intptr_t i = simd_oprsz(desc); \
118
+ uint64_t *g = vg; \
119
+ do { \
120
+ uint64_t pg = g[(i - 1) >> 6]; \
121
+ do { \
122
+ i -= sizeof(TYPE); \
123
+ if (likely((pg >> (i & 63)) & 1)) { \
124
+ TYPE nn = *(TYPE *)(vn + H(i)); \
125
+ TYPE mm = *(TYPE *)(vm + H(i)); \
126
+ *(TYPE *)(vd + H(i)) = OP(nn, mm, status); \
127
+ } \
128
+ } while (i & 63); \
129
+ } while (i != 0); \
130
+}
131
+
132
+DO_ZPZZ_FP(sve_fadd_h, uint16_t, H1_2, float16_add)
133
+DO_ZPZZ_FP(sve_fadd_s, uint32_t, H1_4, float32_add)
134
+DO_ZPZZ_FP(sve_fadd_d, uint64_t, , float64_add)
135
+
136
+DO_ZPZZ_FP(sve_fsub_h, uint16_t, H1_2, float16_sub)
137
+DO_ZPZZ_FP(sve_fsub_s, uint32_t, H1_4, float32_sub)
138
+DO_ZPZZ_FP(sve_fsub_d, uint64_t, , float64_sub)
139
+
140
+DO_ZPZZ_FP(sve_fmul_h, uint16_t, H1_2, float16_mul)
141
+DO_ZPZZ_FP(sve_fmul_s, uint32_t, H1_4, float32_mul)
142
+DO_ZPZZ_FP(sve_fmul_d, uint64_t, , float64_mul)
143
+
144
+DO_ZPZZ_FP(sve_fdiv_h, uint16_t, H1_2, float16_div)
145
+DO_ZPZZ_FP(sve_fdiv_s, uint32_t, H1_4, float32_div)
146
+DO_ZPZZ_FP(sve_fdiv_d, uint64_t, , float64_div)
147
+
148
+DO_ZPZZ_FP(sve_fmin_h, uint16_t, H1_2, float16_min)
149
+DO_ZPZZ_FP(sve_fmin_s, uint32_t, H1_4, float32_min)
150
+DO_ZPZZ_FP(sve_fmin_d, uint64_t, , float64_min)
151
+
152
+DO_ZPZZ_FP(sve_fmax_h, uint16_t, H1_2, float16_max)
153
+DO_ZPZZ_FP(sve_fmax_s, uint32_t, H1_4, float32_max)
154
+DO_ZPZZ_FP(sve_fmax_d, uint64_t, , float64_max)
155
+
156
+DO_ZPZZ_FP(sve_fminnum_h, uint16_t, H1_2, float16_minnum)
157
+DO_ZPZZ_FP(sve_fminnum_s, uint32_t, H1_4, float32_minnum)
158
+DO_ZPZZ_FP(sve_fminnum_d, uint64_t, , float64_minnum)
159
+
160
+DO_ZPZZ_FP(sve_fmaxnum_h, uint16_t, H1_2, float16_maxnum)
161
+DO_ZPZZ_FP(sve_fmaxnum_s, uint32_t, H1_4, float32_maxnum)
162
+DO_ZPZZ_FP(sve_fmaxnum_d, uint64_t, , float64_maxnum)
163
+
164
+static inline float16 abd_h(float16 a, float16 b, float_status *s)
165
+{
166
+ return float16_abs(float16_sub(a, b, s));
167
+}
168
+
169
+static inline float32 abd_s(float32 a, float32 b, float_status *s)
170
+{
171
+ return float32_abs(float32_sub(a, b, s));
172
+}
173
+
174
+static inline float64 abd_d(float64 a, float64 b, float_status *s)
175
+{
176
+ return float64_abs(float64_sub(a, b, s));
177
+}
178
+
179
+DO_ZPZZ_FP(sve_fabd_h, uint16_t, H1_2, abd_h)
180
+DO_ZPZZ_FP(sve_fabd_s, uint32_t, H1_4, abd_s)
181
+DO_ZPZZ_FP(sve_fabd_d, uint64_t, , abd_d)
182
+
183
+static inline float64 scalbn_d(float64 a, int64_t b, float_status *s)
184
+{
185
+ int b_int = MIN(MAX(b, INT_MIN), INT_MAX);
186
+ return float64_scalbn(a, b_int, s);
187
+}
188
+
189
+DO_ZPZZ_FP(sve_fscalbn_h, int16_t, H1_2, float16_scalbn)
190
+DO_ZPZZ_FP(sve_fscalbn_s, int32_t, H1_4, float32_scalbn)
191
+DO_ZPZZ_FP(sve_fscalbn_d, int64_t, , scalbn_d)
192
+
193
+DO_ZPZZ_FP(sve_fmulx_h, uint16_t, H1_2, helper_advsimd_mulxh)
194
+DO_ZPZZ_FP(sve_fmulx_s, uint32_t, H1_4, helper_vfp_mulxs)
195
+DO_ZPZZ_FP(sve_fmulx_d, uint64_t, , helper_vfp_mulxd)
196
+
197
+#undef DO_ZPZZ_FP
198
+
199
/* Fully general two-operand expander, controlled by a predicate,
200
* With the extra float_status parameter.
201
*/
128
*/
202
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
129
-static void glue(draw_line12_, DEPTH)(void *opaque,
203
index XXXXXXX..XXXXXXX 100644
130
- uint8_t *d, const uint8_t *s, int width, int deststep)
204
--- a/target/arm/translate-sve.c
131
+static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
205
+++ b/target/arm/translate-sve.c
132
+ int width, int deststep)
206
@@ -XXX,XX +XXX,XX @@ DO_FP3(FRSQRTS, rsqrts)
133
{
207
134
uint16_t v;
208
#undef DO_FP3
135
uint8_t r, g, b;
209
136
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line12_, DEPTH)(void *opaque,
210
+/*
137
r = (v >> 4) & 0xf0;
211
+ *** SVE Floating Point Arithmetic - Predicated Group
138
g = v & 0xf0;
212
+ */
139
b = (v << 4) & 0xf0;
213
+
140
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
214
+static bool do_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
141
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
215
+ gen_helper_gvec_4_ptr *fn)
142
s += 2;
216
+{
143
- d += BPP;
217
+ if (fn == NULL) {
144
+ d += 4;
218
+ return false;
145
} while (-- width != 0);
219
+ }
146
}
220
+ if (sve_access_check(s)) {
221
+ unsigned vsz = vec_full_reg_size(s);
222
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
223
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
224
+ vec_full_reg_offset(s, a->rn),
225
+ vec_full_reg_offset(s, a->rm),
226
+ pred_full_reg_offset(s, a->pg),
227
+ status, vsz, vsz, 0, fn);
228
+ tcg_temp_free_ptr(status);
229
+ }
230
+ return true;
231
+}
232
+
233
+#define DO_FP3(NAME, name) \
234
+static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a, uint32_t insn) \
235
+{ \
236
+ static gen_helper_gvec_4_ptr * const fns[4] = { \
237
+ NULL, gen_helper_sve_##name##_h, \
238
+ gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \
239
+ }; \
240
+ return do_zpzz_fp(s, a, fns[a->esz]); \
241
+}
242
+
243
+DO_FP3(FADD_zpzz, fadd)
244
+DO_FP3(FSUB_zpzz, fsub)
245
+DO_FP3(FMUL_zpzz, fmul)
246
+DO_FP3(FMIN_zpzz, fmin)
247
+DO_FP3(FMAX_zpzz, fmax)
248
+DO_FP3(FMINNM_zpzz, fminnum)
249
+DO_FP3(FMAXNM_zpzz, fmaxnum)
250
+DO_FP3(FABD, fabd)
251
+DO_FP3(FSCALE, fscalbn)
252
+DO_FP3(FDIV, fdiv)
253
+DO_FP3(FMULX, fmulx)
254
+
255
+#undef DO_FP3
256
147
257
/*
148
/*
258
*** SVE Floating Point Unary Operations Predicated Group
149
* 16-bit colour
259
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
150
*/
260
index XXXXXXX..XXXXXXX 100644
151
-static void glue(draw_line16_, DEPTH)(void *opaque,
261
--- a/target/arm/sve.decode
152
- uint8_t *d, const uint8_t *s, int width, int deststep)
262
+++ b/target/arm/sve.decode
153
+static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
263
@@ -XXX,XX +XXX,XX @@ FTSMUL 01100101 .. 0 ..... 000 011 ..... ..... @rd_rn_rm
154
+ int width, int deststep)
264
FRECPS 01100101 .. 0 ..... 000 110 ..... ..... @rd_rn_rm
155
{
265
FRSQRTS 01100101 .. 0 ..... 000 111 ..... ..... @rd_rn_rm
156
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
266
157
memcpy(d, s, width * 2);
267
+### SVE FP Arithmetic Predicated Group
158
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line16_, DEPTH)(void *opaque,
268
+
159
r = (v >> 8) & 0xf8;
269
+# SVE floating-point arithmetic (predicated)
160
g = (v >> 3) & 0xfc;
270
+FADD_zpzz 01100101 .. 00 0000 100 ... ..... ..... @rdn_pg_rm
161
b = (v << 3) & 0xf8;
271
+FSUB_zpzz 01100101 .. 00 0001 100 ... ..... ..... @rdn_pg_rm
162
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
272
+FMUL_zpzz 01100101 .. 00 0010 100 ... ..... ..... @rdn_pg_rm
163
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
273
+FSUB_zpzz 01100101 .. 00 0011 100 ... ..... ..... @rdm_pg_rn # FSUBR
164
s += 2;
274
+FMAXNM_zpzz 01100101 .. 00 0100 100 ... ..... ..... @rdn_pg_rm
165
- d += BPP;
275
+FMINNM_zpzz 01100101 .. 00 0101 100 ... ..... ..... @rdn_pg_rm
166
+ d += 4;
276
+FMAX_zpzz 01100101 .. 00 0110 100 ... ..... ..... @rdn_pg_rm
167
} while (-- width != 0);
277
+FMIN_zpzz 01100101 .. 00 0111 100 ... ..... ..... @rdn_pg_rm
168
#endif
278
+FABD 01100101 .. 00 1000 100 ... ..... ..... @rdn_pg_rm
169
}
279
+FSCALE 01100101 .. 00 1001 100 ... ..... ..... @rdn_pg_rm
170
-
280
+FMULX 01100101 .. 00 1010 100 ... ..... ..... @rdn_pg_rm
171
-#undef DEPTH
281
+FDIV 01100101 .. 00 1100 100 ... ..... ..... @rdm_pg_rn # FDIVR
172
-#undef BPP
282
+FDIV 01100101 .. 00 1101 100 ... ..... ..... @rdn_pg_rm
173
-#undef PIXEL_TYPE
283
+
284
### SVE FP Unary Operations Predicated Group
285
286
# SVE integer convert to floating-point
287
--
174
--
288
2.17.1
175
2.20.1
289
176
290
177
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
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.
2
8
3
Use error_report() + exit() instead of error_setg(&error_fatal),
9
This bug was introduced in commit ea644cf343129, when we dropped
4
as suggested by the "qapi/error.h" documentation:
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.
5
16
6
Please don't error_setg(&error_fatal, ...), use error_report() and
17
Fixes: ea644cf343129
7
exit(), because that's more obvious.
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(-)
8
25
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
26
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Markus Armbruster <armbru@redhat.com>
12
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
13
Message-id: 20180625165749.3910-4-f4bug@amsat.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
device_tree.c | 23 +++++++++++++----------
17
1 file changed, 13 insertions(+), 10 deletions(-)
18
19
diff --git a/device_tree.c b/device_tree.c
20
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
21
--- a/device_tree.c
28
--- a/hw/display/omap_lcd_template.h
22
+++ b/device_tree.c
29
+++ b/hw/display/omap_lcd_template.h
23
@@ -XXX,XX +XXX,XX @@ static void read_fstree(void *fdt, const char *dirname)
30
@@ -XXX,XX +XXX,XX @@ static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
24
const char *parent_node;
31
static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
25
32
int width, int deststep)
26
if (strstr(dirname, root_dir) != dirname) {
33
{
27
- error_setg(&error_fatal, "%s: %s must be searched within %s",
34
-#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
28
- __func__, dirname, root_dir);
35
- memcpy(d, s, width * 2);
29
+ error_report("%s: %s must be searched within %s",
36
-#else
30
+ __func__, dirname, root_dir);
37
uint16_t v;
31
+ exit(1);
38
uint8_t r, g, b;
32
}
39
33
parent_node = &dirname[strlen(SYSFS_DT_BASEDIR)];
40
@@ -XXX,XX +XXX,XX @@ static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
34
41
s += 2;
35
d = opendir(dirname);
42
d += 4;
36
if (!d) {
43
} while (-- width != 0);
37
- error_setg(&error_fatal, "%s cannot open %s", __func__, dirname);
44
-#endif
38
- return;
39
+ error_report("%s cannot open %s", __func__, dirname);
40
+ exit(1);
41
}
42
43
while ((de = readdir(d)) != NULL) {
44
@@ -XXX,XX +XXX,XX @@ static void read_fstree(void *fdt, const char *dirname)
45
tmpnam = g_strdup_printf("%s/%s", dirname, de->d_name);
46
47
if (lstat(tmpnam, &st) < 0) {
48
- error_setg(&error_fatal, "%s cannot lstat %s", __func__, tmpnam);
49
+ error_report("%s cannot lstat %s", __func__, tmpnam);
50
+ exit(1);
51
}
52
53
if (S_ISREG(st.st_mode)) {
54
@@ -XXX,XX +XXX,XX @@ static void read_fstree(void *fdt, const char *dirname)
55
gsize len;
56
57
if (!g_file_get_contents(tmpnam, &val, &len, NULL)) {
58
- error_setg(&error_fatal, "%s not able to extract info from %s",
59
- __func__, tmpnam);
60
+ error_report("%s not able to extract info from %s",
61
+ __func__, tmpnam);
62
+ exit(1);
63
}
64
65
if (strlen(parent_node) > 0) {
66
@@ -XXX,XX +XXX,XX @@ void *load_device_tree_from_sysfs(void)
67
host_fdt = create_device_tree(&host_fdt_size);
68
read_fstree(host_fdt, SYSFS_DT_BASEDIR);
69
if (fdt_check_header(host_fdt)) {
70
- error_setg(&error_fatal,
71
- "%s host device tree extracted into memory is invalid",
72
- __func__);
73
+ error_report("%s host device tree extracted into memory is invalid",
74
+ __func__);
75
+ exit(1);
76
}
77
return host_fdt;
78
}
45
}
79
--
46
--
80
2.17.1
47
2.20.1
81
48
82
49
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
Fix some minor coding style issues in the template header,
2
so checkpatch doesn't complain when we move the code.
2
3
3
The qdev_get_gpio_in() function accept an int as second parameter.
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20210215103215.4944-8-peter.maydell@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
8
---
10
hw/arm/fsl-imx7.c | 6 +++---
9
hw/display/omap_lcd_template.h | 6 +++---
11
1 file changed, 3 insertions(+), 3 deletions(-)
10
1 file changed, 3 insertions(+), 3 deletions(-)
12
11
13
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
12
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/fsl-imx7.c
14
--- a/hw/display/omap_lcd_template.h
16
+++ b/hw/arm/fsl-imx7.c
15
+++ b/hw/display/omap_lcd_template.h
17
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
16
@@ -XXX,XX +XXX,XX @@ static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
18
FSL_IMX7_ECSPI4_ADDR,
17
b = (pal[v & 3] << 4) & 0xf0;
19
};
18
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
20
19
d += 4;
21
- static const hwaddr FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
20
- s ++;
22
+ static const int FSL_IMX7_SPIn_IRQ[FSL_IMX7_NUM_ECSPIS] = {
21
+ s++;
23
FSL_IMX7_ECSPI1_IRQ,
22
width -= 4;
24
FSL_IMX7_ECSPI2_IRQ,
23
} while (width > 0);
25
FSL_IMX7_ECSPI3_IRQ,
24
}
26
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
25
@@ -XXX,XX +XXX,XX @@ static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
27
FSL_IMX7_I2C4_ADDR,
26
b = (pal[v & 0xf] << 4) & 0xf0;
28
};
27
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
29
28
d += 4;
30
- static const hwaddr FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
29
- s ++;
31
+ static const int FSL_IMX7_I2Cn_IRQ[FSL_IMX7_NUM_I2CS] = {
30
+ s++;
32
FSL_IMX7_I2C1_IRQ,
31
width -= 2;
33
FSL_IMX7_I2C2_IRQ,
32
} while (width > 0);
34
FSL_IMX7_I2C3_IRQ,
33
}
35
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
34
@@ -XXX,XX +XXX,XX @@ static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
36
FSL_IMX7_USB3_ADDR,
35
g = pal[v] & 0xf0;
37
};
36
b = (pal[v] << 4) & 0xf0;
38
37
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
39
- static const hwaddr FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
38
- s ++;
40
+ static const int FSL_IMX7_USBn_IRQ[FSL_IMX7_NUM_USBS] = {
39
+ s++;
41
FSL_IMX7_USB1_IRQ,
40
d += 4;
42
FSL_IMX7_USB2_IRQ,
41
} while (-- width != 0);
43
FSL_IMX7_USB3_IRQ,
42
}
44
--
43
--
45
2.17.1
44
2.20.1
46
45
47
46
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
We only include the template header once, so just inline it into the
2
source file for the device.
2
3
3
This helper allows to retrieve the paths of nodes whose name
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
match node-name or node-name@unit-address patterns.
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
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
5
13
6
Signed-off-by: Eric Auger <eric.auger@redhat.com>
14
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
7
Message-id: 1530044492-24921-2-git-send-email-eric.auger@redhat.com
15
deleted file mode 100644
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
index XXXXXXX..XXXXXXX
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
--- a/hw/display/omap_lcd_template.h
10
---
18
+++ /dev/null
11
include/sysemu/device_tree.h | 16 +++++++++++
19
@@ -XXX,XX +XXX,XX @@
12
device_tree.c | 55 ++++++++++++++++++++++++++++++++++++
20
-/*
13
2 files changed, 71 insertions(+)
21
- * QEMU OMAP LCD Emulator templates
14
22
- *
15
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
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/sysemu/device_tree.h
176
--- a/hw/display/omap_lcdc.c
18
+++ b/include/sysemu/device_tree.h
177
+++ b/hw/display/omap_lcdc.c
19
@@ -XXX,XX +XXX,XX @@ void *load_device_tree_from_sysfs(void);
178
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
20
char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
179
21
Error **errp);
180
#define draw_line_func drawfn
22
181
23
+/**
182
-#define DEPTH 32
24
+ * qemu_fdt_node_unit_path: return the paths of nodes matching a given
183
-#include "omap_lcd_template.h"
25
+ * node-name, ie. node-name and node-name@unit-address
184
+/*
26
+ * @fdt: pointer to the dt blob
185
+ * 2-bit colour
27
+ * @name: node name
186
+ */
28
+ * @errp: handle to an error object
187
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
29
+ *
188
+ int width, int deststep)
30
+ * returns a newly allocated NULL-terminated array of node paths.
189
+{
31
+ * Use g_strfreev() to free it. If one or more nodes were found, the
190
+ uint16_t *pal = opaque;
32
+ * array contains the path of each node and the last element equals to
191
+ uint8_t v, r, g, b;
33
+ * NULL. If there is no error but no matching node was found, the
192
+
34
+ * returned array contains a single element equal to NULL. If an error
193
+ do {
35
+ * was encountered when parsing the blob, the function returns NULL
194
+ v = ldub_p((void *) s);
36
+ */
195
+ r = (pal[v & 3] >> 4) & 0xf0;
37
+char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp);
196
+ g = pal[v & 3] & 0xf0;
38
+
197
+ b = (pal[v & 3] << 4) & 0xf0;
39
int qemu_fdt_setprop(void *fdt, const char *node_path,
198
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
40
const char *property, const void *val, int size);
199
+ d += 4;
41
int qemu_fdt_setprop_cell(void *fdt, const char *node_path,
200
+ v >>= 2;
42
diff --git a/device_tree.c b/device_tree.c
201
+ r = (pal[v & 3] >> 4) & 0xf0;
43
index XXXXXXX..XXXXXXX 100644
202
+ g = pal[v & 3] & 0xf0;
44
--- a/device_tree.c
203
+ b = (pal[v & 3] << 4) & 0xf0;
45
+++ b/device_tree.c
204
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
46
@@ -XXX,XX +XXX,XX @@ static int findnode_nofail(void *fdt, const char *node_path)
205
+ d += 4;
47
return offset;
206
+ v >>= 2;
48
}
207
+ r = (pal[v & 3] >> 4) & 0xf0;
49
208
+ g = pal[v & 3] & 0xf0;
50
+char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp)
209
+ b = (pal[v & 3] << 4) & 0xf0;
51
+{
210
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
52
+ char *prefix = g_strdup_printf("%s@", name);
211
+ d += 4;
53
+ unsigned int path_len = 16, n = 0;
212
+ v >>= 2;
54
+ GSList *path_list = NULL, *iter;
213
+ r = (pal[v & 3] >> 4) & 0xf0;
55
+ const char *iter_name;
214
+ g = pal[v & 3] & 0xf0;
56
+ int offset, len, ret;
215
+ b = (pal[v & 3] << 4) & 0xf0;
57
+ char **path_array;
216
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
58
+
217
+ d += 4;
59
+ offset = fdt_next_node(fdt, -1, NULL);
218
+ s++;
60
+
219
+ width -= 4;
61
+ while (offset >= 0) {
220
+ } while (width > 0);
62
+ iter_name = fdt_get_name(fdt, offset, &len);
221
+}
63
+ if (!iter_name) {
222
+
64
+ offset = len;
223
+/*
65
+ break;
224
+ * 4-bit colour
66
+ }
225
+ */
67
+ if (!strcmp(iter_name, name) || g_str_has_prefix(iter_name, prefix)) {
226
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
68
+ char *path;
227
+ int width, int deststep)
69
+
228
+{
70
+ path = g_malloc(path_len);
229
+ uint16_t *pal = opaque;
71
+ while ((ret = fdt_get_path(fdt, offset, path, path_len))
230
+ uint8_t v, r, g, b;
72
+ == -FDT_ERR_NOSPACE) {
231
+
73
+ path_len += 16;
232
+ do {
74
+ path = g_realloc(path, path_len);
233
+ v = ldub_p((void *) s);
75
+ }
234
+ r = (pal[v & 0xf] >> 4) & 0xf0;
76
+ path_list = g_slist_prepend(path_list, path);
235
+ g = pal[v & 0xf] & 0xf0;
77
+ n++;
236
+ b = (pal[v & 0xf] << 4) & 0xf0;
78
+ }
237
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
79
+ offset = fdt_next_node(fdt, offset, NULL);
238
+ d += 4;
80
+ }
239
+ v >>= 4;
81
+ g_free(prefix);
240
+ r = (pal[v & 0xf] >> 4) & 0xf0;
82
+
241
+ g = pal[v & 0xf] & 0xf0;
83
+ if (offset < 0 && offset != -FDT_ERR_NOTFOUND) {
242
+ b = (pal[v & 0xf] << 4) & 0xf0;
84
+ error_setg(errp, "%s: abort parsing dt for %s node units: %s",
243
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
85
+ __func__, name, fdt_strerror(offset));
244
+ d += 4;
86
+ for (iter = path_list; iter; iter = iter->next) {
245
+ s++;
87
+ g_free(iter->data);
246
+ width -= 2;
88
+ }
247
+ } while (width > 0);
89
+ g_slist_free(path_list);
248
+}
90
+ return NULL;
249
+
91
+ }
250
+/*
92
+
251
+ * 8-bit colour
93
+ path_array = g_new(char *, n + 1);
252
+ */
94
+ path_array[n--] = NULL;
253
+static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
95
+
254
+ int width, int deststep)
96
+ for (iter = path_list; iter; iter = iter->next) {
255
+{
97
+ path_array[n--] = iter->data;
256
+ uint16_t *pal = opaque;
98
+ }
257
+ uint8_t v, r, g, b;
99
+
258
+
100
+ g_slist_free(path_list);
259
+ do {
101
+
260
+ v = ldub_p((void *) s);
102
+ return path_array;
261
+ r = (pal[v] >> 4) & 0xf0;
103
+}
262
+ g = pal[v] & 0xf0;
104
+
263
+ b = (pal[v] << 4) & 0xf0;
105
char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
264
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
106
Error **errp)
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)
107
{
311
{
108
--
312
--
109
2.17.1
313
2.20.1
110
314
111
315
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
The macro draw_line_func is used only once; just expand it.
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-17-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: 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
---
7
---
8
target/arm/helper-sve.h | 49 ++++++++++++++++++++++++++++++
8
hw/display/omap_lcdc.c | 4 +---
9
target/arm/sve_helper.c | 62 ++++++++++++++++++++++++++++++++++++++
9
1 file changed, 1 insertion(+), 3 deletions(-)
10
target/arm/translate-sve.c | 40 ++++++++++++++++++++++++
11
target/arm/sve.decode | 11 +++++++
12
4 files changed, 162 insertions(+)
13
10
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
11
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
13
--- a/hw/display/omap_lcdc.c
17
+++ b/target/arm/helper-sve.h
14
+++ b/hw/display/omap_lcdc.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_ucvt_ds, TCG_CALL_NO_RWG,
15
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
19
DEF_HELPER_FLAGS_5(sve_ucvt_dd, TCG_CALL_NO_RWG,
16
qemu_irq_lower(s->irq);
20
void, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_6(sve_fcmge_h, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_6(sve_fcmge_s, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, ptr, ptr, i32)
26
+DEF_HELPER_FLAGS_6(sve_fcmge_d, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, ptr, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_6(sve_fcmgt_h, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_6(sve_fcmgt_s, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_6(sve_fcmgt_d, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, ptr, i32)
35
+
36
+DEF_HELPER_FLAGS_6(sve_fcmeq_h, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, ptr, ptr, i32)
38
+DEF_HELPER_FLAGS_6(sve_fcmeq_s, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_6(sve_fcmeq_d, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, ptr, i32)
42
+
43
+DEF_HELPER_FLAGS_6(sve_fcmne_h, TCG_CALL_NO_RWG,
44
+ void, ptr, ptr, ptr, ptr, ptr, i32)
45
+DEF_HELPER_FLAGS_6(sve_fcmne_s, TCG_CALL_NO_RWG,
46
+ void, ptr, ptr, ptr, ptr, ptr, i32)
47
+DEF_HELPER_FLAGS_6(sve_fcmne_d, TCG_CALL_NO_RWG,
48
+ void, ptr, ptr, ptr, ptr, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_6(sve_fcmuo_h, TCG_CALL_NO_RWG,
51
+ void, ptr, ptr, ptr, ptr, ptr, i32)
52
+DEF_HELPER_FLAGS_6(sve_fcmuo_s, TCG_CALL_NO_RWG,
53
+ void, ptr, ptr, ptr, ptr, ptr, i32)
54
+DEF_HELPER_FLAGS_6(sve_fcmuo_d, TCG_CALL_NO_RWG,
55
+ void, ptr, ptr, ptr, ptr, ptr, i32)
56
+
57
+DEF_HELPER_FLAGS_6(sve_facge_h, TCG_CALL_NO_RWG,
58
+ void, ptr, ptr, ptr, ptr, ptr, i32)
59
+DEF_HELPER_FLAGS_6(sve_facge_s, TCG_CALL_NO_RWG,
60
+ void, ptr, ptr, ptr, ptr, ptr, i32)
61
+DEF_HELPER_FLAGS_6(sve_facge_d, TCG_CALL_NO_RWG,
62
+ void, ptr, ptr, ptr, ptr, ptr, i32)
63
+
64
+DEF_HELPER_FLAGS_6(sve_facgt_h, TCG_CALL_NO_RWG,
65
+ void, ptr, ptr, ptr, ptr, ptr, i32)
66
+DEF_HELPER_FLAGS_6(sve_facgt_s, TCG_CALL_NO_RWG,
67
+ void, ptr, ptr, ptr, ptr, ptr, i32)
68
+DEF_HELPER_FLAGS_6(sve_facgt_d, TCG_CALL_NO_RWG,
69
+ void, ptr, ptr, ptr, ptr, ptr, i32)
70
+
71
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
72
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
73
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
74
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/arm/sve_helper.c
77
+++ b/target/arm/sve_helper.c
78
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_fnmls_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
79
do_fmla_zpzzz_d(env, vg, desc, 0, INT64_MIN);
80
}
17
}
81
18
82
+/* Two operand floating-point comparison controlled by a predicate.
19
-#define draw_line_func drawfn
83
+ * Unlike the integer version, we are not allowed to optimistically
20
-
84
+ * compare operands, since the comparison may have side effects wrt
85
+ * the FPSR.
86
+ */
87
+#define DO_FPCMP_PPZZ(NAME, TYPE, H, OP) \
88
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, \
89
+ void *status, uint32_t desc) \
90
+{ \
91
+ intptr_t i = simd_oprsz(desc), j = (i - 1) >> 6; \
92
+ uint64_t *d = vd, *g = vg; \
93
+ do { \
94
+ uint64_t out = 0, pg = g[j]; \
95
+ do { \
96
+ i -= sizeof(TYPE), out <<= sizeof(TYPE); \
97
+ if (likely((pg >> (i & 63)) & 1)) { \
98
+ TYPE nn = *(TYPE *)(vn + H(i)); \
99
+ TYPE mm = *(TYPE *)(vm + H(i)); \
100
+ out |= OP(TYPE, nn, mm, status); \
101
+ } \
102
+ } while (i & 63); \
103
+ d[j--] = out; \
104
+ } while (i > 0); \
105
+}
106
+
107
+#define DO_FPCMP_PPZZ_H(NAME, OP) \
108
+ DO_FPCMP_PPZZ(NAME##_h, float16, H1_2, OP)
109
+#define DO_FPCMP_PPZZ_S(NAME, OP) \
110
+ DO_FPCMP_PPZZ(NAME##_s, float32, H1_4, OP)
111
+#define DO_FPCMP_PPZZ_D(NAME, OP) \
112
+ DO_FPCMP_PPZZ(NAME##_d, float64, , OP)
113
+
114
+#define DO_FPCMP_PPZZ_ALL(NAME, OP) \
115
+ DO_FPCMP_PPZZ_H(NAME, OP) \
116
+ DO_FPCMP_PPZZ_S(NAME, OP) \
117
+ DO_FPCMP_PPZZ_D(NAME, OP)
118
+
119
+#define DO_FCMGE(TYPE, X, Y, ST) TYPE##_compare(Y, X, ST) <= 0
120
+#define DO_FCMGT(TYPE, X, Y, ST) TYPE##_compare(Y, X, ST) < 0
121
+#define DO_FCMEQ(TYPE, X, Y, ST) TYPE##_compare_quiet(X, Y, ST) == 0
122
+#define DO_FCMNE(TYPE, X, Y, ST) TYPE##_compare_quiet(X, Y, ST) != 0
123
+#define DO_FCMUO(TYPE, X, Y, ST) \
124
+ TYPE##_compare_quiet(X, Y, ST) == float_relation_unordered
125
+#define DO_FACGE(TYPE, X, Y, ST) \
126
+ TYPE##_compare(TYPE##_abs(Y), TYPE##_abs(X), ST) <= 0
127
+#define DO_FACGT(TYPE, X, Y, ST) \
128
+ TYPE##_compare(TYPE##_abs(Y), TYPE##_abs(X), ST) < 0
129
+
130
+DO_FPCMP_PPZZ_ALL(sve_fcmge, DO_FCMGE)
131
+DO_FPCMP_PPZZ_ALL(sve_fcmgt, DO_FCMGT)
132
+DO_FPCMP_PPZZ_ALL(sve_fcmeq, DO_FCMEQ)
133
+DO_FPCMP_PPZZ_ALL(sve_fcmne, DO_FCMNE)
134
+DO_FPCMP_PPZZ_ALL(sve_fcmuo, DO_FCMUO)
135
+DO_FPCMP_PPZZ_ALL(sve_facge, DO_FACGE)
136
+DO_FPCMP_PPZZ_ALL(sve_facgt, DO_FACGT)
137
+
138
+#undef DO_FPCMP_PPZZ_ALL
139
+#undef DO_FPCMP_PPZZ_D
140
+#undef DO_FPCMP_PPZZ_S
141
+#undef DO_FPCMP_PPZZ_H
142
+#undef DO_FPCMP_PPZZ
143
+
144
/*
21
/*
145
* Load contiguous data, protected by a governing predicate.
22
* 2-bit colour
146
*/
23
*/
147
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
24
@@ -XXX,XX +XXX,XX @@ static void omap_update_display(void *opaque)
148
index XXXXXXX..XXXXXXX 100644
25
{
149
--- a/target/arm/translate-sve.c
26
struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
150
+++ b/target/arm/translate-sve.c
27
DisplaySurface *surface;
151
@@ -XXX,XX +XXX,XX @@ DO_FP3(FMULX, fmulx)
28
- draw_line_func draw_line;
152
29
+ drawfn draw_line;
153
#undef DO_FP3
30
int size, height, first, last;
154
31
int width, linesize, step, bpp, frame_offset;
155
+static bool do_fp_cmp(DisasContext *s, arg_rprr_esz *a,
32
hwaddr frame_base;
156
+ gen_helper_gvec_4_ptr *fn)
157
+{
158
+ if (fn == NULL) {
159
+ return false;
160
+ }
161
+ if (sve_access_check(s)) {
162
+ unsigned vsz = vec_full_reg_size(s);
163
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
164
+ tcg_gen_gvec_4_ptr(pred_full_reg_offset(s, a->rd),
165
+ vec_full_reg_offset(s, a->rn),
166
+ vec_full_reg_offset(s, a->rm),
167
+ pred_full_reg_offset(s, a->pg),
168
+ status, vsz, vsz, 0, fn);
169
+ tcg_temp_free_ptr(status);
170
+ }
171
+ return true;
172
+}
173
+
174
+#define DO_FPCMP(NAME, name) \
175
+static bool trans_##NAME##_ppzz(DisasContext *s, arg_rprr_esz *a, \
176
+ uint32_t insn) \
177
+{ \
178
+ static gen_helper_gvec_4_ptr * const fns[4] = { \
179
+ NULL, gen_helper_sve_##name##_h, \
180
+ gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \
181
+ }; \
182
+ return do_fp_cmp(s, a, fns[a->esz]); \
183
+}
184
+
185
+DO_FPCMP(FCMGE, fcmge)
186
+DO_FPCMP(FCMGT, fcmgt)
187
+DO_FPCMP(FCMEQ, fcmeq)
188
+DO_FPCMP(FCMNE, fcmne)
189
+DO_FPCMP(FCMUO, fcmuo)
190
+DO_FPCMP(FACGE, facge)
191
+DO_FPCMP(FACGT, facgt)
192
+
193
+#undef DO_FPCMP
194
+
195
typedef void gen_helper_sve_fmla(TCGv_env, TCGv_ptr, TCGv_i32);
196
197
static bool do_fmla(DisasContext *s, arg_rprrr_esz *a, gen_helper_sve_fmla *fn)
198
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
199
index XXXXXXX..XXXXXXX 100644
200
--- a/target/arm/sve.decode
201
+++ b/target/arm/sve.decode
202
@@ -XXX,XX +XXX,XX @@ UXTH 00000100 .. 010 011 101 ... ..... ..... @rd_pg_rn
203
SXTW 00000100 .. 010 100 101 ... ..... ..... @rd_pg_rn
204
UXTW 00000100 .. 010 101 101 ... ..... ..... @rd_pg_rn
205
206
+### SVE Floating Point Compare - Vectors Group
207
+
208
+# SVE floating-point compare vectors
209
+FCMGE_ppzz 01100101 .. 0 ..... 010 ... ..... 0 .... @pd_pg_rn_rm
210
+FCMGT_ppzz 01100101 .. 0 ..... 010 ... ..... 1 .... @pd_pg_rn_rm
211
+FCMEQ_ppzz 01100101 .. 0 ..... 011 ... ..... 0 .... @pd_pg_rn_rm
212
+FCMNE_ppzz 01100101 .. 0 ..... 011 ... ..... 1 .... @pd_pg_rn_rm
213
+FCMUO_ppzz 01100101 .. 0 ..... 110 ... ..... 0 .... @pd_pg_rn_rm
214
+FACGE_ppzz 01100101 .. 0 ..... 110 ... ..... 1 .... @pd_pg_rn_rm
215
+FACGT_ppzz 01100101 .. 0 ..... 111 ... ..... 1 .... @pd_pg_rn_rm
216
+
217
### SVE Integer Multiply-Add Group
218
219
# SVE integer multiply-add writing addend (predicated)
220
--
33
--
221
2.17.1
34
2.20.1
222
35
223
36
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Leave ARM_CP_SVE, removing ARM_CP_FPU; the sve_access_check
9
Drop the never-used BGR-handling code, and assert that we have
4
produced by the flag already includes fp_access_check. If
10
a 32-bit surface rather than just doing nothing if it isn't.
5
we also check ARM_CP_FPU the double fp_access_check asserts.
6
11
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
12
Message-id: 20180629001538.11415-3-richard.henderson@linaro.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210215102149.20513-1-peter.maydell@linaro.org
14
---
16
---
15
target/arm/helper.c | 8 ++++----
17
hw/display/tcx.c | 31 ++++++++-----------------------
16
target/arm/translate-a64.c | 5 ++---
18
1 file changed, 8 insertions(+), 23 deletions(-)
17
2 files changed, 6 insertions(+), 7 deletions(-)
18
19
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
diff --git a/hw/display/tcx.c b/hw/display/tcx.c
20
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
22
--- a/hw/display/tcx.c
22
+++ b/target/arm/helper.c
23
+++ b/hw/display/tcx.c
23
@@ -XXX,XX +XXX,XX @@ static void zcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
24
@@ -XXX,XX +XXX,XX @@ static int tcx_check_dirty(TCXState *s, DirtyBitmapSnapshot *snap,
24
static const ARMCPRegInfo zcr_el1_reginfo = {
25
25
.name = "ZCR_EL1", .state = ARM_CP_STATE_AA64,
26
static void update_palette_entries(TCXState *s, int start, int end)
26
.opc0 = 3, .opc1 = 0, .crn = 1, .crm = 2, .opc2 = 0,
27
{
27
- .access = PL1_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
28
- DisplaySurface *surface = qemu_console_surface(s->con);
28
+ .access = PL1_RW, .type = ARM_CP_SVE,
29
int i;
29
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[1]),
30
30
.writefn = zcr_write, .raw_writefn = raw_write
31
for (i = start; i < end; i++) {
31
};
32
- if (is_surface_bgr(surface)) {
32
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_el1_reginfo = {
33
- s->palette[i] = rgb_to_pixel32bgr(s->r[i], s->g[i], s->b[i]);
33
static const ARMCPRegInfo zcr_el2_reginfo = {
34
- } else {
34
.name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
35
- s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
35
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
36
- }
36
- .access = PL2_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
37
+ s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
37
+ .access = PL2_RW, .type = ARM_CP_SVE,
38
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[2]),
39
.writefn = zcr_write, .raw_writefn = raw_write
40
};
41
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo zcr_el2_reginfo = {
42
static const ARMCPRegInfo zcr_no_el2_reginfo = {
43
.name = "ZCR_EL2", .state = ARM_CP_STATE_AA64,
44
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 2, .opc2 = 0,
45
- .access = PL2_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
46
+ .access = PL2_RW, .type = ARM_CP_SVE,
47
.readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore
48
};
49
50
static const ARMCPRegInfo zcr_el3_reginfo = {
51
.name = "ZCR_EL3", .state = ARM_CP_STATE_AA64,
52
.opc0 = 3, .opc1 = 6, .crn = 1, .crm = 2, .opc2 = 0,
53
- .access = PL3_RW, .type = ARM_CP_SVE | ARM_CP_FPU,
54
+ .access = PL3_RW, .type = ARM_CP_SVE,
55
.fieldoffset = offsetof(CPUARMState, vfp.zcr_el[3]),
56
.writefn = zcr_write, .raw_writefn = raw_write
57
};
58
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate-a64.c
61
+++ b/target/arm/translate-a64.c
62
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
63
default:
64
break;
65
}
38
}
66
- if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
39
tcx_set_dirty(s, 0, memory_region_size(&s->vram_mem));
40
}
41
@@ -XXX,XX +XXX,XX @@ static void tcx_draw_cursor32(TCXState *s1, uint8_t *d,
42
}
43
44
/*
45
- XXX Could be much more optimal:
46
- * detect if line/page/whole screen is in 24 bit mode
47
- * if destination is also BGR, use memcpy
48
- */
49
+ * XXX Could be much more optimal:
50
+ * detect if line/page/whole screen is in 24 bit mode
51
+ */
52
static inline void tcx24_draw_line32(TCXState *s1, uint8_t *d,
53
const uint8_t *s, int width,
54
const uint32_t *cplane,
55
const uint32_t *s24)
56
{
57
- DisplaySurface *surface = qemu_console_surface(s1->con);
58
- int x, bgr, r, g, b;
59
+ int x, r, g, b;
60
uint8_t val, *p8;
61
uint32_t *p = (uint32_t *)d;
62
uint32_t dval;
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) {
67
- return;
84
- return;
68
- }
85
- }
69
if ((ri->type & ARM_CP_FPU) && !fp_access_check(s)) {
86
+ assert(surface_bits_per_pixel(surface) == 32);
70
return;
87
71
+ } else if ((ri->type & ARM_CP_SVE) && !sve_access_check(s)) {
88
page = 0;
72
+ return;
89
y_start = -1;
73
}
90
@@ -XXX,XX +XXX,XX @@ static void tcx24_update_display(void *opaque)
74
91
uint8_t *d, *s;
75
if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
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;
76
--
101
--
77
2.17.1
102
2.20.1
78
103
79
104
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-24-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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-2-peter.maydell@linaro.org
7
---
9
---
8
target/arm/helper-sve.h | 13 +++++++++
10
hw/arm/mps2-tz.c | 10 ++++++----
9
target/arm/sve_helper.c | 55 ++++++++++++++++++++++++++++++++++++++
11
1 file changed, 6 insertions(+), 4 deletions(-)
10
target/arm/translate-sve.c | 30 +++++++++++++++++++++
11
target/arm/sve.decode | 8 ++++++
12
4 files changed, 106 insertions(+)
13
12
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
15
--- a/hw/arm/mps2-tz.c
17
+++ b/target/arm/helper-sve.h
16
+++ b/hw/arm/mps2-tz.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_fmins_s, TCG_CALL_NO_RWG,
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
19
DEF_HELPER_FLAGS_6(sve_fmins_d, TCG_CALL_NO_RWG,
18
MachineClass parent;
20
void, ptr, ptr, ptr, i64, ptr, i32)
19
MPS2TZFPGAType fpga_type;
21
20
uint32_t scc_id;
22
+DEF_HELPER_FLAGS_5(sve_fcvt_sh, TCG_CALL_NO_RWG,
21
+ uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
23
+ void, ptr, ptr, ptr, ptr, i32)
22
const char *armsse_type;
24
+DEF_HELPER_FLAGS_5(sve_fcvt_dh, TCG_CALL_NO_RWG,
23
};
25
+ void, ptr, ptr, ptr, ptr, i32)
24
26
+DEF_HELPER_FLAGS_5(sve_fcvt_hs, TCG_CALL_NO_RWG,
25
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
27
+ void, ptr, ptr, ptr, ptr, i32)
26
28
+DEF_HELPER_FLAGS_5(sve_fcvt_ds, TCG_CALL_NO_RWG,
27
OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
29
+ void, ptr, ptr, ptr, ptr, i32)
28
30
+DEF_HELPER_FLAGS_5(sve_fcvt_hd, TCG_CALL_NO_RWG,
29
-/* Main SYSCLK frequency in Hz */
31
+ void, ptr, ptr, ptr, ptr, i32)
30
-#define SYSCLK_FRQ 20000000
32
+DEF_HELPER_FLAGS_5(sve_fcvt_sd, TCG_CALL_NO_RWG,
31
/* Slow 32Khz S32KCLK frequency in Hz */
33
+ void, ptr, ptr, ptr, ptr, i32)
32
#define S32KCLK_FRQ (32 * 1000)
34
+
33
35
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
36
void, ptr, ptr, ptr, ptr, i32)
35
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
37
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
36
const char *name, hwaddr size)
38
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
37
{
39
index XXXXXXX..XXXXXXX 100644
38
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
40
--- a/target/arm/sve_helper.c
39
CMSDKAPBUART *uart = opaque;
41
+++ b/target/arm/sve_helper.c
40
int i = uart - &mms->uart[0];
42
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vg, void *status, uint32_t desc) \
41
int rxirqno = i * 2;
43
} while (i != 0); \
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;
44
}
66
}
45
67
46
+/* SVE fp16 conversions always use IEEE mode. Like AdvSIMD, they ignore
68
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
47
+ * FZ16. When converting from fp16, this affects flushing input denormals;
69
mmc->fpga_type = FPGA_AN521;
48
+ * when converting to fp16, this affects flushing output denormals.
70
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
49
+ */
71
mmc->scc_id = 0x41045210;
50
+static inline float32 sve_f16_to_f32(float16 f, float_status *fpst)
72
+ mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
51
+{
73
mmc->armsse_type = TYPE_SSE200;
52
+ flag save = get_flush_inputs_to_zero(fpst);
53
+ float32 ret;
54
+
55
+ set_flush_inputs_to_zero(false, fpst);
56
+ ret = float16_to_float32(f, true, fpst);
57
+ set_flush_inputs_to_zero(save, fpst);
58
+ return ret;
59
+}
60
+
61
+static inline float64 sve_f16_to_f64(float16 f, float_status *fpst)
62
+{
63
+ flag save = get_flush_inputs_to_zero(fpst);
64
+ float64 ret;
65
+
66
+ set_flush_inputs_to_zero(false, fpst);
67
+ ret = float16_to_float64(f, true, fpst);
68
+ set_flush_inputs_to_zero(save, fpst);
69
+ return ret;
70
+}
71
+
72
+static inline float16 sve_f32_to_f16(float32 f, float_status *fpst)
73
+{
74
+ flag save = get_flush_to_zero(fpst);
75
+ float16 ret;
76
+
77
+ set_flush_to_zero(false, fpst);
78
+ ret = float32_to_float16(f, true, fpst);
79
+ set_flush_to_zero(save, fpst);
80
+ return ret;
81
+}
82
+
83
+static inline float16 sve_f64_to_f16(float64 f, float_status *fpst)
84
+{
85
+ flag save = get_flush_to_zero(fpst);
86
+ float16 ret;
87
+
88
+ set_flush_to_zero(false, fpst);
89
+ ret = float64_to_float16(f, true, fpst);
90
+ set_flush_to_zero(save, fpst);
91
+ return ret;
92
+}
93
+
94
+DO_ZPZ_FP(sve_fcvt_sh, uint32_t, H1_4, sve_f32_to_f16)
95
+DO_ZPZ_FP(sve_fcvt_hs, uint32_t, H1_4, sve_f16_to_f32)
96
+DO_ZPZ_FP(sve_fcvt_dh, uint64_t, , sve_f64_to_f16)
97
+DO_ZPZ_FP(sve_fcvt_hd, uint64_t, , sve_f16_to_f64)
98
+DO_ZPZ_FP(sve_fcvt_ds, uint64_t, , float64_to_float32)
99
+DO_ZPZ_FP(sve_fcvt_sd, uint64_t, , float32_to_float64)
100
+
101
DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
102
DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
103
DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
104
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/target/arm/translate-sve.c
107
+++ b/target/arm/translate-sve.c
108
@@ -XXX,XX +XXX,XX @@ static bool do_zpz_ptr(DisasContext *s, int rd, int rn, int pg,
109
return true;
110
}
74
}
111
75
112
+static bool trans_FCVT_sh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
113
+{
114
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_sh);
115
+}
116
+
117
+static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
118
+{
119
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_hs);
120
+}
121
+
122
+static bool trans_FCVT_dh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
123
+{
124
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_dh);
125
+}
126
+
127
+static bool trans_FCVT_hd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
128
+{
129
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_hd);
130
+}
131
+
132
+static bool trans_FCVT_ds(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
133
+{
134
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_ds);
135
+}
136
+
137
+static bool trans_FCVT_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
138
+{
139
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_sd);
140
+}
141
+
142
static bool trans_SCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
143
{
144
return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_hh);
145
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
146
index XXXXXXX..XXXXXXX 100644
147
--- a/target/arm/sve.decode
148
+++ b/target/arm/sve.decode
149
@@ -XXX,XX +XXX,XX @@ FNMLS_zpzzz 01100101 .. 1 ..... 111 ... ..... ..... @rdn_pg_rm_ra
150
151
### SVE FP Unary Operations Predicated Group
152
153
+# SVE floating-point convert precision
154
+FCVT_sh 01100101 10 0010 00 101 ... ..... ..... @rd_pg_rn_e0
155
+FCVT_hs 01100101 10 0010 01 101 ... ..... ..... @rd_pg_rn_e0
156
+FCVT_dh 01100101 11 0010 00 101 ... ..... ..... @rd_pg_rn_e0
157
+FCVT_hd 01100101 11 0010 01 101 ... ..... ..... @rd_pg_rn_e0
158
+FCVT_ds 01100101 11 0010 10 101 ... ..... ..... @rd_pg_rn_e0
159
+FCVT_sd 01100101 11 0010 11 101 ... ..... ..... @rd_pg_rn_e0
160
+
161
# SVE integer convert to floating-point
162
SCVTF_hh 01100101 01 010 01 0 101 ... ..... ..... @rd_pg_rn_e0
163
SCVTF_sh 01100101 01 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
164
--
76
--
165
2.17.1
77
2.20.1
166
78
167
79
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
With a variable-length property array, the SCC no longer specifies
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
default values for the OSCCLKs, so we must set them explicitly in the
5
Message-id: 20180627043328.11531-33-richard.henderson@linaro.org
9
board code. This defaults are actually incorrect for the an521 and
6
[PMM: moved 'ra=%reg_movprfx' here from following patch]
10
an505; we will correct this bug in a following patch.
11
12
This is a migration compatibility break for all the mps boards.
13
7
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
8
---
18
---
9
target/arm/helper.h | 5 +++
19
include/hw/misc/mps2-scc.h | 7 +++----
10
target/arm/translate-sve.c | 17 ++++++++++
20
hw/arm/mps2-tz.c | 5 +++++
11
target/arm/vec_helper.c | 67 ++++++++++++++++++++++++++++++++++++++
21
hw/arm/mps2.c | 5 +++++
12
target/arm/sve.decode | 3 ++
22
hw/misc/mps2-scc.c | 24 +++++++++++++-----------
13
4 files changed, 92 insertions(+)
23
4 files changed, 26 insertions(+), 15 deletions(-)
14
24
15
diff --git a/target/arm/helper.h b/target/arm/helper.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/target/arm/helper.h
27
--- a/include/hw/misc/mps2-scc.h
18
+++ b/target/arm/helper.h
28
+++ b/include/hw/misc/mps2-scc.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_qrdmlah_s32, TCG_CALL_NO_RWG,
29
@@ -XXX,XX +XXX,XX @@
20
DEF_HELPER_FLAGS_5(gvec_qrdmlsh_s32, TCG_CALL_NO_RWG,
30
#define TYPE_MPS2_SCC "mps2-scc"
21
void, ptr, ptr, ptr, ptr, i32)
31
OBJECT_DECLARE_SIMPLE_TYPE(MPS2SCC, MPS2_SCC)
22
32
23
+DEF_HELPER_FLAGS_4(gvec_sdot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
-#define NUM_OSCCLK 3
24
+DEF_HELPER_FLAGS_4(gvec_udot_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
34
-
25
+DEF_HELPER_FLAGS_4(gvec_sdot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
35
struct MPS2SCC {
26
+DEF_HELPER_FLAGS_4(gvec_udot_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
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;
47
};
48
49
#endif
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
}
27
+
117
+
28
DEF_HELPER_FLAGS_5(gvec_fcaddh, TCG_CALL_NO_RWG,
118
+ s->oscclk = g_new0(uint32_t, s->num_oscclk);
29
void, ptr, ptr, ptr, ptr, i32)
30
DEF_HELPER_FLAGS_5(gvec_fcadds, TCG_CALL_NO_RWG,
31
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate-sve.c
34
+++ b/target/arm/translate-sve.c
35
@@ -XXX,XX +XXX,XX @@ DO_ZZI(UMIN, umin)
36
37
#undef DO_ZZI
38
39
+static bool trans_DOT_zzz(DisasContext *s, arg_DOT_zzz *a, uint32_t insn)
40
+{
41
+ static gen_helper_gvec_3 * const fns[2][2] = {
42
+ { gen_helper_gvec_sdot_b, gen_helper_gvec_sdot_h },
43
+ { gen_helper_gvec_udot_b, gen_helper_gvec_udot_h }
44
+ };
45
+
46
+ if (sve_access_check(s)) {
47
+ unsigned vsz = vec_full_reg_size(s);
48
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, a->rd),
49
+ vec_full_reg_offset(s, a->rn),
50
+ vec_full_reg_offset(s, a->rm),
51
+ vsz, vsz, 0, fns[a->u][a->sz]);
52
+ }
53
+ return true;
54
+}
55
+
56
/*
57
*** SVE Floating Point Multiply-Add Indexed Group
58
*/
59
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/vec_helper.c
62
+++ b/target/arm/vec_helper.c
63
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_qrdmlsh_s32)(void *vd, void *vn, void *vm,
64
clear_tail(d, opr_sz, simd_maxsz(desc));
65
}
119
}
66
120
67
+/* Integer 8 and 16-bit dot-product.
121
static const VMStateDescription mps2_scc_vmstate = {
68
+ *
122
.name = "mps2-scc",
69
+ * Note that for the loops herein, host endianness does not matter
123
- .version_id = 1,
70
+ * with respect to the ordering of data within the 64-bit lanes.
124
- .minimum_version_id = 1,
71
+ * All elements are treated equally, no matter where they are.
125
+ .version_id = 2,
72
+ */
126
+ .minimum_version_id = 2,
73
+
127
.fields = (VMStateField[]) {
74
+void HELPER(gvec_sdot_b)(void *vd, void *vn, void *vm, uint32_t desc)
128
VMSTATE_UINT32(cfg0, MPS2SCC),
75
+{
129
VMSTATE_UINT32(cfg1, MPS2SCC),
76
+ intptr_t i, opr_sz = simd_oprsz(desc);
130
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
77
+ uint32_t *d = vd;
131
VMSTATE_UINT32(cfgctrl, MPS2SCC),
78
+ int8_t *n = vn, *m = vm;
132
VMSTATE_UINT32(cfgstat, MPS2SCC),
79
+
133
VMSTATE_UINT32(dll, MPS2SCC),
80
+ for (i = 0; i < opr_sz / 4; ++i) {
134
- VMSTATE_UINT32_ARRAY(oscclk, MPS2SCC, NUM_OSCCLK),
81
+ d[i] += n[i * 4 + 0] * m[i * 4 + 0]
135
+ VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
82
+ + n[i * 4 + 1] * m[i * 4 + 1]
136
+ 0, vmstate_info_uint32, uint32_t),
83
+ + n[i * 4 + 2] * m[i * 4 + 2]
137
VMSTATE_END_OF_LIST()
84
+ + n[i * 4 + 3] * m[i * 4 + 3];
138
}
85
+ }
139
};
86
+ clear_tail(d, opr_sz, simd_maxsz(desc));
140
@@ -XXX,XX +XXX,XX @@ static Property mps2_scc_properties[] = {
87
+}
141
DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0),
88
+
142
DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
89
+void HELPER(gvec_udot_b)(void *vd, void *vn, void *vm, uint32_t desc)
143
DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0),
90
+{
144
- /* These are the initial settings for the source clocks on the board.
91
+ intptr_t i, opr_sz = simd_oprsz(desc);
145
+ /*
92
+ uint32_t *d = vd;
146
+ * These are the initial settings for the source clocks on the board.
93
+ uint8_t *n = vn, *m = vm;
147
* In hardware they can be configured via a config file read by the
94
+
148
* motherboard configuration controller to suit the FPGA image.
95
+ for (i = 0; i < opr_sz / 4; ++i) {
149
- * These default values are used by most of the standard FPGA images.
96
+ d[i] += n[i * 4 + 0] * m[i * 4 + 0]
150
*/
97
+ + n[i * 4 + 1] * m[i * 4 + 1]
151
- DEFINE_PROP_UINT32("oscclk0", MPS2SCC, oscclk_reset[0], 50000000),
98
+ + n[i * 4 + 2] * m[i * 4 + 2]
152
- DEFINE_PROP_UINT32("oscclk1", MPS2SCC, oscclk_reset[1], 24576000),
99
+ + n[i * 4 + 3] * m[i * 4 + 3];
153
- DEFINE_PROP_UINT32("oscclk2", MPS2SCC, oscclk_reset[2], 25000000),
100
+ }
154
+ DEFINE_PROP_ARRAY("oscclk", MPS2SCC, num_oscclk, oscclk_reset,
101
+ clear_tail(d, opr_sz, simd_maxsz(desc));
155
+ qdev_prop_uint32, uint32_t),
102
+}
156
DEFINE_PROP_END_OF_LIST(),
103
+
157
};
104
+void HELPER(gvec_sdot_h)(void *vd, void *vn, void *vm, uint32_t desc)
158
105
+{
106
+ intptr_t i, opr_sz = simd_oprsz(desc);
107
+ uint64_t *d = vd;
108
+ int16_t *n = vn, *m = vm;
109
+
110
+ for (i = 0; i < opr_sz / 8; ++i) {
111
+ d[i] += (int64_t)n[i * 4 + 0] * m[i * 4 + 0]
112
+ + (int64_t)n[i * 4 + 1] * m[i * 4 + 1]
113
+ + (int64_t)n[i * 4 + 2] * m[i * 4 + 2]
114
+ + (int64_t)n[i * 4 + 3] * m[i * 4 + 3];
115
+ }
116
+ clear_tail(d, opr_sz, simd_maxsz(desc));
117
+}
118
+
119
+void HELPER(gvec_udot_h)(void *vd, void *vn, void *vm, uint32_t desc)
120
+{
121
+ intptr_t i, opr_sz = simd_oprsz(desc);
122
+ uint64_t *d = vd;
123
+ uint16_t *n = vn, *m = vm;
124
+
125
+ for (i = 0; i < opr_sz / 8; ++i) {
126
+ d[i] += (uint64_t)n[i * 4 + 0] * m[i * 4 + 0]
127
+ + (uint64_t)n[i * 4 + 1] * m[i * 4 + 1]
128
+ + (uint64_t)n[i * 4 + 2] * m[i * 4 + 2]
129
+ + (uint64_t)n[i * 4 + 3] * m[i * 4 + 3];
130
+ }
131
+ clear_tail(d, opr_sz, simd_maxsz(desc));
132
+}
133
+
134
void HELPER(gvec_fcaddh)(void *vd, void *vn, void *vm,
135
void *vfpst, uint32_t desc)
136
{
137
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
138
index XXXXXXX..XXXXXXX 100644
139
--- a/target/arm/sve.decode
140
+++ b/target/arm/sve.decode
141
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
142
# SVE integer multiply immediate (unpredicated)
143
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
144
145
+# SVE integer dot product (unpredicated)
146
+DOT_zzz 01000100 1 sz:1 0 rm:5 00000 u:1 rn:5 rd:5 ra=%reg_movprfx
147
+
148
# SVE floating-point complex add (predicated)
149
FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
150
rn=%reg_movprfx
151
--
159
--
152
2.17.1
160
2.20.1
153
161
154
162
diff view generated by jsdifflib
1
From: Aaron Lindsay <alindsay@codeaurora.org>
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.
2
6
3
KVM implies V7VE, which implies ARM_DIV and THUMB_DIV. The conditional
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
detection here is therefore unnecessary. Because V7VE is already
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
unconditionally specified for all KVM hosts, ARM_DIV and THUMB_DIV are
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
already indirectly specified and do not need to be included here at all.
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(-)
7
14
8
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
9
Message-id: 1529699547-17044-6-git-send-email-alindsay@codeaurora.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/kvm32.c | 19 +------------------
13
1 file changed, 1 insertion(+), 18 deletions(-)
14
15
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/kvm32.c
17
--- a/hw/arm/mps2-tz.c
18
+++ b/target/arm/kvm32.c
18
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
19
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
20
* and then query that CPU for the relevant ID registers.
20
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
21
*/
21
/* This will need to be per-FPGA image eventually */
22
int i, ret, fdarray[3];
22
qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
23
- uint32_t midr, id_pfr0, id_isar0, mvfr1;
23
- qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
24
+ uint32_t midr, id_pfr0, mvfr1;
24
- qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
25
uint64_t features = 0;
25
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 40000000);
26
/* Old kernels may not know about the PREFERRED_TARGET ioctl: however
26
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24580000);
27
* we know these will only support creating one kind of guest CPU,
27
qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
28
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
28
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
29
| ENCODE_CP_REG(15, 0, 0, 0, 1, 0, 0),
29
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
30
.addr = (uintptr_t)&id_pfr0,
31
},
32
- {
33
- .id = KVM_REG_ARM | KVM_REG_SIZE_U32
34
- | ENCODE_CP_REG(15, 0, 0, 0, 2, 0, 0),
35
- .addr = (uintptr_t)&id_isar0,
36
- },
37
{
38
.id = KVM_REG_ARM | KVM_REG_SIZE_U32
39
| KVM_REG_ARM_VFP | KVM_REG_ARM_VFP_MVFR1,
40
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
41
set_feature(&features, ARM_FEATURE_VFP3);
42
set_feature(&features, ARM_FEATURE_GENERIC_TIMER);
43
44
- switch (extract32(id_isar0, 24, 4)) {
45
- case 1:
46
- set_feature(&features, ARM_FEATURE_THUMB_DIV);
47
- break;
48
- case 2:
49
- set_feature(&features, ARM_FEATURE_ARM_DIV);
50
- set_feature(&features, ARM_FEATURE_THUMB_DIV);
51
- break;
52
- default:
53
- break;
54
- }
55
-
56
if (extract32(id_pfr0, 12, 4) == 1) {
57
set_feature(&features, ARM_FEATURE_THUMB2EE);
58
}
59
--
30
--
60
2.17.1
31
2.20.1
61
32
62
33
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-26-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
7
---
9
---
8
target/arm/helper-sve.h | 14 +++++++
10
hw/arm/mps2-tz.c | 23 ++++++++++++++++++-----
9
target/arm/sve_helper.c | 8 ++++
11
1 file changed, 18 insertions(+), 5 deletions(-)
10
target/arm/translate-sve.c | 77 ++++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 9 +++++
12
4 files changed, 108 insertions(+)
13
12
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
15
--- a/hw/arm/mps2-tz.c
17
+++ b/target/arm/helper-sve.h
16
+++ b/hw/arm/mps2-tz.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_fcvtzu_sd, TCG_CALL_NO_RWG,
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
19
DEF_HELPER_FLAGS_5(sve_fcvtzu_dd, TCG_CALL_NO_RWG,
18
MPS2TZFPGAType fpga_type;
20
void, ptr, ptr, ptr, ptr, i32)
19
uint32_t scc_id;
21
20
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
22
+DEF_HELPER_FLAGS_5(sve_frint_h, TCG_CALL_NO_RWG,
21
+ uint32_t len_oscclk;
23
+ void, ptr, ptr, ptr, ptr, i32)
22
+ const uint32_t *oscclk;
24
+DEF_HELPER_FLAGS_5(sve_frint_s, TCG_CALL_NO_RWG,
23
const char *armsse_type;
25
+ void, ptr, ptr, ptr, ptr, i32)
24
};
26
+DEF_HELPER_FLAGS_5(sve_frint_d, TCG_CALL_NO_RWG,
25
27
+ void, ptr, ptr, ptr, ptr, i32)
26
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
28
+
27
/* Slow 32Khz S32KCLK frequency in Hz */
29
+DEF_HELPER_FLAGS_5(sve_frintx_h, TCG_CALL_NO_RWG,
28
#define S32KCLK_FRQ (32 * 1000)
30
+ void, ptr, ptr, ptr, ptr, i32)
29
31
+DEF_HELPER_FLAGS_5(sve_frintx_s, TCG_CALL_NO_RWG,
30
+static const uint32_t an505_oscclk[] = {
32
+ void, ptr, ptr, ptr, ptr, i32)
31
+ 40000000,
33
+DEF_HELPER_FLAGS_5(sve_frintx_d, TCG_CALL_NO_RWG,
32
+ 24580000,
34
+ void, ptr, ptr, ptr, ptr, i32)
33
+ 25000000,
35
+
36
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
37
void, ptr, ptr, ptr, ptr, i32)
38
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
39
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/sve_helper.c
42
+++ b/target/arm/sve_helper.c
43
@@ -XXX,XX +XXX,XX @@ DO_ZPZ_FP(sve_fcvtzu_sd, uint64_t, , vfp_float32_to_uint64_rtz)
44
DO_ZPZ_FP(sve_fcvtzu_ds, uint64_t, , helper_vfp_touizd)
45
DO_ZPZ_FP(sve_fcvtzu_dd, uint64_t, , vfp_float64_to_uint64_rtz)
46
47
+DO_ZPZ_FP(sve_frint_h, uint16_t, H1_2, helper_advsimd_rinth)
48
+DO_ZPZ_FP(sve_frint_s, uint32_t, H1_4, helper_rints)
49
+DO_ZPZ_FP(sve_frint_d, uint64_t, , helper_rintd)
50
+
51
+DO_ZPZ_FP(sve_frintx_h, uint16_t, H1_2, float16_round_to_int)
52
+DO_ZPZ_FP(sve_frintx_s, uint32_t, H1_4, float32_round_to_int)
53
+DO_ZPZ_FP(sve_frintx_d, uint64_t, , float64_round_to_int)
54
+
55
DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
56
DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
57
DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
58
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate-sve.c
61
+++ b/target/arm/translate-sve.c
62
@@ -XXX,XX +XXX,XX @@ static bool trans_FCVTZU_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
63
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzu_dd);
64
}
65
66
+static gen_helper_gvec_3_ptr * const frint_fns[3] = {
67
+ gen_helper_sve_frint_h,
68
+ gen_helper_sve_frint_s,
69
+ gen_helper_sve_frint_d
70
+};
34
+};
71
+
35
+
72
+static bool trans_FRINTI(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
36
/* Create an alias of an entire original MemoryRegion @orig
73
+{
37
* located at @base in the memory map.
74
+ if (a->esz == 0) {
38
*/
75
+ return false;
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]);
76
+ }
59
+ }
77
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, a->esz == MO_16,
60
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
78
+ frint_fns[a->esz - 1]);
61
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
79
+}
62
}
80
+
63
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
81
+static bool trans_FRINTX(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
64
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
82
+{
65
mmc->scc_id = 0x41045050;
83
+ static gen_helper_gvec_3_ptr * const fns[3] = {
66
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
84
+ gen_helper_sve_frintx_h,
67
+ mmc->oscclk = an505_oscclk;
85
+ gen_helper_sve_frintx_s,
68
+ mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
86
+ gen_helper_sve_frintx_d
69
mmc->armsse_type = TYPE_IOTKIT;
87
+ };
70
}
88
+ if (a->esz == 0) {
71
89
+ return false;
72
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
90
+ }
73
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
91
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, a->esz == MO_16, fns[a->esz - 1]);
74
mmc->scc_id = 0x41045210;
92
+}
75
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
93
+
76
+ mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
94
+static bool do_frint_mode(DisasContext *s, arg_rpr_esz *a, int mode)
77
+ mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
95
+{
78
mmc->armsse_type = TYPE_SSE200;
96
+ if (a->esz == 0) {
79
}
97
+ return false;
80
98
+ }
99
+ if (sve_access_check(s)) {
100
+ unsigned vsz = vec_full_reg_size(s);
101
+ TCGv_i32 tmode = tcg_const_i32(mode);
102
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
103
+
104
+ gen_helper_set_rmode(tmode, tmode, status);
105
+
106
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
107
+ vec_full_reg_offset(s, a->rn),
108
+ pred_full_reg_offset(s, a->pg),
109
+ status, vsz, vsz, 0, frint_fns[a->esz - 1]);
110
+
111
+ gen_helper_set_rmode(tmode, tmode, status);
112
+ tcg_temp_free_i32(tmode);
113
+ tcg_temp_free_ptr(status);
114
+ }
115
+ return true;
116
+}
117
+
118
+static bool trans_FRINTN(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
119
+{
120
+ return do_frint_mode(s, a, float_round_nearest_even);
121
+}
122
+
123
+static bool trans_FRINTP(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
124
+{
125
+ return do_frint_mode(s, a, float_round_up);
126
+}
127
+
128
+static bool trans_FRINTM(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
129
+{
130
+ return do_frint_mode(s, a, float_round_down);
131
+}
132
+
133
+static bool trans_FRINTZ(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
134
+{
135
+ return do_frint_mode(s, a, float_round_to_zero);
136
+}
137
+
138
+static bool trans_FRINTA(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
139
+{
140
+ return do_frint_mode(s, a, float_round_ties_away);
141
+}
142
+
143
static bool trans_SCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
144
{
145
return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_hh);
146
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
147
index XXXXXXX..XXXXXXX 100644
148
--- a/target/arm/sve.decode
149
+++ b/target/arm/sve.decode
150
@@ -XXX,XX +XXX,XX @@ FCVTZU_sd 01100101 11 011 10 1 101 ... ..... ..... @rd_pg_rn_e0
151
FCVTZS_dd 01100101 11 011 11 0 101 ... ..... ..... @rd_pg_rn_e0
152
FCVTZU_dd 01100101 11 011 11 1 101 ... ..... ..... @rd_pg_rn_e0
153
154
+# SVE floating-point round to integral value
155
+FRINTN 01100101 .. 000 000 101 ... ..... ..... @rd_pg_rn
156
+FRINTP 01100101 .. 000 001 101 ... ..... ..... @rd_pg_rn
157
+FRINTM 01100101 .. 000 010 101 ... ..... ..... @rd_pg_rn
158
+FRINTZ 01100101 .. 000 011 101 ... ..... ..... @rd_pg_rn
159
+FRINTA 01100101 .. 000 100 101 ... ..... ..... @rd_pg_rn
160
+FRINTX 01100101 .. 000 110 101 ... ..... ..... @rd_pg_rn
161
+FRINTI 01100101 .. 000 111 101 ... ..... ..... @rd_pg_rn
162
+
163
# SVE integer convert to floating-point
164
SCVTF_hh 01100101 01 010 01 0 101 ... ..... ..... @rd_pg_rn_e0
165
SCVTF_sh 01100101 01 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
166
--
81
--
167
2.17.1
82
2.20.1
168
83
169
84
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20180627043328.11531-14-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
8
---
10
---
9
target/arm/helper-sve.h | 67 +++++++++++++++++++++++++
11
include/hw/misc/mps2-fpgaio.h | 5 ++++-
10
target/arm/sve_helper.c | 77 ++++++++++++++++++++++++++++
12
hw/misc/mps2-fpgaio.c | 31 +++++++++++++++++++++++--------
11
target/arm/translate-sve.c | 100 +++++++++++++++++++++++++++++++++++++
13
2 files changed, 27 insertions(+), 9 deletions(-)
12
target/arm/sve.decode | 57 +++++++++++++++++++++
13
4 files changed, 301 insertions(+)
14
14
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
17
--- a/include/hw/misc/mps2-fpgaio.h
18
+++ b/target/arm/helper-sve.h
18
+++ b/include/hw/misc/mps2-fpgaio.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_st1hd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
19
@@ -XXX,XX +XXX,XX @@
20
20
#define TYPE_MPS2_FPGAIO "mps2-fpgaio"
21
DEF_HELPER_FLAGS_4(sve_st1sd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
21
OBJECT_DECLARE_SIMPLE_TYPE(MPS2FPGAIO, MPS2_FPGAIO)
22
22
23
+DEF_HELPER_FLAGS_6(sve_ldbsu_zsu, TCG_CALL_NO_WG,
23
+#define MPS2FPGAIO_MAX_LEDS 32
24
+ void, env, ptr, ptr, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_6(sve_ldhsu_zsu, TCG_CALL_NO_WG,
26
+ void, env, ptr, ptr, ptr, tl, i32)
27
+DEF_HELPER_FLAGS_6(sve_ldssu_zsu, TCG_CALL_NO_WG,
28
+ void, env, ptr, ptr, ptr, tl, i32)
29
+DEF_HELPER_FLAGS_6(sve_ldbss_zsu, TCG_CALL_NO_WG,
30
+ void, env, ptr, ptr, ptr, tl, i32)
31
+DEF_HELPER_FLAGS_6(sve_ldhss_zsu, TCG_CALL_NO_WG,
32
+ void, env, ptr, ptr, ptr, tl, i32)
33
+
24
+
34
+DEF_HELPER_FLAGS_6(sve_ldbsu_zss, TCG_CALL_NO_WG,
25
struct MPS2FPGAIO {
35
+ void, env, ptr, ptr, ptr, tl, i32)
26
/*< private >*/
36
+DEF_HELPER_FLAGS_6(sve_ldhsu_zss, TCG_CALL_NO_WG,
27
SysBusDevice parent_obj;
37
+ void, env, ptr, ptr, ptr, tl, i32)
28
38
+DEF_HELPER_FLAGS_6(sve_ldssu_zss, TCG_CALL_NO_WG,
29
/*< public >*/
39
+ void, env, ptr, ptr, ptr, tl, i32)
30
MemoryRegion iomem;
40
+DEF_HELPER_FLAGS_6(sve_ldbss_zss, TCG_CALL_NO_WG,
31
- LEDState *led[2];
41
+ void, env, ptr, ptr, ptr, tl, i32)
32
+ LEDState *led[MPS2FPGAIO_MAX_LEDS];
42
+DEF_HELPER_FLAGS_6(sve_ldhss_zss, TCG_CALL_NO_WG,
33
+ uint32_t num_leds;
43
+ void, env, ptr, ptr, ptr, tl, i32)
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;
44
+
50
+
45
+DEF_HELPER_FLAGS_6(sve_ldbdu_zsu, TCG_CALL_NO_WG,
51
+ s->led0 = value & MAKE_64BIT_MASK(0, s->num_leds);
46
+ void, env, ptr, ptr, ptr, tl, i32)
52
+ for (i = 0; i < s->num_leds; i++) {
47
+DEF_HELPER_FLAGS_6(sve_ldhdu_zsu, TCG_CALL_NO_WG,
53
+ led_set_state(s->led[i], value & (1 << i));
48
+ void, env, ptr, ptr, ptr, tl, i32)
54
+ }
49
+DEF_HELPER_FLAGS_6(sve_ldsdu_zsu, TCG_CALL_NO_WG,
55
+ }
50
+ void, env, ptr, ptr, ptr, tl, i32)
56
break;
51
+DEF_HELPER_FLAGS_6(sve_ldddu_zsu, TCG_CALL_NO_WG,
57
case A_PRESCALE:
52
+ void, env, ptr, ptr, ptr, tl, i32)
58
resync_counter(s);
53
+DEF_HELPER_FLAGS_6(sve_ldbds_zsu, TCG_CALL_NO_WG,
59
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_reset(DeviceState *dev)
54
+ void, env, ptr, ptr, ptr, tl, i32)
60
s->pscntr = 0;
55
+DEF_HELPER_FLAGS_6(sve_ldhds_zsu, TCG_CALL_NO_WG,
61
s->pscntr_sync_ticks = now;
56
+ void, env, ptr, ptr, ptr, tl, i32)
62
57
+DEF_HELPER_FLAGS_6(sve_ldsds_zsu, TCG_CALL_NO_WG,
63
- for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
58
+ void, env, ptr, ptr, ptr, tl, i32)
64
+ for (size_t i = 0; i < s->num_leds; i++) {
59
+
65
device_cold_reset(DEVICE(s->led[i]));
60
+DEF_HELPER_FLAGS_6(sve_ldbdu_zss, TCG_CALL_NO_WG,
61
+ void, env, ptr, ptr, ptr, tl, i32)
62
+DEF_HELPER_FLAGS_6(sve_ldhdu_zss, TCG_CALL_NO_WG,
63
+ void, env, ptr, ptr, ptr, tl, i32)
64
+DEF_HELPER_FLAGS_6(sve_ldsdu_zss, TCG_CALL_NO_WG,
65
+ void, env, ptr, ptr, ptr, tl, i32)
66
+DEF_HELPER_FLAGS_6(sve_ldddu_zss, TCG_CALL_NO_WG,
67
+ void, env, ptr, ptr, ptr, tl, i32)
68
+DEF_HELPER_FLAGS_6(sve_ldbds_zss, TCG_CALL_NO_WG,
69
+ void, env, ptr, ptr, ptr, tl, i32)
70
+DEF_HELPER_FLAGS_6(sve_ldhds_zss, TCG_CALL_NO_WG,
71
+ void, env, ptr, ptr, ptr, tl, i32)
72
+DEF_HELPER_FLAGS_6(sve_ldsds_zss, TCG_CALL_NO_WG,
73
+ void, env, ptr, ptr, ptr, tl, i32)
74
+
75
+DEF_HELPER_FLAGS_6(sve_ldbdu_zd, TCG_CALL_NO_WG,
76
+ void, env, ptr, ptr, ptr, tl, i32)
77
+DEF_HELPER_FLAGS_6(sve_ldhdu_zd, TCG_CALL_NO_WG,
78
+ void, env, ptr, ptr, ptr, tl, i32)
79
+DEF_HELPER_FLAGS_6(sve_ldsdu_zd, TCG_CALL_NO_WG,
80
+ void, env, ptr, ptr, ptr, tl, i32)
81
+DEF_HELPER_FLAGS_6(sve_ldddu_zd, TCG_CALL_NO_WG,
82
+ void, env, ptr, ptr, ptr, tl, i32)
83
+DEF_HELPER_FLAGS_6(sve_ldbds_zd, TCG_CALL_NO_WG,
84
+ void, env, ptr, ptr, ptr, tl, i32)
85
+DEF_HELPER_FLAGS_6(sve_ldhds_zd, TCG_CALL_NO_WG,
86
+ void, env, ptr, ptr, ptr, tl, i32)
87
+DEF_HELPER_FLAGS_6(sve_ldsds_zd, TCG_CALL_NO_WG,
88
+ void, env, ptr, ptr, ptr, tl, i32)
89
+
90
DEF_HELPER_FLAGS_6(sve_stbs_zsu, TCG_CALL_NO_WG,
91
void, env, ptr, ptr, ptr, tl, i32)
92
DEF_HELPER_FLAGS_6(sve_sths_zsu, TCG_CALL_NO_WG,
93
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/sve_helper.c
96
+++ b/target/arm/sve_helper.c
97
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_st4dd_r)(CPUARMState *env, void *vg,
98
}
66
}
99
}
67
}
100
68
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_init(Object *obj)
101
+/* Loads with a vector index. */
69
static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
102
+
70
{
103
+#define DO_LD1_ZPZ_S(NAME, TYPEI, TYPEM, FN) \
71
MPS2FPGAIO *s = MPS2_FPGAIO(dev);
104
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
72
+ uint32_t i;
105
+ target_ulong base, uint32_t desc) \
73
106
+{ \
74
- s->led[0] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
107
+ intptr_t i, oprsz = simd_oprsz(desc); \
75
- LED_COLOR_GREEN, "USERLED0");
108
+ unsigned scale = simd_data(desc); \
76
- s->led[1] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
109
+ uintptr_t ra = GETPC(); \
77
- LED_COLOR_GREEN, "USERLED1");
110
+ for (i = 0; i < oprsz; i++) { \
78
+ if (s->num_leds > MPS2FPGAIO_MAX_LEDS) {
111
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
79
+ error_setg(errp, "num-leds cannot be greater than %d",
112
+ do { \
80
+ MPS2FPGAIO_MAX_LEDS);
113
+ TYPEM m = 0; \
81
+ return;
114
+ if (pg & 1) { \
115
+ target_ulong off = *(TYPEI *)(vm + H1_4(i)); \
116
+ m = FN(env, base + (off << scale), ra); \
117
+ } \
118
+ *(uint32_t *)(vd + H1_4(i)) = m; \
119
+ i += 4, pg >>= 4; \
120
+ } while (i & 15); \
121
+ } \
122
+}
123
+
124
+#define DO_LD1_ZPZ_D(NAME, TYPEI, TYPEM, FN) \
125
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
126
+ target_ulong base, uint32_t desc) \
127
+{ \
128
+ intptr_t i, oprsz = simd_oprsz(desc) / 8; \
129
+ unsigned scale = simd_data(desc); \
130
+ uintptr_t ra = GETPC(); \
131
+ uint64_t *d = vd, *m = vm; uint8_t *pg = vg; \
132
+ for (i = 0; i < oprsz; i++) { \
133
+ TYPEM mm = 0; \
134
+ if (pg[H1(i)] & 1) { \
135
+ target_ulong off = (TYPEI)m[i]; \
136
+ mm = FN(env, base + (off << scale), ra); \
137
+ } \
138
+ d[i] = mm; \
139
+ } \
140
+}
141
+
142
+DO_LD1_ZPZ_S(sve_ldbsu_zsu, uint32_t, uint8_t, cpu_ldub_data_ra)
143
+DO_LD1_ZPZ_S(sve_ldhsu_zsu, uint32_t, uint16_t, cpu_lduw_data_ra)
144
+DO_LD1_ZPZ_S(sve_ldssu_zsu, uint32_t, uint32_t, cpu_ldl_data_ra)
145
+DO_LD1_ZPZ_S(sve_ldbss_zsu, uint32_t, int8_t, cpu_ldub_data_ra)
146
+DO_LD1_ZPZ_S(sve_ldhss_zsu, uint32_t, int16_t, cpu_lduw_data_ra)
147
+
148
+DO_LD1_ZPZ_S(sve_ldbsu_zss, int32_t, uint8_t, cpu_ldub_data_ra)
149
+DO_LD1_ZPZ_S(sve_ldhsu_zss, int32_t, uint16_t, cpu_lduw_data_ra)
150
+DO_LD1_ZPZ_S(sve_ldssu_zss, int32_t, uint32_t, cpu_ldl_data_ra)
151
+DO_LD1_ZPZ_S(sve_ldbss_zss, int32_t, int8_t, cpu_ldub_data_ra)
152
+DO_LD1_ZPZ_S(sve_ldhss_zss, int32_t, int16_t, cpu_lduw_data_ra)
153
+
154
+DO_LD1_ZPZ_D(sve_ldbdu_zsu, uint32_t, uint8_t, cpu_ldub_data_ra)
155
+DO_LD1_ZPZ_D(sve_ldhdu_zsu, uint32_t, uint16_t, cpu_lduw_data_ra)
156
+DO_LD1_ZPZ_D(sve_ldsdu_zsu, uint32_t, uint32_t, cpu_ldl_data_ra)
157
+DO_LD1_ZPZ_D(sve_ldddu_zsu, uint32_t, uint64_t, cpu_ldq_data_ra)
158
+DO_LD1_ZPZ_D(sve_ldbds_zsu, uint32_t, int8_t, cpu_ldub_data_ra)
159
+DO_LD1_ZPZ_D(sve_ldhds_zsu, uint32_t, int16_t, cpu_lduw_data_ra)
160
+DO_LD1_ZPZ_D(sve_ldsds_zsu, uint32_t, int32_t, cpu_ldl_data_ra)
161
+
162
+DO_LD1_ZPZ_D(sve_ldbdu_zss, int32_t, uint8_t, cpu_ldub_data_ra)
163
+DO_LD1_ZPZ_D(sve_ldhdu_zss, int32_t, uint16_t, cpu_lduw_data_ra)
164
+DO_LD1_ZPZ_D(sve_ldsdu_zss, int32_t, uint32_t, cpu_ldl_data_ra)
165
+DO_LD1_ZPZ_D(sve_ldddu_zss, int32_t, uint64_t, cpu_ldq_data_ra)
166
+DO_LD1_ZPZ_D(sve_ldbds_zss, int32_t, int8_t, cpu_ldub_data_ra)
167
+DO_LD1_ZPZ_D(sve_ldhds_zss, int32_t, int16_t, cpu_lduw_data_ra)
168
+DO_LD1_ZPZ_D(sve_ldsds_zss, int32_t, int32_t, cpu_ldl_data_ra)
169
+
170
+DO_LD1_ZPZ_D(sve_ldbdu_zd, uint64_t, uint8_t, cpu_ldub_data_ra)
171
+DO_LD1_ZPZ_D(sve_ldhdu_zd, uint64_t, uint16_t, cpu_lduw_data_ra)
172
+DO_LD1_ZPZ_D(sve_ldsdu_zd, uint64_t, uint32_t, cpu_ldl_data_ra)
173
+DO_LD1_ZPZ_D(sve_ldddu_zd, uint64_t, uint64_t, cpu_ldq_data_ra)
174
+DO_LD1_ZPZ_D(sve_ldbds_zd, uint64_t, int8_t, cpu_ldub_data_ra)
175
+DO_LD1_ZPZ_D(sve_ldhds_zd, uint64_t, int16_t, cpu_lduw_data_ra)
176
+DO_LD1_ZPZ_D(sve_ldsds_zd, uint64_t, int32_t, cpu_ldl_data_ra)
177
+
178
/* Stores with a vector index. */
179
180
#define DO_ST1_ZPZ_S(NAME, TYPEI, FN) \
181
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
182
index XXXXXXX..XXXXXXX 100644
183
--- a/target/arm/translate-sve.c
184
+++ b/target/arm/translate-sve.c
185
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm, int scale,
186
tcg_temp_free_i32(desc);
187
}
188
189
+/* Indexed by [ff][xs][u][msz]. */
190
+static gen_helper_gvec_mem_scatter * const gather_load_fn32[2][2][2][3] = {
191
+ { { { gen_helper_sve_ldbss_zsu,
192
+ gen_helper_sve_ldhss_zsu,
193
+ NULL, },
194
+ { gen_helper_sve_ldbsu_zsu,
195
+ gen_helper_sve_ldhsu_zsu,
196
+ gen_helper_sve_ldssu_zsu, } },
197
+ { { gen_helper_sve_ldbss_zss,
198
+ gen_helper_sve_ldhss_zss,
199
+ NULL, },
200
+ { gen_helper_sve_ldbsu_zss,
201
+ gen_helper_sve_ldhsu_zss,
202
+ gen_helper_sve_ldssu_zss, } } },
203
+ /* TODO fill in first-fault handlers */
204
+};
205
+
206
+/* Note that we overload xs=2 to indicate 64-bit offset. */
207
+static gen_helper_gvec_mem_scatter * const gather_load_fn64[2][3][2][4] = {
208
+ { { { gen_helper_sve_ldbds_zsu,
209
+ gen_helper_sve_ldhds_zsu,
210
+ gen_helper_sve_ldsds_zsu,
211
+ NULL, },
212
+ { gen_helper_sve_ldbdu_zsu,
213
+ gen_helper_sve_ldhdu_zsu,
214
+ gen_helper_sve_ldsdu_zsu,
215
+ gen_helper_sve_ldddu_zsu, } },
216
+ { { gen_helper_sve_ldbds_zss,
217
+ gen_helper_sve_ldhds_zss,
218
+ gen_helper_sve_ldsds_zss,
219
+ NULL, },
220
+ { gen_helper_sve_ldbdu_zss,
221
+ gen_helper_sve_ldhdu_zss,
222
+ gen_helper_sve_ldsdu_zss,
223
+ gen_helper_sve_ldddu_zss, } },
224
+ { { gen_helper_sve_ldbds_zd,
225
+ gen_helper_sve_ldhds_zd,
226
+ gen_helper_sve_ldsds_zd,
227
+ NULL, },
228
+ { gen_helper_sve_ldbdu_zd,
229
+ gen_helper_sve_ldhdu_zd,
230
+ gen_helper_sve_ldsdu_zd,
231
+ gen_helper_sve_ldddu_zd, } } },
232
+ /* TODO fill in first-fault handlers */
233
+};
234
+
235
+static bool trans_LD1_zprz(DisasContext *s, arg_LD1_zprz *a, uint32_t insn)
236
+{
237
+ gen_helper_gvec_mem_scatter *fn = NULL;
238
+
239
+ if (!sve_access_check(s)) {
240
+ return true;
241
+ }
82
+ }
242
+
83
+
243
+ switch (a->esz) {
84
+ for (i = 0; i < s->num_leds; i++) {
244
+ case MO_32:
85
+ g_autofree char *ledname = g_strdup_printf("USERLED%d", i);
245
+ fn = gather_load_fn32[a->ff][a->xs][a->u][a->msz];
86
+ s->led[i] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
246
+ break;
87
+ LED_COLOR_GREEN, ledname);
247
+ case MO_64:
248
+ fn = gather_load_fn64[a->ff][a->xs][a->u][a->msz];
249
+ break;
250
+ }
88
+ }
251
+ assert(fn != NULL);
89
}
252
+
90
253
+ do_mem_zpz(s, a->rd, a->pg, a->rm, a->scale * a->msz,
91
static bool mps2_fpgaio_counters_needed(void *opaque)
254
+ cpu_reg_sp(s, a->rn), fn);
92
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_fpgaio_vmstate = {
255
+ return true;
93
static Property mps2_fpgaio_properties[] = {
256
+}
94
/* Frequency of the prescale counter */
257
+
95
DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000),
258
+static bool trans_LD1_zpiz(DisasContext *s, arg_LD1_zpiz *a, uint32_t insn)
96
+ /* Number of LEDs controlled by LED0 register */
259
+{
97
+ DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
260
+ gen_helper_gvec_mem_scatter *fn = NULL;
98
DEFINE_PROP_END_OF_LIST(),
261
+ TCGv_i64 imm;
99
};
262
+
263
+ if (a->esz < a->msz || (a->esz == a->msz && !a->u)) {
264
+ return false;
265
+ }
266
+ if (!sve_access_check(s)) {
267
+ return true;
268
+ }
269
+
270
+ switch (a->esz) {
271
+ case MO_32:
272
+ fn = gather_load_fn32[a->ff][0][a->u][a->msz];
273
+ break;
274
+ case MO_64:
275
+ fn = gather_load_fn64[a->ff][2][a->u][a->msz];
276
+ break;
277
+ }
278
+ assert(fn != NULL);
279
+
280
+ /* Treat LD1_zpiz (zn[x] + imm) the same way as LD1_zprz (rn + zm[x])
281
+ * by loading the immediate into the scalar parameter.
282
+ */
283
+ imm = tcg_const_i64(a->imm << a->msz);
284
+ do_mem_zpz(s, a->rd, a->pg, a->rn, 0, imm, fn);
285
+ tcg_temp_free_i64(imm);
286
+ return true;
287
+}
288
+
289
static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
290
{
291
/* Indexed by [xs][msz]. */
292
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
293
index XXXXXXX..XXXXXXX 100644
294
--- a/target/arm/sve.decode
295
+++ b/target/arm/sve.decode
296
@@ -XXX,XX +XXX,XX @@
297
&rpri_load rd pg rn imm dtype nreg
298
&rprr_store rd pg rn rm msz esz nreg
299
&rpri_store rd pg rn imm msz esz nreg
300
+&rprr_gather_load rd pg rn rm esz msz u ff xs scale
301
+&rpri_gather_load rd pg rn imm esz msz u ff
302
&rprr_scatter_store rd pg rn rm esz msz xs scale
303
304
###########################################################################
305
@@ -XXX,XX +XXX,XX @@
306
@rpri_load_msz ....... .... . imm:s4 ... pg:3 rn:5 rd:5 \
307
&rpri_load dtype=%msz_dtype
308
309
+# Gather Loads.
310
+@rprr_g_load_u ....... .. . . rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
311
+ &rprr_gather_load xs=2
312
+@rprr_g_load_xs_u ....... .. xs:1 . rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
313
+ &rprr_gather_load
314
+@rprr_g_load_xs_u_sc ....... .. xs:1 scale:1 rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
315
+ &rprr_gather_load
316
+@rprr_g_load_xs_sc ....... .. xs:1 scale:1 rm:5 . . ff:1 pg:3 rn:5 rd:5 \
317
+ &rprr_gather_load
318
+@rprr_g_load_u_sc ....... .. . scale:1 rm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
319
+ &rprr_gather_load xs=2
320
+@rprr_g_load_sc ....... .. . scale:1 rm:5 . . ff:1 pg:3 rn:5 rd:5 \
321
+ &rprr_gather_load xs=2
322
+@rpri_g_load ....... msz:2 .. imm:5 . u:1 ff:1 pg:3 rn:5 rd:5 \
323
+ &rpri_gather_load
324
+
325
# Stores; user must fill in ESZ, MSZ, NREG as needed.
326
@rprr_store ....... .. .. rm:5 ... pg:3 rn:5 rd:5 &rprr_store
327
@rpri_store_msz ....... msz:2 .. . imm:s4 ... pg:3 rn:5 rd:5 &rpri_store
328
@@ -XXX,XX +XXX,XX @@ LDR_zri 10000101 10 ...... 010 ... ..... ..... @rd_rn_i9
329
LD1R_zpri 1000010 .. 1 imm:6 1.. pg:3 rn:5 rd:5 \
330
&rpri_load dtype=%dtype_23_13 nreg=0
331
332
+# SVE 32-bit gather load (scalar plus 32-bit unscaled offsets)
333
+# SVE 32-bit gather load (scalar plus 32-bit scaled offsets)
334
+LD1_zprz 1000010 00 .0 ..... 0.. ... ..... ..... \
335
+ @rprr_g_load_xs_u esz=2 msz=0 scale=0
336
+LD1_zprz 1000010 01 .. ..... 0.. ... ..... ..... \
337
+ @rprr_g_load_xs_u_sc esz=2 msz=1
338
+LD1_zprz 1000010 10 .. ..... 01. ... ..... ..... \
339
+ @rprr_g_load_xs_sc esz=2 msz=2 u=1
340
+
341
+# SVE 32-bit gather load (vector plus immediate)
342
+LD1_zpiz 1000010 .. 01 ..... 1.. ... ..... ..... \
343
+ @rpri_g_load esz=2
344
+
345
### SVE Memory Contiguous Load Group
346
347
# SVE contiguous load (scalar plus scalar)
348
@@ -XXX,XX +XXX,XX @@ PRF_rr 1000010 -- 00 rm:5 110 --- ----- 0 ----
349
350
### SVE Memory 64-bit Gather Group
351
352
+# SVE 64-bit gather load (scalar plus 32-bit unpacked unscaled offsets)
353
+# SVE 64-bit gather load (scalar plus 32-bit unpacked scaled offsets)
354
+LD1_zprz 1100010 00 .0 ..... 0.. ... ..... ..... \
355
+ @rprr_g_load_xs_u esz=3 msz=0 scale=0
356
+LD1_zprz 1100010 01 .. ..... 0.. ... ..... ..... \
357
+ @rprr_g_load_xs_u_sc esz=3 msz=1
358
+LD1_zprz 1100010 10 .. ..... 0.. ... ..... ..... \
359
+ @rprr_g_load_xs_u_sc esz=3 msz=2
360
+LD1_zprz 1100010 11 .. ..... 01. ... ..... ..... \
361
+ @rprr_g_load_xs_sc esz=3 msz=3 u=1
362
+
363
+# SVE 64-bit gather load (scalar plus 64-bit unscaled offsets)
364
+# SVE 64-bit gather load (scalar plus 64-bit scaled offsets)
365
+LD1_zprz 1100010 00 10 ..... 1.. ... ..... ..... \
366
+ @rprr_g_load_u esz=3 msz=0 scale=0
367
+LD1_zprz 1100010 01 1. ..... 1.. ... ..... ..... \
368
+ @rprr_g_load_u_sc esz=3 msz=1
369
+LD1_zprz 1100010 10 1. ..... 1.. ... ..... ..... \
370
+ @rprr_g_load_u_sc esz=3 msz=2
371
+LD1_zprz 1100010 11 1. ..... 11. ... ..... ..... \
372
+ @rprr_g_load_sc esz=3 msz=3 u=1
373
+
374
+# SVE 64-bit gather load (vector plus immediate)
375
+LD1_zpiz 1100010 .. 01 ..... 1.. ... ..... ..... \
376
+ @rpri_g_load esz=3
377
+
378
# SVE 64-bit gather prefetch (scalar plus 64-bit scaled offsets)
379
PRF 1100010 00 11 ----- 1-- --- ----- 0 ----
380
100
381
--
101
--
382
2.17.1
102
2.20.1
383
103
384
104
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-15-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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-7-peter.maydell@linaro.org
7
---
9
---
8
target/arm/helper-sve.h | 67 +++++++++++++++++++++++++++++
10
include/hw/misc/mps2-fpgaio.h | 1 +
9
target/arm/sve_helper.c | 88 ++++++++++++++++++++++++++++++++++++++
11
hw/misc/mps2-fpgaio.c | 10 ++++++++++
10
target/arm/translate-sve.c | 40 ++++++++++++++++-
12
2 files changed, 11 insertions(+)
11
3 files changed, 193 insertions(+), 2 deletions(-)
12
13
13
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.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-sve.h
16
--- a/include/hw/misc/mps2-fpgaio.h
16
+++ b/target/arm/helper-sve.h
17
+++ b/include/hw/misc/mps2-fpgaio.h
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_ldhds_zd, TCG_CALL_NO_WG,
18
@@ -XXX,XX +XXX,XX @@ struct MPS2FPGAIO {
18
DEF_HELPER_FLAGS_6(sve_ldsds_zd, TCG_CALL_NO_WG,
19
MemoryRegion iomem;
19
void, env, ptr, ptr, ptr, tl, i32)
20
LEDState *led[MPS2FPGAIO_MAX_LEDS];
20
21
uint32_t num_leds;
21
+DEF_HELPER_FLAGS_6(sve_ldffbsu_zsu, TCG_CALL_NO_WG,
22
+ bool has_switches;
22
+ void, env, ptr, ptr, ptr, tl, i32)
23
23
+DEF_HELPER_FLAGS_6(sve_ldffhsu_zsu, TCG_CALL_NO_WG,
24
uint32_t led0;
24
+ void, env, ptr, ptr, ptr, tl, i32)
25
uint32_t prescale;
25
+DEF_HELPER_FLAGS_6(sve_ldffssu_zsu, TCG_CALL_NO_WG,
26
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
26
+ void, env, ptr, ptr, ptr, tl, i32)
27
+DEF_HELPER_FLAGS_6(sve_ldffbss_zsu, TCG_CALL_NO_WG,
28
+ void, env, ptr, ptr, ptr, tl, i32)
29
+DEF_HELPER_FLAGS_6(sve_ldffhss_zsu, TCG_CALL_NO_WG,
30
+ void, env, ptr, ptr, ptr, tl, i32)
31
+
32
+DEF_HELPER_FLAGS_6(sve_ldffbsu_zss, TCG_CALL_NO_WG,
33
+ void, env, ptr, ptr, ptr, tl, i32)
34
+DEF_HELPER_FLAGS_6(sve_ldffhsu_zss, TCG_CALL_NO_WG,
35
+ void, env, ptr, ptr, ptr, tl, i32)
36
+DEF_HELPER_FLAGS_6(sve_ldffssu_zss, TCG_CALL_NO_WG,
37
+ void, env, ptr, ptr, ptr, tl, i32)
38
+DEF_HELPER_FLAGS_6(sve_ldffbss_zss, TCG_CALL_NO_WG,
39
+ void, env, ptr, ptr, ptr, tl, i32)
40
+DEF_HELPER_FLAGS_6(sve_ldffhss_zss, TCG_CALL_NO_WG,
41
+ void, env, ptr, ptr, ptr, tl, i32)
42
+
43
+DEF_HELPER_FLAGS_6(sve_ldffbdu_zsu, TCG_CALL_NO_WG,
44
+ void, env, ptr, ptr, ptr, tl, i32)
45
+DEF_HELPER_FLAGS_6(sve_ldffhdu_zsu, TCG_CALL_NO_WG,
46
+ void, env, ptr, ptr, ptr, tl, i32)
47
+DEF_HELPER_FLAGS_6(sve_ldffsdu_zsu, TCG_CALL_NO_WG,
48
+ void, env, ptr, ptr, ptr, tl, i32)
49
+DEF_HELPER_FLAGS_6(sve_ldffddu_zsu, TCG_CALL_NO_WG,
50
+ void, env, ptr, ptr, ptr, tl, i32)
51
+DEF_HELPER_FLAGS_6(sve_ldffbds_zsu, TCG_CALL_NO_WG,
52
+ void, env, ptr, ptr, ptr, tl, i32)
53
+DEF_HELPER_FLAGS_6(sve_ldffhds_zsu, TCG_CALL_NO_WG,
54
+ void, env, ptr, ptr, ptr, tl, i32)
55
+DEF_HELPER_FLAGS_6(sve_ldffsds_zsu, TCG_CALL_NO_WG,
56
+ void, env, ptr, ptr, ptr, tl, i32)
57
+
58
+DEF_HELPER_FLAGS_6(sve_ldffbdu_zss, TCG_CALL_NO_WG,
59
+ void, env, ptr, ptr, ptr, tl, i32)
60
+DEF_HELPER_FLAGS_6(sve_ldffhdu_zss, TCG_CALL_NO_WG,
61
+ void, env, ptr, ptr, ptr, tl, i32)
62
+DEF_HELPER_FLAGS_6(sve_ldffsdu_zss, TCG_CALL_NO_WG,
63
+ void, env, ptr, ptr, ptr, tl, i32)
64
+DEF_HELPER_FLAGS_6(sve_ldffddu_zss, TCG_CALL_NO_WG,
65
+ void, env, ptr, ptr, ptr, tl, i32)
66
+DEF_HELPER_FLAGS_6(sve_ldffbds_zss, TCG_CALL_NO_WG,
67
+ void, env, ptr, ptr, ptr, tl, i32)
68
+DEF_HELPER_FLAGS_6(sve_ldffhds_zss, TCG_CALL_NO_WG,
69
+ void, env, ptr, ptr, ptr, tl, i32)
70
+DEF_HELPER_FLAGS_6(sve_ldffsds_zss, TCG_CALL_NO_WG,
71
+ void, env, ptr, ptr, ptr, tl, i32)
72
+
73
+DEF_HELPER_FLAGS_6(sve_ldffbdu_zd, TCG_CALL_NO_WG,
74
+ void, env, ptr, ptr, ptr, tl, i32)
75
+DEF_HELPER_FLAGS_6(sve_ldffhdu_zd, TCG_CALL_NO_WG,
76
+ void, env, ptr, ptr, ptr, tl, i32)
77
+DEF_HELPER_FLAGS_6(sve_ldffsdu_zd, TCG_CALL_NO_WG,
78
+ void, env, ptr, ptr, ptr, tl, i32)
79
+DEF_HELPER_FLAGS_6(sve_ldffddu_zd, TCG_CALL_NO_WG,
80
+ void, env, ptr, ptr, ptr, tl, i32)
81
+DEF_HELPER_FLAGS_6(sve_ldffbds_zd, TCG_CALL_NO_WG,
82
+ void, env, ptr, ptr, ptr, tl, i32)
83
+DEF_HELPER_FLAGS_6(sve_ldffhds_zd, TCG_CALL_NO_WG,
84
+ void, env, ptr, ptr, ptr, tl, i32)
85
+DEF_HELPER_FLAGS_6(sve_ldffsds_zd, TCG_CALL_NO_WG,
86
+ void, env, ptr, ptr, ptr, tl, i32)
87
+
88
DEF_HELPER_FLAGS_6(sve_stbs_zsu, TCG_CALL_NO_WG,
89
void, env, ptr, ptr, ptr, tl, i32)
90
DEF_HELPER_FLAGS_6(sve_sths_zsu, TCG_CALL_NO_WG,
91
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
92
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/sve_helper.c
28
--- a/hw/misc/mps2-fpgaio.c
94
+++ b/target/arm/sve_helper.c
29
+++ b/hw/misc/mps2-fpgaio.c
95
@@ -XXX,XX +XXX,XX @@ DO_LD1_ZPZ_D(sve_ldbds_zd, uint64_t, int8_t, cpu_ldub_data_ra)
30
@@ -XXX,XX +XXX,XX @@ REG32(CLK100HZ, 0x14)
96
DO_LD1_ZPZ_D(sve_ldhds_zd, uint64_t, int16_t, cpu_lduw_data_ra)
31
REG32(COUNTER, 0x18)
97
DO_LD1_ZPZ_D(sve_ldsds_zd, uint64_t, int32_t, cpu_ldl_data_ra)
32
REG32(PRESCALE, 0x1c)
98
33
REG32(PSCNTR, 0x20)
99
+/* First fault loads with a vector index. */
34
+REG32(SWITCH, 0x28)
100
+
35
REG32(MISC, 0x4c)
101
+#ifdef CONFIG_USER_ONLY
36
102
+
37
static uint32_t counter_from_tickoff(int64_t now, int64_t tick_offset, int frq)
103
+#define DO_LDFF1_ZPZ(NAME, TYPEE, TYPEI, TYPEM, FN, H) \
38
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
104
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
39
resync_counter(s);
105
+ target_ulong base, uint32_t desc) \
40
r = s->pscntr;
106
+{ \
41
break;
107
+ intptr_t i, oprsz = simd_oprsz(desc); \
42
+ case A_SWITCH:
108
+ unsigned scale = simd_data(desc); \
43
+ if (!s->has_switches) {
109
+ uintptr_t ra = GETPC(); \
44
+ goto bad_offset;
110
+ bool first = true; \
45
+ }
111
+ mmap_lock(); \
46
+ /* User-togglable board switches. We don't model that, so report 0. */
112
+ for (i = 0; i < oprsz; i++) { \
47
+ r = 0;
113
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
48
+ break;
114
+ do { \
49
default:
115
+ TYPEM m = 0; \
50
+ bad_offset:
116
+ if (pg & 1) { \
51
qemu_log_mask(LOG_GUEST_ERROR,
117
+ target_ulong off = *(TYPEI *)(vm + H(i)); \
52
"MPS2 FPGAIO read: bad offset %x\n", (int) offset);
118
+ target_ulong addr = base + (off << scale); \
53
r = 0;
119
+ if (!first && \
54
@@ -XXX,XX +XXX,XX @@ static Property mps2_fpgaio_properties[] = {
120
+ page_check_range(addr, sizeof(TYPEM), PAGE_READ)) { \
55
DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000),
121
+ record_fault(env, i, oprsz); \
56
/* Number of LEDs controlled by LED0 register */
122
+ goto exit; \
57
DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
123
+ } \
58
+ DEFINE_PROP_BOOL("has-switches", MPS2FPGAIO, has_switches, false),
124
+ m = FN(env, addr, ra); \
59
DEFINE_PROP_END_OF_LIST(),
125
+ first = false; \
126
+ } \
127
+ *(TYPEE *)(vd + H(i)) = m; \
128
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
129
+ } while (i & 15); \
130
+ } \
131
+ exit: \
132
+ mmap_unlock(); \
133
+}
134
+
135
+#else
136
+
137
+#define DO_LDFF1_ZPZ(NAME, TYPEE, TYPEI, TYPEM, FN, H) \
138
+void HELPER(NAME)(CPUARMState *env, void *vd, void *vg, void *vm, \
139
+ target_ulong base, uint32_t desc) \
140
+{ \
141
+ g_assert_not_reached(); \
142
+}
143
+
144
+#endif
145
+
146
+#define DO_LDFF1_ZPZ_S(NAME, TYPEI, TYPEM, FN) \
147
+ DO_LDFF1_ZPZ(NAME, uint32_t, TYPEI, TYPEM, FN, H1_4)
148
+#define DO_LDFF1_ZPZ_D(NAME, TYPEI, TYPEM, FN) \
149
+ DO_LDFF1_ZPZ(NAME, uint64_t, TYPEI, TYPEM, FN, )
150
+
151
+DO_LDFF1_ZPZ_S(sve_ldffbsu_zsu, uint32_t, uint8_t, cpu_ldub_data_ra)
152
+DO_LDFF1_ZPZ_S(sve_ldffhsu_zsu, uint32_t, uint16_t, cpu_lduw_data_ra)
153
+DO_LDFF1_ZPZ_S(sve_ldffssu_zsu, uint32_t, uint32_t, cpu_ldl_data_ra)
154
+DO_LDFF1_ZPZ_S(sve_ldffbss_zsu, uint32_t, int8_t, cpu_ldub_data_ra)
155
+DO_LDFF1_ZPZ_S(sve_ldffhss_zsu, uint32_t, int16_t, cpu_lduw_data_ra)
156
+
157
+DO_LDFF1_ZPZ_S(sve_ldffbsu_zss, int32_t, uint8_t, cpu_ldub_data_ra)
158
+DO_LDFF1_ZPZ_S(sve_ldffhsu_zss, int32_t, uint16_t, cpu_lduw_data_ra)
159
+DO_LDFF1_ZPZ_S(sve_ldffssu_zss, int32_t, uint32_t, cpu_ldl_data_ra)
160
+DO_LDFF1_ZPZ_S(sve_ldffbss_zss, int32_t, int8_t, cpu_ldub_data_ra)
161
+DO_LDFF1_ZPZ_S(sve_ldffhss_zss, int32_t, int16_t, cpu_lduw_data_ra)
162
+
163
+DO_LDFF1_ZPZ_D(sve_ldffbdu_zsu, uint32_t, uint8_t, cpu_ldub_data_ra)
164
+DO_LDFF1_ZPZ_D(sve_ldffhdu_zsu, uint32_t, uint16_t, cpu_lduw_data_ra)
165
+DO_LDFF1_ZPZ_D(sve_ldffsdu_zsu, uint32_t, uint32_t, cpu_ldl_data_ra)
166
+DO_LDFF1_ZPZ_D(sve_ldffddu_zsu, uint32_t, uint64_t, cpu_ldq_data_ra)
167
+DO_LDFF1_ZPZ_D(sve_ldffbds_zsu, uint32_t, int8_t, cpu_ldub_data_ra)
168
+DO_LDFF1_ZPZ_D(sve_ldffhds_zsu, uint32_t, int16_t, cpu_lduw_data_ra)
169
+DO_LDFF1_ZPZ_D(sve_ldffsds_zsu, uint32_t, int32_t, cpu_ldl_data_ra)
170
+
171
+DO_LDFF1_ZPZ_D(sve_ldffbdu_zss, int32_t, uint8_t, cpu_ldub_data_ra)
172
+DO_LDFF1_ZPZ_D(sve_ldffhdu_zss, int32_t, uint16_t, cpu_lduw_data_ra)
173
+DO_LDFF1_ZPZ_D(sve_ldffsdu_zss, int32_t, uint32_t, cpu_ldl_data_ra)
174
+DO_LDFF1_ZPZ_D(sve_ldffddu_zss, int32_t, uint64_t, cpu_ldq_data_ra)
175
+DO_LDFF1_ZPZ_D(sve_ldffbds_zss, int32_t, int8_t, cpu_ldub_data_ra)
176
+DO_LDFF1_ZPZ_D(sve_ldffhds_zss, int32_t, int16_t, cpu_lduw_data_ra)
177
+DO_LDFF1_ZPZ_D(sve_ldffsds_zss, int32_t, int32_t, cpu_ldl_data_ra)
178
+
179
+DO_LDFF1_ZPZ_D(sve_ldffbdu_zd, uint64_t, uint8_t, cpu_ldub_data_ra)
180
+DO_LDFF1_ZPZ_D(sve_ldffhdu_zd, uint64_t, uint16_t, cpu_lduw_data_ra)
181
+DO_LDFF1_ZPZ_D(sve_ldffsdu_zd, uint64_t, uint32_t, cpu_ldl_data_ra)
182
+DO_LDFF1_ZPZ_D(sve_ldffddu_zd, uint64_t, uint64_t, cpu_ldq_data_ra)
183
+DO_LDFF1_ZPZ_D(sve_ldffbds_zd, uint64_t, int8_t, cpu_ldub_data_ra)
184
+DO_LDFF1_ZPZ_D(sve_ldffhds_zd, uint64_t, int16_t, cpu_lduw_data_ra)
185
+DO_LDFF1_ZPZ_D(sve_ldffsds_zd, uint64_t, int32_t, cpu_ldl_data_ra)
186
+
187
/* Stores with a vector index. */
188
189
#define DO_ST1_ZPZ_S(NAME, TYPEI, FN) \
190
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
191
index XXXXXXX..XXXXXXX 100644
192
--- a/target/arm/translate-sve.c
193
+++ b/target/arm/translate-sve.c
194
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_mem_scatter * const gather_load_fn32[2][2][2][3] = {
195
{ gen_helper_sve_ldbsu_zss,
196
gen_helper_sve_ldhsu_zss,
197
gen_helper_sve_ldssu_zss, } } },
198
- /* TODO fill in first-fault handlers */
199
+
200
+ { { { gen_helper_sve_ldffbss_zsu,
201
+ gen_helper_sve_ldffhss_zsu,
202
+ NULL, },
203
+ { gen_helper_sve_ldffbsu_zsu,
204
+ gen_helper_sve_ldffhsu_zsu,
205
+ gen_helper_sve_ldffssu_zsu, } },
206
+ { { gen_helper_sve_ldffbss_zss,
207
+ gen_helper_sve_ldffhss_zss,
208
+ NULL, },
209
+ { gen_helper_sve_ldffbsu_zss,
210
+ gen_helper_sve_ldffhsu_zss,
211
+ gen_helper_sve_ldffssu_zss, } } }
212
};
60
};
213
61
214
/* Note that we overload xs=2 to indicate 64-bit offset. */
215
@@ -XXX,XX +XXX,XX @@ static gen_helper_gvec_mem_scatter * const gather_load_fn64[2][3][2][4] = {
216
gen_helper_sve_ldhdu_zd,
217
gen_helper_sve_ldsdu_zd,
218
gen_helper_sve_ldddu_zd, } } },
219
- /* TODO fill in first-fault handlers */
220
+
221
+ { { { gen_helper_sve_ldffbds_zsu,
222
+ gen_helper_sve_ldffhds_zsu,
223
+ gen_helper_sve_ldffsds_zsu,
224
+ NULL, },
225
+ { gen_helper_sve_ldffbdu_zsu,
226
+ gen_helper_sve_ldffhdu_zsu,
227
+ gen_helper_sve_ldffsdu_zsu,
228
+ gen_helper_sve_ldffddu_zsu, } },
229
+ { { gen_helper_sve_ldffbds_zss,
230
+ gen_helper_sve_ldffhds_zss,
231
+ gen_helper_sve_ldffsds_zss,
232
+ NULL, },
233
+ { gen_helper_sve_ldffbdu_zss,
234
+ gen_helper_sve_ldffhdu_zss,
235
+ gen_helper_sve_ldffsdu_zss,
236
+ gen_helper_sve_ldffddu_zss, } },
237
+ { { gen_helper_sve_ldffbds_zd,
238
+ gen_helper_sve_ldffhds_zd,
239
+ gen_helper_sve_ldffsds_zd,
240
+ NULL, },
241
+ { gen_helper_sve_ldffbdu_zd,
242
+ gen_helper_sve_ldffhdu_zd,
243
+ gen_helper_sve_ldffsdu_zd,
244
+ gen_helper_sve_ldffddu_zd, } } }
245
};
246
247
static bool trans_LD1_zprz(DisasContext *s, arg_LD1_zprz *a, uint32_t insn)
248
--
62
--
249
2.17.1
63
2.20.1
250
64
251
65
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180627043328.11531-2-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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-8-peter.maydell@linaro.org
8
---
10
---
9
target/arm/helper-sve.h | 35 +++++++++
11
hw/arm/mps2-tz.c | 9 +++++++++
10
target/arm/sve_helper.c | 153 +++++++++++++++++++++++++++++++++++++
12
1 file changed, 9 insertions(+)
11
target/arm/translate-sve.c | 121 +++++++++++++++++++++++++++++
12
target/arm/sve.decode | 34 +++++++++
13
4 files changed, 343 insertions(+)
14
13
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
14
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
16
--- a/hw/arm/mps2-tz.c
18
+++ b/target/arm/helper-sve.h
17
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
18
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
20
void, ptr, ptr, ptr, ptr, i32)
19
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
21
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
20
uint32_t len_oscclk;
22
void, ptr, ptr, ptr, ptr, i32)
21
const uint32_t *oscclk;
23
+
22
+ uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
24
+DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
23
+ bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
25
+DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
24
const char *armsse_type;
26
+DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
25
};
27
+DEF_HELPER_FLAGS_4(sve_ld4bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
26
28
+
27
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
29
+DEF_HELPER_FLAGS_4(sve_ld1hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
28
const char *name, hwaddr size)
30
+DEF_HELPER_FLAGS_4(sve_ld2hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
29
{
31
+DEF_HELPER_FLAGS_4(sve_ld3hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
30
MPS2FPGAIO *fpgaio = opaque;
32
+DEF_HELPER_FLAGS_4(sve_ld4hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
31
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
33
+
32
34
+DEF_HELPER_FLAGS_4(sve_ld1ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
33
object_initialize_child(OBJECT(mms), "fpgaio", fpgaio, TYPE_MPS2_FPGAIO);
35
+DEF_HELPER_FLAGS_4(sve_ld2ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
34
+ qdev_prop_set_uint32(DEVICE(fpgaio), "num-leds", mmc->fpgaio_num_leds);
36
+DEF_HELPER_FLAGS_4(sve_ld3ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
35
+ qdev_prop_set_bit(DEVICE(fpgaio), "has-switches", mmc->fpgaio_has_switches);
37
+DEF_HELPER_FLAGS_4(sve_ld4ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
36
sysbus_realize(SYS_BUS_DEVICE(fpgaio), &error_fatal);
38
+
37
return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
39
+DEF_HELPER_FLAGS_4(sve_ld1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
40
+DEF_HELPER_FLAGS_4(sve_ld2dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
+DEF_HELPER_FLAGS_4(sve_ld3dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
42
+DEF_HELPER_FLAGS_4(sve_ld4dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
43
+
44
+DEF_HELPER_FLAGS_4(sve_ld1bhu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
45
+DEF_HELPER_FLAGS_4(sve_ld1bsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
46
+DEF_HELPER_FLAGS_4(sve_ld1bdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
47
+DEF_HELPER_FLAGS_4(sve_ld1bhs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
48
+DEF_HELPER_FLAGS_4(sve_ld1bss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
49
+DEF_HELPER_FLAGS_4(sve_ld1bds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
50
+
51
+DEF_HELPER_FLAGS_4(sve_ld1hsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
52
+DEF_HELPER_FLAGS_4(sve_ld1hdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
53
+DEF_HELPER_FLAGS_4(sve_ld1hss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
54
+DEF_HELPER_FLAGS_4(sve_ld1hds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
55
+
56
+DEF_HELPER_FLAGS_4(sve_ld1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
57
+DEF_HELPER_FLAGS_4(sve_ld1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
58
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/sve_helper.c
61
+++ b/target/arm/sve_helper.c
62
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
63
64
return predtest_ones(d, oprsz, esz_mask);
65
}
38
}
66
+
39
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
67
+/*
40
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
68
+ * Load contiguous data, protected by a governing predicate.
41
mmc->oscclk = an505_oscclk;
69
+ */
42
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
70
+#define DO_LD1(NAME, FN, TYPEE, TYPEM, H) \
43
+ mmc->fpgaio_num_leds = 2;
71
+static void do_##NAME(CPUARMState *env, void *vd, void *vg, \
44
+ mmc->fpgaio_has_switches = false;
72
+ target_ulong addr, intptr_t oprsz, \
45
mmc->armsse_type = TYPE_IOTKIT;
73
+ uintptr_t ra) \
74
+{ \
75
+ intptr_t i = 0; \
76
+ do { \
77
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
78
+ do { \
79
+ TYPEM m = 0; \
80
+ if (pg & 1) { \
81
+ m = FN(env, addr, ra); \
82
+ } \
83
+ *(TYPEE *)(vd + H(i)) = m; \
84
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
85
+ addr += sizeof(TYPEM); \
86
+ } while (i & 15); \
87
+ } while (i < oprsz); \
88
+} \
89
+void HELPER(NAME)(CPUARMState *env, void *vg, \
90
+ target_ulong addr, uint32_t desc) \
91
+{ \
92
+ do_##NAME(env, &env->vfp.zregs[simd_data(desc)], vg, \
93
+ addr, simd_oprsz(desc), GETPC()); \
94
+}
95
+
96
+#define DO_LD2(NAME, FN, TYPEE, TYPEM, H) \
97
+void HELPER(NAME)(CPUARMState *env, void *vg, \
98
+ target_ulong addr, uint32_t desc) \
99
+{ \
100
+ intptr_t i, oprsz = simd_oprsz(desc); \
101
+ intptr_t ra = GETPC(); \
102
+ unsigned rd = simd_data(desc); \
103
+ void *d1 = &env->vfp.zregs[rd]; \
104
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
105
+ for (i = 0; i < oprsz; ) { \
106
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
107
+ do { \
108
+ TYPEM m1 = 0, m2 = 0; \
109
+ if (pg & 1) { \
110
+ m1 = FN(env, addr, ra); \
111
+ m2 = FN(env, addr + sizeof(TYPEM), ra); \
112
+ } \
113
+ *(TYPEE *)(d1 + H(i)) = m1; \
114
+ *(TYPEE *)(d2 + H(i)) = m2; \
115
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
116
+ addr += 2 * sizeof(TYPEM); \
117
+ } while (i & 15); \
118
+ } \
119
+}
120
+
121
+#define DO_LD3(NAME, FN, TYPEE, TYPEM, H) \
122
+void HELPER(NAME)(CPUARMState *env, void *vg, \
123
+ target_ulong addr, uint32_t desc) \
124
+{ \
125
+ intptr_t i, oprsz = simd_oprsz(desc); \
126
+ intptr_t ra = GETPC(); \
127
+ unsigned rd = simd_data(desc); \
128
+ void *d1 = &env->vfp.zregs[rd]; \
129
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
130
+ void *d3 = &env->vfp.zregs[(rd + 2) & 31]; \
131
+ for (i = 0; i < oprsz; ) { \
132
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
133
+ do { \
134
+ TYPEM m1 = 0, m2 = 0, m3 = 0; \
135
+ if (pg & 1) { \
136
+ m1 = FN(env, addr, ra); \
137
+ m2 = FN(env, addr + sizeof(TYPEM), ra); \
138
+ m3 = FN(env, addr + 2 * sizeof(TYPEM), ra); \
139
+ } \
140
+ *(TYPEE *)(d1 + H(i)) = m1; \
141
+ *(TYPEE *)(d2 + H(i)) = m2; \
142
+ *(TYPEE *)(d3 + H(i)) = m3; \
143
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
144
+ addr += 3 * sizeof(TYPEM); \
145
+ } while (i & 15); \
146
+ } \
147
+}
148
+
149
+#define DO_LD4(NAME, FN, TYPEE, TYPEM, H) \
150
+void HELPER(NAME)(CPUARMState *env, void *vg, \
151
+ target_ulong addr, uint32_t desc) \
152
+{ \
153
+ intptr_t i, oprsz = simd_oprsz(desc); \
154
+ intptr_t ra = GETPC(); \
155
+ unsigned rd = simd_data(desc); \
156
+ void *d1 = &env->vfp.zregs[rd]; \
157
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
158
+ void *d3 = &env->vfp.zregs[(rd + 2) & 31]; \
159
+ void *d4 = &env->vfp.zregs[(rd + 3) & 31]; \
160
+ for (i = 0; i < oprsz; ) { \
161
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
162
+ do { \
163
+ TYPEM m1 = 0, m2 = 0, m3 = 0, m4 = 0; \
164
+ if (pg & 1) { \
165
+ m1 = FN(env, addr, ra); \
166
+ m2 = FN(env, addr + sizeof(TYPEM), ra); \
167
+ m3 = FN(env, addr + 2 * sizeof(TYPEM), ra); \
168
+ m4 = FN(env, addr + 3 * sizeof(TYPEM), ra); \
169
+ } \
170
+ *(TYPEE *)(d1 + H(i)) = m1; \
171
+ *(TYPEE *)(d2 + H(i)) = m2; \
172
+ *(TYPEE *)(d3 + H(i)) = m3; \
173
+ *(TYPEE *)(d4 + H(i)) = m4; \
174
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
175
+ addr += 4 * sizeof(TYPEM); \
176
+ } while (i & 15); \
177
+ } \
178
+}
179
+
180
+DO_LD1(sve_ld1bhu_r, cpu_ldub_data_ra, uint16_t, uint8_t, H1_2)
181
+DO_LD1(sve_ld1bhs_r, cpu_ldsb_data_ra, uint16_t, int8_t, H1_2)
182
+DO_LD1(sve_ld1bsu_r, cpu_ldub_data_ra, uint32_t, uint8_t, H1_4)
183
+DO_LD1(sve_ld1bss_r, cpu_ldsb_data_ra, uint32_t, int8_t, H1_4)
184
+DO_LD1(sve_ld1bdu_r, cpu_ldub_data_ra, uint64_t, uint8_t, )
185
+DO_LD1(sve_ld1bds_r, cpu_ldsb_data_ra, uint64_t, int8_t, )
186
+
187
+DO_LD1(sve_ld1hsu_r, cpu_lduw_data_ra, uint32_t, uint16_t, H1_4)
188
+DO_LD1(sve_ld1hss_r, cpu_ldsw_data_ra, uint32_t, int8_t, H1_4)
189
+DO_LD1(sve_ld1hdu_r, cpu_lduw_data_ra, uint64_t, uint16_t, )
190
+DO_LD1(sve_ld1hds_r, cpu_ldsw_data_ra, uint64_t, int16_t, )
191
+
192
+DO_LD1(sve_ld1sdu_r, cpu_ldl_data_ra, uint64_t, uint32_t, )
193
+DO_LD1(sve_ld1sds_r, cpu_ldl_data_ra, uint64_t, int32_t, )
194
+
195
+DO_LD1(sve_ld1bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
196
+DO_LD2(sve_ld2bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
197
+DO_LD3(sve_ld3bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
198
+DO_LD4(sve_ld4bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
199
+
200
+DO_LD1(sve_ld1hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
201
+DO_LD2(sve_ld2hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
202
+DO_LD3(sve_ld3hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
203
+DO_LD4(sve_ld4hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
204
+
205
+DO_LD1(sve_ld1ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
206
+DO_LD2(sve_ld2ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
207
+DO_LD3(sve_ld3ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
208
+DO_LD4(sve_ld4ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
209
+
210
+DO_LD1(sve_ld1dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
211
+DO_LD2(sve_ld2dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
212
+DO_LD3(sve_ld3dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
213
+DO_LD4(sve_ld4dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
214
+
215
+#undef DO_LD1
216
+#undef DO_LD2
217
+#undef DO_LD3
218
+#undef DO_LD4
219
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
220
index XXXXXXX..XXXXXXX 100644
221
--- a/target/arm/translate-sve.c
222
+++ b/target/arm/translate-sve.c
223
@@ -XXX,XX +XXX,XX @@ typedef void gen_helper_gvec_flags_3(TCGv_i32, TCGv_ptr, TCGv_ptr,
224
typedef void gen_helper_gvec_flags_4(TCGv_i32, TCGv_ptr, TCGv_ptr,
225
TCGv_ptr, TCGv_ptr, TCGv_i32);
226
227
+typedef void gen_helper_gvec_mem(TCGv_env, TCGv_ptr, TCGv_i64, TCGv_i32);
228
+
229
/*
230
* Helpers for extracting complex instruction fields.
231
*/
232
@@ -XXX,XX +XXX,XX @@ static inline int expand_imm_sh8u(int x)
233
return (uint8_t)x << (x & 0x100 ? 8 : 0);
234
}
46
}
235
47
236
+/* Convert a 2-bit memory size (msz) to a 4-bit data type (dtype)
48
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
237
+ * with unsigned data. C.f. SVE Memory Contiguous Load Group.
49
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
238
+ */
50
mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
239
+static inline int msz_dtype(int msz)
51
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
240
+{
52
+ mmc->fpgaio_num_leds = 2;
241
+ static const uint8_t dtype[4] = { 0, 5, 10, 15 };
53
+ mmc->fpgaio_has_switches = false;
242
+ return dtype[msz];
54
mmc->armsse_type = TYPE_SSE200;
243
+}
244
+
245
/*
246
* Include the generated decoder.
247
*/
248
@@ -XXX,XX +XXX,XX @@ static bool trans_LDR_pri(DisasContext *s, arg_rri *a, uint32_t insn)
249
}
250
return true;
251
}
55
}
252
+
56
253
+/*
254
+ *** SVE Memory - Contiguous Load Group
255
+ */
256
+
257
+/* The memory mode of the dtype. */
258
+static const TCGMemOp dtype_mop[16] = {
259
+ MO_UB, MO_UB, MO_UB, MO_UB,
260
+ MO_SL, MO_UW, MO_UW, MO_UW,
261
+ MO_SW, MO_SW, MO_UL, MO_UL,
262
+ MO_SB, MO_SB, MO_SB, MO_Q
263
+};
264
+
265
+#define dtype_msz(x) (dtype_mop[x] & MO_SIZE)
266
+
267
+/* The vector element size of dtype. */
268
+static const uint8_t dtype_esz[16] = {
269
+ 0, 1, 2, 3,
270
+ 3, 1, 2, 3,
271
+ 3, 2, 2, 3,
272
+ 3, 2, 1, 3
273
+};
274
+
275
+static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
276
+ gen_helper_gvec_mem *fn)
277
+{
278
+ unsigned vsz = vec_full_reg_size(s);
279
+ TCGv_ptr t_pg;
280
+ TCGv_i32 desc;
281
+
282
+ /* For e.g. LD4, there are not enough arguments to pass all 4
283
+ * registers as pointers, so encode the regno into the data field.
284
+ * For consistency, do this even for LD1.
285
+ */
286
+ desc = tcg_const_i32(simd_desc(vsz, vsz, zt));
287
+ t_pg = tcg_temp_new_ptr();
288
+
289
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
290
+ fn(cpu_env, t_pg, addr, desc);
291
+
292
+ tcg_temp_free_ptr(t_pg);
293
+ tcg_temp_free_i32(desc);
294
+}
295
+
296
+static void do_ld_zpa(DisasContext *s, int zt, int pg,
297
+ TCGv_i64 addr, int dtype, int nreg)
298
+{
299
+ static gen_helper_gvec_mem * const fns[16][4] = {
300
+ { gen_helper_sve_ld1bb_r, gen_helper_sve_ld2bb_r,
301
+ gen_helper_sve_ld3bb_r, gen_helper_sve_ld4bb_r },
302
+ { gen_helper_sve_ld1bhu_r, NULL, NULL, NULL },
303
+ { gen_helper_sve_ld1bsu_r, NULL, NULL, NULL },
304
+ { gen_helper_sve_ld1bdu_r, NULL, NULL, NULL },
305
+
306
+ { gen_helper_sve_ld1sds_r, NULL, NULL, NULL },
307
+ { gen_helper_sve_ld1hh_r, gen_helper_sve_ld2hh_r,
308
+ gen_helper_sve_ld3hh_r, gen_helper_sve_ld4hh_r },
309
+ { gen_helper_sve_ld1hsu_r, NULL, NULL, NULL },
310
+ { gen_helper_sve_ld1hdu_r, NULL, NULL, NULL },
311
+
312
+ { gen_helper_sve_ld1hds_r, NULL, NULL, NULL },
313
+ { gen_helper_sve_ld1hss_r, NULL, NULL, NULL },
314
+ { gen_helper_sve_ld1ss_r, gen_helper_sve_ld2ss_r,
315
+ gen_helper_sve_ld3ss_r, gen_helper_sve_ld4ss_r },
316
+ { gen_helper_sve_ld1sdu_r, NULL, NULL, NULL },
317
+
318
+ { gen_helper_sve_ld1bds_r, NULL, NULL, NULL },
319
+ { gen_helper_sve_ld1bss_r, NULL, NULL, NULL },
320
+ { gen_helper_sve_ld1bhs_r, NULL, NULL, NULL },
321
+ { gen_helper_sve_ld1dd_r, gen_helper_sve_ld2dd_r,
322
+ gen_helper_sve_ld3dd_r, gen_helper_sve_ld4dd_r },
323
+ };
324
+ gen_helper_gvec_mem *fn = fns[dtype][nreg];
325
+
326
+ /* While there are holes in the table, they are not
327
+ * accessible via the instruction encoding.
328
+ */
329
+ assert(fn != NULL);
330
+ do_mem_zpa(s, zt, pg, addr, fn);
331
+}
332
+
333
+static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a, uint32_t insn)
334
+{
335
+ if (a->rm == 31) {
336
+ return false;
337
+ }
338
+ if (sve_access_check(s)) {
339
+ TCGv_i64 addr = new_tmp_a64(s);
340
+ tcg_gen_muli_i64(addr, cpu_reg(s, a->rm),
341
+ (a->nreg + 1) << dtype_msz(a->dtype));
342
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
343
+ do_ld_zpa(s, a->rd, a->pg, addr, a->dtype, a->nreg);
344
+ }
345
+ return true;
346
+}
347
+
348
+static bool trans_LD_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
349
+{
350
+ if (sve_access_check(s)) {
351
+ int vsz = vec_full_reg_size(s);
352
+ int elements = vsz >> dtype_esz[a->dtype];
353
+ TCGv_i64 addr = new_tmp_a64(s);
354
+
355
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn),
356
+ (a->imm * elements * (a->nreg + 1))
357
+ << dtype_msz(a->dtype));
358
+ do_ld_zpa(s, a->rd, a->pg, addr, a->dtype, a->nreg);
359
+ }
360
+ return true;
361
+}
362
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
363
index XXXXXXX..XXXXXXX 100644
364
--- a/target/arm/sve.decode
365
+++ b/target/arm/sve.decode
366
@@ -XXX,XX +XXX,XX @@
367
# Unsigned 8-bit immediate, optionally shifted left by 8.
368
%sh8_i8u 5:9 !function=expand_imm_sh8u
369
370
+# Unsigned load of msz into esz=2, represented as a dtype.
371
+%msz_dtype 23:2 !function=msz_dtype
372
+
373
# Either a copy of rd (at bit 0), or a different source
374
# as propagated via the MOVPRFX instruction.
375
%reg_movprfx 0:5
376
@@ -XXX,XX +XXX,XX @@
377
&incdec2_cnt rd rn pat esz imm d u
378
&incdec_pred rd pg esz d u
379
&incdec2_pred rd rn pg esz d u
380
+&rprr_load rd pg rn rm dtype nreg
381
+&rpri_load rd pg rn imm dtype nreg
382
383
###########################################################################
384
# Named instruction formats. These are generally used to
385
@@ -XXX,XX +XXX,XX @@
386
@incdec2_pred ........ esz:2 .... .. ..... .. pg:4 rd:5 \
387
&incdec2_pred rn=%reg_movprfx
388
389
+# Loads; user must fill in NREG.
390
+@rprr_load_dt ....... dtype:4 rm:5 ... pg:3 rn:5 rd:5 &rprr_load
391
+@rpri_load_dt ....... dtype:4 . imm:s4 ... pg:3 rn:5 rd:5 &rpri_load
392
+
393
+@rprr_load_msz ....... .... rm:5 ... pg:3 rn:5 rd:5 \
394
+ &rprr_load dtype=%msz_dtype
395
+@rpri_load_msz ....... .... . imm:s4 ... pg:3 rn:5 rd:5 \
396
+ &rpri_load dtype=%msz_dtype
397
+
398
###########################################################################
399
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
400
401
@@ -XXX,XX +XXX,XX @@ LDR_pri 10000101 10 ...... 000 ... ..... 0 .... @pd_rn_i9
402
403
# SVE load vector register
404
LDR_zri 10000101 10 ...... 010 ... ..... ..... @rd_rn_i9
405
+
406
+### SVE Memory Contiguous Load Group
407
+
408
+# SVE contiguous load (scalar plus scalar)
409
+LD_zprr 1010010 .... ..... 010 ... ..... ..... @rprr_load_dt nreg=0
410
+
411
+# SVE contiguous load (scalar plus immediate)
412
+LD_zpri 1010010 .... 0.... 101 ... ..... ..... @rpri_load_dt nreg=0
413
+
414
+# SVE contiguous non-temporal load (scalar plus scalar)
415
+# LDNT1B, LDNT1H, LDNT1W, LDNT1D
416
+# SVE load multiple structures (scalar plus scalar)
417
+# LD2B, LD2H, LD2W, LD2D; etc.
418
+LD_zprr 1010010 .. nreg:2 ..... 110 ... ..... ..... @rprr_load_msz
419
+
420
+# SVE contiguous non-temporal load (scalar plus immediate)
421
+# LDNT1B, LDNT1H, LDNT1W, LDNT1D
422
+# SVE load multiple structures (scalar plus immediate)
423
+# LD2B, LD2H, LD2W, LD2D; etc.
424
+LD_zpri 1010010 .. nreg:2 0.... 111 ... ..... ..... @rpri_load_msz
425
--
57
--
426
2.17.1
58
2.20.1
427
59
428
60
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
We can avoid making an explicit check on the board type constant by
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
instead creating and using the IRQ splitters for any board with more
5
Message-id: 20180627043328.11531-29-richard.henderson@linaro.org
8
than 1 CPU. This avoids having to add extra cases to the
9
conditionals every time we add new boards.
10
6
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
7
---
15
---
8
target/arm/helper-sve.h | 7 +++
16
hw/arm/mps2-tz.c | 19 +++++++++----------
9
target/arm/sve_helper.c | 100 +++++++++++++++++++++++++++++++++++++
17
1 file changed, 9 insertions(+), 10 deletions(-)
10
target/arm/translate-sve.c | 24 +++++++++
11
target/arm/sve.decode | 4 ++
12
4 files changed, 135 insertions(+)
13
18
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
19
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
21
--- a/hw/arm/mps2-tz.c
17
+++ b/target/arm/helper-sve.h
22
+++ b/hw/arm/mps2-tz.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_facgt_s, TCG_CALL_NO_RWG,
23
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
19
DEF_HELPER_FLAGS_6(sve_facgt_d, TCG_CALL_NO_RWG,
24
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
20
void, ptr, ptr, ptr, ptr, ptr, i32)
25
{
21
26
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
22
+DEF_HELPER_FLAGS_6(sve_fcadd_h, TCG_CALL_NO_RWG,
27
- MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
23
+ void, ptr, ptr, ptr, ptr, ptr, i32)
28
+ MachineClass *mc = MACHINE_GET_CLASS(mms);
24
+DEF_HELPER_FLAGS_6(sve_fcadd_s, TCG_CALL_NO_RWG,
29
25
+ void, ptr, ptr, ptr, ptr, ptr, i32)
30
assert(irqno < MPS2TZ_NUMIRQ);
26
+DEF_HELPER_FLAGS_6(sve_fcadd_d, TCG_CALL_NO_RWG,
31
27
+ void, ptr, ptr, ptr, ptr, ptr, i32)
32
- switch (mmc->fpga_type) {
28
+
33
- case FPGA_AN505:
29
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
34
- return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
30
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
35
- case FPGA_AN521:
31
DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
36
+ if (mc->max_cpus > 1) {
32
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
37
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
33
index XXXXXXX..XXXXXXX 100644
38
- default:
34
--- a/target/arm/sve_helper.c
39
- g_assert_not_reached();
35
+++ b/target/arm/sve_helper.c
40
+ } else {
36
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_ftmad_d)(void *vd, void *vn, void *vm, void *vs, uint32_t desc)
41
+ return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
37
}
42
}
38
}
43
}
39
44
40
+/*
45
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
41
+ * FP Complex Add
46
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
42
+ */
47
43
+
48
/*
44
+void HELPER(sve_fcadd_h)(void *vd, void *vn, void *vm, void *vg,
49
- * The AN521 needs us to create splitters to feed the IRQ inputs
45
+ void *vs, uint32_t desc)
50
- * for each CPU in the SSE-200 from each device in the board.
46
+{
51
+ * If this board has more than one CPU, then we need to create splitters
47
+ intptr_t j, i = simd_oprsz(desc);
52
+ * to feed the IRQ inputs for each CPU in the SSE from each device in the
48
+ uint64_t *g = vg;
53
+ * board. If there is only one CPU, we can just wire the device IRQ
49
+ float16 neg_imag = float16_set_sign(0, simd_data(desc));
54
+ * directly to the SSE's IRQ input.
50
+ float16 neg_real = float16_chs(neg_imag);
55
*/
51
+
56
- if (mmc->fpga_type == FPGA_AN521) {
52
+ do {
57
+ if (mc->max_cpus > 1) {
53
+ uint64_t pg = g[(i - 1) >> 6];
58
for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
54
+ do {
59
char *name = g_strdup_printf("mps2-irq-splitter%d", i);
55
+ float16 e0, e1, e2, e3;
60
SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
56
+
57
+ /* I holds the real index; J holds the imag index. */
58
+ j = i - sizeof(float16);
59
+ i -= 2 * sizeof(float16);
60
+
61
+ e0 = *(float16 *)(vn + H1_2(i));
62
+ e1 = *(float16 *)(vm + H1_2(j)) ^ neg_real;
63
+ e2 = *(float16 *)(vn + H1_2(j));
64
+ e3 = *(float16 *)(vm + H1_2(i)) ^ neg_imag;
65
+
66
+ if (likely((pg >> (i & 63)) & 1)) {
67
+ *(float16 *)(vd + H1_2(i)) = float16_add(e0, e1, vs);
68
+ }
69
+ if (likely((pg >> (j & 63)) & 1)) {
70
+ *(float16 *)(vd + H1_2(j)) = float16_add(e2, e3, vs);
71
+ }
72
+ } while (i & 63);
73
+ } while (i != 0);
74
+}
75
+
76
+void HELPER(sve_fcadd_s)(void *vd, void *vn, void *vm, void *vg,
77
+ void *vs, uint32_t desc)
78
+{
79
+ intptr_t j, i = simd_oprsz(desc);
80
+ uint64_t *g = vg;
81
+ float32 neg_imag = float32_set_sign(0, simd_data(desc));
82
+ float32 neg_real = float32_chs(neg_imag);
83
+
84
+ do {
85
+ uint64_t pg = g[(i - 1) >> 6];
86
+ do {
87
+ float32 e0, e1, e2, e3;
88
+
89
+ /* I holds the real index; J holds the imag index. */
90
+ j = i - sizeof(float32);
91
+ i -= 2 * sizeof(float32);
92
+
93
+ e0 = *(float32 *)(vn + H1_2(i));
94
+ e1 = *(float32 *)(vm + H1_2(j)) ^ neg_real;
95
+ e2 = *(float32 *)(vn + H1_2(j));
96
+ e3 = *(float32 *)(vm + H1_2(i)) ^ neg_imag;
97
+
98
+ if (likely((pg >> (i & 63)) & 1)) {
99
+ *(float32 *)(vd + H1_2(i)) = float32_add(e0, e1, vs);
100
+ }
101
+ if (likely((pg >> (j & 63)) & 1)) {
102
+ *(float32 *)(vd + H1_2(j)) = float32_add(e2, e3, vs);
103
+ }
104
+ } while (i & 63);
105
+ } while (i != 0);
106
+}
107
+
108
+void HELPER(sve_fcadd_d)(void *vd, void *vn, void *vm, void *vg,
109
+ void *vs, uint32_t desc)
110
+{
111
+ intptr_t j, i = simd_oprsz(desc);
112
+ uint64_t *g = vg;
113
+ float64 neg_imag = float64_set_sign(0, simd_data(desc));
114
+ float64 neg_real = float64_chs(neg_imag);
115
+
116
+ do {
117
+ uint64_t pg = g[(i - 1) >> 6];
118
+ do {
119
+ float64 e0, e1, e2, e3;
120
+
121
+ /* I holds the real index; J holds the imag index. */
122
+ j = i - sizeof(float64);
123
+ i -= 2 * sizeof(float64);
124
+
125
+ e0 = *(float64 *)(vn + H1_2(i));
126
+ e1 = *(float64 *)(vm + H1_2(j)) ^ neg_real;
127
+ e2 = *(float64 *)(vn + H1_2(j));
128
+ e3 = *(float64 *)(vm + H1_2(i)) ^ neg_imag;
129
+
130
+ if (likely((pg >> (i & 63)) & 1)) {
131
+ *(float64 *)(vd + H1_2(i)) = float64_add(e0, e1, vs);
132
+ }
133
+ if (likely((pg >> (j & 63)) & 1)) {
134
+ *(float64 *)(vd + H1_2(j)) = float64_add(e2, e3, vs);
135
+ }
136
+ } while (i & 63);
137
+ } while (i != 0);
138
+}
139
+
140
/*
141
* Load contiguous data, protected by a governing predicate.
142
*/
143
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/target/arm/translate-sve.c
146
+++ b/target/arm/translate-sve.c
147
@@ -XXX,XX +XXX,XX @@ DO_FPCMP(FACGT, facgt)
148
149
#undef DO_FPCMP
150
151
+static bool trans_FCADD(DisasContext *s, arg_FCADD *a, uint32_t insn)
152
+{
153
+ static gen_helper_gvec_4_ptr * const fns[3] = {
154
+ gen_helper_sve_fcadd_h,
155
+ gen_helper_sve_fcadd_s,
156
+ gen_helper_sve_fcadd_d
157
+ };
158
+
159
+ if (a->esz == 0) {
160
+ return false;
161
+ }
162
+ if (sve_access_check(s)) {
163
+ unsigned vsz = vec_full_reg_size(s);
164
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
165
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
166
+ vec_full_reg_offset(s, a->rn),
167
+ vec_full_reg_offset(s, a->rm),
168
+ pred_full_reg_offset(s, a->pg),
169
+ status, vsz, vsz, a->rot, fns[a->esz - 1]);
170
+ tcg_temp_free_ptr(status);
171
+ }
172
+ return true;
173
+}
174
+
175
typedef void gen_helper_sve_fmla(TCGv_env, TCGv_ptr, TCGv_i32);
176
177
static bool do_fmla(DisasContext *s, arg_rprrr_esz *a, gen_helper_sve_fmla *fn)
178
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
179
index XXXXXXX..XXXXXXX 100644
180
--- a/target/arm/sve.decode
181
+++ b/target/arm/sve.decode
182
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
183
# SVE integer multiply immediate (unpredicated)
184
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
185
186
+# SVE floating-point complex add (predicated)
187
+FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
188
+ rn=%reg_movprfx
189
+
190
### SVE FP Multiply-Add Indexed Group
191
192
# SVE floating-point multiply-add (indexed)
193
--
61
--
194
2.17.1
62
2.20.1
195
63
196
64
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Since the difference is small (92 on the current boards and 95 on the
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
new one) we don't dynamically allocate the cpu_irq_splitter[] array
5
Message-id: 20180627043328.11531-20-richard.henderson@linaro.org
6
but leave it as a fixed length array whose size is the maximum needed
7
for any of the boards.
8
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-10-peter.maydell@linaro.org
7
---
13
---
8
target/arm/helper-sve.h | 35 ++++++++++++++++++++++
14
hw/arm/mps2-tz.c | 15 ++++++++++-----
9
target/arm/sve_helper.c | 61 ++++++++++++++++++++++++++++++++++++++
15
1 file changed, 10 insertions(+), 5 deletions(-)
10
target/arm/translate-sve.c | 57 +++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 8 +++++
12
4 files changed, 161 insertions(+)
13
16
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
19
--- a/hw/arm/mps2-tz.c
17
+++ b/target/arm/helper-sve.h
20
+++ b/hw/arm/mps2-tz.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
21
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
22
#include "hw/qdev-clock.h"
20
void, ptr, ptr, ptr, ptr, i32)
23
#include "qom/object.h"
21
24
22
+DEF_HELPER_FLAGS_4(sve_faddv_h, TCG_CALL_NO_RWG,
25
-#define MPS2TZ_NUMIRQ 92
23
+ i64, ptr, ptr, ptr, i32)
26
+#define MPS2TZ_NUMIRQ_MAX 92
24
+DEF_HELPER_FLAGS_4(sve_faddv_s, TCG_CALL_NO_RWG,
27
25
+ i64, ptr, ptr, ptr, i32)
28
typedef enum MPS2TZFPGAType {
26
+DEF_HELPER_FLAGS_4(sve_faddv_d, TCG_CALL_NO_RWG,
29
FPGA_AN505,
27
+ i64, ptr, ptr, ptr, i32)
30
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
28
+
31
const uint32_t *oscclk;
29
+DEF_HELPER_FLAGS_4(sve_fmaxnmv_h, TCG_CALL_NO_RWG,
32
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
30
+ i64, ptr, ptr, ptr, i32)
33
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
31
+DEF_HELPER_FLAGS_4(sve_fmaxnmv_s, TCG_CALL_NO_RWG,
34
+ int numirq; /* Number of external interrupts */
32
+ i64, ptr, ptr, ptr, i32)
35
const char *armsse_type;
33
+DEF_HELPER_FLAGS_4(sve_fmaxnmv_d, TCG_CALL_NO_RWG,
36
};
34
+ i64, ptr, ptr, ptr, i32)
37
35
+
38
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
36
+DEF_HELPER_FLAGS_4(sve_fminnmv_h, TCG_CALL_NO_RWG,
39
SplitIRQ sec_resp_splitter;
37
+ i64, ptr, ptr, ptr, i32)
40
qemu_or_irq uart_irq_orgate;
38
+DEF_HELPER_FLAGS_4(sve_fminnmv_s, TCG_CALL_NO_RWG,
41
DeviceState *lan9118;
39
+ i64, ptr, ptr, ptr, i32)
42
- SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
40
+DEF_HELPER_FLAGS_4(sve_fminnmv_d, TCG_CALL_NO_RWG,
43
+ SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
41
+ i64, ptr, ptr, ptr, i32)
44
Clock *sysclk;
42
+
45
Clock *s32kclk;
43
+DEF_HELPER_FLAGS_4(sve_fmaxv_h, TCG_CALL_NO_RWG,
46
};
44
+ i64, ptr, ptr, ptr, i32)
47
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
45
+DEF_HELPER_FLAGS_4(sve_fmaxv_s, TCG_CALL_NO_RWG,
48
{
46
+ i64, ptr, ptr, ptr, i32)
49
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
47
+DEF_HELPER_FLAGS_4(sve_fmaxv_d, TCG_CALL_NO_RWG,
50
MachineClass *mc = MACHINE_GET_CLASS(mms);
48
+ i64, ptr, ptr, ptr, i32)
51
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
49
+
52
50
+DEF_HELPER_FLAGS_4(sve_fminv_h, TCG_CALL_NO_RWG,
53
- assert(irqno < MPS2TZ_NUMIRQ);
51
+ i64, ptr, ptr, ptr, i32)
54
+ assert(irqno < mmc->numirq);
52
+DEF_HELPER_FLAGS_4(sve_fminv_s, TCG_CALL_NO_RWG,
55
53
+ i64, ptr, ptr, ptr, i32)
56
if (mc->max_cpus > 1) {
54
+DEF_HELPER_FLAGS_4(sve_fminv_d, TCG_CALL_NO_RWG,
57
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
55
+ i64, ptr, ptr, ptr, i32)
58
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
56
+
59
iotkitdev = DEVICE(&mms->iotkit);
57
DEF_HELPER_FLAGS_5(sve_fadda_h, TCG_CALL_NO_RWG,
60
object_property_set_link(OBJECT(&mms->iotkit), "memory",
58
i64, i64, ptr, ptr, ptr, i32)
61
OBJECT(system_memory), &error_abort);
59
DEF_HELPER_FLAGS_5(sve_fadda_s, TCG_CALL_NO_RWG,
62
- qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
60
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
63
+ qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
61
index XXXXXXX..XXXXXXX 100644
64
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
62
--- a/target/arm/sve_helper.c
65
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
63
+++ b/target/arm/sve_helper.c
66
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
64
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
67
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
65
return predtest_ones(d, oprsz, esz_mask);
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;
66
}
84
}
67
85
68
+/* Recursive reduction on a function;
86
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
69
+ * C.f. the ARM ARM function ReducePredicated.
87
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
70
+ *
88
mmc->fpgaio_num_leds = 2;
71
+ * While it would be possible to write this without the DATA temporary,
89
mmc->fpgaio_has_switches = false;
72
+ * it is much simpler to process the predicate register this way.
90
+ mmc->numirq = 92;
73
+ * The recursion is bounded to depth 7 (128 fp16 elements), so there's
91
mmc->armsse_type = TYPE_SSE200;
74
+ * little to gain with a more complex non-recursive form.
75
+ */
76
+#define DO_REDUCE(NAME, TYPE, H, FUNC, IDENT) \
77
+static TYPE NAME##_reduce(TYPE *data, float_status *status, uintptr_t n) \
78
+{ \
79
+ if (n == 1) { \
80
+ return *data; \
81
+ } else { \
82
+ uintptr_t half = n / 2; \
83
+ TYPE lo = NAME##_reduce(data, status, half); \
84
+ TYPE hi = NAME##_reduce(data + half, status, half); \
85
+ return TYPE##_##FUNC(lo, hi, status); \
86
+ } \
87
+} \
88
+uint64_t HELPER(NAME)(void *vn, void *vg, void *vs, uint32_t desc) \
89
+{ \
90
+ uintptr_t i, oprsz = simd_oprsz(desc), maxsz = simd_maxsz(desc); \
91
+ TYPE data[sizeof(ARMVectorReg) / sizeof(TYPE)]; \
92
+ for (i = 0; i < oprsz; ) { \
93
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
94
+ do { \
95
+ TYPE nn = *(TYPE *)(vn + H(i)); \
96
+ *(TYPE *)((void *)data + i) = (pg & 1 ? nn : IDENT); \
97
+ i += sizeof(TYPE), pg >>= sizeof(TYPE); \
98
+ } while (i & 15); \
99
+ } \
100
+ for (; i < maxsz; i += sizeof(TYPE)) { \
101
+ *(TYPE *)((void *)data + i) = IDENT; \
102
+ } \
103
+ return NAME##_reduce(data, vs, maxsz / sizeof(TYPE)); \
104
+}
105
+
106
+DO_REDUCE(sve_faddv_h, float16, H1_2, add, float16_zero)
107
+DO_REDUCE(sve_faddv_s, float32, H1_4, add, float32_zero)
108
+DO_REDUCE(sve_faddv_d, float64, , add, float64_zero)
109
+
110
+/* Identity is floatN_default_nan, without the function call. */
111
+DO_REDUCE(sve_fminnmv_h, float16, H1_2, minnum, 0x7E00)
112
+DO_REDUCE(sve_fminnmv_s, float32, H1_4, minnum, 0x7FC00000)
113
+DO_REDUCE(sve_fminnmv_d, float64, , minnum, 0x7FF8000000000000ULL)
114
+
115
+DO_REDUCE(sve_fmaxnmv_h, float16, H1_2, maxnum, 0x7E00)
116
+DO_REDUCE(sve_fmaxnmv_s, float32, H1_4, maxnum, 0x7FC00000)
117
+DO_REDUCE(sve_fmaxnmv_d, float64, , maxnum, 0x7FF8000000000000ULL)
118
+
119
+DO_REDUCE(sve_fminv_h, float16, H1_2, min, float16_infinity)
120
+DO_REDUCE(sve_fminv_s, float32, H1_4, min, float32_infinity)
121
+DO_REDUCE(sve_fminv_d, float64, , min, float64_infinity)
122
+
123
+DO_REDUCE(sve_fmaxv_h, float16, H1_2, max, float16_chs(float16_infinity))
124
+DO_REDUCE(sve_fmaxv_s, float32, H1_4, max, float32_chs(float32_infinity))
125
+DO_REDUCE(sve_fmaxv_d, float64, , max, float64_chs(float64_infinity))
126
+
127
+#undef DO_REDUCE
128
+
129
uint64_t HELPER(sve_fadda_h)(uint64_t nn, void *vm, void *vg,
130
void *status, uint32_t desc)
131
{
132
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/target/arm/translate-sve.c
135
+++ b/target/arm/translate-sve.c
136
@@ -XXX,XX +XXX,XX @@ static bool trans_FMUL_zzx(DisasContext *s, arg_FMUL_zzx *a, uint32_t insn)
137
return true;
138
}
92
}
139
93
140
+/*
141
+ *** SVE Floating Point Fast Reduction Group
142
+ */
143
+
144
+typedef void gen_helper_fp_reduce(TCGv_i64, TCGv_ptr, TCGv_ptr,
145
+ TCGv_ptr, TCGv_i32);
146
+
147
+static void do_reduce(DisasContext *s, arg_rpr_esz *a,
148
+ gen_helper_fp_reduce *fn)
149
+{
150
+ unsigned vsz = vec_full_reg_size(s);
151
+ unsigned p2vsz = pow2ceil(vsz);
152
+ TCGv_i32 t_desc = tcg_const_i32(simd_desc(vsz, p2vsz, 0));
153
+ TCGv_ptr t_zn, t_pg, status;
154
+ TCGv_i64 temp;
155
+
156
+ temp = tcg_temp_new_i64();
157
+ t_zn = tcg_temp_new_ptr();
158
+ t_pg = tcg_temp_new_ptr();
159
+
160
+ tcg_gen_addi_ptr(t_zn, cpu_env, vec_full_reg_offset(s, a->rn));
161
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, a->pg));
162
+ status = get_fpstatus_ptr(a->esz == MO_16);
163
+
164
+ fn(temp, t_zn, t_pg, status, t_desc);
165
+ tcg_temp_free_ptr(t_zn);
166
+ tcg_temp_free_ptr(t_pg);
167
+ tcg_temp_free_ptr(status);
168
+ tcg_temp_free_i32(t_desc);
169
+
170
+ write_fp_dreg(s, a->rd, temp);
171
+ tcg_temp_free_i64(temp);
172
+}
173
+
174
+#define DO_VPZ(NAME, name) \
175
+static bool trans_##NAME(DisasContext *s, arg_rpr_esz *a, uint32_t insn) \
176
+{ \
177
+ static gen_helper_fp_reduce * const fns[3] = { \
178
+ gen_helper_sve_##name##_h, \
179
+ gen_helper_sve_##name##_s, \
180
+ gen_helper_sve_##name##_d, \
181
+ }; \
182
+ if (a->esz == 0) { \
183
+ return false; \
184
+ } \
185
+ if (sve_access_check(s)) { \
186
+ do_reduce(s, a, fns[a->esz - 1]); \
187
+ } \
188
+ return true; \
189
+}
190
+
191
+DO_VPZ(FADDV, faddv)
192
+DO_VPZ(FMINNMV, fminnmv)
193
+DO_VPZ(FMAXNMV, fmaxnmv)
194
+DO_VPZ(FMINV, fminv)
195
+DO_VPZ(FMAXV, fmaxv)
196
+
197
/*
198
*** SVE Floating Point Accumulating Reduction Group
199
*/
200
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
201
index XXXXXXX..XXXXXXX 100644
202
--- a/target/arm/sve.decode
203
+++ b/target/arm/sve.decode
204
@@ -XXX,XX +XXX,XX @@ FMUL_zzx 01100100 0.1 .. rm:3 001000 rn:5 rd:5 \
205
FMUL_zzx 01100100 101 index:2 rm:3 001000 rn:5 rd:5 esz=2
206
FMUL_zzx 01100100 111 index:1 rm:4 001000 rn:5 rd:5 esz=3
207
208
+### SVE FP Fast Reduction Group
209
+
210
+FADDV 01100101 .. 000 000 001 ... ..... ..... @rd_pg_rn
211
+FMAXNMV 01100101 .. 000 100 001 ... ..... ..... @rd_pg_rn
212
+FMINNMV 01100101 .. 000 101 001 ... ..... ..... @rd_pg_rn
213
+FMAXV 01100101 .. 000 110 001 ... ..... ..... @rd_pg_rn
214
+FMINV 01100101 .. 000 111 001 ... ..... ..... @rd_pg_rn
215
+
216
### SVE FP Accumulating Reduction Group
217
218
# SVE floating-point serial reduction (predicated)
219
--
94
--
220
2.17.1
95
2.20.1
221
96
222
97
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Each board in this family can have minor differences in the meaning
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
of the CFG registers, so rather than trying to specify all the
5
Message-id: 20180627043328.11531-27-richard.henderson@linaro.org
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210215115138.20465-11-peter.maydell@linaro.org
7
---
20
---
8
target/arm/helper-sve.h | 14 ++++++++++++++
21
include/hw/misc/mps2-scc.h | 3 ++
9
target/arm/sve_helper.c | 8 ++++++++
22
hw/misc/mps2-scc.c | 71 ++++++++++++++++++++++++++++++++++++--
10
target/arm/translate-sve.c | 26 ++++++++++++++++++++++++++
23
2 files changed, 72 insertions(+), 2 deletions(-)
11
target/arm/sve.decode | 4 ++++
12
4 files changed, 52 insertions(+)
13
24
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
25
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
15
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
27
--- a/include/hw/misc/mps2-scc.h
17
+++ b/target/arm/helper-sve.h
28
+++ b/include/hw/misc/mps2-scc.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_frintx_s, TCG_CALL_NO_RWG,
29
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
19
DEF_HELPER_FLAGS_5(sve_frintx_d, TCG_CALL_NO_RWG,
30
20
void, ptr, ptr, ptr, ptr, i32)
31
uint32_t cfg0;
21
32
uint32_t cfg1;
22
+DEF_HELPER_FLAGS_5(sve_frecpx_h, TCG_CALL_NO_RWG,
33
+ uint32_t cfg2;
23
+ void, ptr, ptr, ptr, ptr, i32)
34
uint32_t cfg4;
24
+DEF_HELPER_FLAGS_5(sve_frecpx_s, TCG_CALL_NO_RWG,
35
+ uint32_t cfg5;
25
+ void, ptr, ptr, ptr, ptr, i32)
36
+ uint32_t cfg6;
26
+DEF_HELPER_FLAGS_5(sve_frecpx_d, TCG_CALL_NO_RWG,
37
uint32_t cfgdata_rtn;
27
+ void, ptr, ptr, ptr, ptr, i32)
38
uint32_t cfgdata_out;
28
+
39
uint32_t cfgctrl;
29
+DEF_HELPER_FLAGS_5(sve_fsqrt_h, TCG_CALL_NO_RWG,
40
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
30
+ void, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_5(sve_fsqrt_s, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(sve_fsqrt_d, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, i32)
35
+
36
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
37
void, ptr, ptr, ptr, ptr, i32)
38
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
39
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
40
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/sve_helper.c
42
--- a/hw/misc/mps2-scc.c
42
+++ b/target/arm/sve_helper.c
43
+++ b/hw/misc/mps2-scc.c
43
@@ -XXX,XX +XXX,XX @@ DO_ZPZ_FP(sve_frintx_h, uint16_t, H1_2, float16_round_to_int)
44
@@ -XXX,XX +XXX,XX @@
44
DO_ZPZ_FP(sve_frintx_s, uint32_t, H1_4, float32_round_to_int)
45
45
DO_ZPZ_FP(sve_frintx_d, uint64_t, , float64_round_to_int)
46
REG32(CFG0, 0)
46
47
REG32(CFG1, 4)
47
+DO_ZPZ_FP(sve_frecpx_h, uint16_t, H1_2, helper_frecpx_f16)
48
+REG32(CFG2, 8)
48
+DO_ZPZ_FP(sve_frecpx_s, uint32_t, H1_4, helper_frecpx_f32)
49
REG32(CFG3, 0xc)
49
+DO_ZPZ_FP(sve_frecpx_d, uint64_t, , helper_frecpx_f64)
50
REG32(CFG4, 0x10)
50
+
51
+REG32(CFG5, 0x14)
51
+DO_ZPZ_FP(sve_fsqrt_h, uint16_t, H1_2, float16_sqrt)
52
+REG32(CFG6, 0x18)
52
+DO_ZPZ_FP(sve_fsqrt_s, uint32_t, H1_4, float32_sqrt)
53
REG32(CFGDATA_RTN, 0xa0)
53
+DO_ZPZ_FP(sve_fsqrt_d, uint64_t, , float64_sqrt)
54
REG32(CFGDATA_OUT, 0xa4)
54
+
55
REG32(CFGCTRL, 0xa8)
55
DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
56
@@ -XXX,XX +XXX,XX @@ REG32(DLL, 0x100)
56
DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
57
REG32(AID, 0xFF8)
57
DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
58
REG32(ID, 0xFFC)
58
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
59
59
index XXXXXXX..XXXXXXX 100644
60
+static int scc_partno(MPS2SCC *s)
60
--- a/target/arm/translate-sve.c
61
+++ b/target/arm/translate-sve.c
62
@@ -XXX,XX +XXX,XX @@ static bool trans_FRINTA(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
63
return do_frint_mode(s, a, float_round_ties_away);
64
}
65
66
+static bool trans_FRECPX(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
67
+{
61
+{
68
+ static gen_helper_gvec_3_ptr * const fns[3] = {
62
+ /* Return the partno field of the SCC_ID (0x524, 0x511, etc) */
69
+ gen_helper_sve_frecpx_h,
63
+ return extract32(s->id, 4, 8);
70
+ gen_helper_sve_frecpx_s,
71
+ gen_helper_sve_frecpx_d
72
+ };
73
+ if (a->esz == 0) {
74
+ return false;
75
+ }
76
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, a->esz == MO_16, fns[a->esz - 1]);
77
+}
64
+}
78
+
65
+
79
+static bool trans_FSQRT(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
66
/* Handle a write via the SYS_CFG channel to the specified function/device.
80
+{
67
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
81
+ static gen_helper_gvec_3_ptr * const fns[3] = {
68
*/
82
+ gen_helper_sve_fsqrt_h,
69
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
83
+ gen_helper_sve_fsqrt_s,
70
case A_CFG1:
84
+ gen_helper_sve_fsqrt_d
71
r = s->cfg1;
85
+ };
72
break;
86
+ if (a->esz == 0) {
73
+ case A_CFG2:
87
+ return false;
74
+ if (scc_partno(s) != 0x524) {
88
+ }
75
+ /* CFG2 reserved on other boards */
89
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, a->esz == MO_16, fns[a->esz - 1]);
76
+ goto bad_offset;
90
+}
77
+ }
91
+
78
+ r = s->cfg2;
92
static bool trans_SCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
79
+ break;
93
{
80
case A_CFG3:
94
return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_hh);
81
+ if (scc_partno(s) == 0x524) {
95
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
82
+ /* CFG3 reserved on AN524 */
96
index XXXXXXX..XXXXXXX 100644
83
+ goto bad_offset;
97
--- a/target/arm/sve.decode
84
+ }
98
+++ b/target/arm/sve.decode
85
/* These are user-settable DIP switches on the board. We don't
99
@@ -XXX,XX +XXX,XX @@ FRINTA 01100101 .. 000 100 101 ... ..... ..... @rd_pg_rn
86
* model that, so just return zeroes.
100
FRINTX 01100101 .. 000 110 101 ... ..... ..... @rd_pg_rn
87
*/
101
FRINTI 01100101 .. 000 111 101 ... ..... ..... @rd_pg_rn
88
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
102
89
case A_CFG4:
103
+# SVE floating-point unary operations
90
r = s->cfg4;
104
+FRECPX 01100101 .. 001 100 101 ... ..... ..... @rd_pg_rn
91
break;
105
+FSQRT 01100101 .. 001 101 101 ... ..... ..... @rd_pg_rn
92
+ case A_CFG5:
106
+
93
+ if (scc_partno(s) != 0x524) {
107
# SVE integer convert to floating-point
94
+ /* CFG5 reserved on other boards */
108
SCVTF_hh 01100101 01 010 01 0 101 ... ..... ..... @rd_pg_rn_e0
95
+ goto bad_offset;
109
SCVTF_sh 01100101 01 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
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;
111
break;
112
default:
113
+ bad_offset:
114
qemu_log_mask(LOG_GUEST_ERROR,
115
"MPS2 SCC read: bad offset %x\n", (int) offset);
116
r = 0;
117
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
118
led_set_state(s->led[i], extract32(value, i, 1));
119
}
120
break;
121
+ case A_CFG2:
122
+ if (scc_partno(s) != 0x524) {
123
+ /* CFG2 reserved on other boards */
124
+ goto bad_offset;
125
+ }
126
+ /* AN524: QSPI Select signal */
127
+ s->cfg2 = value;
128
+ 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),
110
--
184
--
111
2.17.1
185
2.20.1
112
186
113
187
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Within our implementation, because the external interrupts must be
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
connected to the EXP_IRQ[0...n] lines of the SSE object, we made the
5
Message-id: 20180627043328.11531-22-richard.henderson@linaro.org
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.
14
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20210215115138.20465-12-peter.maydell@linaro.org
7
---
26
---
8
target/arm/helper-sve.h | 42 +++++++++++++++++++++++++++++++++++++
27
hw/arm/mps2-tz.c | 24 +++++++++++++++++-------
9
target/arm/sve_helper.c | 43 ++++++++++++++++++++++++++++++++++++++
28
1 file changed, 17 insertions(+), 7 deletions(-)
10
target/arm/translate-sve.c | 43 ++++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 10 +++++++++
12
4 files changed, 138 insertions(+)
13
29
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
30
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
32
--- a/hw/arm/mps2-tz.c
17
+++ b/target/arm/helper-sve.h
33
+++ b/hw/arm/mps2-tz.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_fadda_s, TCG_CALL_NO_RWG,
34
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
19
DEF_HELPER_FLAGS_5(sve_fadda_d, TCG_CALL_NO_RWG,
35
20
i64, i64, ptr, ptr, ptr, i32)
36
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
21
37
{
22
+DEF_HELPER_FLAGS_5(sve_fcmge0_h, TCG_CALL_NO_RWG,
38
- /* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
23
+ void, ptr, ptr, ptr, ptr, i32)
39
+ /*
24
+DEF_HELPER_FLAGS_5(sve_fcmge0_s, TCG_CALL_NO_RWG,
40
+ * Return a qemu_irq which will signal IRQ n to all CPUs in the
25
+ void, ptr, ptr, ptr, ptr, i32)
41
+ * SSE. The irqno should be as the CPU sees it, so the first
26
+DEF_HELPER_FLAGS_5(sve_fcmge0_d, TCG_CALL_NO_RWG,
42
+ * external-to-the-SSE interrupt is 32.
27
+ void, ptr, ptr, ptr, ptr, i32)
43
+ */
44
MachineClass *mc = MACHINE_GET_CLASS(mms);
45
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
46
47
- assert(irqno < mmc->numirq);
48
+ assert(irqno >= 32 && irqno < (mmc->numirq + 32));
28
+
49
+
29
+DEF_HELPER_FLAGS_5(sve_fcmgt0_h, TCG_CALL_NO_RWG,
50
+ /*
30
+ void, ptr, ptr, ptr, ptr, i32)
51
+ * Convert from "CPU irq number" (as listed in the FPGA image
31
+DEF_HELPER_FLAGS_5(sve_fcmgt0_s, TCG_CALL_NO_RWG,
52
+ * documentation) to the SSE external-interrupt number.
32
+ void, ptr, ptr, ptr, ptr, i32)
53
+ */
33
+DEF_HELPER_FLAGS_5(sve_fcmgt0_d, TCG_CALL_NO_RWG,
54
+ irqno -= 32;
34
+ void, ptr, ptr, ptr, ptr, i32)
55
35
+
56
if (mc->max_cpus > 1) {
36
+DEF_HELPER_FLAGS_5(sve_fcmlt0_h, TCG_CALL_NO_RWG,
57
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
37
+ void, ptr, ptr, ptr, ptr, i32)
58
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
38
+DEF_HELPER_FLAGS_5(sve_fcmlt0_s, TCG_CALL_NO_RWG,
59
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
39
+ void, ptr, ptr, ptr, ptr, i32)
60
CMSDKAPBUART *uart = opaque;
40
+DEF_HELPER_FLAGS_5(sve_fcmlt0_d, TCG_CALL_NO_RWG,
61
int i = uart - &mms->uart[0];
41
+ void, ptr, ptr, ptr, ptr, i32)
62
- int rxirqno = i * 2;
42
+
63
- int txirqno = i * 2 + 1;
43
+DEF_HELPER_FLAGS_5(sve_fcmle0_h, TCG_CALL_NO_RWG,
64
- int combirqno = i + 10;
44
+ void, ptr, ptr, ptr, ptr, i32)
65
+ int rxirqno = i * 2 + 32;
45
+DEF_HELPER_FLAGS_5(sve_fcmle0_s, TCG_CALL_NO_RWG,
66
+ int txirqno = i * 2 + 33;
46
+ void, ptr, ptr, ptr, ptr, i32)
67
+ int combirqno = i + 42;
47
+DEF_HELPER_FLAGS_5(sve_fcmle0_d, TCG_CALL_NO_RWG,
68
SysBusDevice *s;
48
+ void, ptr, ptr, ptr, ptr, i32)
69
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
49
+
70
50
+DEF_HELPER_FLAGS_5(sve_fcmeq0_h, TCG_CALL_NO_RWG,
71
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
51
+ void, ptr, ptr, ptr, ptr, i32)
72
52
+DEF_HELPER_FLAGS_5(sve_fcmeq0_s, TCG_CALL_NO_RWG,
73
s = SYS_BUS_DEVICE(mms->lan9118);
53
+ void, ptr, ptr, ptr, ptr, i32)
74
sysbus_realize_and_unref(s, &error_fatal);
54
+DEF_HELPER_FLAGS_5(sve_fcmeq0_d, TCG_CALL_NO_RWG,
75
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 16));
55
+ void, ptr, ptr, ptr, ptr, i32)
76
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 48));
56
+
77
return sysbus_mmio_get_region(s, 0);
57
+DEF_HELPER_FLAGS_5(sve_fcmne0_h, TCG_CALL_NO_RWG,
58
+ void, ptr, ptr, ptr, ptr, i32)
59
+DEF_HELPER_FLAGS_5(sve_fcmne0_s, TCG_CALL_NO_RWG,
60
+ void, ptr, ptr, ptr, ptr, i32)
61
+DEF_HELPER_FLAGS_5(sve_fcmne0_d, TCG_CALL_NO_RWG,
62
+ void, ptr, ptr, ptr, ptr, i32)
63
+
64
DEF_HELPER_FLAGS_6(sve_fadd_h, TCG_CALL_NO_RWG,
65
void, ptr, ptr, ptr, ptr, ptr, i32)
66
DEF_HELPER_FLAGS_6(sve_fadd_s, TCG_CALL_NO_RWG,
67
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/arm/sve_helper.c
70
+++ b/target/arm/sve_helper.c
71
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *vn, void *vm, void *vg, \
72
73
#define DO_FCMGE(TYPE, X, Y, ST) TYPE##_compare(Y, X, ST) <= 0
74
#define DO_FCMGT(TYPE, X, Y, ST) TYPE##_compare(Y, X, ST) < 0
75
+#define DO_FCMLE(TYPE, X, Y, ST) TYPE##_compare(X, Y, ST) <= 0
76
+#define DO_FCMLT(TYPE, X, Y, ST) TYPE##_compare(X, Y, ST) < 0
77
#define DO_FCMEQ(TYPE, X, Y, ST) TYPE##_compare_quiet(X, Y, ST) == 0
78
#define DO_FCMNE(TYPE, X, Y, ST) TYPE##_compare_quiet(X, Y, ST) != 0
79
#define DO_FCMUO(TYPE, X, Y, ST) \
80
@@ -XXX,XX +XXX,XX @@ DO_FPCMP_PPZZ_ALL(sve_facgt, DO_FACGT)
81
#undef DO_FPCMP_PPZZ_H
82
#undef DO_FPCMP_PPZZ
83
84
+/* One operand floating-point comparison against zero, controlled
85
+ * by a predicate.
86
+ */
87
+#define DO_FPCMP_PPZ0(NAME, TYPE, H, OP) \
88
+void HELPER(NAME)(void *vd, void *vn, void *vg, \
89
+ void *status, uint32_t desc) \
90
+{ \
91
+ intptr_t i = simd_oprsz(desc), j = (i - 1) >> 6; \
92
+ uint64_t *d = vd, *g = vg; \
93
+ do { \
94
+ uint64_t out = 0, pg = g[j]; \
95
+ do { \
96
+ i -= sizeof(TYPE), out <<= sizeof(TYPE); \
97
+ if ((pg >> (i & 63)) & 1) { \
98
+ TYPE nn = *(TYPE *)(vn + H(i)); \
99
+ out |= OP(TYPE, nn, 0, status); \
100
+ } \
101
+ } while (i & 63); \
102
+ d[j--] = out; \
103
+ } while (i > 0); \
104
+}
105
+
106
+#define DO_FPCMP_PPZ0_H(NAME, OP) \
107
+ DO_FPCMP_PPZ0(NAME##_h, float16, H1_2, OP)
108
+#define DO_FPCMP_PPZ0_S(NAME, OP) \
109
+ DO_FPCMP_PPZ0(NAME##_s, float32, H1_4, OP)
110
+#define DO_FPCMP_PPZ0_D(NAME, OP) \
111
+ DO_FPCMP_PPZ0(NAME##_d, float64, , OP)
112
+
113
+#define DO_FPCMP_PPZ0_ALL(NAME, OP) \
114
+ DO_FPCMP_PPZ0_H(NAME, OP) \
115
+ DO_FPCMP_PPZ0_S(NAME, OP) \
116
+ DO_FPCMP_PPZ0_D(NAME, OP)
117
+
118
+DO_FPCMP_PPZ0_ALL(sve_fcmge0, DO_FCMGE)
119
+DO_FPCMP_PPZ0_ALL(sve_fcmgt0, DO_FCMGT)
120
+DO_FPCMP_PPZ0_ALL(sve_fcmle0, DO_FCMLE)
121
+DO_FPCMP_PPZ0_ALL(sve_fcmlt0, DO_FCMLT)
122
+DO_FPCMP_PPZ0_ALL(sve_fcmeq0, DO_FCMEQ)
123
+DO_FPCMP_PPZ0_ALL(sve_fcmne0, DO_FCMNE)
124
+
125
/*
126
* Load contiguous data, protected by a governing predicate.
127
*/
128
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/target/arm/translate-sve.c
131
+++ b/target/arm/translate-sve.c
132
@@ -XXX,XX +XXX,XX @@ static bool trans_FRSQRTE(DisasContext *s, arg_rr_esz *a, uint32_t insn)
133
return true;
134
}
78
}
135
79
136
+/*
80
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
137
+ *** SVE Floating Point Compare with Zero Group
81
&error_fatal);
138
+ */
82
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
139
+
83
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
140
+static void do_ppz_fp(DisasContext *s, arg_rpr_esz *a,
84
- get_sse_irq_in(mms, 15));
141
+ gen_helper_gvec_3_ptr *fn)
85
+ get_sse_irq_in(mms, 47));
142
+{
86
143
+ unsigned vsz = vec_full_reg_size(s);
87
/* Most of the devices in the FPGA are behind Peripheral Protection
144
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
88
* Controllers. The required order for initializing things is:
145
+
146
+ tcg_gen_gvec_3_ptr(pred_full_reg_offset(s, a->rd),
147
+ vec_full_reg_offset(s, a->rn),
148
+ pred_full_reg_offset(s, a->pg),
149
+ status, vsz, vsz, 0, fn);
150
+ tcg_temp_free_ptr(status);
151
+}
152
+
153
+#define DO_PPZ(NAME, name) \
154
+static bool trans_##NAME(DisasContext *s, arg_rpr_esz *a, uint32_t insn) \
155
+{ \
156
+ static gen_helper_gvec_3_ptr * const fns[3] = { \
157
+ gen_helper_sve_##name##_h, \
158
+ gen_helper_sve_##name##_s, \
159
+ gen_helper_sve_##name##_d, \
160
+ }; \
161
+ if (a->esz == 0) { \
162
+ return false; \
163
+ } \
164
+ if (sve_access_check(s)) { \
165
+ do_ppz_fp(s, a, fns[a->esz - 1]); \
166
+ } \
167
+ return true; \
168
+}
169
+
170
+DO_PPZ(FCMGE_ppz0, fcmge0)
171
+DO_PPZ(FCMGT_ppz0, fcmgt0)
172
+DO_PPZ(FCMLE_ppz0, fcmle0)
173
+DO_PPZ(FCMLT_ppz0, fcmlt0)
174
+DO_PPZ(FCMEQ_ppz0, fcmeq0)
175
+DO_PPZ(FCMNE_ppz0, fcmne0)
176
+
177
+#undef DO_PPZ
178
+
179
/*
180
*** SVE Floating Point Accumulating Reduction Group
181
*/
182
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
183
index XXXXXXX..XXXXXXX 100644
184
--- a/target/arm/sve.decode
185
+++ b/target/arm/sve.decode
186
@@ -XXX,XX +XXX,XX @@
187
# One register operand, with governing predicate, vector element size
188
@rd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 &rpr_esz
189
@rd_pg4_pn ........ esz:2 ... ... .. pg:4 . rn:4 rd:5 &rpr_esz
190
+@pd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 . rd:4 &rpr_esz
191
192
# One register operand, with governing predicate, no vector element size
193
@rd_pg_rn_e0 ........ .. ... ... ... pg:3 rn:5 rd:5 &rpr_esz esz=0
194
@@ -XXX,XX +XXX,XX @@ FMINV 01100101 .. 000 111 001 ... ..... ..... @rd_pg_rn
195
FRECPE 01100101 .. 001 110 001100 ..... ..... @rd_rn
196
FRSQRTE 01100101 .. 001 111 001100 ..... ..... @rd_rn
197
198
+### SVE FP Compare with Zero Group
199
+
200
+FCMGE_ppz0 01100101 .. 0100 00 001 ... ..... 0 .... @pd_pg_rn
201
+FCMGT_ppz0 01100101 .. 0100 00 001 ... ..... 1 .... @pd_pg_rn
202
+FCMLT_ppz0 01100101 .. 0100 01 001 ... ..... 0 .... @pd_pg_rn
203
+FCMLE_ppz0 01100101 .. 0100 01 001 ... ..... 1 .... @pd_pg_rn
204
+FCMEQ_ppz0 01100101 .. 0100 10 001 ... ..... 0 .... @pd_pg_rn
205
+FCMNE_ppz0 01100101 .. 0100 11 001 ... ..... 0 .... @pd_pg_rn
206
+
207
### SVE FP Accumulating Reduction Group
208
209
# SVE floating-point serial reduction (predicated)
210
--
89
--
211
2.17.1
90
2.20.1
212
91
213
92
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
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
When running dtc on the guest /proc/device-tree we get the
8
This commit adds the framework to allow PPCPortInfo structures to
4
following warnings: "Warning (unit_address_vs_reg): Node <name>
9
specify interrupt numbers. We add an array of interrupt numbers to
5
has a reg or ranges property, but no unit name", with name:
10
the PPCPortInfo struct, and pass it through to the make_* helpers.
6
/intc, /intc/its, /intc/v2m.
11
The following commit will change the make_* helpers over to using the
12
framework.
7
13
8
Nodes should have a name in the form <name>[@<unit-address>] where
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
unit-address is the primary address used to access the device, listed
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
in the node's reg property. This fix seems to make dtc happy.
16
Message-id: 20210215115138.20465-13-peter.maydell@linaro.org
17
---
18
hw/arm/mps2-tz.c | 36 ++++++++++++++++++++++++------------
19
1 file changed, 24 insertions(+), 12 deletions(-)
11
20
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
21
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 1530044492-24921-3-git-send-email-eric.auger@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/arm/virt.c | 63 +++++++++++++++++++++++++++++++--------------------
18
1 file changed, 39 insertions(+), 24 deletions(-)
19
20
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/virt.c
23
--- a/hw/arm/mps2-tz.c
23
+++ b/hw/arm/virt.c
24
+++ b/hw/arm/mps2-tz.c
24
@@ -XXX,XX +XXX,XX @@ static void fdt_add_cpu_nodes(const VirtMachineState *vms)
25
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
25
26
* needs to be plugged into the downstream end of the PPC port.
26
static void fdt_add_its_gic_node(VirtMachineState *vms)
27
*/
28
typedef MemoryRegion *MakeDevFn(MPS2TZMachineState *mms, void *opaque,
29
- const char *name, hwaddr size);
30
+ const char *name, hwaddr size,
31
+ const int *irqs);
32
33
typedef struct PPCPortInfo {
34
const char *name;
35
@@ -XXX,XX +XXX,XX @@ typedef struct PPCPortInfo {
36
void *opaque;
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)
27
{
52
{
28
+ char *nodename;
53
/* Initialize, configure and realize a TYPE_UNIMPLEMENTED_DEVICE,
29
+
54
* and return a pointer to its MemoryRegion.
30
vms->msi_phandle = qemu_fdt_alloc_phandle(vms->fdt);
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
31
- qemu_fdt_add_subnode(vms->fdt, "/intc/its");
32
- qemu_fdt_setprop_string(vms->fdt, "/intc/its", "compatible",
33
+ nodename = g_strdup_printf("/intc/its@%" PRIx64,
34
+ vms->memmap[VIRT_GIC_ITS].base);
35
+ qemu_fdt_add_subnode(vms->fdt, nodename);
36
+ qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
37
"arm,gic-v3-its");
38
- qemu_fdt_setprop(vms->fdt, "/intc/its", "msi-controller", NULL, 0);
39
- qemu_fdt_setprop_sized_cells(vms->fdt, "/intc/its", "reg",
40
+ qemu_fdt_setprop(vms->fdt, nodename, "msi-controller", NULL, 0);
41
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
42
2, vms->memmap[VIRT_GIC_ITS].base,
43
2, vms->memmap[VIRT_GIC_ITS].size);
44
- qemu_fdt_setprop_cell(vms->fdt, "/intc/its", "phandle", vms->msi_phandle);
45
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->msi_phandle);
46
+ g_free(nodename);
47
}
56
}
48
57
49
static void fdt_add_v2m_gic_node(VirtMachineState *vms)
58
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
59
- const char *name, hwaddr size)
60
+ const char *name, hwaddr size,
61
+ const int *irqs)
50
{
62
{
51
+ char *nodename;
63
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
52
+
64
CMSDKAPBUART *uart = opaque;
53
+ nodename = g_strdup_printf("/intc/v2m@%" PRIx64,
65
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
54
+ vms->memmap[VIRT_GIC_V2M].base);
55
vms->msi_phandle = qemu_fdt_alloc_phandle(vms->fdt);
56
- qemu_fdt_add_subnode(vms->fdt, "/intc/v2m");
57
- qemu_fdt_setprop_string(vms->fdt, "/intc/v2m", "compatible",
58
+ qemu_fdt_add_subnode(vms->fdt, nodename);
59
+ qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
60
"arm,gic-v2m-frame");
61
- qemu_fdt_setprop(vms->fdt, "/intc/v2m", "msi-controller", NULL, 0);
62
- qemu_fdt_setprop_sized_cells(vms->fdt, "/intc/v2m", "reg",
63
+ qemu_fdt_setprop(vms->fdt, nodename, "msi-controller", NULL, 0);
64
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
65
2, vms->memmap[VIRT_GIC_V2M].base,
66
2, vms->memmap[VIRT_GIC_V2M].size);
67
- qemu_fdt_setprop_cell(vms->fdt, "/intc/v2m", "phandle", vms->msi_phandle);
68
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->msi_phandle);
69
+ g_free(nodename);
70
}
66
}
71
67
72
static void fdt_add_gic_node(VirtMachineState *vms)
68
static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
69
- const char *name, hwaddr size)
70
+ const char *name, hwaddr size,
71
+ const int *irqs)
73
{
72
{
74
+ char *nodename;
73
MPS2SCC *scc = opaque;
75
+
74
DeviceState *sccdev;
76
vms->gic_phandle = qemu_fdt_alloc_phandle(vms->fdt);
75
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
77
qemu_fdt_setprop_cell(vms->fdt, "/", "interrupt-parent", vms->gic_phandle);
78
79
- qemu_fdt_add_subnode(vms->fdt, "/intc");
80
- qemu_fdt_setprop_cell(vms->fdt, "/intc", "#interrupt-cells", 3);
81
- qemu_fdt_setprop(vms->fdt, "/intc", "interrupt-controller", NULL, 0);
82
- qemu_fdt_setprop_cell(vms->fdt, "/intc", "#address-cells", 0x2);
83
- qemu_fdt_setprop_cell(vms->fdt, "/intc", "#size-cells", 0x2);
84
- qemu_fdt_setprop(vms->fdt, "/intc", "ranges", NULL, 0);
85
+ nodename = g_strdup_printf("/intc@%" PRIx64,
86
+ vms->memmap[VIRT_GIC_DIST].base);
87
+ qemu_fdt_add_subnode(vms->fdt, nodename);
88
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "#interrupt-cells", 3);
89
+ qemu_fdt_setprop(vms->fdt, nodename, "interrupt-controller", NULL, 0);
90
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "#address-cells", 0x2);
91
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "#size-cells", 0x2);
92
+ qemu_fdt_setprop(vms->fdt, nodename, "ranges", NULL, 0);
93
if (vms->gic_version == 3) {
94
int nb_redist_regions = virt_gicv3_redist_region_count(vms);
95
96
- qemu_fdt_setprop_string(vms->fdt, "/intc", "compatible",
97
+ qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
98
"arm,gic-v3");
99
100
- qemu_fdt_setprop_cell(vms->fdt, "/intc",
101
+ qemu_fdt_setprop_cell(vms->fdt, nodename,
102
"#redistributor-regions", nb_redist_regions);
103
104
if (nb_redist_regions == 1) {
105
- qemu_fdt_setprop_sized_cells(vms->fdt, "/intc", "reg",
106
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
107
2, vms->memmap[VIRT_GIC_DIST].base,
108
2, vms->memmap[VIRT_GIC_DIST].size,
109
2, vms->memmap[VIRT_GIC_REDIST].base,
110
2, vms->memmap[VIRT_GIC_REDIST].size);
111
} else {
112
- qemu_fdt_setprop_sized_cells(vms->fdt, "/intc", "reg",
113
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
114
2, vms->memmap[VIRT_GIC_DIST].base,
115
2, vms->memmap[VIRT_GIC_DIST].size,
116
2, vms->memmap[VIRT_GIC_REDIST].base,
117
@@ -XXX,XX +XXX,XX @@ static void fdt_add_gic_node(VirtMachineState *vms)
118
}
119
120
if (vms->virt) {
121
- qemu_fdt_setprop_cells(vms->fdt, "/intc", "interrupts",
122
+ qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts",
123
GIC_FDT_IRQ_TYPE_PPI, ARCH_GICV3_MAINT_IRQ,
124
GIC_FDT_IRQ_FLAGS_LEVEL_HI);
125
}
126
} else {
127
/* 'cortex-a15-gic' means 'GIC v2' */
128
- qemu_fdt_setprop_string(vms->fdt, "/intc", "compatible",
129
+ qemu_fdt_setprop_string(vms->fdt, nodename, "compatible",
130
"arm,cortex-a15-gic");
131
- qemu_fdt_setprop_sized_cells(vms->fdt, "/intc", "reg",
132
+ qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
133
2, vms->memmap[VIRT_GIC_DIST].base,
134
2, vms->memmap[VIRT_GIC_DIST].size,
135
2, vms->memmap[VIRT_GIC_CPU].base,
136
2, vms->memmap[VIRT_GIC_CPU].size);
137
}
138
139
- qemu_fdt_setprop_cell(vms->fdt, "/intc", "phandle", vms->gic_phandle);
140
+ qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", vms->gic_phandle);
141
+ g_free(nodename);
142
}
76
}
143
77
144
static void fdt_add_pmu_nodes(const VirtMachineState *vms)
78
static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
79
- const char *name, hwaddr size)
80
+ const char *name, hwaddr size,
81
+ const int *irqs)
82
{
83
MPS2FPGAIO *fpgaio = opaque;
84
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
85
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
86
}
87
88
static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
89
- const char *name, hwaddr size)
90
+ const char *name, hwaddr size,
91
+ const int *irqs)
92
{
93
SysBusDevice *s;
94
NICInfo *nd = &nd_table[0];
95
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
96
}
97
98
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
99
- const char *name, hwaddr size)
100
+ const char *name, hwaddr size,
101
+ const int *irqs)
102
{
103
TZMPC *mpc = opaque;
104
int i = mpc - &mms->ssram_mpc[0];
105
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
106
}
107
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);
145
--
145
--
146
2.17.1
146
2.20.1
147
147
148
148
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Tested-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20180627043328.11531-3-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/helper-sve.h | 40 ++++++++++
10
target/arm/sve_helper.c | 157 +++++++++++++++++++++++++++++++++++++
11
target/arm/translate-sve.c | 69 ++++++++++++++++
12
target/arm/sve.decode | 6 ++
13
4 files changed, 272 insertions(+)
14
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
18
+++ b/target/arm/helper-sve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_ld1hds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
20
21
DEF_HELPER_FLAGS_4(sve_ld1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
22
DEF_HELPER_FLAGS_4(sve_ld1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
23
+
24
+DEF_HELPER_FLAGS_4(sve_ldff1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_4(sve_ldff1bhu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
26
+DEF_HELPER_FLAGS_4(sve_ldff1bsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
27
+DEF_HELPER_FLAGS_4(sve_ldff1bdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
28
+DEF_HELPER_FLAGS_4(sve_ldff1bhs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
29
+DEF_HELPER_FLAGS_4(sve_ldff1bss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
30
+DEF_HELPER_FLAGS_4(sve_ldff1bds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
31
+
32
+DEF_HELPER_FLAGS_4(sve_ldff1hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
33
+DEF_HELPER_FLAGS_4(sve_ldff1hsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
34
+DEF_HELPER_FLAGS_4(sve_ldff1hdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
35
+DEF_HELPER_FLAGS_4(sve_ldff1hss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
36
+DEF_HELPER_FLAGS_4(sve_ldff1hds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
37
+
38
+DEF_HELPER_FLAGS_4(sve_ldff1ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
39
+DEF_HELPER_FLAGS_4(sve_ldff1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
40
+DEF_HELPER_FLAGS_4(sve_ldff1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
+
42
+DEF_HELPER_FLAGS_4(sve_ldff1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
43
+
44
+DEF_HELPER_FLAGS_4(sve_ldnf1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
45
+DEF_HELPER_FLAGS_4(sve_ldnf1bhu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
46
+DEF_HELPER_FLAGS_4(sve_ldnf1bsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
47
+DEF_HELPER_FLAGS_4(sve_ldnf1bdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
48
+DEF_HELPER_FLAGS_4(sve_ldnf1bhs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
49
+DEF_HELPER_FLAGS_4(sve_ldnf1bss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
50
+DEF_HELPER_FLAGS_4(sve_ldnf1bds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
51
+
52
+DEF_HELPER_FLAGS_4(sve_ldnf1hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
53
+DEF_HELPER_FLAGS_4(sve_ldnf1hsu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
54
+DEF_HELPER_FLAGS_4(sve_ldnf1hdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
55
+DEF_HELPER_FLAGS_4(sve_ldnf1hss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
56
+DEF_HELPER_FLAGS_4(sve_ldnf1hds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
57
+
58
+DEF_HELPER_FLAGS_4(sve_ldnf1ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
59
+DEF_HELPER_FLAGS_4(sve_ldnf1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
60
+DEF_HELPER_FLAGS_4(sve_ldnf1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
61
+
62
+DEF_HELPER_FLAGS_4(sve_ldnf1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
63
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/sve_helper.c
66
+++ b/target/arm/sve_helper.c
67
@@ -XXX,XX +XXX,XX @@ DO_LD4(sve_ld4dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
68
#undef DO_LD2
69
#undef DO_LD3
70
#undef DO_LD4
71
+
72
+/*
73
+ * Load contiguous data, first-fault and no-fault.
74
+ */
75
+
76
+#ifdef CONFIG_USER_ONLY
77
+
78
+/* Fault on byte I. All bits in FFR from I are cleared. The vector
79
+ * result from I is CONSTRAINED UNPREDICTABLE; we choose the MERGE
80
+ * option, which leaves subsequent data unchanged.
81
+ */
82
+static void record_fault(CPUARMState *env, uintptr_t i, uintptr_t oprsz)
83
+{
84
+ uint64_t *ffr = env->vfp.pregs[FFR_PRED_NUM].p;
85
+
86
+ if (i & 63) {
87
+ ffr[i / 64] &= MAKE_64BIT_MASK(0, i & 63);
88
+ i = ROUND_UP(i, 64);
89
+ }
90
+ for (; i < oprsz; i += 64) {
91
+ ffr[i / 64] = 0;
92
+ }
93
+}
94
+
95
+/* Hold the mmap lock during the operation so that there is no race
96
+ * between page_check_range and the load operation. We expect the
97
+ * usual case to have no faults at all, so we check the whole range
98
+ * first and if successful defer to the normal load operation.
99
+ *
100
+ * TODO: Change mmap_lock to a rwlock so that multiple readers
101
+ * can run simultaneously. This will probably help other uses
102
+ * within QEMU as well.
103
+ */
104
+#define DO_LDFF1(PART, FN, TYPEE, TYPEM, H) \
105
+static void do_sve_ldff1##PART(CPUARMState *env, void *vd, void *vg, \
106
+ target_ulong addr, intptr_t oprsz, \
107
+ bool first, uintptr_t ra) \
108
+{ \
109
+ intptr_t i = 0; \
110
+ do { \
111
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
112
+ do { \
113
+ TYPEM m = 0; \
114
+ if (pg & 1) { \
115
+ if (!first && \
116
+ unlikely(page_check_range(addr, sizeof(TYPEM), \
117
+ PAGE_READ))) { \
118
+ record_fault(env, i, oprsz); \
119
+ return; \
120
+ } \
121
+ m = FN(env, addr, ra); \
122
+ first = false; \
123
+ } \
124
+ *(TYPEE *)(vd + H(i)) = m; \
125
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
126
+ addr += sizeof(TYPEM); \
127
+ } while (i & 15); \
128
+ } while (i < oprsz); \
129
+} \
130
+void HELPER(sve_ldff1##PART)(CPUARMState *env, void *vg, \
131
+ target_ulong addr, uint32_t desc) \
132
+{ \
133
+ intptr_t oprsz = simd_oprsz(desc); \
134
+ unsigned rd = simd_data(desc); \
135
+ void *vd = &env->vfp.zregs[rd]; \
136
+ mmap_lock(); \
137
+ if (likely(page_check_range(addr, oprsz, PAGE_READ) == 0)) { \
138
+ do_sve_ld1##PART(env, vd, vg, addr, oprsz, GETPC()); \
139
+ } else { \
140
+ do_sve_ldff1##PART(env, vd, vg, addr, oprsz, true, GETPC()); \
141
+ } \
142
+ mmap_unlock(); \
143
+}
144
+
145
+/* No-fault loads are like first-fault loads without the
146
+ * first faulting special case.
147
+ */
148
+#define DO_LDNF1(PART) \
149
+void HELPER(sve_ldnf1##PART)(CPUARMState *env, void *vg, \
150
+ target_ulong addr, uint32_t desc) \
151
+{ \
152
+ intptr_t oprsz = simd_oprsz(desc); \
153
+ unsigned rd = simd_data(desc); \
154
+ void *vd = &env->vfp.zregs[rd]; \
155
+ mmap_lock(); \
156
+ if (likely(page_check_range(addr, oprsz, PAGE_READ) == 0)) { \
157
+ do_sve_ld1##PART(env, vd, vg, addr, oprsz, GETPC()); \
158
+ } else { \
159
+ do_sve_ldff1##PART(env, vd, vg, addr, oprsz, false, GETPC()); \
160
+ } \
161
+ mmap_unlock(); \
162
+}
163
+
164
+#else
165
+
166
+/* TODO: System mode is not yet supported.
167
+ * This would probably use tlb_vaddr_to_host.
168
+ */
169
+#define DO_LDFF1(PART, FN, TYPEE, TYPEM, H) \
170
+void HELPER(sve_ldff1##PART)(CPUARMState *env, void *vg, \
171
+ target_ulong addr, uint32_t desc) \
172
+{ \
173
+ g_assert_not_reached(); \
174
+}
175
+
176
+#define DO_LDNF1(PART) \
177
+void HELPER(sve_ldnf1##PART)(CPUARMState *env, void *vg, \
178
+ target_ulong addr, uint32_t desc) \
179
+{ \
180
+ g_assert_not_reached(); \
181
+}
182
+
183
+#endif
184
+
185
+DO_LDFF1(bb_r, cpu_ldub_data_ra, uint8_t, uint8_t, H1)
186
+DO_LDFF1(bhu_r, cpu_ldub_data_ra, uint16_t, uint8_t, H1_2)
187
+DO_LDFF1(bhs_r, cpu_ldsb_data_ra, uint16_t, int8_t, H1_2)
188
+DO_LDFF1(bsu_r, cpu_ldub_data_ra, uint32_t, uint8_t, H1_4)
189
+DO_LDFF1(bss_r, cpu_ldsb_data_ra, uint32_t, int8_t, H1_4)
190
+DO_LDFF1(bdu_r, cpu_ldub_data_ra, uint64_t, uint8_t, )
191
+DO_LDFF1(bds_r, cpu_ldsb_data_ra, uint64_t, int8_t, )
192
+
193
+DO_LDFF1(hh_r, cpu_lduw_data_ra, uint16_t, uint16_t, H1_2)
194
+DO_LDFF1(hsu_r, cpu_lduw_data_ra, uint32_t, uint16_t, H1_4)
195
+DO_LDFF1(hss_r, cpu_ldsw_data_ra, uint32_t, int8_t, H1_4)
196
+DO_LDFF1(hdu_r, cpu_lduw_data_ra, uint64_t, uint16_t, )
197
+DO_LDFF1(hds_r, cpu_ldsw_data_ra, uint64_t, int16_t, )
198
+
199
+DO_LDFF1(ss_r, cpu_ldl_data_ra, uint32_t, uint32_t, H1_4)
200
+DO_LDFF1(sdu_r, cpu_ldl_data_ra, uint64_t, uint32_t, )
201
+DO_LDFF1(sds_r, cpu_ldl_data_ra, uint64_t, int32_t, )
202
+
203
+DO_LDFF1(dd_r, cpu_ldq_data_ra, uint64_t, uint64_t, )
204
+
205
+#undef DO_LDFF1
206
+
207
+DO_LDNF1(bb_r)
208
+DO_LDNF1(bhu_r)
209
+DO_LDNF1(bhs_r)
210
+DO_LDNF1(bsu_r)
211
+DO_LDNF1(bss_r)
212
+DO_LDNF1(bdu_r)
213
+DO_LDNF1(bds_r)
214
+
215
+DO_LDNF1(hh_r)
216
+DO_LDNF1(hsu_r)
217
+DO_LDNF1(hss_r)
218
+DO_LDNF1(hdu_r)
219
+DO_LDNF1(hds_r)
220
+
221
+DO_LDNF1(ss_r)
222
+DO_LDNF1(sdu_r)
223
+DO_LDNF1(sds_r)
224
+
225
+DO_LDNF1(dd_r)
226
+
227
+#undef DO_LDNF1
228
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
229
index XXXXXXX..XXXXXXX 100644
230
--- a/target/arm/translate-sve.c
231
+++ b/target/arm/translate-sve.c
232
@@ -XXX,XX +XXX,XX @@ static bool trans_LD_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
233
}
234
return true;
235
}
236
+
237
+static bool trans_LDFF1_zprr(DisasContext *s, arg_rprr_load *a, uint32_t insn)
238
+{
239
+ static gen_helper_gvec_mem * const fns[16] = {
240
+ gen_helper_sve_ldff1bb_r,
241
+ gen_helper_sve_ldff1bhu_r,
242
+ gen_helper_sve_ldff1bsu_r,
243
+ gen_helper_sve_ldff1bdu_r,
244
+
245
+ gen_helper_sve_ldff1sds_r,
246
+ gen_helper_sve_ldff1hh_r,
247
+ gen_helper_sve_ldff1hsu_r,
248
+ gen_helper_sve_ldff1hdu_r,
249
+
250
+ gen_helper_sve_ldff1hds_r,
251
+ gen_helper_sve_ldff1hss_r,
252
+ gen_helper_sve_ldff1ss_r,
253
+ gen_helper_sve_ldff1sdu_r,
254
+
255
+ gen_helper_sve_ldff1bds_r,
256
+ gen_helper_sve_ldff1bss_r,
257
+ gen_helper_sve_ldff1bhs_r,
258
+ gen_helper_sve_ldff1dd_r,
259
+ };
260
+
261
+ if (sve_access_check(s)) {
262
+ TCGv_i64 addr = new_tmp_a64(s);
263
+ tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), dtype_msz(a->dtype));
264
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
265
+ do_mem_zpa(s, a->rd, a->pg, addr, fns[a->dtype]);
266
+ }
267
+ return true;
268
+}
269
+
270
+static bool trans_LDNF1_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
271
+{
272
+ static gen_helper_gvec_mem * const fns[16] = {
273
+ gen_helper_sve_ldnf1bb_r,
274
+ gen_helper_sve_ldnf1bhu_r,
275
+ gen_helper_sve_ldnf1bsu_r,
276
+ gen_helper_sve_ldnf1bdu_r,
277
+
278
+ gen_helper_sve_ldnf1sds_r,
279
+ gen_helper_sve_ldnf1hh_r,
280
+ gen_helper_sve_ldnf1hsu_r,
281
+ gen_helper_sve_ldnf1hdu_r,
282
+
283
+ gen_helper_sve_ldnf1hds_r,
284
+ gen_helper_sve_ldnf1hss_r,
285
+ gen_helper_sve_ldnf1ss_r,
286
+ gen_helper_sve_ldnf1sdu_r,
287
+
288
+ gen_helper_sve_ldnf1bds_r,
289
+ gen_helper_sve_ldnf1bss_r,
290
+ gen_helper_sve_ldnf1bhs_r,
291
+ gen_helper_sve_ldnf1dd_r,
292
+ };
293
+
294
+ if (sve_access_check(s)) {
295
+ int vsz = vec_full_reg_size(s);
296
+ int elements = vsz >> dtype_esz[a->dtype];
297
+ int off = (a->imm * elements) << dtype_msz(a->dtype);
298
+ TCGv_i64 addr = new_tmp_a64(s);
299
+
300
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn), off);
301
+ do_mem_zpa(s, a->rd, a->pg, addr, fns[a->dtype]);
302
+ }
303
+ return true;
304
+}
305
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
306
index XXXXXXX..XXXXXXX 100644
307
--- a/target/arm/sve.decode
308
+++ b/target/arm/sve.decode
309
@@ -XXX,XX +XXX,XX @@ LDR_zri 10000101 10 ...... 010 ... ..... ..... @rd_rn_i9
310
# SVE contiguous load (scalar plus scalar)
311
LD_zprr 1010010 .... ..... 010 ... ..... ..... @rprr_load_dt nreg=0
312
313
+# SVE contiguous first-fault load (scalar plus scalar)
314
+LDFF1_zprr 1010010 .... ..... 011 ... ..... ..... @rprr_load_dt nreg=0
315
+
316
# SVE contiguous load (scalar plus immediate)
317
LD_zpri 1010010 .... 0.... 101 ... ..... ..... @rpri_load_dt nreg=0
318
319
+# SVE contiguous non-fault load (scalar plus immediate)
320
+LDNF1_zpri 1010010 .... 1.... 101 ... ..... ..... @rpri_load_dt nreg=0
321
+
322
# SVE contiguous non-temporal load (scalar plus scalar)
323
# LDNT1B, LDNT1H, LDNT1W, LDNT1D
324
# SVE load multiple structures (scalar plus scalar)
325
--
326
2.17.1
327
328
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-4-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 29 +++++
9
target/arm/sve_helper.c | 211 +++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 65 ++++++++++++
11
target/arm/sve.decode | 38 +++++++
12
4 files changed, 343 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_4(sve_ldnf1sdu_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
19
DEF_HELPER_FLAGS_4(sve_ldnf1sds_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
20
21
DEF_HELPER_FLAGS_4(sve_ldnf1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
22
+
23
+DEF_HELPER_FLAGS_4(sve_st1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
24
+DEF_HELPER_FLAGS_4(sve_st2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
25
+DEF_HELPER_FLAGS_4(sve_st3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
26
+DEF_HELPER_FLAGS_4(sve_st4bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
27
+
28
+DEF_HELPER_FLAGS_4(sve_st1hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
29
+DEF_HELPER_FLAGS_4(sve_st2hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
30
+DEF_HELPER_FLAGS_4(sve_st3hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
31
+DEF_HELPER_FLAGS_4(sve_st4hh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
32
+
33
+DEF_HELPER_FLAGS_4(sve_st1ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
34
+DEF_HELPER_FLAGS_4(sve_st2ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
35
+DEF_HELPER_FLAGS_4(sve_st3ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
36
+DEF_HELPER_FLAGS_4(sve_st4ss_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
37
+
38
+DEF_HELPER_FLAGS_4(sve_st1dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
39
+DEF_HELPER_FLAGS_4(sve_st2dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
40
+DEF_HELPER_FLAGS_4(sve_st3dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
41
+DEF_HELPER_FLAGS_4(sve_st4dd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
42
+
43
+DEF_HELPER_FLAGS_4(sve_st1bh_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
44
+DEF_HELPER_FLAGS_4(sve_st1bs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
45
+DEF_HELPER_FLAGS_4(sve_st1bd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
46
+
47
+DEF_HELPER_FLAGS_4(sve_st1hs_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
48
+DEF_HELPER_FLAGS_4(sve_st1hd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
49
+
50
+DEF_HELPER_FLAGS_4(sve_st1sd_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
51
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/sve_helper.c
54
+++ b/target/arm/sve_helper.c
55
@@ -XXX,XX +XXX,XX @@ DO_LDNF1(sds_r)
56
DO_LDNF1(dd_r)
57
58
#undef DO_LDNF1
59
+
60
+/*
61
+ * Store contiguous data, protected by a governing predicate.
62
+ */
63
+#define DO_ST1(NAME, FN, TYPEE, TYPEM, H) \
64
+void HELPER(NAME)(CPUARMState *env, void *vg, \
65
+ target_ulong addr, uint32_t desc) \
66
+{ \
67
+ intptr_t i, oprsz = simd_oprsz(desc); \
68
+ intptr_t ra = GETPC(); \
69
+ unsigned rd = simd_data(desc); \
70
+ void *vd = &env->vfp.zregs[rd]; \
71
+ for (i = 0; i < oprsz; ) { \
72
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
73
+ do { \
74
+ if (pg & 1) { \
75
+ TYPEM m = *(TYPEE *)(vd + H(i)); \
76
+ FN(env, addr, m, ra); \
77
+ } \
78
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
79
+ addr += sizeof(TYPEM); \
80
+ } while (i & 15); \
81
+ } \
82
+}
83
+
84
+#define DO_ST1_D(NAME, FN, TYPEM) \
85
+void HELPER(NAME)(CPUARMState *env, void *vg, \
86
+ target_ulong addr, uint32_t desc) \
87
+{ \
88
+ intptr_t i, oprsz = simd_oprsz(desc) / 8; \
89
+ intptr_t ra = GETPC(); \
90
+ unsigned rd = simd_data(desc); \
91
+ uint64_t *d = &env->vfp.zregs[rd].d[0]; \
92
+ uint8_t *pg = vg; \
93
+ for (i = 0; i < oprsz; i += 1) { \
94
+ if (pg[H1(i)] & 1) { \
95
+ FN(env, addr, d[i], ra); \
96
+ } \
97
+ addr += sizeof(TYPEM); \
98
+ } \
99
+}
100
+
101
+#define DO_ST2(NAME, FN, TYPEE, TYPEM, H) \
102
+void HELPER(NAME)(CPUARMState *env, void *vg, \
103
+ target_ulong addr, uint32_t desc) \
104
+{ \
105
+ intptr_t i, oprsz = simd_oprsz(desc); \
106
+ intptr_t ra = GETPC(); \
107
+ unsigned rd = simd_data(desc); \
108
+ void *d1 = &env->vfp.zregs[rd]; \
109
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
110
+ for (i = 0; i < oprsz; ) { \
111
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
112
+ do { \
113
+ if (pg & 1) { \
114
+ TYPEM m1 = *(TYPEE *)(d1 + H(i)); \
115
+ TYPEM m2 = *(TYPEE *)(d2 + H(i)); \
116
+ FN(env, addr, m1, ra); \
117
+ FN(env, addr + sizeof(TYPEM), m2, ra); \
118
+ } \
119
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
120
+ addr += 2 * sizeof(TYPEM); \
121
+ } while (i & 15); \
122
+ } \
123
+}
124
+
125
+#define DO_ST3(NAME, FN, TYPEE, TYPEM, H) \
126
+void HELPER(NAME)(CPUARMState *env, void *vg, \
127
+ target_ulong addr, uint32_t desc) \
128
+{ \
129
+ intptr_t i, oprsz = simd_oprsz(desc); \
130
+ intptr_t ra = GETPC(); \
131
+ unsigned rd = simd_data(desc); \
132
+ void *d1 = &env->vfp.zregs[rd]; \
133
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
134
+ void *d3 = &env->vfp.zregs[(rd + 2) & 31]; \
135
+ for (i = 0; i < oprsz; ) { \
136
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
137
+ do { \
138
+ if (pg & 1) { \
139
+ TYPEM m1 = *(TYPEE *)(d1 + H(i)); \
140
+ TYPEM m2 = *(TYPEE *)(d2 + H(i)); \
141
+ TYPEM m3 = *(TYPEE *)(d3 + H(i)); \
142
+ FN(env, addr, m1, ra); \
143
+ FN(env, addr + sizeof(TYPEM), m2, ra); \
144
+ FN(env, addr + 2 * sizeof(TYPEM), m3, ra); \
145
+ } \
146
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
147
+ addr += 3 * sizeof(TYPEM); \
148
+ } while (i & 15); \
149
+ } \
150
+}
151
+
152
+#define DO_ST4(NAME, FN, TYPEE, TYPEM, H) \
153
+void HELPER(NAME)(CPUARMState *env, void *vg, \
154
+ target_ulong addr, uint32_t desc) \
155
+{ \
156
+ intptr_t i, oprsz = simd_oprsz(desc); \
157
+ intptr_t ra = GETPC(); \
158
+ unsigned rd = simd_data(desc); \
159
+ void *d1 = &env->vfp.zregs[rd]; \
160
+ void *d2 = &env->vfp.zregs[(rd + 1) & 31]; \
161
+ void *d3 = &env->vfp.zregs[(rd + 2) & 31]; \
162
+ void *d4 = &env->vfp.zregs[(rd + 3) & 31]; \
163
+ for (i = 0; i < oprsz; ) { \
164
+ uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
165
+ do { \
166
+ if (pg & 1) { \
167
+ TYPEM m1 = *(TYPEE *)(d1 + H(i)); \
168
+ TYPEM m2 = *(TYPEE *)(d2 + H(i)); \
169
+ TYPEM m3 = *(TYPEE *)(d3 + H(i)); \
170
+ TYPEM m4 = *(TYPEE *)(d4 + H(i)); \
171
+ FN(env, addr, m1, ra); \
172
+ FN(env, addr + sizeof(TYPEM), m2, ra); \
173
+ FN(env, addr + 2 * sizeof(TYPEM), m3, ra); \
174
+ FN(env, addr + 3 * sizeof(TYPEM), m4, ra); \
175
+ } \
176
+ i += sizeof(TYPEE), pg >>= sizeof(TYPEE); \
177
+ addr += 4 * sizeof(TYPEM); \
178
+ } while (i & 15); \
179
+ } \
180
+}
181
+
182
+DO_ST1(sve_st1bh_r, cpu_stb_data_ra, uint16_t, uint8_t, H1_2)
183
+DO_ST1(sve_st1bs_r, cpu_stb_data_ra, uint32_t, uint8_t, H1_4)
184
+DO_ST1_D(sve_st1bd_r, cpu_stb_data_ra, uint8_t)
185
+
186
+DO_ST1(sve_st1hs_r, cpu_stw_data_ra, uint32_t, uint16_t, H1_4)
187
+DO_ST1_D(sve_st1hd_r, cpu_stw_data_ra, uint16_t)
188
+
189
+DO_ST1_D(sve_st1sd_r, cpu_stl_data_ra, uint32_t)
190
+
191
+DO_ST1(sve_st1bb_r, cpu_stb_data_ra, uint8_t, uint8_t, H1)
192
+DO_ST2(sve_st2bb_r, cpu_stb_data_ra, uint8_t, uint8_t, H1)
193
+DO_ST3(sve_st3bb_r, cpu_stb_data_ra, uint8_t, uint8_t, H1)
194
+DO_ST4(sve_st4bb_r, cpu_stb_data_ra, uint8_t, uint8_t, H1)
195
+
196
+DO_ST1(sve_st1hh_r, cpu_stw_data_ra, uint16_t, uint16_t, H1_2)
197
+DO_ST2(sve_st2hh_r, cpu_stw_data_ra, uint16_t, uint16_t, H1_2)
198
+DO_ST3(sve_st3hh_r, cpu_stw_data_ra, uint16_t, uint16_t, H1_2)
199
+DO_ST4(sve_st4hh_r, cpu_stw_data_ra, uint16_t, uint16_t, H1_2)
200
+
201
+DO_ST1(sve_st1ss_r, cpu_stl_data_ra, uint32_t, uint32_t, H1_4)
202
+DO_ST2(sve_st2ss_r, cpu_stl_data_ra, uint32_t, uint32_t, H1_4)
203
+DO_ST3(sve_st3ss_r, cpu_stl_data_ra, uint32_t, uint32_t, H1_4)
204
+DO_ST4(sve_st4ss_r, cpu_stl_data_ra, uint32_t, uint32_t, H1_4)
205
+
206
+DO_ST1_D(sve_st1dd_r, cpu_stq_data_ra, uint64_t)
207
+
208
+void HELPER(sve_st2dd_r)(CPUARMState *env, void *vg,
209
+ target_ulong addr, uint32_t desc)
210
+{
211
+ intptr_t i, oprsz = simd_oprsz(desc) / 8;
212
+ intptr_t ra = GETPC();
213
+ unsigned rd = simd_data(desc);
214
+ uint64_t *d1 = &env->vfp.zregs[rd].d[0];
215
+ uint64_t *d2 = &env->vfp.zregs[(rd + 1) & 31].d[0];
216
+ uint8_t *pg = vg;
217
+
218
+ for (i = 0; i < oprsz; i += 1) {
219
+ if (pg[H1(i)] & 1) {
220
+ cpu_stq_data_ra(env, addr, d1[i], ra);
221
+ cpu_stq_data_ra(env, addr + 8, d2[i], ra);
222
+ }
223
+ addr += 2 * 8;
224
+ }
225
+}
226
+
227
+void HELPER(sve_st3dd_r)(CPUARMState *env, void *vg,
228
+ target_ulong addr, uint32_t desc)
229
+{
230
+ intptr_t i, oprsz = simd_oprsz(desc) / 8;
231
+ intptr_t ra = GETPC();
232
+ unsigned rd = simd_data(desc);
233
+ uint64_t *d1 = &env->vfp.zregs[rd].d[0];
234
+ uint64_t *d2 = &env->vfp.zregs[(rd + 1) & 31].d[0];
235
+ uint64_t *d3 = &env->vfp.zregs[(rd + 2) & 31].d[0];
236
+ uint8_t *pg = vg;
237
+
238
+ for (i = 0; i < oprsz; i += 1) {
239
+ if (pg[H1(i)] & 1) {
240
+ cpu_stq_data_ra(env, addr, d1[i], ra);
241
+ cpu_stq_data_ra(env, addr + 8, d2[i], ra);
242
+ cpu_stq_data_ra(env, addr + 16, d3[i], ra);
243
+ }
244
+ addr += 3 * 8;
245
+ }
246
+}
247
+
248
+void HELPER(sve_st4dd_r)(CPUARMState *env, void *vg,
249
+ target_ulong addr, uint32_t desc)
250
+{
251
+ intptr_t i, oprsz = simd_oprsz(desc) / 8;
252
+ intptr_t ra = GETPC();
253
+ unsigned rd = simd_data(desc);
254
+ uint64_t *d1 = &env->vfp.zregs[rd].d[0];
255
+ uint64_t *d2 = &env->vfp.zregs[(rd + 1) & 31].d[0];
256
+ uint64_t *d3 = &env->vfp.zregs[(rd + 2) & 31].d[0];
257
+ uint64_t *d4 = &env->vfp.zregs[(rd + 3) & 31].d[0];
258
+ uint8_t *pg = vg;
259
+
260
+ for (i = 0; i < oprsz; i += 1) {
261
+ if (pg[H1(i)] & 1) {
262
+ cpu_stq_data_ra(env, addr, d1[i], ra);
263
+ cpu_stq_data_ra(env, addr + 8, d2[i], ra);
264
+ cpu_stq_data_ra(env, addr + 16, d3[i], ra);
265
+ cpu_stq_data_ra(env, addr + 24, d4[i], ra);
266
+ }
267
+ addr += 4 * 8;
268
+ }
269
+}
270
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
271
index XXXXXXX..XXXXXXX 100644
272
--- a/target/arm/translate-sve.c
273
+++ b/target/arm/translate-sve.c
274
@@ -XXX,XX +XXX,XX @@ static bool trans_LDNF1_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
275
}
276
return true;
277
}
278
+
279
+static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
280
+ int msz, int esz, int nreg)
281
+{
282
+ static gen_helper_gvec_mem * const fn_single[4][4] = {
283
+ { gen_helper_sve_st1bb_r, gen_helper_sve_st1bh_r,
284
+ gen_helper_sve_st1bs_r, gen_helper_sve_st1bd_r },
285
+ { NULL, gen_helper_sve_st1hh_r,
286
+ gen_helper_sve_st1hs_r, gen_helper_sve_st1hd_r },
287
+ { NULL, NULL,
288
+ gen_helper_sve_st1ss_r, gen_helper_sve_st1sd_r },
289
+ { NULL, NULL, NULL, gen_helper_sve_st1dd_r },
290
+ };
291
+ static gen_helper_gvec_mem * const fn_multiple[3][4] = {
292
+ { gen_helper_sve_st2bb_r, gen_helper_sve_st2hh_r,
293
+ gen_helper_sve_st2ss_r, gen_helper_sve_st2dd_r },
294
+ { gen_helper_sve_st3bb_r, gen_helper_sve_st3hh_r,
295
+ gen_helper_sve_st3ss_r, gen_helper_sve_st3dd_r },
296
+ { gen_helper_sve_st4bb_r, gen_helper_sve_st4hh_r,
297
+ gen_helper_sve_st4ss_r, gen_helper_sve_st4dd_r },
298
+ };
299
+ gen_helper_gvec_mem *fn;
300
+
301
+ if (nreg == 0) {
302
+ /* ST1 */
303
+ fn = fn_single[msz][esz];
304
+ } else {
305
+ /* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
306
+ assert(msz == esz);
307
+ fn = fn_multiple[nreg - 1][msz];
308
+ }
309
+ assert(fn != NULL);
310
+ do_mem_zpa(s, zt, pg, addr, fn);
311
+}
312
+
313
+static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a, uint32_t insn)
314
+{
315
+ if (a->rm == 31 || a->msz > a->esz) {
316
+ return false;
317
+ }
318
+ if (sve_access_check(s)) {
319
+ TCGv_i64 addr = new_tmp_a64(s);
320
+ tcg_gen_muli_i64(addr, cpu_reg(s, a->rm), (a->nreg + 1) << a->msz);
321
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
322
+ do_st_zpa(s, a->rd, a->pg, addr, a->msz, a->esz, a->nreg);
323
+ }
324
+ return true;
325
+}
326
+
327
+static bool trans_ST_zpri(DisasContext *s, arg_rpri_store *a, uint32_t insn)
328
+{
329
+ if (a->msz > a->esz) {
330
+ return false;
331
+ }
332
+ if (sve_access_check(s)) {
333
+ int vsz = vec_full_reg_size(s);
334
+ int elements = vsz >> a->esz;
335
+ TCGv_i64 addr = new_tmp_a64(s);
336
+
337
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn),
338
+ (a->imm * elements * (a->nreg + 1)) << a->msz);
339
+ do_st_zpa(s, a->rd, a->pg, addr, a->msz, a->esz, a->nreg);
340
+ }
341
+ return true;
342
+}
343
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
344
index XXXXXXX..XXXXXXX 100644
345
--- a/target/arm/sve.decode
346
+++ b/target/arm/sve.decode
347
@@ -XXX,XX +XXX,XX @@
348
%imm7_22_16 22:2 16:5
349
%imm8_16_10 16:5 10:3
350
%imm9_16_10 16:s6 10:3
351
+%size_23 23:2
352
353
# A combination of tsz:imm3 -- extract esize.
354
%tszimm_esz 22:2 5:5 !function=tszimm_esz
355
@@ -XXX,XX +XXX,XX @@
356
&incdec2_pred rd rn pg esz d u
357
&rprr_load rd pg rn rm dtype nreg
358
&rpri_load rd pg rn imm dtype nreg
359
+&rprr_store rd pg rn rm msz esz nreg
360
+&rpri_store rd pg rn imm msz esz nreg
361
362
###########################################################################
363
# Named instruction formats. These are generally used to
364
@@ -XXX,XX +XXX,XX @@
365
@rpri_load_msz ....... .... . imm:s4 ... pg:3 rn:5 rd:5 \
366
&rpri_load dtype=%msz_dtype
367
368
+# Stores; user must fill in ESZ, MSZ, NREG as needed.
369
+@rprr_store ....... .. .. rm:5 ... pg:3 rn:5 rd:5 &rprr_store
370
+@rpri_store_msz ....... msz:2 .. . imm:s4 ... pg:3 rn:5 rd:5 &rpri_store
371
+@rprr_store_esz_n0 ....... .. esz:2 rm:5 ... pg:3 rn:5 rd:5 \
372
+ &rprr_store nreg=0
373
+
374
###########################################################################
375
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
376
377
@@ -XXX,XX +XXX,XX @@ LD_zprr 1010010 .. nreg:2 ..... 110 ... ..... ..... @rprr_load_msz
378
# SVE load multiple structures (scalar plus immediate)
379
# LD2B, LD2H, LD2W, LD2D; etc.
380
LD_zpri 1010010 .. nreg:2 0.... 111 ... ..... ..... @rpri_load_msz
381
+
382
+### SVE Memory Store Group
383
+
384
+# SVE contiguous store (scalar plus immediate)
385
+# ST1B, ST1H, ST1W, ST1D; require msz <= esz
386
+ST_zpri 1110010 .. esz:2 0.... 111 ... ..... ..... \
387
+ @rpri_store_msz nreg=0
388
+
389
+# SVE contiguous store (scalar plus scalar)
390
+# ST1B, ST1H, ST1W, ST1D; require msz <= esz
391
+# Enumerate msz lest we conflict with STR_zri.
392
+ST_zprr 1110010 00 .. ..... 010 ... ..... ..... \
393
+ @rprr_store_esz_n0 msz=0
394
+ST_zprr 1110010 01 .. ..... 010 ... ..... ..... \
395
+ @rprr_store_esz_n0 msz=1
396
+ST_zprr 1110010 10 .. ..... 010 ... ..... ..... \
397
+ @rprr_store_esz_n0 msz=2
398
+ST_zprr 1110010 11 11 ..... 010 ... ..... ..... \
399
+ @rprr_store msz=3 esz=3 nreg=0
400
+
401
+# SVE contiguous non-temporal store (scalar plus immediate) (nreg == 0)
402
+# SVE store multiple structures (scalar plus immediate) (nreg != 0)
403
+ST_zpri 1110010 .. nreg:2 1.... 111 ... ..... ..... \
404
+ @rpri_store_msz esz=%size_23
405
+
406
+# SVE contiguous non-temporal store (scalar plus scalar) (nreg == 0)
407
+# SVE store multiple structures (scalar plus scalar) (nreg != 0)
408
+ST_zprr 1110010 msz:2 nreg:2 ..... 011 ... ..... ..... \
409
+ @rprr_store esz=%size_23
410
--
411
2.17.1
412
413
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-25-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-14-peter.maydell@linaro.org
7
---
9
---
8
target/arm/helper-sve.h | 30 +++++++++++++
10
hw/arm/mps2-tz.c | 52 +++++++++++++++++++++++-------------------------
9
target/arm/helper.h | 12 +++---
11
1 file changed, 25 insertions(+), 27 deletions(-)
10
target/arm/helper.c | 2 +-
11
target/arm/sve_helper.c | 88 ++++++++++++++++++++++++++++++++++++++
12
target/arm/translate-sve.c | 70 ++++++++++++++++++++++++++++++
13
target/arm/sve.decode | 16 +++++++
14
6 files changed, 211 insertions(+), 7 deletions(-)
15
12
16
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-sve.h
15
--- a/hw/arm/mps2-tz.c
19
+++ b/target/arm/helper-sve.h
16
+++ b/hw/arm/mps2-tz.c
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_fcvt_hd, TCG_CALL_NO_RWG,
17
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
21
DEF_HELPER_FLAGS_5(sve_fcvt_sd, TCG_CALL_NO_RWG,
18
const char *name, hwaddr size,
22
void, ptr, ptr, ptr, ptr, i32)
19
const int *irqs)
23
20
{
24
+DEF_HELPER_FLAGS_5(sve_fcvtzs_hh, TCG_CALL_NO_RWG,
21
+ /* The irq[] array is tx, rx, combined, in that order */
25
+ void, ptr, ptr, ptr, ptr, i32)
22
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
26
+DEF_HELPER_FLAGS_5(sve_fcvtzs_hs, TCG_CALL_NO_RWG,
23
CMSDKAPBUART *uart = opaque;
27
+ void, ptr, ptr, ptr, ptr, i32)
24
int i = uart - &mms->uart[0];
28
+DEF_HELPER_FLAGS_5(sve_fcvtzs_ss, TCG_CALL_NO_RWG,
25
- int rxirqno = i * 2 + 32;
29
+ void, ptr, ptr, ptr, ptr, i32)
26
- int txirqno = i * 2 + 33;
30
+DEF_HELPER_FLAGS_5(sve_fcvtzs_ds, TCG_CALL_NO_RWG,
27
- int combirqno = i + 42;
31
+ void, ptr, ptr, ptr, ptr, i32)
28
SysBusDevice *s;
32
+DEF_HELPER_FLAGS_5(sve_fcvtzs_hd, TCG_CALL_NO_RWG,
29
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
33
+ void, ptr, ptr, ptr, ptr, i32)
30
34
+DEF_HELPER_FLAGS_5(sve_fcvtzs_sd, TCG_CALL_NO_RWG,
31
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
35
+ void, ptr, ptr, ptr, ptr, i32)
32
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
36
+DEF_HELPER_FLAGS_5(sve_fcvtzs_dd, TCG_CALL_NO_RWG,
33
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
37
+ void, ptr, ptr, ptr, ptr, i32)
34
s = SYS_BUS_DEVICE(uart);
38
+
35
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
39
+DEF_HELPER_FLAGS_5(sve_fcvtzu_hh, TCG_CALL_NO_RWG,
36
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, rxirqno));
40
+ void, ptr, ptr, ptr, ptr, i32)
37
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
41
+DEF_HELPER_FLAGS_5(sve_fcvtzu_hs, TCG_CALL_NO_RWG,
38
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
42
+ void, ptr, ptr, ptr, ptr, i32)
39
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
43
+DEF_HELPER_FLAGS_5(sve_fcvtzu_ss, TCG_CALL_NO_RWG,
40
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
44
+ void, ptr, ptr, ptr, ptr, i32)
41
- sysbus_connect_irq(s, 4, get_sse_irq_in(mms, combirqno));
45
+DEF_HELPER_FLAGS_5(sve_fcvtzu_ds, TCG_CALL_NO_RWG,
42
+ sysbus_connect_irq(s, 4, get_sse_irq_in(mms, irqs[2]));
46
+ void, ptr, ptr, ptr, ptr, i32)
43
return sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0);
47
+DEF_HELPER_FLAGS_5(sve_fcvtzu_hd, TCG_CALL_NO_RWG,
48
+ void, ptr, ptr, ptr, ptr, i32)
49
+DEF_HELPER_FLAGS_5(sve_fcvtzu_sd, TCG_CALL_NO_RWG,
50
+ void, ptr, ptr, ptr, ptr, i32)
51
+DEF_HELPER_FLAGS_5(sve_fcvtzu_dd, TCG_CALL_NO_RWG,
52
+ void, ptr, ptr, ptr, ptr, i32)
53
+
54
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
55
void, ptr, ptr, ptr, ptr, i32)
56
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
57
diff --git a/target/arm/helper.h b/target/arm/helper.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/helper.h
60
+++ b/target/arm/helper.h
61
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(vfp_touid, i32, f64, ptr)
62
DEF_HELPER_2(vfp_touizh, i32, f16, ptr)
63
DEF_HELPER_2(vfp_touizs, i32, f32, ptr)
64
DEF_HELPER_2(vfp_touizd, i32, f64, ptr)
65
-DEF_HELPER_2(vfp_tosih, i32, f16, ptr)
66
-DEF_HELPER_2(vfp_tosis, i32, f32, ptr)
67
-DEF_HELPER_2(vfp_tosid, i32, f64, ptr)
68
-DEF_HELPER_2(vfp_tosizh, i32, f16, ptr)
69
-DEF_HELPER_2(vfp_tosizs, i32, f32, ptr)
70
-DEF_HELPER_2(vfp_tosizd, i32, f64, ptr)
71
+DEF_HELPER_2(vfp_tosih, s32, f16, ptr)
72
+DEF_HELPER_2(vfp_tosis, s32, f32, ptr)
73
+DEF_HELPER_2(vfp_tosid, s32, f64, ptr)
74
+DEF_HELPER_2(vfp_tosizh, s32, f16, ptr)
75
+DEF_HELPER_2(vfp_tosizs, s32, f32, ptr)
76
+DEF_HELPER_2(vfp_tosizd, s32, f64, ptr)
77
78
DEF_HELPER_3(vfp_toshs_round_to_zero, i32, f32, i32, ptr)
79
DEF_HELPER_3(vfp_tosls_round_to_zero, i32, f32, i32, ptr)
80
diff --git a/target/arm/helper.c b/target/arm/helper.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/arm/helper.c
83
+++ b/target/arm/helper.c
84
@@ -XXX,XX +XXX,XX @@ ftype HELPER(name)(uint32_t x, void *fpstp) \
85
}
44
}
86
45
87
#define CONV_FTOI(name, ftype, fsz, sign, round) \
46
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
88
-uint32_t HELPER(name)(ftype x, void *fpstp) \
47
89
+sign##int32_t HELPER(name)(ftype x, void *fpstp) \
48
s = SYS_BUS_DEVICE(mms->lan9118);
90
{ \
49
sysbus_realize_and_unref(s, &error_fatal);
91
float_status *fpst = fpstp; \
50
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 48));
92
if (float##fsz##_is_any_nan(x)) { \
51
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
93
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
52
return sysbus_mmio_get_region(s, 0);
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/sve_helper.c
96
+++ b/target/arm/sve_helper.c
97
@@ -XXX,XX +XXX,XX @@ static inline float16 sve_f64_to_f16(float64 f, float_status *fpst)
98
return ret;
99
}
53
}
100
54
101
+static inline int16_t vfp_float16_to_int16_rtz(float16 f, float_status *s)
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
102
+{
56
const char *name, hwaddr size,
103
+ if (float16_is_any_nan(f)) {
57
const int *irqs)
104
+ float_raise(float_flag_invalid, s);
58
{
105
+ return 0;
59
+ /* The irq[] array is DMACINTR, DMACINTERR, DMACINTTC, in that order */
106
+ }
60
PL080State *dma = opaque;
107
+ return float16_to_int16_round_to_zero(f, s);
61
int i = dma - &mms->dma[0];
108
+}
62
SysBusDevice *s;
109
+
63
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
110
+static inline int64_t vfp_float16_to_int64_rtz(float16 f, float_status *s)
64
111
+{
65
s = SYS_BUS_DEVICE(dma);
112
+ if (float16_is_any_nan(f)) {
66
/* Wire up DMACINTR, DMACINTERR, DMACINTTC */
113
+ float_raise(float_flag_invalid, s);
67
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 58 + i * 3));
114
+ return 0;
68
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, 56 + i * 3));
115
+ }
69
- sysbus_connect_irq(s, 2, get_sse_irq_in(mms, 57 + i * 3));
116
+ return float16_to_int64_round_to_zero(f, s);
70
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
117
+}
71
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
118
+
72
+ sysbus_connect_irq(s, 2, get_sse_irq_in(mms, irqs[2]));
119
+static inline int64_t vfp_float32_to_int64_rtz(float32 f, float_status *s)
73
120
+{
74
g_free(mscname);
121
+ if (float32_is_any_nan(f)) {
75
return sysbus_mmio_get_region(s, 0);
122
+ float_raise(float_flag_invalid, s);
76
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
123
+ return 0;
77
* lines are set via the "MISC" register in the MPS2 FPGAIO device.
124
+ }
78
*/
125
+ return float32_to_int64_round_to_zero(f, s);
79
PL022State *spi = opaque;
126
+}
80
- int i = spi - &mms->spi[0];
127
+
81
SysBusDevice *s;
128
+static inline int64_t vfp_float64_to_int64_rtz(float64 f, float_status *s)
82
129
+{
83
object_initialize_child(OBJECT(mms), name, spi, TYPE_PL022);
130
+ if (float64_is_any_nan(f)) {
84
sysbus_realize(SYS_BUS_DEVICE(spi), &error_fatal);
131
+ float_raise(float_flag_invalid, s);
85
s = SYS_BUS_DEVICE(spi);
132
+ return 0;
86
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 51 + i));
133
+ }
87
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
134
+ return float64_to_int64_round_to_zero(f, s);
88
return sysbus_mmio_get_region(s, 0);
135
+}
136
+
137
+static inline uint16_t vfp_float16_to_uint16_rtz(float16 f, float_status *s)
138
+{
139
+ if (float16_is_any_nan(f)) {
140
+ float_raise(float_flag_invalid, s);
141
+ return 0;
142
+ }
143
+ return float16_to_uint16_round_to_zero(f, s);
144
+}
145
+
146
+static inline uint64_t vfp_float16_to_uint64_rtz(float16 f, float_status *s)
147
+{
148
+ if (float16_is_any_nan(f)) {
149
+ float_raise(float_flag_invalid, s);
150
+ return 0;
151
+ }
152
+ return float16_to_uint64_round_to_zero(f, s);
153
+}
154
+
155
+static inline uint64_t vfp_float32_to_uint64_rtz(float32 f, float_status *s)
156
+{
157
+ if (float32_is_any_nan(f)) {
158
+ float_raise(float_flag_invalid, s);
159
+ return 0;
160
+ }
161
+ return float32_to_uint64_round_to_zero(f, s);
162
+}
163
+
164
+static inline uint64_t vfp_float64_to_uint64_rtz(float64 f, float_status *s)
165
+{
166
+ if (float64_is_any_nan(f)) {
167
+ float_raise(float_flag_invalid, s);
168
+ return 0;
169
+ }
170
+ return float64_to_uint64_round_to_zero(f, s);
171
+}
172
+
173
DO_ZPZ_FP(sve_fcvt_sh, uint32_t, H1_4, sve_f32_to_f16)
174
DO_ZPZ_FP(sve_fcvt_hs, uint32_t, H1_4, sve_f16_to_f32)
175
DO_ZPZ_FP(sve_fcvt_dh, uint64_t, , sve_f64_to_f16)
176
@@ -XXX,XX +XXX,XX @@ DO_ZPZ_FP(sve_fcvt_hd, uint64_t, , sve_f16_to_f64)
177
DO_ZPZ_FP(sve_fcvt_ds, uint64_t, , float64_to_float32)
178
DO_ZPZ_FP(sve_fcvt_sd, uint64_t, , float32_to_float64)
179
180
+DO_ZPZ_FP(sve_fcvtzs_hh, uint16_t, H1_2, vfp_float16_to_int16_rtz)
181
+DO_ZPZ_FP(sve_fcvtzs_hs, uint32_t, H1_4, helper_vfp_tosizh)
182
+DO_ZPZ_FP(sve_fcvtzs_ss, uint32_t, H1_4, helper_vfp_tosizs)
183
+DO_ZPZ_FP(sve_fcvtzs_hd, uint64_t, , vfp_float16_to_int64_rtz)
184
+DO_ZPZ_FP(sve_fcvtzs_sd, uint64_t, , vfp_float32_to_int64_rtz)
185
+DO_ZPZ_FP(sve_fcvtzs_ds, uint64_t, , helper_vfp_tosizd)
186
+DO_ZPZ_FP(sve_fcvtzs_dd, uint64_t, , vfp_float64_to_int64_rtz)
187
+
188
+DO_ZPZ_FP(sve_fcvtzu_hh, uint16_t, H1_2, vfp_float16_to_uint16_rtz)
189
+DO_ZPZ_FP(sve_fcvtzu_hs, uint32_t, H1_4, helper_vfp_touizh)
190
+DO_ZPZ_FP(sve_fcvtzu_ss, uint32_t, H1_4, helper_vfp_touizs)
191
+DO_ZPZ_FP(sve_fcvtzu_hd, uint64_t, , vfp_float16_to_uint64_rtz)
192
+DO_ZPZ_FP(sve_fcvtzu_sd, uint64_t, , vfp_float32_to_uint64_rtz)
193
+DO_ZPZ_FP(sve_fcvtzu_ds, uint64_t, , helper_vfp_touizd)
194
+DO_ZPZ_FP(sve_fcvtzu_dd, uint64_t, , vfp_float64_to_uint64_rtz)
195
+
196
DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
197
DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
198
DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
199
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/target/arm/translate-sve.c
202
+++ b/target/arm/translate-sve.c
203
@@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
204
return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_sd);
205
}
89
}
206
90
207
+static bool trans_FCVTZS_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
91
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
208
+{
92
}, {
209
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvtzs_hh);
93
.name = "apb_ppcexp1",
210
+}
94
.ports = {
211
+
95
- { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000 },
212
+static bool trans_FCVTZU_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
96
- { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000 },
213
+{
97
- { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000 },
214
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvtzu_hh);
98
- { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000 },
215
+}
99
- { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000 },
216
+
100
- { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000 },
217
+static bool trans_FCVTZS_hs(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
101
- { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000 },
218
+{
102
- { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
219
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvtzs_hs);
103
- { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
220
+}
104
- { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
221
+
105
+ { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000, { 51 } },
222
+static bool trans_FCVTZU_hs(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
106
+ { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000, { 52 } },
223
+{
107
+ { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000, { 53 } },
224
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvtzu_hs);
108
+ { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000, { 54 } },
225
+}
109
+ { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000, { 55 } },
226
+
110
+ { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000, { 32, 33, 42 } },
227
+static bool trans_FCVTZS_hd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
111
+ { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000, { 34, 35, 43 } },
228
+{
112
+ { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000, { 36, 37, 44 } },
229
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvtzs_hd);
113
+ { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000, { 38, 39, 45 } },
230
+}
114
+ { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000, { 40, 41, 46 } },
231
+
115
{ "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
232
+static bool trans_FCVTZU_hd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
116
{ "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
233
+{
117
{ "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
234
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvtzu_hd);
118
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
235
+}
119
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x40101000, 0x1000 },
236
+
120
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x40102000, 0x1000 },
237
+static bool trans_FCVTZS_ss(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
121
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x40103000, 0x1000 },
238
+{
122
- { "eth", make_eth_dev, NULL, 0x42000000, 0x100000 },
239
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzs_ss);
123
+ { "eth", make_eth_dev, NULL, 0x42000000, 0x100000, { 48 } },
240
+}
124
},
241
+
125
}, {
242
+static bool trans_FCVTZU_ss(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
126
.name = "ahb_ppcexp1",
243
+{
127
.ports = {
244
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzu_ss);
128
- { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000 },
245
+}
129
- { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000 },
246
+
130
- { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000 },
247
+static bool trans_FCVTZS_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
131
- { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000 },
248
+{
132
+ { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000, { 58, 56, 57 } },
249
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzs_sd);
133
+ { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000, { 61, 59, 60 } },
250
+}
134
+ { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000, { 64, 62, 63 } },
251
+
135
+ { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000, { 67, 65, 66 } },
252
+static bool trans_FCVTZU_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
136
},
253
+{
137
},
254
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzu_sd);
138
};
255
+}
256
+
257
+static bool trans_FCVTZS_ds(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
258
+{
259
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzs_ds);
260
+}
261
+
262
+static bool trans_FCVTZU_ds(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
263
+{
264
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzu_ds);
265
+}
266
+
267
+static bool trans_FCVTZS_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
268
+{
269
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzs_dd);
270
+}
271
+
272
+static bool trans_FCVTZU_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
273
+{
274
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvtzu_dd);
275
+}
276
+
277
static bool trans_SCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
278
{
279
return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_hh);
280
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
281
index XXXXXXX..XXXXXXX 100644
282
--- a/target/arm/sve.decode
283
+++ b/target/arm/sve.decode
284
@@ -XXX,XX +XXX,XX @@ FCVT_hd 01100101 11 0010 01 101 ... ..... ..... @rd_pg_rn_e0
285
FCVT_ds 01100101 11 0010 10 101 ... ..... ..... @rd_pg_rn_e0
286
FCVT_sd 01100101 11 0010 11 101 ... ..... ..... @rd_pg_rn_e0
287
288
+# SVE floating-point convert to integer
289
+FCVTZS_hh 01100101 01 011 01 0 101 ... ..... ..... @rd_pg_rn_e0
290
+FCVTZU_hh 01100101 01 011 01 1 101 ... ..... ..... @rd_pg_rn_e0
291
+FCVTZS_hs 01100101 01 011 10 0 101 ... ..... ..... @rd_pg_rn_e0
292
+FCVTZU_hs 01100101 01 011 10 1 101 ... ..... ..... @rd_pg_rn_e0
293
+FCVTZS_hd 01100101 01 011 11 0 101 ... ..... ..... @rd_pg_rn_e0
294
+FCVTZU_hd 01100101 01 011 11 1 101 ... ..... ..... @rd_pg_rn_e0
295
+FCVTZS_ss 01100101 10 011 10 0 101 ... ..... ..... @rd_pg_rn_e0
296
+FCVTZU_ss 01100101 10 011 10 1 101 ... ..... ..... @rd_pg_rn_e0
297
+FCVTZS_ds 01100101 11 011 00 0 101 ... ..... ..... @rd_pg_rn_e0
298
+FCVTZU_ds 01100101 11 011 00 1 101 ... ..... ..... @rd_pg_rn_e0
299
+FCVTZS_sd 01100101 11 011 10 0 101 ... ..... ..... @rd_pg_rn_e0
300
+FCVTZU_sd 01100101 11 011 10 1 101 ... ..... ..... @rd_pg_rn_e0
301
+FCVTZS_dd 01100101 11 011 11 0 101 ... ..... ..... @rd_pg_rn_e0
302
+FCVTZU_dd 01100101 11 011 11 1 101 ... ..... ..... @rd_pg_rn_e0
303
+
304
# SVE integer convert to floating-point
305
SCVTF_hh 01100101 01 010 01 0 101 ... ..... ..... @rd_pg_rn_e0
306
SCVTF_sh 01100101 01 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
307
--
139
--
308
2.17.1
140
2.20.1
309
141
310
142
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
We create an OR gate to wire together the overflow IRQs for all the
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.)
2
8
3
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210215115138.20465-15-peter.maydell@linaro.org
6
---
12
---
7
hw/arm/fsl-imx7.c | 2 +-
13
hw/arm/mps2-tz.c | 11 ++++++++---
8
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 8 insertions(+), 3 deletions(-)
9
15
10
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.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/hw/arm/fsl-imx7.c
18
--- a/hw/arm/mps2-tz.c
13
+++ b/hw/arm/fsl-imx7.c
19
+++ b/hw/arm/mps2-tz.c
14
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
20
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
15
/*
16
* SRC
17
*/
21
*/
18
- create_unimplemented_device("sdma", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
22
memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
19
+ create_unimplemented_device("src", FSL_IMX7_SRC_ADDR, FSL_IMX7_SRC_SIZE);
23
20
24
- /* The overflow IRQs for all UARTs are ORed together.
21
/*
25
+ /*
22
* Watchdog
26
+ * The overflow IRQs for all UARTs are ORed together.
27
* Tx, Rx and "combined" IRQs are sent to the NVIC separately.
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.17.1
43
2.20.1
25
44
26
45
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Message-id: 20180627043328.11531-8-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
---
8
---
9
target/arm/helper-sve.h | 16 ++++
9
hw/arm/mps2-tz.c | 16 ++++++++++++++--
10
target/arm/sve_helper.c | 158 +++++++++++++++++++++++++++++++++++++
10
1 file changed, 14 insertions(+), 2 deletions(-)
11
target/arm/translate-sve.c | 49 ++++++++++++
12
target/arm/sve.decode | 18 +++++
13
4 files changed, 241 insertions(+)
14
11
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
14
--- a/hw/arm/mps2-tz.c
18
+++ b/target/arm/helper-sve.h
15
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(sve_ucvt_ds, TCG_CALL_NO_RWG,
16
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
20
DEF_HELPER_FLAGS_5(sve_ucvt_dd, TCG_CALL_NO_RWG,
17
MemoryRegion *system_memory = get_system_memory();
21
void, ptr, ptr, ptr, ptr, i32)
18
DeviceState *iotkitdev;
22
19
DeviceState *dev_splitter;
23
+DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
20
+ const PPCInfo *ppcs;
24
+DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
21
+ int num_ppcs;
25
+DEF_HELPER_FLAGS_3(sve_fmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
22
int i;
26
+
23
27
+DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
24
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
28
+DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
25
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
29
+DEF_HELPER_FLAGS_3(sve_fmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
26
* + wire up the PPC's control lines to the IoTKit object
30
+
27
*/
31
+DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
28
32
+DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
29
- const PPCInfo ppcs[] = { {
33
+DEF_HELPER_FLAGS_3(sve_fnmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
30
+ const PPCInfo an505_ppcs[] = { {
34
+
31
.name = "apb_ppcexp0",
35
+DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
32
.ports = {
36
+DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
33
{ "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
37
+DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
34
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
38
+
35
},
39
DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
36
};
40
DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
37
41
DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
38
- for (i = 0; i < ARRAY_SIZE(ppcs); i++) {
42
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
39
+ switch (mmc->fpga_type) {
43
index XXXXXXX..XXXXXXX 100644
40
+ case FPGA_AN505:
44
--- a/target/arm/sve_helper.c
41
+ case FPGA_AN521:
45
+++ b/target/arm/sve_helper.c
42
+ ppcs = an505_ppcs;
46
@@ -XXX,XX +XXX,XX @@ DO_ZPZ_FP(sve_ucvt_dd, uint64_t, , uint64_to_float64)
43
+ num_ppcs = ARRAY_SIZE(an505_ppcs);
47
44
+ break;
48
#undef DO_ZPZ_FP
45
+ default:
49
46
+ g_assert_not_reached();
50
+/* 4-operand predicated multiply-add. This requires 7 operands to pass
51
+ * "properly", so we need to encode some of the registers into DESC.
52
+ */
53
+QEMU_BUILD_BUG_ON(SIMD_DATA_SHIFT + 20 > 32);
54
+
55
+static void do_fmla_zpzzz_h(CPUARMState *env, void *vg, uint32_t desc,
56
+ uint16_t neg1, uint16_t neg3)
57
+{
58
+ intptr_t i = simd_oprsz(desc);
59
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
60
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
61
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
62
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
63
+ void *vd = &env->vfp.zregs[rd];
64
+ void *vn = &env->vfp.zregs[rn];
65
+ void *vm = &env->vfp.zregs[rm];
66
+ void *va = &env->vfp.zregs[ra];
67
+ uint64_t *g = vg;
68
+
69
+ do {
70
+ uint64_t pg = g[(i - 1) >> 6];
71
+ do {
72
+ i -= 2;
73
+ if (likely((pg >> (i & 63)) & 1)) {
74
+ float16 e1, e2, e3, r;
75
+
76
+ e1 = *(uint16_t *)(vn + H1_2(i)) ^ neg1;
77
+ e2 = *(uint16_t *)(vm + H1_2(i));
78
+ e3 = *(uint16_t *)(va + H1_2(i)) ^ neg3;
79
+ r = float16_muladd(e1, e2, e3, 0, &env->vfp.fp_status);
80
+ *(uint16_t *)(vd + H1_2(i)) = r;
81
+ }
82
+ } while (i & 63);
83
+ } while (i != 0);
84
+}
85
+
86
+void HELPER(sve_fmla_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
87
+{
88
+ do_fmla_zpzzz_h(env, vg, desc, 0, 0);
89
+}
90
+
91
+void HELPER(sve_fmls_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
92
+{
93
+ do_fmla_zpzzz_h(env, vg, desc, 0x8000, 0);
94
+}
95
+
96
+void HELPER(sve_fnmla_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
97
+{
98
+ do_fmla_zpzzz_h(env, vg, desc, 0x8000, 0x8000);
99
+}
100
+
101
+void HELPER(sve_fnmls_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
102
+{
103
+ do_fmla_zpzzz_h(env, vg, desc, 0, 0x8000);
104
+}
105
+
106
+static void do_fmla_zpzzz_s(CPUARMState *env, void *vg, uint32_t desc,
107
+ uint32_t neg1, uint32_t neg3)
108
+{
109
+ intptr_t i = simd_oprsz(desc);
110
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
111
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
112
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
113
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
114
+ void *vd = &env->vfp.zregs[rd];
115
+ void *vn = &env->vfp.zregs[rn];
116
+ void *vm = &env->vfp.zregs[rm];
117
+ void *va = &env->vfp.zregs[ra];
118
+ uint64_t *g = vg;
119
+
120
+ do {
121
+ uint64_t pg = g[(i - 1) >> 6];
122
+ do {
123
+ i -= 4;
124
+ if (likely((pg >> (i & 63)) & 1)) {
125
+ float32 e1, e2, e3, r;
126
+
127
+ e1 = *(uint32_t *)(vn + H1_4(i)) ^ neg1;
128
+ e2 = *(uint32_t *)(vm + H1_4(i));
129
+ e3 = *(uint32_t *)(va + H1_4(i)) ^ neg3;
130
+ r = float32_muladd(e1, e2, e3, 0, &env->vfp.fp_status);
131
+ *(uint32_t *)(vd + H1_4(i)) = r;
132
+ }
133
+ } while (i & 63);
134
+ } while (i != 0);
135
+}
136
+
137
+void HELPER(sve_fmla_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
138
+{
139
+ do_fmla_zpzzz_s(env, vg, desc, 0, 0);
140
+}
141
+
142
+void HELPER(sve_fmls_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
143
+{
144
+ do_fmla_zpzzz_s(env, vg, desc, 0x80000000, 0);
145
+}
146
+
147
+void HELPER(sve_fnmla_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
148
+{
149
+ do_fmla_zpzzz_s(env, vg, desc, 0x80000000, 0x80000000);
150
+}
151
+
152
+void HELPER(sve_fnmls_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
153
+{
154
+ do_fmla_zpzzz_s(env, vg, desc, 0, 0x80000000);
155
+}
156
+
157
+static void do_fmla_zpzzz_d(CPUARMState *env, void *vg, uint32_t desc,
158
+ uint64_t neg1, uint64_t neg3)
159
+{
160
+ intptr_t i = simd_oprsz(desc);
161
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
162
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
163
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
164
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
165
+ void *vd = &env->vfp.zregs[rd];
166
+ void *vn = &env->vfp.zregs[rn];
167
+ void *vm = &env->vfp.zregs[rm];
168
+ void *va = &env->vfp.zregs[ra];
169
+ uint64_t *g = vg;
170
+
171
+ do {
172
+ uint64_t pg = g[(i - 1) >> 6];
173
+ do {
174
+ i -= 8;
175
+ if (likely((pg >> (i & 63)) & 1)) {
176
+ float64 e1, e2, e3, r;
177
+
178
+ e1 = *(uint64_t *)(vn + i) ^ neg1;
179
+ e2 = *(uint64_t *)(vm + i);
180
+ e3 = *(uint64_t *)(va + i) ^ neg3;
181
+ r = float64_muladd(e1, e2, e3, 0, &env->vfp.fp_status);
182
+ *(uint64_t *)(vd + i) = r;
183
+ }
184
+ } while (i & 63);
185
+ } while (i != 0);
186
+}
187
+
188
+void HELPER(sve_fmla_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
189
+{
190
+ do_fmla_zpzzz_d(env, vg, desc, 0, 0);
191
+}
192
+
193
+void HELPER(sve_fmls_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
194
+{
195
+ do_fmla_zpzzz_d(env, vg, desc, INT64_MIN, 0);
196
+}
197
+
198
+void HELPER(sve_fnmla_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
199
+{
200
+ do_fmla_zpzzz_d(env, vg, desc, INT64_MIN, INT64_MIN);
201
+}
202
+
203
+void HELPER(sve_fnmls_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
204
+{
205
+ do_fmla_zpzzz_d(env, vg, desc, 0, INT64_MIN);
206
+}
207
+
208
/*
209
* Load contiguous data, protected by a governing predicate.
210
*/
211
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
212
index XXXXXXX..XXXXXXX 100644
213
--- a/target/arm/translate-sve.c
214
+++ b/target/arm/translate-sve.c
215
@@ -XXX,XX +XXX,XX @@ DO_FP3(FMULX, fmulx)
216
217
#undef DO_FP3
218
219
+typedef void gen_helper_sve_fmla(TCGv_env, TCGv_ptr, TCGv_i32);
220
+
221
+static bool do_fmla(DisasContext *s, arg_rprrr_esz *a, gen_helper_sve_fmla *fn)
222
+{
223
+ if (fn == NULL) {
224
+ return false;
225
+ }
226
+ if (!sve_access_check(s)) {
227
+ return true;
228
+ }
47
+ }
229
+
48
+
230
+ unsigned vsz = vec_full_reg_size(s);
49
+ for (i = 0; i < num_ppcs; i++) {
231
+ unsigned desc;
50
const PPCInfo *ppcinfo = &ppcs[i];
232
+ TCGv_i32 t_desc;
51
TZPPC *ppc = &mms->ppc[i];
233
+ TCGv_ptr pg = tcg_temp_new_ptr();
52
DeviceState *ppcdev;
234
+
235
+ /* We would need 7 operands to pass these arguments "properly".
236
+ * So we encode all the register numbers into the descriptor.
237
+ */
238
+ desc = deposit32(a->rd, 5, 5, a->rn);
239
+ desc = deposit32(desc, 10, 5, a->rm);
240
+ desc = deposit32(desc, 15, 5, a->ra);
241
+ desc = simd_desc(vsz, vsz, desc);
242
+
243
+ t_desc = tcg_const_i32(desc);
244
+ tcg_gen_addi_ptr(pg, cpu_env, pred_full_reg_offset(s, a->pg));
245
+ fn(cpu_env, pg, t_desc);
246
+ tcg_temp_free_i32(t_desc);
247
+ tcg_temp_free_ptr(pg);
248
+ return true;
249
+}
250
+
251
+#define DO_FMLA(NAME, name) \
252
+static bool trans_##NAME(DisasContext *s, arg_rprrr_esz *a, uint32_t insn) \
253
+{ \
254
+ static gen_helper_sve_fmla * const fns[4] = { \
255
+ NULL, gen_helper_sve_##name##_h, \
256
+ gen_helper_sve_##name##_s, gen_helper_sve_##name##_d \
257
+ }; \
258
+ return do_fmla(s, a, fns[a->esz]); \
259
+}
260
+
261
+DO_FMLA(FMLA_zpzzz, fmla_zpzzz)
262
+DO_FMLA(FMLS_zpzzz, fmls_zpzzz)
263
+DO_FMLA(FNMLA_zpzzz, fnmla_zpzzz)
264
+DO_FMLA(FNMLS_zpzzz, fnmls_zpzzz)
265
+
266
+#undef DO_FMLA
267
+
268
/*
269
*** SVE Floating Point Unary Operations Predicated Group
270
*/
271
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
272
index XXXXXXX..XXXXXXX 100644
273
--- a/target/arm/sve.decode
274
+++ b/target/arm/sve.decode
275
@@ -XXX,XX +XXX,XX @@
276
&rprrr_esz ra=%reg_movprfx
277
@rdn_pg_ra_rm ........ esz:2 . rm:5 ... pg:3 ra:5 rd:5 \
278
&rprrr_esz rn=%reg_movprfx
279
+@rdn_pg_rm_ra ........ esz:2 . ra:5 ... pg:3 rm:5 rd:5 \
280
+ &rprrr_esz rn=%reg_movprfx
281
282
# One register operand, with governing predicate, vector element size
283
@rd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 &rpr_esz
284
@@ -XXX,XX +XXX,XX @@ FMULX 01100101 .. 00 1010 100 ... ..... ..... @rdn_pg_rm
285
FDIV 01100101 .. 00 1100 100 ... ..... ..... @rdm_pg_rn # FDIVR
286
FDIV 01100101 .. 00 1101 100 ... ..... ..... @rdn_pg_rm
287
288
+### SVE FP Multiply-Add Group
289
+
290
+# SVE floating-point multiply-accumulate writing addend
291
+FMLA_zpzzz 01100101 .. 1 ..... 000 ... ..... ..... @rda_pg_rn_rm
292
+FMLS_zpzzz 01100101 .. 1 ..... 001 ... ..... ..... @rda_pg_rn_rm
293
+FNMLA_zpzzz 01100101 .. 1 ..... 010 ... ..... ..... @rda_pg_rn_rm
294
+FNMLS_zpzzz 01100101 .. 1 ..... 011 ... ..... ..... @rda_pg_rn_rm
295
+
296
+# SVE floating-point multiply-accumulate writing multiplicand
297
+# Alter the operand extraction order and reuse the helpers from above.
298
+# FMAD, FMSB, FNMAD, FNMS
299
+FMLA_zpzzz 01100101 .. 1 ..... 100 ... ..... ..... @rdn_pg_rm_ra
300
+FMLS_zpzzz 01100101 .. 1 ..... 101 ... ..... ..... @rdn_pg_rm_ra
301
+FNMLA_zpzzz 01100101 .. 1 ..... 110 ... ..... ..... @rdn_pg_rm_ra
302
+FNMLS_zpzzz 01100101 .. 1 ..... 111 ... ..... ..... @rdn_pg_rm_ra
303
+
304
### SVE FP Unary Operations Predicated Group
305
306
# SVE integer convert to floating-point
307
--
53
--
308
2.17.1
54
2.20.1
309
55
310
56
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
of it are behind which MPCs with a data-driven approach.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Message-id: 20180627043328.11531-19-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210215115138.20465-17-peter.maydell@linaro.org
7
---
8
---
8
target/arm/helper.h | 14 +++++++++++
9
hw/arm/mps2-tz.c | 175 +++++++++++++++++++++++++++++++++++++----------
9
target/arm/translate-sve.c | 50 ++++++++++++++++++++++++++++++++++++++
10
1 file changed, 138 insertions(+), 37 deletions(-)
10
target/arm/vec_helper.c | 48 ++++++++++++++++++++++++++++++++++++
11
11
target/arm/sve.decode | 19 +++++++++++++++
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
12
4 files changed, 131 insertions(+)
13
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.h
14
--- a/hw/arm/mps2-tz.c
17
+++ b/target/arm/helper.h
15
+++ b/hw/arm/mps2-tz.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_ftsmul_s, TCG_CALL_NO_RWG,
16
@@ -XXX,XX +XXX,XX @@
19
DEF_HELPER_FLAGS_5(gvec_ftsmul_d, TCG_CALL_NO_RWG,
17
#include "qom/object.h"
20
void, ptr, ptr, ptr, ptr, i32)
18
21
19
#define MPS2TZ_NUMIRQ_MAX 92
22
+DEF_HELPER_FLAGS_5(gvec_fmul_idx_h, TCG_CALL_NO_RWG,
20
+#define MPS2TZ_RAM_MAX 4
23
+ void, ptr, ptr, ptr, ptr, i32)
21
24
+DEF_HELPER_FLAGS_5(gvec_fmul_idx_s, TCG_CALL_NO_RWG,
22
typedef enum MPS2TZFPGAType {
25
+ void, ptr, ptr, ptr, ptr, i32)
23
FPGA_AN505,
26
+DEF_HELPER_FLAGS_5(gvec_fmul_idx_d, TCG_CALL_NO_RWG,
24
FPGA_AN521,
27
+ void, ptr, ptr, ptr, ptr, i32)
25
} MPS2TZFPGAType;
28
+
29
+DEF_HELPER_FLAGS_6(gvec_fmla_idx_h, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_6(gvec_fmla_idx_s, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_6(gvec_fmla_idx_d, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, ptr, i32)
35
+
36
#ifdef TARGET_AARCH64
37
#include "helper-a64.h"
38
#include "helper-sve.h"
39
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/translate-sve.c
42
+++ b/target/arm/translate-sve.c
43
@@ -XXX,XX +XXX,XX @@ DO_ZZI(UMIN, umin)
44
45
#undef DO_ZZI
46
26
47
+/*
27
+/*
48
+ *** SVE Floating Point Multiply-Add Indexed Group
28
+ * Define the layout of RAM in a board, including which parts are
29
+ * behind which MPCs.
30
+ * mrindex specifies the index into mms->ram[] to use for the backing RAM;
31
+ * -1 means "use the system RAM".
49
+ */
32
+ */
50
+
33
+typedef struct RAMInfo {
51
+static bool trans_FMLA_zzxz(DisasContext *s, arg_FMLA_zzxz *a, uint32_t insn)
34
+ const char *name;
35
+ uint32_t base;
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)
52
+{
117
+{
53
+ static gen_helper_gvec_4_ptr * const fns[3] = {
118
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
54
+ gen_helper_gvec_fmla_idx_h,
119
+ const RAMInfo *p;
55
+ gen_helper_gvec_fmla_idx_s,
120
+
56
+ gen_helper_gvec_fmla_idx_d,
121
+ for (p = mmc->raminfo; p->name; p++) {
57
+ };
122
+ if (p->mpc == mpc && !(p->flags & IS_ALIAS)) {
58
+
123
+ return p;
59
+ if (sve_access_check(s)) {
124
+ }
60
+ unsigned vsz = vec_full_reg_size(s);
61
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
62
+ tcg_gen_gvec_4_ptr(vec_full_reg_offset(s, a->rd),
63
+ vec_full_reg_offset(s, a->rn),
64
+ vec_full_reg_offset(s, a->rm),
65
+ vec_full_reg_offset(s, a->ra),
66
+ status, vsz, vsz, (a->index << 1) | a->sub,
67
+ fns[a->esz - 1]);
68
+ tcg_temp_free_ptr(status);
69
+ }
125
+ }
70
+ return true;
126
+ /* if raminfo array doesn't have an entry for each MPC this is a bug */
127
+ g_assert_not_reached();
71
+}
128
+}
72
+
129
+
73
+/*
130
+static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
74
+ *** SVE Floating Point Multiply Indexed Group
131
+ const RAMInfo *raminfo)
75
+ */
76
+
77
+static bool trans_FMUL_zzx(DisasContext *s, arg_FMUL_zzx *a, uint32_t insn)
78
+{
132
+{
79
+ static gen_helper_gvec_3_ptr * const fns[3] = {
133
+ /* Return an initialized MemoryRegion for the RAMInfo. */
80
+ gen_helper_gvec_fmul_idx_h,
134
+ MemoryRegion *ram;
81
+ gen_helper_gvec_fmul_idx_s,
135
+
82
+ gen_helper_gvec_fmul_idx_d,
136
+ if (raminfo->mrindex < 0) {
83
+ };
137
+ /* Means this RAMInfo is for QEMU's "system memory" */
84
+
138
+ MachineState *machine = MACHINE(mms);
85
+ if (sve_access_check(s)) {
139
+ return machine->ram;
86
+ unsigned vsz = vec_full_reg_size(s);
87
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
88
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
89
+ vec_full_reg_offset(s, a->rn),
90
+ vec_full_reg_offset(s, a->rm),
91
+ status, vsz, vsz, a->index, fns[a->esz - 1]);
92
+ tcg_temp_free_ptr(status);
93
+ }
140
+ }
94
+ return true;
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;
95
+}
148
+}
96
+
149
+
97
/*
150
/* Create an alias of an entire original MemoryRegion @orig
98
*** SVE Floating Point Accumulating Reduction Group
151
* located at @base in the memory map.
99
*/
152
*/
100
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
153
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
101
index XXXXXXX..XXXXXXX 100644
154
const int *irqs)
102
--- a/target/arm/vec_helper.c
155
{
103
+++ b/target/arm/vec_helper.c
156
TZMPC *mpc = opaque;
104
@@ -XXX,XX +XXX,XX @@ DO_3OP(gvec_rsqrts_d, helper_rsqrtsf_f64, float64)
157
- int i = mpc - &mms->ssram_mpc[0];
105
158
- MemoryRegion *ssram = &mms->ssram[i];
106
#endif
159
+ int i = mpc - &mms->mpc[0];
107
#undef DO_3OP
160
MemoryRegion *upstream;
108
+
161
- char *mpcname = g_strdup_printf("%s-mpc", name);
109
+/* For the indexed ops, SVE applies the index per 128-bit vector segment.
162
- static uint32_t ramsize[] = { 0x00400000, 0x00200000, 0x00200000 };
110
+ * For AdvSIMD, there is of course only one such vector segment.
163
- static uint32_t rambase[] = { 0x00000000, 0x28000000, 0x28200000 };
111
+ */
164
+ const RAMInfo *raminfo = find_raminfo_for_mpc(mms, i);
112
+
165
+ MemoryRegion *ram = mr_for_raminfo(mms, raminfo);
113
+#define DO_MUL_IDX(NAME, TYPE, H) \
166
114
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *stat, uint32_t desc) \
167
- memory_region_init_ram(ssram, NULL, name, ramsize[i], &error_fatal);
115
+{ \
168
-
116
+ intptr_t i, j, oprsz = simd_oprsz(desc), segment = 16 / sizeof(TYPE); \
169
- object_initialize_child(OBJECT(mms), mpcname, mpc, TYPE_TZ_MPC);
117
+ intptr_t idx = simd_data(desc); \
170
- object_property_set_link(OBJECT(mpc), "downstream", OBJECT(ssram),
118
+ TYPE *d = vd, *n = vn, *m = vm; \
171
+ object_initialize_child(OBJECT(mms), name, mpc, TYPE_TZ_MPC);
119
+ for (i = 0; i < oprsz / sizeof(TYPE); i += segment) { \
172
+ object_property_set_link(OBJECT(mpc), "downstream", OBJECT(ram),
120
+ TYPE mm = m[H(i + idx)]; \
173
&error_fatal);
121
+ for (j = 0; j < segment; j++) { \
174
sysbus_realize(SYS_BUS_DEVICE(mpc), &error_fatal);
122
+ d[i + j] = TYPE##_mul(n[i + j], mm, stat); \
175
/* Map the upstream end of the MPC into system memory */
123
+ } \
176
upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
124
+ } \
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)
200
+{
201
+ /*
202
+ * Handle the RAMs which are either not behind MPCs or which are
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
+ }
125
+}
219
+}
126
+
220
+
127
+DO_MUL_IDX(gvec_fmul_idx_h, float16, H2)
221
static void mps2tz_common_init(MachineState *machine)
128
+DO_MUL_IDX(gvec_fmul_idx_s, float32, H4)
222
{
129
+DO_MUL_IDX(gvec_fmul_idx_d, float64, )
223
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
130
+
224
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
131
+#undef DO_MUL_IDX
225
qdev_connect_gpio_out_named(iotkitdev, "sec_resp_cfg", 0,
132
+
226
qdev_get_gpio_in(dev_splitter, 0));
133
+#define DO_FMLA_IDX(NAME, TYPE, H) \
227
134
+void HELPER(NAME)(void *vd, void *vn, void *vm, void *va, \
228
- /* The IoTKit sets up much of the memory layout, including
135
+ void *stat, uint32_t desc) \
229
+ /*
136
+{ \
230
+ * The IoTKit sets up much of the memory layout, including
137
+ intptr_t i, j, oprsz = simd_oprsz(desc), segment = 16 / sizeof(TYPE); \
231
* the aliases between secure and non-secure regions in the
138
+ TYPE op1_neg = extract32(desc, SIMD_DATA_SHIFT, 1); \
232
- * address space. The FPGA itself contains:
139
+ intptr_t idx = desc >> (SIMD_DATA_SHIFT + 1); \
233
- *
140
+ TYPE *d = vd, *n = vn, *m = vm, *a = va; \
234
- * 0x00000000..0x003fffff SSRAM1
141
+ op1_neg <<= (8 * sizeof(TYPE) - 1); \
235
- * 0x00400000..0x007fffff alias of SSRAM1
142
+ for (i = 0; i < oprsz / sizeof(TYPE); i += segment) { \
236
- * 0x28000000..0x283fffff 4MB SSRAM2 + SSRAM3
143
+ TYPE mm = m[H(i + idx)]; \
237
- * 0x40100000..0x4fffffff AHB Master Expansion 1 interface devices
144
+ for (j = 0; j < segment; j++) { \
238
- * 0x80000000..0x80ffffff 16MB PSRAM
145
+ d[i + j] = TYPE##_muladd(n[i + j] ^ op1_neg, \
239
- */
146
+ mm, a[i + j], 0, stat); \
240
-
147
+ } \
241
- /* The FPGA images have an odd combination of different RAMs,
148
+ } \
242
+ * address space, and also most of the devices in the system.
149
+}
243
+ * The FPGA itself contains various RAMs and some additional devices.
150
+
244
+ * The FPGA images have an odd combination of different RAMs,
151
+DO_FMLA_IDX(gvec_fmla_idx_h, float16, H2)
245
* because in hardware they are different implementations and
152
+DO_FMLA_IDX(gvec_fmla_idx_s, float32, H4)
246
* connected to different buses, giving varying performance/size
153
+DO_FMLA_IDX(gvec_fmla_idx_d, float64, )
247
* tradeoffs. For QEMU they're all just RAM, though. We arbitrarily
154
+
248
- * call the 16MB our "system memory", as it's the largest lump.
155
+#undef DO_FMLA_IDX
249
+ * call the largest lump our "system memory".
156
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
250
*/
157
index XXXXXXX..XXXXXXX 100644
251
- memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
158
--- a/target/arm/sve.decode
252
159
+++ b/target/arm/sve.decode
253
/*
160
@@ -XXX,XX +XXX,XX @@
254
* The overflow IRQs for all UARTs are ORed together.
161
%imm9_16_10 16:s6 10:3
255
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
162
%size_23 23:2
256
const PPCInfo an505_ppcs[] = { {
163
%dtype_23_13 23:2 13:2
257
.name = "apb_ppcexp0",
164
+%index3_22_19 22:1 19:2
258
.ports = {
165
259
- { "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
166
# A combination of tsz:imm3 -- extract esize.
260
- { "ssram-1", make_mpc, &mms->ssram_mpc[1], 0x58008000, 0x1000 },
167
%tszimm_esz 22:2 5:5 !function=tszimm_esz
261
- { "ssram-2", make_mpc, &mms->ssram_mpc[2], 0x58009000, 0x1000 },
168
@@ -XXX,XX +XXX,XX @@ UMIN_zzi 00100101 .. 101 011 110 ........ ..... @rdn_i8u
262
+ { "ssram-0-mpc", make_mpc, &mms->mpc[0], 0x58007000, 0x1000 },
169
# SVE integer multiply immediate (unpredicated)
263
+ { "ssram-1-mpc", make_mpc, &mms->mpc[1], 0x58008000, 0x1000 },
170
MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
264
+ { "ssram-2-mpc", make_mpc, &mms->mpc[2], 0x58009000, 0x1000 },
171
265
},
172
+### SVE FP Multiply-Add Indexed Group
266
}, {
173
+
267
.name = "apb_ppcexp1",
174
+# SVE floating-point multiply-add (indexed)
268
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
175
+FMLA_zzxz 01100100 0.1 .. rm:3 00000 sub:1 rn:5 rd:5 \
269
176
+ ra=%reg_movprfx index=%index3_22_19 esz=1
270
create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000);
177
+FMLA_zzxz 01100100 101 index:2 rm:3 00000 sub:1 rn:5 rd:5 \
271
178
+ ra=%reg_movprfx esz=2
272
+ create_non_mpc_ram(mms);
179
+FMLA_zzxz 01100100 111 index:1 rm:4 00000 sub:1 rn:5 rd:5 \
273
+
180
+ ra=%reg_movprfx esz=3
274
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
181
+
275
}
182
+### SVE FP Multiply Indexed Group
276
183
+
277
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
184
+# SVE floating-point multiply (indexed)
278
mmc->fpgaio_num_leds = 2;
185
+FMUL_zzx 01100100 0.1 .. rm:3 001000 rn:5 rd:5 \
279
mmc->fpgaio_has_switches = false;
186
+ index=%index3_22_19 esz=1
280
mmc->numirq = 92;
187
+FMUL_zzx 01100100 101 index:2 rm:3 001000 rn:5 rd:5 esz=2
281
+ mmc->raminfo = an505_raminfo;
188
+FMUL_zzx 01100100 111 index:1 rm:4 001000 rn:5 rd:5 esz=3
282
mmc->armsse_type = TYPE_IOTKIT;
189
+
283
}
190
### SVE FP Accumulating Reduction Group
284
191
285
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
192
# SVE floating-point serial reduction (predicated)
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
193
--
293
--
194
2.17.1
294
2.20.1
195
295
196
296
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
We've already added the helpers with an SVE patch, all that remains
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
is to wire up the aa64 and aa32 translators. Enable the feature
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
within -cpu max for CONFIG_USER_ONLY.
8
Message-id: 20210215115138.20465-18-peter.maydell@linaro.org
9
---
10
hw/arm/mps2-tz.c | 24 ++++++++++++++++++++++--
11
1 file changed, 22 insertions(+), 2 deletions(-)
6
12
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180627043328.11531-36-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 1 +
13
linux-user/elfload.c | 1 +
14
target/arm/cpu.c | 1 +
15
target/arm/cpu64.c | 1 +
16
target/arm/translate-a64.c | 36 +++++++++++++++++++
17
target/arm/translate.c | 74 +++++++++++++++++++++++++++-----------
18
6 files changed, 93 insertions(+), 21 deletions(-)
19
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
15
--- a/hw/arm/mps2-tz.c
23
+++ b/target/arm/cpu.h
16
+++ b/hw/arm/mps2-tz.c
24
@@ -XXX,XX +XXX,XX @@ enum arm_features {
17
@@ -XXX,XX +XXX,XX @@ static void mps2tz_class_init(ObjectClass *oc, void *data)
25
ARM_FEATURE_V8_SM4, /* implements SM4 part of v8 Crypto Extensions */
18
26
ARM_FEATURE_V8_ATOMICS, /* ARMv8.1-Atomics feature */
19
mc->init = mps2tz_common_init;
27
ARM_FEATURE_V8_RDM, /* implements v8.1 simd round multiply */
20
iic->check = mps2_tz_idau_check;
28
+ ARM_FEATURE_V8_DOTPROD, /* implements v8.2 simd dot product */
21
- mc->default_ram_size = 16 * MiB;
29
ARM_FEATURE_V8_FP16, /* implements v8.2 half-precision float */
22
- mc->default_ram_id = "mps.ram";
30
ARM_FEATURE_V8_FCMA, /* has complex number part of v8.3 extensions. */
31
ARM_FEATURE_M_MAIN, /* M profile Main Extension */
32
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/linux-user/elfload.c
35
+++ b/linux-user/elfload.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
37
ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
38
GET_FEATURE(ARM_FEATURE_V8_ATOMICS, ARM_HWCAP_A64_ATOMICS);
39
GET_FEATURE(ARM_FEATURE_V8_RDM, ARM_HWCAP_A64_ASIMDRDM);
40
+ GET_FEATURE(ARM_FEATURE_V8_DOTPROD, ARM_HWCAP_A64_ASIMDDP);
41
GET_FEATURE(ARM_FEATURE_V8_FCMA, ARM_HWCAP_A64_FCMA);
42
GET_FEATURE(ARM_FEATURE_SVE, ARM_HWCAP_A64_SVE);
43
#undef GET_FEATURE
44
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu.c
47
+++ b/target/arm/cpu.c
48
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
49
set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
50
set_feature(&cpu->env, ARM_FEATURE_CRC);
51
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
52
+ set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
53
set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
54
#endif
55
}
56
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/cpu64.c
59
+++ b/target/arm/cpu64.c
60
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
61
set_feature(&cpu->env, ARM_FEATURE_CRC);
62
set_feature(&cpu->env, ARM_FEATURE_V8_ATOMICS);
63
set_feature(&cpu->env, ARM_FEATURE_V8_RDM);
64
+ set_feature(&cpu->env, ARM_FEATURE_V8_DOTPROD);
65
set_feature(&cpu->env, ARM_FEATURE_V8_FP16);
66
set_feature(&cpu->env, ARM_FEATURE_V8_FCMA);
67
set_feature(&cpu->env, ARM_FEATURE_SVE);
68
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/translate-a64.c
71
+++ b/target/arm/translate-a64.c
72
@@ -XXX,XX +XXX,XX @@ static void gen_gvec_op3(DisasContext *s, bool is_q, int rd,
73
vec_full_reg_size(s), gvec_op);
74
}
75
76
+/* Expand a 3-operand operation using an out-of-line helper. */
77
+static void gen_gvec_op3_ool(DisasContext *s, bool is_q, int rd,
78
+ int rn, int rm, int data, gen_helper_gvec_3 *fn)
79
+{
80
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
81
+ vec_full_reg_offset(s, rn),
82
+ vec_full_reg_offset(s, rm),
83
+ is_q ? 16 : 8, vec_full_reg_size(s), data, fn);
84
+}
23
+}
85
+
24
+
86
/* Expand a 3-operand + env pointer operation using
25
+static void mps2tz_set_default_ram_info(MPS2TZMachineClass *mmc)
87
* an out-of-line helper.
26
+{
88
*/
27
+ /*
89
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
28
+ * Set mc->default_ram_size and default_ram_id from the
90
}
29
+ * information in mmc->raminfo.
91
feature = ARM_FEATURE_V8_RDM;
30
+ */
92
break;
31
+ MachineClass *mc = MACHINE_CLASS(mmc);
93
+ case 0x02: /* SDOT (vector) */
32
+ const RAMInfo *p;
94
+ case 0x12: /* UDOT (vector) */
33
+
95
+ if (size != MO_32) {
34
+ for (p = mmc->raminfo; p->name; p++) {
96
+ unallocated_encoding(s);
35
+ if (p->mrindex < 0) {
36
+ /* Found the entry for "system memory" */
37
+ mc->default_ram_size = p->size;
38
+ mc->default_ram_id = p->name;
97
+ return;
39
+ return;
98
+ }
40
+ }
99
+ feature = ARM_FEATURE_V8_DOTPROD;
100
+ break;
101
case 0x8: /* FCMLA, #0 */
102
case 0x9: /* FCMLA, #90 */
103
case 0xa: /* FCMLA, #180 */
104
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
105
}
106
return;
107
108
+ case 0x2: /* SDOT / UDOT */
109
+ gen_gvec_op3_ool(s, is_q, rd, rn, rm, 0,
110
+ u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b);
111
+ return;
112
+
113
case 0x8: /* FCMLA, #0 */
114
case 0x9: /* FCMLA, #90 */
115
case 0xa: /* FCMLA, #180 */
116
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
117
return;
118
}
119
break;
120
+ case 0x0e: /* SDOT */
121
+ case 0x1e: /* UDOT */
122
+ if (size != MO_32 || !arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
123
+ unallocated_encoding(s);
124
+ return;
125
+ }
126
+ break;
127
case 0x11: /* FCMLA #0 */
128
case 0x13: /* FCMLA #90 */
129
case 0x15: /* FCMLA #180 */
130
@@ -XXX,XX +XXX,XX @@ static void disas_simd_indexed(DisasContext *s, uint32_t insn)
131
}
132
133
switch (16 * u + opcode) {
134
+ case 0x0e: /* SDOT */
135
+ case 0x1e: /* UDOT */
136
+ gen_gvec_op3_ool(s, is_q, rd, rn, rm, index,
137
+ u ? gen_helper_gvec_udot_idx_b
138
+ : gen_helper_gvec_sdot_idx_b);
139
+ return;
140
case 0x11: /* FCMLA #0 */
141
case 0x13: /* FCMLA #90 */
142
case 0x15: /* FCMLA #180 */
143
diff --git a/target/arm/translate.c b/target/arm/translate.c
144
index XXXXXXX..XXXXXXX 100644
145
--- a/target/arm/translate.c
146
+++ b/target/arm/translate.c
147
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
148
*/
149
static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
150
{
151
- gen_helper_gvec_3_ptr *fn_gvec_ptr;
152
- int rd, rn, rm, rot, size, opr_sz;
153
- TCGv_ptr fpst;
154
+ gen_helper_gvec_3 *fn_gvec = NULL;
155
+ gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
156
+ int rd, rn, rm, opr_sz;
157
+ int data = 0;
158
bool q;
159
160
q = extract32(insn, 6, 1);
161
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
162
163
if ((insn & 0xfe200f10) == 0xfc200800) {
164
/* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
165
- size = extract32(insn, 20, 1);
166
- rot = extract32(insn, 23, 2);
167
+ int size = extract32(insn, 20, 1);
168
+ data = extract32(insn, 23, 2); /* rot */
169
if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
170
|| (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
171
return 1;
172
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
173
fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
174
} else if ((insn & 0xfea00f10) == 0xfc800800) {
175
/* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
176
- size = extract32(insn, 20, 1);
177
- rot = extract32(insn, 24, 1);
178
+ int size = extract32(insn, 20, 1);
179
+ data = extract32(insn, 24, 1); /* rot */
180
if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
181
|| (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
182
return 1;
183
}
184
fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
185
+ } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
186
+ /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
187
+ bool u = extract32(insn, 4, 1);
188
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
189
+ return 1;
190
+ }
191
+ fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
192
} else {
193
return 1;
194
}
195
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
196
}
197
198
opr_sz = (1 + q) * 8;
199
- fpst = get_fpstatus_ptr(1);
200
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
201
- vfp_reg_offset(1, rn),
202
- vfp_reg_offset(1, rm), fpst,
203
- opr_sz, opr_sz, rot, fn_gvec_ptr);
204
- tcg_temp_free_ptr(fpst);
205
+ if (fn_gvec_ptr) {
206
+ TCGv_ptr fpst = get_fpstatus_ptr(1);
207
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
208
+ vfp_reg_offset(1, rn),
209
+ vfp_reg_offset(1, rm), fpst,
210
+ opr_sz, opr_sz, data, fn_gvec_ptr);
211
+ tcg_temp_free_ptr(fpst);
212
+ } else {
213
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
214
+ vfp_reg_offset(1, rn),
215
+ vfp_reg_offset(1, rm),
216
+ opr_sz, opr_sz, data, fn_gvec);
217
+ }
41
+ }
218
return 0;
42
+ g_assert_not_reached();
219
}
43
}
220
44
221
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
45
static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
222
46
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
223
static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
47
mmc->numirq = 92;
224
{
48
mmc->raminfo = an505_raminfo;
225
- gen_helper_gvec_3_ptr *fn_gvec_ptr;
49
mmc->armsse_type = TYPE_IOTKIT;
226
+ gen_helper_gvec_3 *fn_gvec = NULL;
50
+ mps2tz_set_default_ram_info(mmc);
227
+ gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
228
int rd, rn, rm, opr_sz, data;
229
- TCGv_ptr fpst;
230
bool q;
231
232
q = extract32(insn, 6, 1);
233
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
234
data = (index << 2) | rot;
235
fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
236
: gen_helper_gvec_fcmlah_idx);
237
+ } else if ((insn & 0xffb00f00) == 0xfe200d00) {
238
+ /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
239
+ int u = extract32(insn, 4, 1);
240
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
241
+ return 1;
242
+ }
243
+ fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
244
+ /* rm is just Vm, and index is M. */
245
+ data = extract32(insn, 5, 1); /* index */
246
+ rm = extract32(insn, 0, 4);
247
} else {
248
return 1;
249
}
250
@@ -XXX,XX +XXX,XX @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
251
}
252
253
opr_sz = (1 + q) * 8;
254
- fpst = get_fpstatus_ptr(1);
255
- tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
256
- vfp_reg_offset(1, rn),
257
- vfp_reg_offset(1, rm), fpst,
258
- opr_sz, opr_sz, data, fn_gvec_ptr);
259
- tcg_temp_free_ptr(fpst);
260
+ if (fn_gvec_ptr) {
261
+ TCGv_ptr fpst = get_fpstatus_ptr(1);
262
+ tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
263
+ vfp_reg_offset(1, rn),
264
+ vfp_reg_offset(1, rm), fpst,
265
+ opr_sz, opr_sz, data, fn_gvec_ptr);
266
+ tcg_temp_free_ptr(fpst);
267
+ } else {
268
+ tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
269
+ vfp_reg_offset(1, rn),
270
+ vfp_reg_offset(1, rm),
271
+ opr_sz, opr_sz, data, fn_gvec);
272
+ }
273
return 0;
274
}
51
}
275
52
53
static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
54
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
55
mmc->numirq = 92;
56
mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
57
mmc->armsse_type = TYPE_SSE200;
58
+ mps2tz_set_default_ram_info(mmc);
59
}
60
61
static const TypeInfo mps2tz_info = {
276
--
62
--
277
2.17.1
63
2.20.1
278
64
279
65
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-21-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215115138.20465-19-peter.maydell@linaro.org
7
---
7
---
8
target/arm/helper.h | 8 +++++++
8
hw/arm/mps2-tz.c | 6 ++++++
9
target/arm/translate-sve.c | 47 ++++++++++++++++++++++++++++++++++++++
9
1 file changed, 6 insertions(+)
10
target/arm/vec_helper.c | 20 ++++++++++++++++
11
target/arm/sve.decode | 5 ++++
12
4 files changed, 80 insertions(+)
13
10
14
diff --git a/target/arm/helper.h b/target/arm/helper.h
11
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.h
13
--- a/hw/arm/mps2-tz.c
17
+++ b/target/arm/helper.h
14
+++ b/hw/arm/mps2-tz.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_fcmlas_idx, TCG_CALL_NO_RWG,
15
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
19
DEF_HELPER_FLAGS_5(gvec_fcmlad, TCG_CALL_NO_RWG,
16
* Flag values:
20
void, ptr, ptr, ptr, ptr, i32)
17
* IS_ALIAS: this RAM area is an alias to the upstream end of the
21
18
* MPC specified by its .mpc value
22
+DEF_HELPER_FLAGS_4(gvec_frecpe_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
19
+ * IS_ROM: this RAM area is read-only
23
+DEF_HELPER_FLAGS_4(gvec_frecpe_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
20
*/
24
+DEF_HELPER_FLAGS_4(gvec_frecpe_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
21
#define IS_ALIAS 1
25
+
22
+#define IS_ROM 2
26
+DEF_HELPER_FLAGS_4(gvec_frsqrte_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
27
+DEF_HELPER_FLAGS_4(gvec_frsqrte_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
struct MPS2TZMachineClass {
28
+DEF_HELPER_FLAGS_4(gvec_frsqrte_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
MachineClass parent;
29
+
26
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
30
DEF_HELPER_FLAGS_5(gvec_fadd_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
27
if (raminfo->mrindex < 0) {
31
DEF_HELPER_FLAGS_5(gvec_fadd_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
28
/* Means this RAMInfo is for QEMU's "system memory" */
32
DEF_HELPER_FLAGS_5(gvec_fadd_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
29
MachineState *machine = MACHINE(mms);
33
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
30
+ assert(!(raminfo->flags & IS_ROM));
34
index XXXXXXX..XXXXXXX 100644
31
return machine->ram;
35
--- a/target/arm/translate-sve.c
32
}
36
+++ b/target/arm/translate-sve.c
33
37
@@ -XXX,XX +XXX,XX @@ DO_VPZ(FMAXNMV, fmaxnmv)
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
38
DO_VPZ(FMINV, fminv)
35
39
DO_VPZ(FMAXV, fmaxv)
36
memory_region_init_ram(ram, NULL, raminfo->name,
40
37
raminfo->size, &error_fatal);
41
+/*
38
+ if (raminfo->flags & IS_ROM) {
42
+ *** SVE Floating Point Unary Operations - Unpredicated Group
39
+ memory_region_set_readonly(ram, true);
43
+ */
44
+
45
+static void do_zz_fp(DisasContext *s, arg_rr_esz *a, gen_helper_gvec_2_ptr *fn)
46
+{
47
+ unsigned vsz = vec_full_reg_size(s);
48
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
49
+
50
+ tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, a->rd),
51
+ vec_full_reg_offset(s, a->rn),
52
+ status, vsz, vsz, 0, fn);
53
+ tcg_temp_free_ptr(status);
54
+}
55
+
56
+static bool trans_FRECPE(DisasContext *s, arg_rr_esz *a, uint32_t insn)
57
+{
58
+ static gen_helper_gvec_2_ptr * const fns[3] = {
59
+ gen_helper_gvec_frecpe_h,
60
+ gen_helper_gvec_frecpe_s,
61
+ gen_helper_gvec_frecpe_d,
62
+ };
63
+ if (a->esz == 0) {
64
+ return false;
65
+ }
40
+ }
66
+ if (sve_access_check(s)) {
41
return ram;
67
+ do_zz_fp(s, a, fns[a->esz - 1]);
68
+ }
69
+ return true;
70
+}
71
+
72
+static bool trans_FRSQRTE(DisasContext *s, arg_rr_esz *a, uint32_t insn)
73
+{
74
+ static gen_helper_gvec_2_ptr * const fns[3] = {
75
+ gen_helper_gvec_frsqrte_h,
76
+ gen_helper_gvec_frsqrte_s,
77
+ gen_helper_gvec_frsqrte_d,
78
+ };
79
+ if (a->esz == 0) {
80
+ return false;
81
+ }
82
+ if (sve_access_check(s)) {
83
+ do_zz_fp(s, a, fns[a->esz - 1]);
84
+ }
85
+ return true;
86
+}
87
+
88
/*
89
*** SVE Floating Point Accumulating Reduction Group
90
*/
91
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/arm/vec_helper.c
94
+++ b/target/arm/vec_helper.c
95
@@ -XXX,XX +XXX,XX @@ void HELPER(gvec_fcmlad)(void *vd, void *vn, void *vm,
96
clear_tail(d, opr_sz, simd_maxsz(desc));
97
}
42
}
98
43
99
+#define DO_2OP(NAME, FUNC, TYPE) \
100
+void HELPER(NAME)(void *vd, void *vn, void *stat, uint32_t desc) \
101
+{ \
102
+ intptr_t i, oprsz = simd_oprsz(desc); \
103
+ TYPE *d = vd, *n = vn; \
104
+ for (i = 0; i < oprsz / sizeof(TYPE); i++) { \
105
+ d[i] = FUNC(n[i], stat); \
106
+ } \
107
+}
108
+
109
+DO_2OP(gvec_frecpe_h, helper_recpe_f16, float16)
110
+DO_2OP(gvec_frecpe_s, helper_recpe_f32, float32)
111
+DO_2OP(gvec_frecpe_d, helper_recpe_f64, float64)
112
+
113
+DO_2OP(gvec_frsqrte_h, helper_rsqrte_f16, float16)
114
+DO_2OP(gvec_frsqrte_s, helper_rsqrte_f32, float32)
115
+DO_2OP(gvec_frsqrte_d, helper_rsqrte_f64, float64)
116
+
117
+#undef DO_2OP
118
+
119
/* Floating-point trigonometric starting value.
120
* See the ARM ARM pseudocode function FPTrigSMul.
121
*/
122
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
123
index XXXXXXX..XXXXXXX 100644
124
--- a/target/arm/sve.decode
125
+++ b/target/arm/sve.decode
126
@@ -XXX,XX +XXX,XX @@ FMINNMV 01100101 .. 000 101 001 ... ..... ..... @rd_pg_rn
127
FMAXV 01100101 .. 000 110 001 ... ..... ..... @rd_pg_rn
128
FMINV 01100101 .. 000 111 001 ... ..... ..... @rd_pg_rn
129
130
+## SVE Floating Point Unary Operations - Unpredicated Group
131
+
132
+FRECPE 01100101 .. 001 110 001100 ..... ..... @rd_rn
133
+FRSQRTE 01100101 .. 001 111 001100 ..... ..... @rd_rn
134
+
135
### SVE FP Accumulating Reduction Group
136
137
# SVE floating-point serial reduction (predicated)
138
--
44
--
139
2.17.1
45
2.20.1
140
46
141
47
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Instead of hardcoding this value, find the RAMInfo corresponding to
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
the 0 address and extract its size.
5
Message-id: 20180627043328.11531-10-richard.henderson@linaro.org
8
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-20-peter.maydell@linaro.org
7
---
13
---
8
target/arm/helper-sve.h | 5 +++
14
hw/arm/mps2-tz.c | 17 ++++++++++++++++-
9
target/arm/sve_helper.c | 41 +++++++++++++++++++++++++
15
1 file changed, 16 insertions(+), 1 deletion(-)
10
target/arm/translate-sve.c | 62 ++++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 5 +++
12
4 files changed, 113 insertions(+)
13
16
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
19
--- a/hw/arm/mps2-tz.c
17
+++ b/target/arm/helper-sve.h
20
+++ b/hw/arm/mps2-tz.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve_clr_h, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
21
@@ -XXX,XX +XXX,XX @@ static void create_non_mpc_ram(MPS2TZMachineState *mms)
19
DEF_HELPER_FLAGS_3(sve_clr_s, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
20
DEF_HELPER_FLAGS_3(sve_clr_d, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_4(sve_movz_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_4(sve_movz_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_4(sve_movz_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_4(sve_movz_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
26
+
27
DEF_HELPER_FLAGS_4(sve_asr_zpzi_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
DEF_HELPER_FLAGS_4(sve_asr_zpzi_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
29
DEF_HELPER_FLAGS_4(sve_asr_zpzi_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
30
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/sve_helper.c
33
+++ b/target/arm/sve_helper.c
34
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_clr_d)(void *vd, void *vg, uint32_t desc)
35
}
22
}
36
}
23
}
37
24
38
+/* Copy Zn into Zd, and store zero into inactive elements. */
25
+static uint32_t boot_ram_size(MPS2TZMachineState *mms)
39
+void HELPER(sve_movz_b)(void *vd, void *vn, void *vg, uint32_t desc)
40
+{
26
+{
41
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
27
+ /* Return the size of the RAM block at guest address zero */
42
+ uint64_t *d = vd, *n = vn;
28
+ const RAMInfo *p;
43
+ uint8_t *pg = vg;
29
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
44
+ for (i = 0; i < opr_sz; i += 1) {
30
+
45
+ d[i] = n[i] & expand_pred_b(pg[H1(i)]);
31
+ for (p = mmc->raminfo; p->name; p++) {
32
+ if (p->base == 0) {
33
+ return p->size;
34
+ }
46
+ }
35
+ }
36
+ g_assert_not_reached();
47
+}
37
+}
48
+
38
+
49
+void HELPER(sve_movz_h)(void *vd, void *vn, void *vg, uint32_t desc)
39
static void mps2tz_common_init(MachineState *machine)
50
+{
40
{
51
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
41
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
52
+ uint64_t *d = vd, *n = vn;
42
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
53
+ uint8_t *pg = vg;
43
54
+ for (i = 0; i < opr_sz; i += 1) {
44
create_non_mpc_ram(mms);
55
+ d[i] = n[i] & expand_pred_h(pg[H1(i)]);
45
56
+ }
46
- armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
57
+}
47
+ armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
58
+
48
+ boot_ram_size(mms));
59
+void HELPER(sve_movz_s)(void *vd, void *vn, void *vg, uint32_t desc)
60
+{
61
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
62
+ uint64_t *d = vd, *n = vn;
63
+ uint8_t *pg = vg;
64
+ for (i = 0; i < opr_sz; i += 1) {
65
+ d[i] = n[i] & expand_pred_s(pg[H1(i)]);
66
+ }
67
+}
68
+
69
+void HELPER(sve_movz_d)(void *vd, void *vn, void *vg, uint32_t desc)
70
+{
71
+ intptr_t i, opr_sz = simd_oprsz(desc) / 8;
72
+ uint64_t *d = vd, *n = vn;
73
+ uint8_t *pg = vg;
74
+ for (i = 0; i < opr_sz; i += 1) {
75
+ d[i] = n[1] & -(uint64_t)(pg[H1(i)] & 1);
76
+ }
77
+}
78
+
79
/* Three-operand expander, immediate operand, controlled by a predicate.
80
*/
81
#define DO_ZPZI(NAME, TYPE, H, OP) \
82
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/target/arm/translate-sve.c
85
+++ b/target/arm/translate-sve.c
86
@@ -XXX,XX +XXX,XX @@ static bool do_clr_zp(DisasContext *s, int rd, int pg, int esz)
87
return true;
88
}
49
}
89
50
90
+/* Copy Zn into Zd, storing zeros into inactive elements. */
51
static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
91
+static void do_movz_zpz(DisasContext *s, int rd, int rn, int pg, int esz)
92
+{
93
+ static gen_helper_gvec_3 * const fns[4] = {
94
+ gen_helper_sve_movz_b, gen_helper_sve_movz_h,
95
+ gen_helper_sve_movz_s, gen_helper_sve_movz_d,
96
+ };
97
+ unsigned vsz = vec_full_reg_size(s);
98
+ tcg_gen_gvec_3_ool(vec_full_reg_offset(s, rd),
99
+ vec_full_reg_offset(s, rn),
100
+ pred_full_reg_offset(s, pg),
101
+ vsz, vsz, 0, fns[esz]);
102
+}
103
+
104
static bool do_zpzi_ool(DisasContext *s, arg_rpri_esz *a,
105
gen_helper_gvec_3 *fn)
106
{
107
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1RQ_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
108
return true;
109
}
110
111
+/* Load and broadcast element. */
112
+static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
113
+{
114
+ if (!sve_access_check(s)) {
115
+ return true;
116
+ }
117
+
118
+ unsigned vsz = vec_full_reg_size(s);
119
+ unsigned psz = pred_full_reg_size(s);
120
+ unsigned esz = dtype_esz[a->dtype];
121
+ TCGLabel *over = gen_new_label();
122
+ TCGv_i64 temp;
123
+
124
+ /* If the guarding predicate has no bits set, no load occurs. */
125
+ if (psz <= 8) {
126
+ /* Reduce the pred_esz_masks value simply to reduce the
127
+ * size of the code generated here.
128
+ */
129
+ uint64_t psz_mask = MAKE_64BIT_MASK(0, psz * 8);
130
+ temp = tcg_temp_new_i64();
131
+ tcg_gen_ld_i64(temp, cpu_env, pred_full_reg_offset(s, a->pg));
132
+ tcg_gen_andi_i64(temp, temp, pred_esz_masks[esz] & psz_mask);
133
+ tcg_gen_brcondi_i64(TCG_COND_EQ, temp, 0, over);
134
+ tcg_temp_free_i64(temp);
135
+ } else {
136
+ TCGv_i32 t32 = tcg_temp_new_i32();
137
+ find_last_active(s, t32, esz, a->pg);
138
+ tcg_gen_brcondi_i32(TCG_COND_LT, t32, 0, over);
139
+ tcg_temp_free_i32(t32);
140
+ }
141
+
142
+ /* Load the data. */
143
+ temp = tcg_temp_new_i64();
144
+ tcg_gen_addi_i64(temp, cpu_reg_sp(s, a->rn), a->imm << esz);
145
+ tcg_gen_qemu_ld_i64(temp, temp, get_mem_index(s),
146
+ s->be_data | dtype_mop[a->dtype]);
147
+
148
+ /* Broadcast to *all* elements. */
149
+ tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd),
150
+ vsz, vsz, temp);
151
+ tcg_temp_free_i64(temp);
152
+
153
+ /* Zero the inactive elements. */
154
+ gen_set_label(over);
155
+ do_movz_zpz(s, a->rd, a->rd, a->pg, esz);
156
+ return true;
157
+}
158
+
159
static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
160
int msz, int esz, int nreg)
161
{
162
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
163
index XXXXXXX..XXXXXXX 100644
164
--- a/target/arm/sve.decode
165
+++ b/target/arm/sve.decode
166
@@ -XXX,XX +XXX,XX @@
167
%imm8_16_10 16:5 10:3
168
%imm9_16_10 16:s6 10:3
169
%size_23 23:2
170
+%dtype_23_13 23:2 13:2
171
172
# A combination of tsz:imm3 -- extract esize.
173
%tszimm_esz 22:2 5:5 !function=tszimm_esz
174
@@ -XXX,XX +XXX,XX @@ LDR_pri 10000101 10 ...... 000 ... ..... 0 .... @pd_rn_i9
175
# SVE load vector register
176
LDR_zri 10000101 10 ...... 010 ... ..... ..... @rd_rn_i9
177
178
+# SVE load and broadcast element
179
+LD1R_zpri 1000010 .. 1 imm:6 1.. pg:3 rn:5 rd:5 \
180
+ &rpri_load dtype=%dtype_23_13 nreg=0
181
+
182
### SVE Memory Contiguous Load Group
183
184
# SVE contiguous load (scalar plus scalar)
185
--
52
--
186
2.17.1
53
2.20.1
187
54
188
55
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Add support for the mps3-an524 board; this is an SSE-200 based FPGA
2
2
image, like the existing mps2-an521. It has a usefully larger amount
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
of RAM, and a PL031 RTC, as well as some more minor differences.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Message-id: 20180627043328.11531-16-richard.henderson@linaro.org
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
7
---
13
---
8
target/arm/translate-sve.c | 85 ++++++++++++++++++++++++++------------
14
hw/arm/mps2-tz.c | 139 +++++++++++++++++++++++++++++++++++++++++++++--
9
target/arm/sve.decode | 11 +++++
15
1 file changed, 135 insertions(+), 4 deletions(-)
10
2 files changed, 70 insertions(+), 26 deletions(-)
16
11
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
19
--- a/hw/arm/mps2-tz.c
15
+++ b/target/arm/translate-sve.c
20
+++ b/hw/arm/mps2-tz.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1_zpiz(DisasContext *s, arg_LD1_zpiz *a, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@
17
return true;
22
* This source file covers the following FPGA images, for TrustZone cores:
18
}
23
* "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
19
24
* "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
20
+/* Indexed by [xs][msz]. */
25
+ * "mps2-an524" -- Dual Cortex-M33 as documented in Application Note AN524
21
+static gen_helper_gvec_mem_scatter * const scatter_store_fn32[2][3] = {
26
*
22
+ { gen_helper_sve_stbs_zsu,
27
* Links to the TRM for the board itself and to the various Application
23
+ gen_helper_sve_sths_zsu,
28
* Notes which document the FPGA images can be found here:
24
+ gen_helper_sve_stss_zsu, },
29
@@ -XXX,XX +XXX,XX @@
25
+ { gen_helper_sve_stbs_zss,
30
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
26
+ gen_helper_sve_sths_zss,
31
* Application Note AN521:
27
+ gen_helper_sve_stss_zss, },
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,
28
+};
96
+};
29
+
97
+
30
+/* Note that we overload xs=2 to indicate 64-bit offset. */
98
static const RAMInfo an505_raminfo[] = { {
31
+static gen_helper_gvec_mem_scatter * const scatter_store_fn64[3][4] = {
99
.name = "ssram-0",
32
+ { gen_helper_sve_stbd_zsu,
100
.base = 0x00000000,
33
+ gen_helper_sve_sthd_zsu,
101
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an505_raminfo[] = { {
34
+ gen_helper_sve_stsd_zsu,
102
},
35
+ gen_helper_sve_stdd_zsu, },
103
};
36
+ { gen_helper_sve_stbd_zss,
104
37
+ gen_helper_sve_sthd_zss,
105
+static const RAMInfo an524_raminfo[] = { {
38
+ gen_helper_sve_stsd_zss,
106
+ .name = "bram",
39
+ gen_helper_sve_stdd_zss, },
107
+ .base = 0x00000000,
40
+ { gen_helper_sve_stbd_zd,
108
+ .size = 512 * KiB,
41
+ gen_helper_sve_sthd_zd,
109
+ .mpc = 0,
42
+ gen_helper_sve_stsd_zd,
110
+ .mrindex = 0,
43
+ gen_helper_sve_stdd_zd, },
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
+ },
44
+};
134
+};
45
+
135
+
46
static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
136
static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
47
{
137
{
48
- /* Indexed by [xs][msz]. */
138
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
49
- static gen_helper_gvec_mem_scatter * const fn32[2][3] = {
139
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
50
- { gen_helper_sve_stbs_zsu,
140
},
51
- gen_helper_sve_sths_zsu,
141
};
52
- gen_helper_sve_stss_zsu, },
142
53
- { gen_helper_sve_stbs_zss,
143
+ const PPCInfo an524_ppcs[] = { {
54
- gen_helper_sve_sths_zss,
144
+ .name = "apb_ppcexp0",
55
- gen_helper_sve_stss_zss, },
145
+ .ports = {
56
- };
146
+ { "bram-mpc", make_mpc, &mms->mpc[0], 0x58007000, 0x1000 },
57
- /* Note that we overload xs=2 to indicate 64-bit offset. */
147
+ { "qspi-mpc", make_mpc, &mms->mpc[1], 0x58008000, 0x1000 },
58
- static gen_helper_gvec_mem_scatter * const fn64[3][4] = {
148
+ { "ddr-mpc", make_mpc, &mms->mpc[2], 0x58009000, 0x1000 },
59
- { gen_helper_sve_stbd_zsu,
149
+ },
60
- gen_helper_sve_sthd_zsu,
150
+ }, {
61
- gen_helper_sve_stsd_zsu,
151
+ .name = "apb_ppcexp1",
62
- gen_helper_sve_stdd_zsu, },
152
+ .ports = {
63
- { gen_helper_sve_stbd_zss,
153
+ { "i2c0", make_i2c, &mms->i2c[0], 0x41200000, 0x1000 },
64
- gen_helper_sve_sthd_zss,
154
+ { "i2c1", make_i2c, &mms->i2c[1], 0x41201000, 0x1000 },
65
- gen_helper_sve_stsd_zss,
155
+ { "spi0", make_spi, &mms->spi[0], 0x41202000, 0x1000, { 52 } },
66
- gen_helper_sve_stdd_zss, },
156
+ { "spi1", make_spi, &mms->spi[1], 0x41203000, 0x1000, { 53 } },
67
- { gen_helper_sve_stbd_zd,
157
+ { "spi2", make_spi, &mms->spi[2], 0x41204000, 0x1000, { 54 } },
68
- gen_helper_sve_sthd_zd,
158
+ { "i2c2", make_i2c, &mms->i2c[2], 0x41205000, 0x1000 },
69
- gen_helper_sve_stsd_zd,
159
+ { "i2c3", make_i2c, &mms->i2c[3], 0x41206000, 0x1000 },
70
- gen_helper_sve_stdd_zd, },
160
+ { /* port 7 reserved */ },
71
- };
161
+ { "i2c4", make_i2c, &mms->i2c[4], 0x41208000, 0x1000 },
72
gen_helper_gvec_mem_scatter *fn;
162
+ },
73
163
+ }, {
74
if (a->esz < a->msz || (a->msz == 0 && a->scale)) {
164
+ .name = "apb_ppcexp2",
75
@@ -XXX,XX +XXX,XX @@ static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
165
+ .ports = {
76
}
166
+ { "scc", make_scc, &mms->scc, 0x41300000, 0x1000 },
77
switch (a->esz) {
167
+ { "i2s-audio", make_unimp_dev, &mms->i2s_audio,
78
case MO_32:
168
+ 0x41301000, 0x1000 },
79
- fn = fn32[a->xs][a->msz];
169
+ { "fpgaio", make_fpgaio, &mms->fpgaio, 0x41302000, 0x1000 },
80
+ fn = scatter_store_fn32[a->xs][a->msz];
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);
81
break;
198
break;
82
case MO_64:
199
+ case FPGA_AN524:
83
- fn = fn64[a->xs][a->msz];
200
+ ppcs = an524_ppcs;
84
+ fn = scatter_store_fn64[a->xs][a->msz];
201
+ num_ppcs = ARRAY_SIZE(an524_ppcs);
85
break;
202
+ break;
86
default:
203
default:
87
g_assert_not_reached();
204
g_assert_not_reached();
88
@@ -XXX,XX +XXX,XX @@ static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
205
}
89
return true;
206
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
207
mps2tz_set_default_ram_info(mmc);
90
}
208
}
91
209
92
+static bool trans_ST1_zpiz(DisasContext *s, arg_ST1_zpiz *a, uint32_t insn)
210
+static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
93
+{
211
+{
94
+ gen_helper_gvec_mem_scatter *fn = NULL;
212
+ MachineClass *mc = MACHINE_CLASS(oc);
95
+ TCGv_i64 imm;
213
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
96
+
214
+
97
+ if (a->esz < a->msz) {
215
+ mc->desc = "ARM MPS3 with AN524 FPGA image for dual Cortex-M33";
98
+ return false;
216
+ mc->default_cpus = 2;
99
+ }
217
+ mc->min_cpus = mc->default_cpus;
100
+ if (!sve_access_check(s)) {
218
+ mc->max_cpus = mc->default_cpus;
101
+ return true;
219
+ mmc->fpga_type = FPGA_AN524;
102
+ }
220
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
103
+
221
+ mmc->scc_id = 0x41045240;
104
+ switch (a->esz) {
222
+ mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
105
+ case MO_32:
223
+ mmc->oscclk = an524_oscclk;
106
+ fn = scatter_store_fn32[0][a->msz];
224
+ mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
107
+ break;
225
+ mmc->fpgaio_num_leds = 10;
108
+ case MO_64:
226
+ mmc->fpgaio_has_switches = true;
109
+ fn = scatter_store_fn64[2][a->msz];
227
+ mmc->numirq = 95;
110
+ break;
228
+ mmc->raminfo = an524_raminfo;
111
+ }
229
+ mmc->armsse_type = TYPE_SSE200;
112
+ assert(fn != NULL);
230
+ mps2tz_set_default_ram_info(mmc);
113
+
114
+ /* Treat ST1_zpiz (zn[x] + imm) the same way as ST1_zprz (rn + zm[x])
115
+ * by loading the immediate into the scalar parameter.
116
+ */
117
+ imm = tcg_const_i64(a->imm << a->msz);
118
+ do_mem_zpz(s, a->rd, a->pg, a->rn, 0, imm, fn);
119
+ tcg_temp_free_i64(imm);
120
+ return true;
121
+}
231
+}
122
+
232
+
123
/*
233
static const TypeInfo mps2tz_info = {
124
* Prefetches
234
.name = TYPE_MPS2TZ_MACHINE,
125
*/
235
.parent = TYPE_MACHINE,
126
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
236
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mps2tz_an521_info = {
127
index XXXXXXX..XXXXXXX 100644
237
.class_init = mps2tz_an521_class_init,
128
--- a/target/arm/sve.decode
238
};
129
+++ b/target/arm/sve.decode
239
130
@@ -XXX,XX +XXX,XX @@
240
+static const TypeInfo mps3tz_an524_info = {
131
&rprr_gather_load rd pg rn rm esz msz u ff xs scale
241
+ .name = TYPE_MPS3TZ_AN524_MACHINE,
132
&rpri_gather_load rd pg rn imm esz msz u ff
242
+ .parent = TYPE_MPS2TZ_MACHINE,
133
&rprr_scatter_store rd pg rn rm esz msz xs scale
243
+ .class_init = mps3tz_an524_class_init,
134
+&rpri_scatter_store rd pg rn imm esz msz
244
+};
135
245
+
136
###########################################################################
246
static void mps2tz_machine_init(void)
137
# Named instruction formats. These are generally used to
247
{
138
@@ -XXX,XX +XXX,XX @@
248
type_register_static(&mps2tz_info);
139
&rprr_store nreg=0
249
type_register_static(&mps2tz_an505_info);
140
@rprr_scatter_store ....... msz:2 .. rm:5 ... pg:3 rn:5 rd:5 \
250
type_register_static(&mps2tz_an521_info);
141
&rprr_scatter_store
251
+ type_register_static(&mps3tz_an524_info);
142
+@rpri_scatter_store ....... msz:2 .. imm:5 ... pg:3 rn:5 rd:5 \
252
}
143
+ &rpri_scatter_store
253
144
254
type_init(mps2tz_machine_init);
145
###########################################################################
146
# Instruction patterns. Grouped according to the SVE encodingindex.xhtml.
147
@@ -XXX,XX +XXX,XX @@ ST1_zprz 1110010 .. 01 ..... 101 ... ..... ..... \
148
ST1_zprz 1110010 .. 00 ..... 101 ... ..... ..... \
149
@rprr_scatter_store xs=2 esz=3 scale=0
150
151
+# SVE 64-bit scatter store (vector plus immediate)
152
+ST1_zpiz 1110010 .. 10 ..... 101 ... ..... ..... \
153
+ @rpri_scatter_store esz=3
154
+
155
+# SVE 32-bit scatter store (vector plus immediate)
156
+ST1_zpiz 1110010 .. 11 ..... 101 ... ..... ..... \
157
+ @rpri_scatter_store esz=2
158
+
159
# SVE 64-bit scatter store (scalar plus unpacked 32-bit scaled offset)
160
# Require msz > 0
161
ST1_zprz 1110010 .. 01 ..... 100 ... ..... ..... \
162
--
255
--
163
2.17.1
256
2.20.1
164
257
165
258
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Implement a make_* function which provides creates a container
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
MemoryRegion with both the ethernet controller and an
5
Message-id: 20180627043328.11531-30-richard.henderson@linaro.org
8
unimplemented-device stub for the USB controller.
9
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210215115138.20465-22-peter.maydell@linaro.org
7
---
14
---
8
target/arm/helper-sve.h | 4 +
15
hw/arm/mps2-tz.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
9
target/arm/sve_helper.c | 162 +++++++++++++++++++++++++++++++++++++
16
1 file changed, 47 insertions(+), 1 deletion(-)
10
target/arm/translate-sve.c | 37 +++++++++
11
target/arm/sve.decode | 4 +
12
4 files changed, 207 insertions(+)
13
17
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
18
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
15
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
20
--- a/hw/arm/mps2-tz.c
17
+++ b/target/arm/helper-sve.h
21
+++ b/hw/arm/mps2-tz.c
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
22
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
19
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
23
20
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
24
ARMSSE iotkit;
21
25
MemoryRegion ram[MPS2TZ_RAM_MAX];
22
+DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
26
+ MemoryRegion eth_usb_container;
23
+DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
24
+DEF_HELPER_FLAGS_3(sve_fcmla_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
25
+
27
+
26
DEF_HELPER_FLAGS_5(sve_ftmad_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
28
MPS2SCC scc;
27
DEF_HELPER_FLAGS_5(sve_ftmad_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
29
MPS2FPGAIO fpgaio;
28
DEF_HELPER_FLAGS_5(sve_ftmad_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
30
TZPPC ppc[5];
29
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
31
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
30
index XXXXXXX..XXXXXXX 100644
32
UnimplementedDeviceState gfx;
31
--- a/target/arm/sve_helper.c
33
UnimplementedDeviceState cldc;
32
+++ b/target/arm/sve_helper.c
34
UnimplementedDeviceState rtc;
33
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_fcadd_d)(void *vd, void *vn, void *vm, void *vg,
35
+ UnimplementedDeviceState usb;
34
} while (i != 0);
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);
35
}
41
}
36
42
37
+/*
43
+static MemoryRegion *make_eth_usb(MPS2TZMachineState *mms, void *opaque,
38
+ * FP Complex Multiply
44
+ const char *name, hwaddr size,
39
+ */
45
+ const int *irqs)
46
+{
47
+ /*
48
+ * The AN524 makes the ethernet and USB share a PPC port.
49
+ * irqs[] is the ethernet IRQ.
50
+ */
51
+ SysBusDevice *s;
52
+ NICInfo *nd = &nd_table[0];
40
+
53
+
41
+QEMU_BUILD_BUG_ON(SIMD_DATA_SHIFT + 22 > 32);
54
+ memory_region_init(&mms->eth_usb_container, OBJECT(mms),
55
+ "mps2-tz-eth-usb-container", 0x200000);
42
+
56
+
43
+void HELPER(sve_fcmla_zpzzz_h)(CPUARMState *env, void *vg, uint32_t desc)
57
+ /*
44
+{
58
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
45
+ intptr_t j, i = simd_oprsz(desc);
59
+ * except that it doesn't support the checksum-offload feature.
46
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
60
+ */
47
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
61
+ qemu_check_nic_model(nd, "lan9118");
48
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
62
+ mms->lan9118 = qdev_new(TYPE_LAN9118);
49
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
63
+ qdev_set_nic_properties(mms->lan9118, nd);
50
+ unsigned rot = extract32(desc, SIMD_DATA_SHIFT + 20, 2);
51
+ bool flip = rot & 1;
52
+ float16 neg_imag, neg_real;
53
+ void *vd = &env->vfp.zregs[rd];
54
+ void *vn = &env->vfp.zregs[rn];
55
+ void *vm = &env->vfp.zregs[rm];
56
+ void *va = &env->vfp.zregs[ra];
57
+ uint64_t *g = vg;
58
+
64
+
59
+ neg_imag = float16_set_sign(0, (rot & 2) != 0);
65
+ s = SYS_BUS_DEVICE(mms->lan9118);
60
+ neg_real = float16_set_sign(0, rot == 1 || rot == 2);
66
+ sysbus_realize_and_unref(s, &error_fatal);
67
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
61
+
68
+
62
+ do {
69
+ memory_region_add_subregion(&mms->eth_usb_container,
63
+ uint64_t pg = g[(i - 1) >> 6];
70
+ 0, sysbus_mmio_get_region(s, 0));
64
+ do {
65
+ float16 e1, e2, e3, e4, nr, ni, mr, mi, d;
66
+
71
+
67
+ /* I holds the real index; J holds the imag index. */
72
+ /* The USB OTG controller is an ISP1763; we don't have a model of it. */
68
+ j = i - sizeof(float16);
73
+ object_initialize_child(OBJECT(mms), "usb-otg",
69
+ i -= 2 * sizeof(float16);
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);
70
+
79
+
71
+ nr = *(float16 *)(vn + H1_2(i));
80
+ memory_region_add_subregion(&mms->eth_usb_container,
72
+ ni = *(float16 *)(vn + H1_2(j));
81
+ 0x100000, sysbus_mmio_get_region(s, 0));
73
+ mr = *(float16 *)(vm + H1_2(i));
74
+ mi = *(float16 *)(vm + H1_2(j));
75
+
82
+
76
+ e2 = (flip ? ni : nr);
83
+ return &mms->eth_usb_container;
77
+ e1 = (flip ? mi : mr) ^ neg_real;
78
+ e4 = e2;
79
+ e3 = (flip ? mr : mi) ^ neg_imag;
80
+
81
+ if (likely((pg >> (i & 63)) & 1)) {
82
+ d = *(float16 *)(va + H1_2(i));
83
+ d = float16_muladd(e2, e1, d, 0, &env->vfp.fp_status_f16);
84
+ *(float16 *)(vd + H1_2(i)) = d;
85
+ }
86
+ if (likely((pg >> (j & 63)) & 1)) {
87
+ d = *(float16 *)(va + H1_2(j));
88
+ d = float16_muladd(e4, e3, d, 0, &env->vfp.fp_status_f16);
89
+ *(float16 *)(vd + H1_2(j)) = d;
90
+ }
91
+ } while (i & 63);
92
+ } while (i != 0);
93
+}
84
+}
94
+
85
+
95
+void HELPER(sve_fcmla_zpzzz_s)(CPUARMState *env, void *vg, uint32_t desc)
86
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
96
+{
87
const char *name, hwaddr size,
97
+ intptr_t j, i = simd_oprsz(desc);
88
const int *irqs)
98
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
89
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
99
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
90
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
100
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
91
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
101
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
92
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
102
+ unsigned rot = extract32(desc, SIMD_DATA_SHIFT + 20, 2);
93
- { "eth", make_eth_dev, NULL, 0x41400000, 0x100000, { 48 } },
103
+ bool flip = rot & 1;
94
+ { "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 48 } },
104
+ float32 neg_imag, neg_real;
95
},
105
+ void *vd = &env->vfp.zregs[rd];
96
},
106
+ void *vn = &env->vfp.zregs[rn];
97
};
107
+ void *vm = &env->vfp.zregs[rm];
108
+ void *va = &env->vfp.zregs[ra];
109
+ uint64_t *g = vg;
110
+
111
+ neg_imag = float32_set_sign(0, (rot & 2) != 0);
112
+ neg_real = float32_set_sign(0, rot == 1 || rot == 2);
113
+
114
+ do {
115
+ uint64_t pg = g[(i - 1) >> 6];
116
+ do {
117
+ float32 e1, e2, e3, e4, nr, ni, mr, mi, d;
118
+
119
+ /* I holds the real index; J holds the imag index. */
120
+ j = i - sizeof(float32);
121
+ i -= 2 * sizeof(float32);
122
+
123
+ nr = *(float32 *)(vn + H1_2(i));
124
+ ni = *(float32 *)(vn + H1_2(j));
125
+ mr = *(float32 *)(vm + H1_2(i));
126
+ mi = *(float32 *)(vm + H1_2(j));
127
+
128
+ e2 = (flip ? ni : nr);
129
+ e1 = (flip ? mi : mr) ^ neg_real;
130
+ e4 = e2;
131
+ e3 = (flip ? mr : mi) ^ neg_imag;
132
+
133
+ if (likely((pg >> (i & 63)) & 1)) {
134
+ d = *(float32 *)(va + H1_2(i));
135
+ d = float32_muladd(e2, e1, d, 0, &env->vfp.fp_status);
136
+ *(float32 *)(vd + H1_2(i)) = d;
137
+ }
138
+ if (likely((pg >> (j & 63)) & 1)) {
139
+ d = *(float32 *)(va + H1_2(j));
140
+ d = float32_muladd(e4, e3, d, 0, &env->vfp.fp_status);
141
+ *(float32 *)(vd + H1_2(j)) = d;
142
+ }
143
+ } while (i & 63);
144
+ } while (i != 0);
145
+}
146
+
147
+void HELPER(sve_fcmla_zpzzz_d)(CPUARMState *env, void *vg, uint32_t desc)
148
+{
149
+ intptr_t j, i = simd_oprsz(desc);
150
+ unsigned rd = extract32(desc, SIMD_DATA_SHIFT, 5);
151
+ unsigned rn = extract32(desc, SIMD_DATA_SHIFT + 5, 5);
152
+ unsigned rm = extract32(desc, SIMD_DATA_SHIFT + 10, 5);
153
+ unsigned ra = extract32(desc, SIMD_DATA_SHIFT + 15, 5);
154
+ unsigned rot = extract32(desc, SIMD_DATA_SHIFT + 20, 2);
155
+ bool flip = rot & 1;
156
+ float64 neg_imag, neg_real;
157
+ void *vd = &env->vfp.zregs[rd];
158
+ void *vn = &env->vfp.zregs[rn];
159
+ void *vm = &env->vfp.zregs[rm];
160
+ void *va = &env->vfp.zregs[ra];
161
+ uint64_t *g = vg;
162
+
163
+ neg_imag = float64_set_sign(0, (rot & 2) != 0);
164
+ neg_real = float64_set_sign(0, rot == 1 || rot == 2);
165
+
166
+ do {
167
+ uint64_t pg = g[(i - 1) >> 6];
168
+ do {
169
+ float64 e1, e2, e3, e4, nr, ni, mr, mi, d;
170
+
171
+ /* I holds the real index; J holds the imag index. */
172
+ j = i - sizeof(float64);
173
+ i -= 2 * sizeof(float64);
174
+
175
+ nr = *(float64 *)(vn + H1_2(i));
176
+ ni = *(float64 *)(vn + H1_2(j));
177
+ mr = *(float64 *)(vm + H1_2(i));
178
+ mi = *(float64 *)(vm + H1_2(j));
179
+
180
+ e2 = (flip ? ni : nr);
181
+ e1 = (flip ? mi : mr) ^ neg_real;
182
+ e4 = e2;
183
+ e3 = (flip ? mr : mi) ^ neg_imag;
184
+
185
+ if (likely((pg >> (i & 63)) & 1)) {
186
+ d = *(float64 *)(va + H1_2(i));
187
+ d = float64_muladd(e2, e1, d, 0, &env->vfp.fp_status);
188
+ *(float64 *)(vd + H1_2(i)) = d;
189
+ }
190
+ if (likely((pg >> (j & 63)) & 1)) {
191
+ d = *(float64 *)(va + H1_2(j));
192
+ d = float64_muladd(e4, e3, d, 0, &env->vfp.fp_status);
193
+ *(float64 *)(vd + H1_2(j)) = d;
194
+ }
195
+ } while (i & 63);
196
+ } while (i != 0);
197
+}
198
+
199
/*
200
* Load contiguous data, protected by a governing predicate.
201
*/
202
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
203
index XXXXXXX..XXXXXXX 100644
204
--- a/target/arm/translate-sve.c
205
+++ b/target/arm/translate-sve.c
206
@@ -XXX,XX +XXX,XX @@ DO_FMLA(FNMLS_zpzzz, fnmls_zpzzz)
207
208
#undef DO_FMLA
209
210
+static bool trans_FCMLA_zpzzz(DisasContext *s,
211
+ arg_FCMLA_zpzzz *a, uint32_t insn)
212
+{
213
+ static gen_helper_sve_fmla * const fns[3] = {
214
+ gen_helper_sve_fcmla_zpzzz_h,
215
+ gen_helper_sve_fcmla_zpzzz_s,
216
+ gen_helper_sve_fcmla_zpzzz_d,
217
+ };
218
+
219
+ if (a->esz == 0) {
220
+ return false;
221
+ }
222
+ if (sve_access_check(s)) {
223
+ unsigned vsz = vec_full_reg_size(s);
224
+ unsigned desc;
225
+ TCGv_i32 t_desc;
226
+ TCGv_ptr pg = tcg_temp_new_ptr();
227
+
228
+ /* We would need 7 operands to pass these arguments "properly".
229
+ * So we encode all the register numbers into the descriptor.
230
+ */
231
+ desc = deposit32(a->rd, 5, 5, a->rn);
232
+ desc = deposit32(desc, 10, 5, a->rm);
233
+ desc = deposit32(desc, 15, 5, a->ra);
234
+ desc = deposit32(desc, 20, 2, a->rot);
235
+ desc = sextract32(desc, 0, 22);
236
+ desc = simd_desc(vsz, vsz, desc);
237
+
238
+ t_desc = tcg_const_i32(desc);
239
+ tcg_gen_addi_ptr(pg, cpu_env, pred_full_reg_offset(s, a->pg));
240
+ fns[a->esz - 1](cpu_env, pg, t_desc);
241
+ tcg_temp_free_i32(t_desc);
242
+ tcg_temp_free_ptr(pg);
243
+ }
244
+ return true;
245
+}
246
+
247
/*
248
*** SVE Floating Point Unary Operations Predicated Group
249
*/
250
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
251
index XXXXXXX..XXXXXXX 100644
252
--- a/target/arm/sve.decode
253
+++ b/target/arm/sve.decode
254
@@ -XXX,XX +XXX,XX @@ MUL_zzi 00100101 .. 110 000 110 ........ ..... @rdn_i8s
255
FCADD 01100100 esz:2 00000 rot:1 100 pg:3 rm:5 rd:5 \
256
rn=%reg_movprfx
257
258
+# SVE floating-point complex multiply-add (predicated)
259
+FCMLA_zpzzz 01100100 esz:2 0 rm:5 0 rot:2 pg:3 rn:5 rd:5 \
260
+ ra=%reg_movprfx
261
+
262
### SVE FP Multiply-Add Indexed Group
263
264
# SVE floating-point multiply-add (indexed)
265
--
98
--
266
2.17.1
99
2.20.1
267
100
268
101
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@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
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-5-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210215115138.20465-23-peter.maydell@linaro.org
7
---
8
---
8
target/arm/translate-sve.c | 52 ++++++++++++++++++++++++++++++++++++++
9
hw/arm/mps2-tz.c | 22 ++++++++++++++++++++--
9
target/arm/sve.decode | 9 +++++++
10
1 file changed, 20 insertions(+), 2 deletions(-)
10
2 files changed, 61 insertions(+)
11
11
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
14
--- a/hw/arm/mps2-tz.c
15
+++ b/target/arm/translate-sve.c
15
+++ b/hw/arm/mps2-tz.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_LDNF1_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
16
@@ -XXX,XX +XXX,XX @@
17
return true;
17
#include "hw/misc/tz-msc.h"
18
#include "hw/arm/armsse.h"
19
#include "hw/dma/pl080.h"
20
+#include "hw/rtc/pl031.h"
21
#include "hw/ssi/pl022.h"
22
#include "hw/i2c/arm_sbcon_i2c.h"
23
#include "hw/net/lan9118.h"
24
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
25
UnimplementedDeviceState gpio[4];
26
UnimplementedDeviceState gfx;
27
UnimplementedDeviceState cldc;
28
- UnimplementedDeviceState rtc;
29
UnimplementedDeviceState usb;
30
+ PL031State rtc;
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);
18
}
36
}
19
37
20
+static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int msz)
38
+static MemoryRegion *make_rtc(MPS2TZMachineState *mms, void *opaque,
39
+ const char *name, hwaddr size,
40
+ const int *irqs)
21
+{
41
+{
22
+ static gen_helper_gvec_mem * const fns[4] = {
42
+ PL031State *pl031 = opaque;
23
+ gen_helper_sve_ld1bb_r, gen_helper_sve_ld1hh_r,
43
+ SysBusDevice *s;
24
+ gen_helper_sve_ld1ss_r, gen_helper_sve_ld1dd_r,
25
+ };
26
+ unsigned vsz = vec_full_reg_size(s);
27
+ TCGv_ptr t_pg;
28
+ TCGv_i32 desc;
29
+
44
+
30
+ /* Load the first quadword using the normal predicated load helpers. */
45
+ object_initialize_child(OBJECT(mms), name, pl031, TYPE_PL031);
31
+ desc = tcg_const_i32(simd_desc(16, 16, zt));
46
+ s = SYS_BUS_DEVICE(pl031);
32
+ t_pg = tcg_temp_new_ptr();
47
+ sysbus_realize(s, &error_fatal);
33
+
48
+ /*
34
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
49
+ * The board docs don't give an IRQ number for the PL031, so
35
+ fns[msz](cpu_env, t_pg, addr, desc);
50
+ * presumably it is not connected.
36
+
51
+ */
37
+ tcg_temp_free_ptr(t_pg);
52
+ return sysbus_mmio_get_region(s, 0);
38
+ tcg_temp_free_i32(desc);
39
+
40
+ /* Replicate that first quadword. */
41
+ if (vsz > 16) {
42
+ unsigned dofs = vec_full_reg_offset(s, zt);
43
+ tcg_gen_gvec_dup_mem(4, dofs + 16, dofs, vsz - 16, vsz - 16);
44
+ }
45
+}
53
+}
46
+
54
+
47
+static bool trans_LD1RQ_zprr(DisasContext *s, arg_rprr_load *a, uint32_t insn)
55
static void create_non_mpc_ram(MPS2TZMachineState *mms)
48
+{
49
+ if (a->rm == 31) {
50
+ return false;
51
+ }
52
+ if (sve_access_check(s)) {
53
+ int msz = dtype_msz(a->dtype);
54
+ TCGv_i64 addr = new_tmp_a64(s);
55
+ tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), msz);
56
+ tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
57
+ do_ldrq(s, a->rd, a->pg, addr, msz);
58
+ }
59
+ return true;
60
+}
61
+
62
+static bool trans_LD1RQ_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
63
+{
64
+ if (sve_access_check(s)) {
65
+ TCGv_i64 addr = new_tmp_a64(s);
66
+ tcg_gen_addi_i64(addr, cpu_reg_sp(s, a->rn), a->imm * 16);
67
+ do_ldrq(s, a->rd, a->pg, addr, dtype_msz(a->dtype));
68
+ }
69
+ return true;
70
+}
71
+
72
static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
73
int msz, int esz, int nreg)
74
{
56
{
75
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
57
/*
76
index XXXXXXX..XXXXXXX 100644
58
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
77
--- a/target/arm/sve.decode
59
78
+++ b/target/arm/sve.decode
60
{ /* port 9 reserved */ },
79
@@ -XXX,XX +XXX,XX @@ LD_zprr 1010010 .. nreg:2 ..... 110 ... ..... ..... @rprr_load_msz
61
{ "clcd", make_unimp_dev, &mms->cldc, 0x4130a000, 0x1000 },
80
# LD2B, LD2H, LD2W, LD2D; etc.
62
- { "rtc", make_unimp_dev, &mms->rtc, 0x4130b000, 0x1000 },
81
LD_zpri 1010010 .. nreg:2 0.... 111 ... ..... ..... @rpri_load_msz
63
+ { "rtc", make_rtc, &mms->rtc, 0x4130b000, 0x1000 },
82
64
},
83
+# SVE load and broadcast quadword (scalar plus scalar)
65
}, {
84
+LD1RQ_zprr 1010010 .. 00 ..... 000 ... ..... ..... \
66
.name = "ahb_ppcexp0",
85
+ @rprr_load_msz nreg=0
86
+
87
+# SVE load and broadcast quadword (scalar plus immediate)
88
+# LD1RQB, LD1RQH, LD1RQS, LD1RQD
89
+LD1RQ_zpri 1010010 .. 00 0.... 001 ... ..... ..... \
90
+ @rpri_load_msz nreg=0
91
+
92
### SVE Memory Store Group
93
94
# SVE contiguous store (scalar plus immediate)
95
--
67
--
96
2.17.1
68
2.20.1
97
69
98
70
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
[PMM: fixed typo]
6
Message-id: 20180627043328.11531-6-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/helper-sve.h | 30 +++++++++++++
10
target/arm/sve_helper.c | 38 ++++++++++++++++
11
target/arm/translate-sve.c | 90 ++++++++++++++++++++++++++++++++++++++
12
target/arm/sve.decode | 22 ++++++++++
13
4 files changed, 180 insertions(+)
14
15
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper-sve.h
18
+++ b/target/arm/helper-sve.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_rsqrts_s, TCG_CALL_NO_RWG,
20
DEF_HELPER_FLAGS_5(gvec_rsqrts_d, TCG_CALL_NO_RWG,
21
void, ptr, ptr, ptr, ptr, i32)
22
23
+DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
24
+ void, ptr, ptr, ptr, ptr, i32)
25
+DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
26
+ void, ptr, ptr, ptr, ptr, i32)
27
+DEF_HELPER_FLAGS_5(sve_scvt_dh, TCG_CALL_NO_RWG,
28
+ void, ptr, ptr, ptr, ptr, i32)
29
+DEF_HELPER_FLAGS_5(sve_scvt_ss, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_5(sve_scvt_sd, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, ptr, i32)
33
+DEF_HELPER_FLAGS_5(sve_scvt_ds, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, ptr, i32)
35
+DEF_HELPER_FLAGS_5(sve_scvt_dd, TCG_CALL_NO_RWG,
36
+ void, ptr, ptr, ptr, ptr, i32)
37
+
38
+DEF_HELPER_FLAGS_5(sve_ucvt_hh, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, ptr, i32)
40
+DEF_HELPER_FLAGS_5(sve_ucvt_sh, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, ptr, i32)
42
+DEF_HELPER_FLAGS_5(sve_ucvt_dh, TCG_CALL_NO_RWG,
43
+ void, ptr, ptr, ptr, ptr, i32)
44
+DEF_HELPER_FLAGS_5(sve_ucvt_ss, TCG_CALL_NO_RWG,
45
+ void, ptr, ptr, ptr, ptr, i32)
46
+DEF_HELPER_FLAGS_5(sve_ucvt_sd, TCG_CALL_NO_RWG,
47
+ void, ptr, ptr, ptr, ptr, i32)
48
+DEF_HELPER_FLAGS_5(sve_ucvt_ds, TCG_CALL_NO_RWG,
49
+ void, ptr, ptr, ptr, ptr, i32)
50
+DEF_HELPER_FLAGS_5(sve_ucvt_dd, TCG_CALL_NO_RWG,
51
+ void, ptr, ptr, ptr, ptr, i32)
52
+
53
DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
54
DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
55
DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
56
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/sve_helper.c
59
+++ b/target/arm/sve_helper.c
60
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
61
return predtest_ones(d, oprsz, esz_mask);
62
}
63
64
+/* Fully general two-operand expander, controlled by a predicate,
65
+ * With the extra float_status parameter.
66
+ */
67
+#define DO_ZPZ_FP(NAME, TYPE, H, OP) \
68
+void HELPER(NAME)(void *vd, void *vn, void *vg, void *status, uint32_t desc) \
69
+{ \
70
+ intptr_t i = simd_oprsz(desc); \
71
+ uint64_t *g = vg; \
72
+ do { \
73
+ uint64_t pg = g[(i - 1) >> 6]; \
74
+ do { \
75
+ i -= sizeof(TYPE); \
76
+ if (likely((pg >> (i & 63)) & 1)) { \
77
+ TYPE nn = *(TYPE *)(vn + H(i)); \
78
+ *(TYPE *)(vd + H(i)) = OP(nn, status); \
79
+ } \
80
+ } while (i & 63); \
81
+ } while (i != 0); \
82
+}
83
+
84
+DO_ZPZ_FP(sve_scvt_hh, uint16_t, H1_2, int16_to_float16)
85
+DO_ZPZ_FP(sve_scvt_sh, uint32_t, H1_4, int32_to_float16)
86
+DO_ZPZ_FP(sve_scvt_ss, uint32_t, H1_4, int32_to_float32)
87
+DO_ZPZ_FP(sve_scvt_sd, uint64_t, , int32_to_float64)
88
+DO_ZPZ_FP(sve_scvt_dh, uint64_t, , int64_to_float16)
89
+DO_ZPZ_FP(sve_scvt_ds, uint64_t, , int64_to_float32)
90
+DO_ZPZ_FP(sve_scvt_dd, uint64_t, , int64_to_float64)
91
+
92
+DO_ZPZ_FP(sve_ucvt_hh, uint16_t, H1_2, uint16_to_float16)
93
+DO_ZPZ_FP(sve_ucvt_sh, uint32_t, H1_4, uint32_to_float16)
94
+DO_ZPZ_FP(sve_ucvt_ss, uint32_t, H1_4, uint32_to_float32)
95
+DO_ZPZ_FP(sve_ucvt_sd, uint64_t, , uint32_to_float64)
96
+DO_ZPZ_FP(sve_ucvt_dh, uint64_t, , uint64_to_float16)
97
+DO_ZPZ_FP(sve_ucvt_ds, uint64_t, , uint64_to_float32)
98
+DO_ZPZ_FP(sve_ucvt_dd, uint64_t, , uint64_to_float64)
99
+
100
+#undef DO_ZPZ_FP
101
+
102
/*
103
* Load contiguous data, protected by a governing predicate.
104
*/
105
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/arm/translate-sve.c
108
+++ b/target/arm/translate-sve.c
109
@@ -XXX,XX +XXX,XX @@ DO_FP3(FRSQRTS, rsqrts)
110
111
#undef DO_FP3
112
113
+
114
+/*
115
+ *** SVE Floating Point Unary Operations Predicated Group
116
+ */
117
+
118
+static bool do_zpz_ptr(DisasContext *s, int rd, int rn, int pg,
119
+ bool is_fp16, gen_helper_gvec_3_ptr *fn)
120
+{
121
+ if (sve_access_check(s)) {
122
+ unsigned vsz = vec_full_reg_size(s);
123
+ TCGv_ptr status = get_fpstatus_ptr(is_fp16);
124
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, rd),
125
+ vec_full_reg_offset(s, rn),
126
+ pred_full_reg_offset(s, pg),
127
+ status, vsz, vsz, 0, fn);
128
+ tcg_temp_free_ptr(status);
129
+ }
130
+ return true;
131
+}
132
+
133
+static bool trans_SCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
134
+{
135
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_hh);
136
+}
137
+
138
+static bool trans_SCVTF_sh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
139
+{
140
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_sh);
141
+}
142
+
143
+static bool trans_SCVTF_dh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
144
+{
145
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_scvt_dh);
146
+}
147
+
148
+static bool trans_SCVTF_ss(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
149
+{
150
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_scvt_ss);
151
+}
152
+
153
+static bool trans_SCVTF_ds(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
154
+{
155
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_scvt_ds);
156
+}
157
+
158
+static bool trans_SCVTF_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
159
+{
160
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_scvt_sd);
161
+}
162
+
163
+static bool trans_SCVTF_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
164
+{
165
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_scvt_dd);
166
+}
167
+
168
+static bool trans_UCVTF_hh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
169
+{
170
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_ucvt_hh);
171
+}
172
+
173
+static bool trans_UCVTF_sh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
174
+{
175
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_ucvt_sh);
176
+}
177
+
178
+static bool trans_UCVTF_dh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
179
+{
180
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_ucvt_dh);
181
+}
182
+
183
+static bool trans_UCVTF_ss(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
184
+{
185
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_ucvt_ss);
186
+}
187
+
188
+static bool trans_UCVTF_ds(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
189
+{
190
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_ucvt_ds);
191
+}
192
+
193
+static bool trans_UCVTF_sd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
194
+{
195
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_ucvt_sd);
196
+}
197
+
198
+static bool trans_UCVTF_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
199
+{
200
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_ucvt_dd);
201
+}
202
+
203
/*
204
*** SVE Memory - 32-bit Gather and Unsized Contiguous Group
205
*/
206
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
207
index XXXXXXX..XXXXXXX 100644
208
--- a/target/arm/sve.decode
209
+++ b/target/arm/sve.decode
210
@@ -XXX,XX +XXX,XX @@
211
@rd_pg_rn ........ esz:2 ... ... ... pg:3 rn:5 rd:5 &rpr_esz
212
@rd_pg4_pn ........ esz:2 ... ... .. pg:4 . rn:4 rd:5 &rpr_esz
213
214
+# One register operand, with governing predicate, no vector element size
215
+@rd_pg_rn_e0 ........ .. ... ... ... pg:3 rn:5 rd:5 &rpr_esz esz=0
216
+
217
# Two register operands with a 6-bit signed immediate.
218
@rd_rn_i6 ........ ... rn:5 ..... imm:s6 rd:5 &rri
219
220
@@ -XXX,XX +XXX,XX @@ FTSMUL 01100101 .. 0 ..... 000 011 ..... ..... @rd_rn_rm
221
FRECPS 01100101 .. 0 ..... 000 110 ..... ..... @rd_rn_rm
222
FRSQRTS 01100101 .. 0 ..... 000 111 ..... ..... @rd_rn_rm
223
224
+### SVE FP Unary Operations Predicated Group
225
+
226
+# SVE integer convert to floating-point
227
+SCVTF_hh 01100101 01 010 01 0 101 ... ..... ..... @rd_pg_rn_e0
228
+SCVTF_sh 01100101 01 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
229
+SCVTF_dh 01100101 01 010 11 0 101 ... ..... ..... @rd_pg_rn_e0
230
+SCVTF_ss 01100101 10 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
231
+SCVTF_sd 01100101 11 010 00 0 101 ... ..... ..... @rd_pg_rn_e0
232
+SCVTF_ds 01100101 11 010 10 0 101 ... ..... ..... @rd_pg_rn_e0
233
+SCVTF_dd 01100101 11 010 11 0 101 ... ..... ..... @rd_pg_rn_e0
234
+
235
+UCVTF_hh 01100101 01 010 01 1 101 ... ..... ..... @rd_pg_rn_e0
236
+UCVTF_sh 01100101 01 010 10 1 101 ... ..... ..... @rd_pg_rn_e0
237
+UCVTF_dh 01100101 01 010 11 1 101 ... ..... ..... @rd_pg_rn_e0
238
+UCVTF_ss 01100101 10 010 10 1 101 ... ..... ..... @rd_pg_rn_e0
239
+UCVTF_sd 01100101 11 010 00 1 101 ... ..... ..... @rd_pg_rn_e0
240
+UCVTF_ds 01100101 11 010 10 1 101 ... ..... ..... @rd_pg_rn_e0
241
+UCVTF_dd 01100101 11 010 11 1 101 ... ..... ..... @rd_pg_rn_e0
242
+
243
### SVE Memory - 32-bit Gather and Unsized Contiguous Group
244
245
# SVE load predicate register
246
--
247
2.17.1
248
249
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-13-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-sve.c | 21 +++++++++++++++++++++
9
target/arm/sve.decode | 23 +++++++++++++++++++++++
10
2 files changed, 44 insertions(+)
11
12
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/translate-sve.c
15
+++ b/target/arm/translate-sve.c
16
@@ -XXX,XX +XXX,XX @@ static bool trans_ST1_zprz(DisasContext *s, arg_ST1_zprz *a, uint32_t insn)
17
cpu_reg_sp(s, a->rn), fn);
18
return true;
19
}
20
+
21
+/*
22
+ * Prefetches
23
+ */
24
+
25
+static bool trans_PRF(DisasContext *s, arg_PRF *a, uint32_t insn)
26
+{
27
+ /* Prefetch is a nop within QEMU. */
28
+ sve_access_check(s);
29
+ return true;
30
+}
31
+
32
+static bool trans_PRF_rr(DisasContext *s, arg_PRF_rr *a, uint32_t insn)
33
+{
34
+ if (a->rm == 31) {
35
+ return false;
36
+ }
37
+ /* Prefetch is a nop within QEMU. */
38
+ sve_access_check(s);
39
+ return true;
40
+}
41
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/sve.decode
44
+++ b/target/arm/sve.decode
45
@@ -XXX,XX +XXX,XX @@ LD1RQ_zprr 1010010 .. 00 ..... 000 ... ..... ..... \
46
LD1RQ_zpri 1010010 .. 00 0.... 001 ... ..... ..... \
47
@rpri_load_msz nreg=0
48
49
+# SVE 32-bit gather prefetch (scalar plus 32-bit scaled offsets)
50
+PRF 1000010 00 -1 ----- 0-- --- ----- 0 ----
51
+
52
+# SVE 32-bit gather prefetch (vector plus immediate)
53
+PRF 1000010 -- 00 ----- 111 --- ----- 0 ----
54
+
55
+# SVE contiguous prefetch (scalar plus immediate)
56
+PRF 1000010 11 1- ----- 0-- --- ----- 0 ----
57
+
58
+# SVE contiguous prefetch (scalar plus scalar)
59
+PRF_rr 1000010 -- 00 rm:5 110 --- ----- 0 ----
60
+
61
+### SVE Memory 64-bit Gather Group
62
+
63
+# SVE 64-bit gather prefetch (scalar plus 64-bit scaled offsets)
64
+PRF 1100010 00 11 ----- 1-- --- ----- 0 ----
65
+
66
+# SVE 64-bit gather prefetch (scalar plus unpacked 32-bit scaled offsets)
67
+PRF 1100010 00 -1 ----- 0-- --- ----- 0 ----
68
+
69
+# SVE 64-bit gather prefetch (vector plus immediate)
70
+PRF 1100010 -- 00 ----- 111 --- ----- 0 ----
71
+
72
### SVE Memory Store Group
73
74
# SVE store predicate register
75
--
76
2.17.1
77
78
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-18-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 56 ++++++++++++++++++++++++++++
9
target/arm/sve_helper.c | 69 +++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 75 ++++++++++++++++++++++++++++++++++++++
11
target/arm/sve.decode | 14 +++++++
12
4 files changed, 214 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_6(sve_fmulx_s, TCG_CALL_NO_RWG,
19
DEF_HELPER_FLAGS_6(sve_fmulx_d, TCG_CALL_NO_RWG,
20
void, ptr, ptr, ptr, ptr, ptr, i32)
21
22
+DEF_HELPER_FLAGS_6(sve_fadds_h, TCG_CALL_NO_RWG,
23
+ void, ptr, ptr, ptr, i64, ptr, i32)
24
+DEF_HELPER_FLAGS_6(sve_fadds_s, TCG_CALL_NO_RWG,
25
+ void, ptr, ptr, ptr, i64, ptr, i32)
26
+DEF_HELPER_FLAGS_6(sve_fadds_d, TCG_CALL_NO_RWG,
27
+ void, ptr, ptr, ptr, i64, ptr, i32)
28
+
29
+DEF_HELPER_FLAGS_6(sve_fsubs_h, TCG_CALL_NO_RWG,
30
+ void, ptr, ptr, ptr, i64, ptr, i32)
31
+DEF_HELPER_FLAGS_6(sve_fsubs_s, TCG_CALL_NO_RWG,
32
+ void, ptr, ptr, ptr, i64, ptr, i32)
33
+DEF_HELPER_FLAGS_6(sve_fsubs_d, TCG_CALL_NO_RWG,
34
+ void, ptr, ptr, ptr, i64, ptr, i32)
35
+
36
+DEF_HELPER_FLAGS_6(sve_fmuls_h, TCG_CALL_NO_RWG,
37
+ void, ptr, ptr, ptr, i64, ptr, i32)
38
+DEF_HELPER_FLAGS_6(sve_fmuls_s, TCG_CALL_NO_RWG,
39
+ void, ptr, ptr, ptr, i64, ptr, i32)
40
+DEF_HELPER_FLAGS_6(sve_fmuls_d, TCG_CALL_NO_RWG,
41
+ void, ptr, ptr, ptr, i64, ptr, i32)
42
+
43
+DEF_HELPER_FLAGS_6(sve_fsubrs_h, TCG_CALL_NO_RWG,
44
+ void, ptr, ptr, ptr, i64, ptr, i32)
45
+DEF_HELPER_FLAGS_6(sve_fsubrs_s, TCG_CALL_NO_RWG,
46
+ void, ptr, ptr, ptr, i64, ptr, i32)
47
+DEF_HELPER_FLAGS_6(sve_fsubrs_d, TCG_CALL_NO_RWG,
48
+ void, ptr, ptr, ptr, i64, ptr, i32)
49
+
50
+DEF_HELPER_FLAGS_6(sve_fmaxnms_h, TCG_CALL_NO_RWG,
51
+ void, ptr, ptr, ptr, i64, ptr, i32)
52
+DEF_HELPER_FLAGS_6(sve_fmaxnms_s, TCG_CALL_NO_RWG,
53
+ void, ptr, ptr, ptr, i64, ptr, i32)
54
+DEF_HELPER_FLAGS_6(sve_fmaxnms_d, TCG_CALL_NO_RWG,
55
+ void, ptr, ptr, ptr, i64, ptr, i32)
56
+
57
+DEF_HELPER_FLAGS_6(sve_fminnms_h, TCG_CALL_NO_RWG,
58
+ void, ptr, ptr, ptr, i64, ptr, i32)
59
+DEF_HELPER_FLAGS_6(sve_fminnms_s, TCG_CALL_NO_RWG,
60
+ void, ptr, ptr, ptr, i64, ptr, i32)
61
+DEF_HELPER_FLAGS_6(sve_fminnms_d, TCG_CALL_NO_RWG,
62
+ void, ptr, ptr, ptr, i64, ptr, i32)
63
+
64
+DEF_HELPER_FLAGS_6(sve_fmaxs_h, TCG_CALL_NO_RWG,
65
+ void, ptr, ptr, ptr, i64, ptr, i32)
66
+DEF_HELPER_FLAGS_6(sve_fmaxs_s, TCG_CALL_NO_RWG,
67
+ void, ptr, ptr, ptr, i64, ptr, i32)
68
+DEF_HELPER_FLAGS_6(sve_fmaxs_d, TCG_CALL_NO_RWG,
69
+ void, ptr, ptr, ptr, i64, ptr, i32)
70
+
71
+DEF_HELPER_FLAGS_6(sve_fmins_h, TCG_CALL_NO_RWG,
72
+ void, ptr, ptr, ptr, i64, ptr, i32)
73
+DEF_HELPER_FLAGS_6(sve_fmins_s, TCG_CALL_NO_RWG,
74
+ void, ptr, ptr, ptr, i64, ptr, i32)
75
+DEF_HELPER_FLAGS_6(sve_fmins_d, TCG_CALL_NO_RWG,
76
+ void, ptr, ptr, ptr, i64, ptr, i32)
77
+
78
DEF_HELPER_FLAGS_5(sve_scvt_hh, TCG_CALL_NO_RWG,
79
void, ptr, ptr, ptr, ptr, i32)
80
DEF_HELPER_FLAGS_5(sve_scvt_sh, TCG_CALL_NO_RWG,
81
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/sve_helper.c
84
+++ b/target/arm/sve_helper.c
85
@@ -XXX,XX +XXX,XX @@ DO_ZPZZ_FP(sve_fmulx_d, uint64_t, , helper_vfp_mulxd)
86
87
#undef DO_ZPZZ_FP
88
89
+/* Three-operand expander, with one scalar operand, controlled by
90
+ * a predicate, with the extra float_status parameter.
91
+ */
92
+#define DO_ZPZS_FP(NAME, TYPE, H, OP) \
93
+void HELPER(NAME)(void *vd, void *vn, void *vg, uint64_t scalar, \
94
+ void *status, uint32_t desc) \
95
+{ \
96
+ intptr_t i = simd_oprsz(desc); \
97
+ uint64_t *g = vg; \
98
+ TYPE mm = scalar; \
99
+ do { \
100
+ uint64_t pg = g[(i - 1) >> 6]; \
101
+ do { \
102
+ i -= sizeof(TYPE); \
103
+ if (likely((pg >> (i & 63)) & 1)) { \
104
+ TYPE nn = *(TYPE *)(vn + H(i)); \
105
+ *(TYPE *)(vd + H(i)) = OP(nn, mm, status); \
106
+ } \
107
+ } while (i & 63); \
108
+ } while (i != 0); \
109
+}
110
+
111
+DO_ZPZS_FP(sve_fadds_h, float16, H1_2, float16_add)
112
+DO_ZPZS_FP(sve_fadds_s, float32, H1_4, float32_add)
113
+DO_ZPZS_FP(sve_fadds_d, float64, , float64_add)
114
+
115
+DO_ZPZS_FP(sve_fsubs_h, float16, H1_2, float16_sub)
116
+DO_ZPZS_FP(sve_fsubs_s, float32, H1_4, float32_sub)
117
+DO_ZPZS_FP(sve_fsubs_d, float64, , float64_sub)
118
+
119
+DO_ZPZS_FP(sve_fmuls_h, float16, H1_2, float16_mul)
120
+DO_ZPZS_FP(sve_fmuls_s, float32, H1_4, float32_mul)
121
+DO_ZPZS_FP(sve_fmuls_d, float64, , float64_mul)
122
+
123
+static inline float16 subr_h(float16 a, float16 b, float_status *s)
124
+{
125
+ return float16_sub(b, a, s);
126
+}
127
+
128
+static inline float32 subr_s(float32 a, float32 b, float_status *s)
129
+{
130
+ return float32_sub(b, a, s);
131
+}
132
+
133
+static inline float64 subr_d(float64 a, float64 b, float_status *s)
134
+{
135
+ return float64_sub(b, a, s);
136
+}
137
+
138
+DO_ZPZS_FP(sve_fsubrs_h, float16, H1_2, subr_h)
139
+DO_ZPZS_FP(sve_fsubrs_s, float32, H1_4, subr_s)
140
+DO_ZPZS_FP(sve_fsubrs_d, float64, , subr_d)
141
+
142
+DO_ZPZS_FP(sve_fmaxnms_h, float16, H1_2, float16_maxnum)
143
+DO_ZPZS_FP(sve_fmaxnms_s, float32, H1_4, float32_maxnum)
144
+DO_ZPZS_FP(sve_fmaxnms_d, float64, , float64_maxnum)
145
+
146
+DO_ZPZS_FP(sve_fminnms_h, float16, H1_2, float16_minnum)
147
+DO_ZPZS_FP(sve_fminnms_s, float32, H1_4, float32_minnum)
148
+DO_ZPZS_FP(sve_fminnms_d, float64, , float64_minnum)
149
+
150
+DO_ZPZS_FP(sve_fmaxs_h, float16, H1_2, float16_max)
151
+DO_ZPZS_FP(sve_fmaxs_s, float32, H1_4, float32_max)
152
+DO_ZPZS_FP(sve_fmaxs_d, float64, , float64_max)
153
+
154
+DO_ZPZS_FP(sve_fmins_h, float16, H1_2, float16_min)
155
+DO_ZPZS_FP(sve_fmins_s, float32, H1_4, float32_min)
156
+DO_ZPZS_FP(sve_fmins_d, float64, , float64_min)
157
+
158
/* Fully general two-operand expander, controlled by a predicate,
159
* With the extra float_status parameter.
160
*/
161
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
162
index XXXXXXX..XXXXXXX 100644
163
--- a/target/arm/translate-sve.c
164
+++ b/target/arm/translate-sve.c
165
@@ -XXX,XX +XXX,XX @@
166
#include "exec/log.h"
167
#include "trace-tcg.h"
168
#include "translate-a64.h"
169
+#include "fpu/softfloat.h"
170
171
172
typedef void GVecGen2sFn(unsigned, uint32_t, uint32_t,
173
@@ -XXX,XX +XXX,XX @@ DO_FP3(FMULX, fmulx)
174
175
#undef DO_FP3
176
177
+typedef void gen_helper_sve_fp2scalar(TCGv_ptr, TCGv_ptr, TCGv_ptr,
178
+ TCGv_i64, TCGv_ptr, TCGv_i32);
179
+
180
+static void do_fp_scalar(DisasContext *s, int zd, int zn, int pg, bool is_fp16,
181
+ TCGv_i64 scalar, gen_helper_sve_fp2scalar *fn)
182
+{
183
+ unsigned vsz = vec_full_reg_size(s);
184
+ TCGv_ptr t_zd, t_zn, t_pg, status;
185
+ TCGv_i32 desc;
186
+
187
+ t_zd = tcg_temp_new_ptr();
188
+ t_zn = tcg_temp_new_ptr();
189
+ t_pg = tcg_temp_new_ptr();
190
+ tcg_gen_addi_ptr(t_zd, cpu_env, vec_full_reg_offset(s, zd));
191
+ tcg_gen_addi_ptr(t_zn, cpu_env, vec_full_reg_offset(s, zn));
192
+ tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
193
+
194
+ status = get_fpstatus_ptr(is_fp16);
195
+ desc = tcg_const_i32(simd_desc(vsz, vsz, 0));
196
+ fn(t_zd, t_zn, t_pg, scalar, status, desc);
197
+
198
+ tcg_temp_free_i32(desc);
199
+ tcg_temp_free_ptr(status);
200
+ tcg_temp_free_ptr(t_pg);
201
+ tcg_temp_free_ptr(t_zn);
202
+ tcg_temp_free_ptr(t_zd);
203
+}
204
+
205
+static void do_fp_imm(DisasContext *s, arg_rpri_esz *a, uint64_t imm,
206
+ gen_helper_sve_fp2scalar *fn)
207
+{
208
+ TCGv_i64 temp = tcg_const_i64(imm);
209
+ do_fp_scalar(s, a->rd, a->rn, a->pg, a->esz == MO_16, temp, fn);
210
+ tcg_temp_free_i64(temp);
211
+}
212
+
213
+#define DO_FP_IMM(NAME, name, const0, const1) \
214
+static bool trans_##NAME##_zpzi(DisasContext *s, arg_rpri_esz *a, \
215
+ uint32_t insn) \
216
+{ \
217
+ static gen_helper_sve_fp2scalar * const fns[3] = { \
218
+ gen_helper_sve_##name##_h, \
219
+ gen_helper_sve_##name##_s, \
220
+ gen_helper_sve_##name##_d \
221
+ }; \
222
+ static uint64_t const val[3][2] = { \
223
+ { float16_##const0, float16_##const1 }, \
224
+ { float32_##const0, float32_##const1 }, \
225
+ { float64_##const0, float64_##const1 }, \
226
+ }; \
227
+ if (a->esz == 0) { \
228
+ return false; \
229
+ } \
230
+ if (sve_access_check(s)) { \
231
+ do_fp_imm(s, a, val[a->esz - 1][a->imm], fns[a->esz - 1]); \
232
+ } \
233
+ return true; \
234
+}
235
+
236
+#define float16_two make_float16(0x4000)
237
+#define float32_two make_float32(0x40000000)
238
+#define float64_two make_float64(0x4000000000000000ULL)
239
+
240
+DO_FP_IMM(FADD, fadds, half, one)
241
+DO_FP_IMM(FSUB, fsubs, half, one)
242
+DO_FP_IMM(FMUL, fmuls, half, two)
243
+DO_FP_IMM(FSUBR, fsubrs, half, one)
244
+DO_FP_IMM(FMAXNM, fmaxnms, zero, one)
245
+DO_FP_IMM(FMINNM, fminnms, zero, one)
246
+DO_FP_IMM(FMAX, fmaxs, zero, one)
247
+DO_FP_IMM(FMIN, fmins, zero, one)
248
+
249
+#undef DO_FP_IMM
250
+
251
static bool do_fp_cmp(DisasContext *s, arg_rprr_esz *a,
252
gen_helper_gvec_4_ptr *fn)
253
{
254
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
255
index XXXXXXX..XXXXXXX 100644
256
--- a/target/arm/sve.decode
257
+++ b/target/arm/sve.decode
258
@@ -XXX,XX +XXX,XX @@
259
@rdn_pg4 ........ esz:2 .. pg:4 ... ........ rd:5 \
260
&rpri_esz rn=%reg_movprfx
261
262
+# Two register operand, one one-bit floating-point operand.
263
+@rdn_i1 ........ esz:2 ......... pg:3 .... imm:1 rd:5 \
264
+ &rpri_esz rn=%reg_movprfx
265
+
266
# Two register operand, one encoded bitmask.
267
@rdn_dbm ........ .. .... dbm:13 rd:5 \
268
&rr_dbm rn=%reg_movprfx
269
@@ -XXX,XX +XXX,XX @@ FMULX 01100101 .. 00 1010 100 ... ..... ..... @rdn_pg_rm
270
FDIV 01100101 .. 00 1100 100 ... ..... ..... @rdm_pg_rn # FDIVR
271
FDIV 01100101 .. 00 1101 100 ... ..... ..... @rdn_pg_rm
272
273
+# SVE floating-point arithmetic with immediate (predicated)
274
+FADD_zpzi 01100101 .. 011 000 100 ... 0000 . ..... @rdn_i1
275
+FSUB_zpzi 01100101 .. 011 001 100 ... 0000 . ..... @rdn_i1
276
+FMUL_zpzi 01100101 .. 011 010 100 ... 0000 . ..... @rdn_i1
277
+FSUBR_zpzi 01100101 .. 011 011 100 ... 0000 . ..... @rdn_i1
278
+FMAXNM_zpzi 01100101 .. 011 100 100 ... 0000 . ..... @rdn_i1
279
+FMINNM_zpzi 01100101 .. 011 101 100 ... 0000 . ..... @rdn_i1
280
+FMAX_zpzi 01100101 .. 011 110 100 ... 0000 . ..... @rdn_i1
281
+FMIN_zpzi 01100101 .. 011 111 100 ... 0000 . ..... @rdn_i1
282
+
283
### SVE FP Multiply-Add Group
284
285
# SVE floating-point multiply-accumulate writing addend
286
--
287
2.17.1
288
289
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20180627043328.11531-23-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-sve.h | 4 +++
9
target/arm/sve_helper.c | 70 ++++++++++++++++++++++++++++++++++++++
10
target/arm/translate-sve.c | 27 +++++++++++++++
11
target/arm/sve.decode | 3 ++
12
4 files changed, 104 insertions(+)
13
14
diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper-sve.h
17
+++ b/target/arm/helper-sve.h
18
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_h, TCG_CALL_NO_RWG, void, env, ptr, i32)
19
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_s, TCG_CALL_NO_RWG, void, env, ptr, i32)
20
DEF_HELPER_FLAGS_3(sve_fnmls_zpzzz_d, TCG_CALL_NO_RWG, void, env, ptr, i32)
21
22
+DEF_HELPER_FLAGS_5(sve_ftmad_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
23
+DEF_HELPER_FLAGS_5(sve_ftmad_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
24
+DEF_HELPER_FLAGS_5(sve_ftmad_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, ptr, i32)
25
+
26
DEF_HELPER_FLAGS_4(sve_ld1bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
27
DEF_HELPER_FLAGS_4(sve_ld2bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
28
DEF_HELPER_FLAGS_4(sve_ld3bb_r, TCG_CALL_NO_WG, void, env, ptr, tl, i32)
29
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/sve_helper.c
32
+++ b/target/arm/sve_helper.c
33
@@ -XXX,XX +XXX,XX @@ DO_FPCMP_PPZ0_ALL(sve_fcmlt0, DO_FCMLT)
34
DO_FPCMP_PPZ0_ALL(sve_fcmeq0, DO_FCMEQ)
35
DO_FPCMP_PPZ0_ALL(sve_fcmne0, DO_FCMNE)
36
37
+/* FP Trig Multiply-Add. */
38
+
39
+void HELPER(sve_ftmad_h)(void *vd, void *vn, void *vm, void *vs, uint32_t desc)
40
+{
41
+ static const float16 coeff[16] = {
42
+ 0x3c00, 0xb155, 0x2030, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
43
+ 0x3c00, 0xb800, 0x293a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
44
+ };
45
+ intptr_t i, opr_sz = simd_oprsz(desc) / sizeof(float16);
46
+ intptr_t x = simd_data(desc);
47
+ float16 *d = vd, *n = vn, *m = vm;
48
+ for (i = 0; i < opr_sz; i++) {
49
+ float16 mm = m[i];
50
+ intptr_t xx = x;
51
+ if (float16_is_neg(mm)) {
52
+ mm = float16_abs(mm);
53
+ xx += 8;
54
+ }
55
+ d[i] = float16_muladd(n[i], mm, coeff[xx], 0, vs);
56
+ }
57
+}
58
+
59
+void HELPER(sve_ftmad_s)(void *vd, void *vn, void *vm, void *vs, uint32_t desc)
60
+{
61
+ static const float32 coeff[16] = {
62
+ 0x3f800000, 0xbe2aaaab, 0x3c088886, 0xb95008b9,
63
+ 0x36369d6d, 0x00000000, 0x00000000, 0x00000000,
64
+ 0x3f800000, 0xbf000000, 0x3d2aaaa6, 0xbab60705,
65
+ 0x37cd37cc, 0x00000000, 0x00000000, 0x00000000,
66
+ };
67
+ intptr_t i, opr_sz = simd_oprsz(desc) / sizeof(float32);
68
+ intptr_t x = simd_data(desc);
69
+ float32 *d = vd, *n = vn, *m = vm;
70
+ for (i = 0; i < opr_sz; i++) {
71
+ float32 mm = m[i];
72
+ intptr_t xx = x;
73
+ if (float32_is_neg(mm)) {
74
+ mm = float32_abs(mm);
75
+ xx += 8;
76
+ }
77
+ d[i] = float32_muladd(n[i], mm, coeff[xx], 0, vs);
78
+ }
79
+}
80
+
81
+void HELPER(sve_ftmad_d)(void *vd, void *vn, void *vm, void *vs, uint32_t desc)
82
+{
83
+ static const float64 coeff[16] = {
84
+ 0x3ff0000000000000ull, 0xbfc5555555555543ull,
85
+ 0x3f8111111110f30cull, 0xbf2a01a019b92fc6ull,
86
+ 0x3ec71de351f3d22bull, 0xbe5ae5e2b60f7b91ull,
87
+ 0x3de5d8408868552full, 0x0000000000000000ull,
88
+ 0x3ff0000000000000ull, 0xbfe0000000000000ull,
89
+ 0x3fa5555555555536ull, 0xbf56c16c16c13a0bull,
90
+ 0x3efa01a019b1e8d8ull, 0xbe927e4f7282f468ull,
91
+ 0x3e21ee96d2641b13ull, 0xbda8f76380fbb401ull,
92
+ };
93
+ intptr_t i, opr_sz = simd_oprsz(desc) / sizeof(float64);
94
+ intptr_t x = simd_data(desc);
95
+ float64 *d = vd, *n = vn, *m = vm;
96
+ for (i = 0; i < opr_sz; i++) {
97
+ float64 mm = m[i];
98
+ intptr_t xx = x;
99
+ if (float64_is_neg(mm)) {
100
+ mm = float64_abs(mm);
101
+ xx += 8;
102
+ }
103
+ d[i] = float64_muladd(n[i], mm, coeff[xx], 0, vs);
104
+ }
105
+}
106
+
107
/*
108
* Load contiguous data, protected by a governing predicate.
109
*/
110
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/arm/translate-sve.c
113
+++ b/target/arm/translate-sve.c
114
@@ -XXX,XX +XXX,XX @@ DO_PPZ(FCMNE_ppz0, fcmne0)
115
116
#undef DO_PPZ
117
118
+/*
119
+ *** SVE floating-point trig multiply-add coefficient
120
+ */
121
+
122
+static bool trans_FTMAD(DisasContext *s, arg_FTMAD *a, uint32_t insn)
123
+{
124
+ static gen_helper_gvec_3_ptr * const fns[3] = {
125
+ gen_helper_sve_ftmad_h,
126
+ gen_helper_sve_ftmad_s,
127
+ gen_helper_sve_ftmad_d,
128
+ };
129
+
130
+ if (a->esz == 0) {
131
+ return false;
132
+ }
133
+ if (sve_access_check(s)) {
134
+ unsigned vsz = vec_full_reg_size(s);
135
+ TCGv_ptr status = get_fpstatus_ptr(a->esz == MO_16);
136
+ tcg_gen_gvec_3_ptr(vec_full_reg_offset(s, a->rd),
137
+ vec_full_reg_offset(s, a->rn),
138
+ vec_full_reg_offset(s, a->rm),
139
+ status, vsz, vsz, a->imm, fns[a->esz - 1]);
140
+ tcg_temp_free_ptr(status);
141
+ }
142
+ return true;
143
+}
144
+
145
/*
146
*** SVE Floating Point Accumulating Reduction Group
147
*/
148
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
149
index XXXXXXX..XXXXXXX 100644
150
--- a/target/arm/sve.decode
151
+++ b/target/arm/sve.decode
152
@@ -XXX,XX +XXX,XX @@ FMINNM_zpzi 01100101 .. 011 101 100 ... 0000 . ..... @rdn_i1
153
FMAX_zpzi 01100101 .. 011 110 100 ... 0000 . ..... @rdn_i1
154
FMIN_zpzi 01100101 .. 011 111 100 ... 0000 . ..... @rdn_i1
155
156
+# SVE floating-point trig multiply-add coefficient
157
+FTMAD 01100101 esz:2 010 imm:3 100000 rm:5 rd:5 rn=%reg_movprfx
158
+
159
### SVE FP Multiply-Add Group
160
161
# SVE floating-point multiply-accumulate writing addend
162
--
163
2.17.1
164
165
diff view generated by jsdifflib
1
We don't actually implement SD command CRC checking, because
1
Add brief documentation of the new mps3-an524 board.
2
for almost all of our SD controllers the CRC generation is
3
done in hardware, and so modelling CRC generation and checking
4
would be a bit pointless. (The exception is that milkymist-memcard
5
makes the guest software compute the CRC.)
6
7
As a result almost all of our SD controller models don't bother
8
to set the SDRequest crc field, and the SD card model doesn't
9
check it. So the tracing of it in sdbus_do_command() provokes
10
Coverity warnings about use of uninitialized data.
11
12
Drop the CRC field from the trace; we can always add it back
13
if and when we do anything useful with the CRC.
14
15
Fixes Coverity issues 1386072, 1386074, 1386076, 1390571.
16
2
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
19
Message-id: 20180626180324.5537-1-peter.maydell@linaro.org
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215115138.20465-24-peter.maydell@linaro.org
20
---
7
---
21
hw/sd/core.c | 2 +-
8
docs/system/arm/mps2.rst | 24 ++++++++++++++++++------
22
hw/sd/trace-events | 2 +-
9
1 file changed, 18 insertions(+), 6 deletions(-)
23
2 files changed, 2 insertions(+), 2 deletions(-)
24
10
25
diff --git a/hw/sd/core.c b/hw/sd/core.c
11
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
26
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/sd/core.c
13
--- a/docs/system/arm/mps2.rst
28
+++ b/hw/sd/core.c
14
+++ b/docs/system/arm/mps2.rst
29
@@ -XXX,XX +XXX,XX @@ int sdbus_do_command(SDBus *sdbus, SDRequest *req, uint8_t *response)
15
@@ -XXX,XX +XXX,XX @@
30
{
16
-Arm MPS2 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``)
31
SDState *card = get_card(sdbus);
17
-================================================================================================================
32
18
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
33
- trace_sdbus_command(sdbus_name(sdbus), req->cmd, req->arg, req->crc);
19
+=========================================================================================================================================
34
+ trace_sdbus_command(sdbus_name(sdbus), req->cmd, req->arg);
20
35
if (card) {
21
These board models all use Arm M-profile CPUs.
36
SDCardClass *sc = SD_CARD_GET_CLASS(card);
22
37
23
-The Arm MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
38
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
24
-FPGA but is otherwise the same as the 2). Since the CPU itself
39
index XXXXXXX..XXXXXXX 100644
25
-and most of the devices are in the FPGA, the details of the board
40
--- a/hw/sd/trace-events
26
-as seen by the guest depend significantly on the FPGA image.
41
+++ b/hw/sd/trace-events
27
+The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
42
@@ -XXX,XX +XXX,XX @@ bcm2835_sdhost_edm_change(const char *why, uint32_t edm) "(%s) EDM now 0x%x"
28
+bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
43
bcm2835_sdhost_update_irq(uint32_t irq) "IRQ bits 0x%x\n"
29
+FPGA again, can handle 4GB of RAM and has a USB controller and QSPI flash).
44
30
+
45
# hw/sd/core.c
31
+Since the CPU itself and most of the devices are in the FPGA, the
46
-sdbus_command(const char *bus_name, uint8_t cmd, uint32_t arg, uint8_t crc) "@%s CMD%02d arg 0x%08x crc 0x%02x"
32
+details of the board as seen by the guest depend significantly on the
47
+sdbus_command(const char *bus_name, uint8_t cmd, uint32_t arg) "@%s CMD%02d arg 0x%08x"
33
+FPGA image.
48
sdbus_read(const char *bus_name, uint8_t value) "@%s value 0x%02x"
34
49
sdbus_write(const char *bus_name, uint8_t value) "@%s value 0x%02x"
35
QEMU models the following FPGA images:
50
sdbus_set_voltage(const char *bus_name, uint16_t millivolts) "@%s %u (mV)"
36
37
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
38
Cortex-M3 'DesignStart' as documented in Arm Application Note AN511
39
``mps2-an521``
40
Dual Cortex-M33 as documented in Arm Application Note AN521
41
+``mps3-an524``
42
+ Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
43
44
Differences between QEMU and real hardware:
45
46
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
47
block RAM is unimplemented (QEMU always maps this to ZBT SSRAM1, as
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.17.1
60
2.20.1
53
61
54
62
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
Update old infocenter.arm.com URLs to the equivalent developer.arm.com
2
2
ones (the old URLs should redirect, but we might as well avoid the
3
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
3
redirection notice, and the new URLs are pleasantly shorter).
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
5
This commit covers the links to the MPS2 board TRM, the various
6
Application Notes, the IoTKit and SSE-200 documents.
7
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
6
---
11
---
7
hw/arm/mcimx7d-sabre.c | 2 --
12
include/hw/arm/armsse.h | 4 ++--
8
1 file changed, 2 deletions(-)
13
include/hw/misc/armsse-cpuid.h | 2 +-
9
14
include/hw/misc/armsse-mhu.h | 2 +-
10
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
15
include/hw/misc/iotkit-secctl.h | 2 +-
11
index XXXXXXX..XXXXXXX 100644
16
include/hw/misc/iotkit-sysctl.h | 2 +-
12
--- a/hw/arm/mcimx7d-sabre.c
17
include/hw/misc/iotkit-sysinfo.h | 2 +-
13
+++ b/hw/arm/mcimx7d-sabre.c
18
include/hw/misc/mps2-fpgaio.h | 2 +-
14
@@ -XXX,XX +XXX,XX @@
19
hw/arm/mps2-tz.c | 11 +++++------
15
#include "hw/arm/fsl-imx7.h"
20
hw/misc/armsse-cpuid.c | 2 +-
16
#include "hw/boards.h"
21
hw/misc/armsse-mhu.c | 2 +-
17
#include "sysemu/sysemu.h"
22
hw/misc/iotkit-sysctl.c | 2 +-
18
-#include "sysemu/device_tree.h"
23
hw/misc/iotkit-sysinfo.c | 2 +-
19
#include "qemu/error-report.h"
24
hw/misc/mps2-fpgaio.c | 2 +-
20
#include "sysemu/qtest.h"
25
hw/misc/mps2-scc.c | 2 +-
21
-#include "net/net.h"
26
14 files changed, 19 insertions(+), 20 deletions(-)
22
27
23
typedef struct {
28
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
24
FslIMX7State soc;
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
25
--
231
--
26
2.17.1
232
2.20.1
27
233
28
234
diff view generated by jsdifflib