1
The following changes since commit 61fee7f45955cd0bf9b79be9fa9c7ebabb5e6a85:
1
target-arm queue: I have a lot more still in my to-review
2
queue, but my rule of thumb is when I get to 50 patches or
3
so to send out what I have.
2
4
3
Merge remote-tracking branch 'remotes/philmd-gitlab/tags/acceptance-testing-20200622' into staging (2020-06-22 20:50:10 +0100)
5
thanks
6
-- PMM
7
8
The following changes since commit 9a7beaad3dbba982f7a461d676b55a5c3851d312:
9
10
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20210304' into staging (2021-03-05 10:47:46 +0000)
4
11
5
are available in the Git repository at:
12
are available in the Git repository at:
6
13
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20200623
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210305
8
15
9
for you to fetch changes up to 539533b85fbd269f777bed931de8ccae1dd837e9:
16
for you to fetch changes up to 2c669ff88ec6733420a000103a2b8b9e93df4945:
10
17
11
arm/virt: Add memory hot remove support (2020-06-23 11:39:48 +0100)
18
hw/arm/mps2: Update old infocenter.arm.com URLs (2021-03-05 15:17:38 +0000)
12
19
13
----------------------------------------------------------------
20
----------------------------------------------------------------
14
target-arm queue:
21
* sbsa-ref: remove cortex-a53 from list of supported cpus
15
* util/oslib-posix : qemu_init_exec_dir implementation for Mac
22
* sbsa-ref: add 'max' to list of allowed cpus
16
* target/arm: Last parts of neon decodetree conversion
23
* target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
17
* hw/arm/virt: Add 5.0 HW compat props
24
* npcm7xx: add EMC model
18
* hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status
25
* xlnx-zynqmp: Remove obsolete 'has_rpu' property
19
* mps2: Add CMSDK APB watchdog, FPGAIO block, S2I devices and I2C devices
26
* target/arm: Speed up aarch64 TBL/TBX
20
* mps2: Add some unimplemented-device stubs for audio and GPIO
27
* virtio-mmio: improve virtio-mmio get_dev_path alog
21
* mps2-tz: Use the ARM SBCon two-wire serial bus interface
28
* target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
22
* target/arm: Check supported KVM features globally (not per vCPU)
29
* target/arm: Restrict v8M IDAU to TCG
23
* tests/qtest/arm-cpu-features: Add feature setting tests
30
* target/arm/cpu: Update coding style to make checkpatch.pl happy
24
* arm/virt: Add memory hot remove support
31
* musicpal, tc6393xb, omap_lcdc, tcx: drop dead code for non-32-bit-RGB surfaces
32
* Add new board: mps3-an524
25
33
26
----------------------------------------------------------------
34
----------------------------------------------------------------
27
Andrew Jones (2):
35
Doug Evans (3):
28
hw/arm/virt: Add 5.0 HW compat props
36
hw/net: Add npcm7xx emc model
29
tests/qtest/arm-cpu-features: Add feature setting tests
37
hw/arm: Add npcm7xx emc model
38
tests/qtests: Add npcm7xx emc model test
30
39
31
David CARLIER (1):
40
Marcin Juszkiewicz (2):
32
util/oslib-posix : qemu_init_exec_dir implementation for Mac
41
sbsa-ref: remove cortex-a53 from list of supported cpus
42
sbsa-ref: add 'max' to list of allowed cpus
33
43
34
Peter Maydell (23):
44
Peter Collingbourne (1):
35
target/arm: Convert Neon 2-reg-misc VREV64 to decodetree
45
target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
36
target/arm: Convert Neon 2-reg-misc pairwise ops to decodetree
37
target/arm: Convert VZIP, VUZP to decodetree
38
target/arm: Convert Neon narrowing moves to decodetree
39
target/arm: Convert Neon 2-reg-misc VSHLL to decodetree
40
target/arm: Convert Neon VCVT f16/f32 insns to decodetree
41
target/arm: Convert vectorised 2-reg-misc Neon ops to decodetree
42
target/arm: Convert Neon 2-reg-misc crypto operations to decodetree
43
target/arm: Rename NeonGenOneOpFn to NeonGenOne64OpFn
44
target/arm: Fix capitalization in NeonGenTwo{Single, Double}OPFn typedefs
45
target/arm: Make gen_swap_half() take separate src and dest
46
target/arm: Convert Neon 2-reg-misc VREV32 and VREV16 to decodetree
47
target/arm: Convert remaining simple 2-reg-misc Neon ops
48
target/arm: Convert Neon VQABS, VQNEG to decodetree
49
target/arm: Convert simple fp Neon 2-reg-misc insns
50
target/arm: Convert Neon 2-reg-misc fp-compare-with-zero insns to decodetree
51
target/arm: Convert Neon 2-reg-misc VRINT insns to decodetree
52
target/arm: Convert Neon 2-reg-misc VCVT insns to decodetree
53
target/arm: Convert Neon VSWP to decodetree
54
target/arm: Convert Neon VTRN to decodetree
55
target/arm: Move some functions used only in translate-neon.inc.c to that file
56
target/arm: Remove unnecessary gen_io_end() calls
57
target/arm: Remove dead code relating to SABA and UABA
58
46
59
Philippe Mathieu-Daudé (15):
47
Peter Maydell (34):
60
hw/watchdog/cmsdk-apb-watchdog: Add trace event for lock status
48
hw/arm/musicpal: Remove dead code for non-32-bit-RGB surfaces
61
hw/i2c/versatile_i2c: Add definitions for register addresses
49
hw/display/tc6393xb: Remove dead code for handling non-32bpp surfaces
62
hw/i2c/versatile_i2c: Add SCL/SDA definitions
50
hw/display/tc6393xb: Expand out macros in template header
63
hw/i2c: Add header for ARM SBCon two-wire serial bus interface
51
hw/display/tc6393xb: Inline tc6393xb_draw_graphic32() at its callsite
64
hw/arm: Use TYPE_VERSATILE_I2C instead of hardcoded string
52
hw/display/omap_lcdc: Expand out macros in template header
65
hw/arm/mps2: Document CMSDK/FPGA APB subsystem sections
53
hw/display/omap_lcdc: Drop broken bigendian ifdef
66
hw/arm/mps2: Rename CMSDK AHB peripheral region
54
hw/display/omap_lcdc: Fix coding style issues in template header
67
hw/arm/mps2: Add CMSDK APB watchdog device
55
hw/display/omap_lcdc: Inline template header into C file
68
hw/arm/mps2: Add CMSDK AHB GPIO peripherals as unimplemented devices
56
hw/display/omap_lcdc: Delete unnecessary macro
69
hw/arm/mps2: Map the FPGA I/O block
57
hw/display/tcx: Drop unnecessary code for handling BGR format outputs
70
hw/arm/mps2: Add SPI devices
58
hw/arm/mps2-tz: Make SYSCLK frequency board-specific
71
hw/arm/mps2: Add I2C devices
59
hw/misc/mps2-scc: Support configurable number of OSCCLK values
72
hw/arm/mps2: Add audio I2S interface as unimplemented device
60
hw/arm/mps2-tz: Correct the OSCCLK settings for mps2-an505 and mps2-an511
73
hw/arm/mps2-tz: Use the ARM SBCon two-wire serial bus interface
61
hw/arm/mps2-tz: Make the OSCCLK settings be configurable per-board
74
target/arm: Check supported KVM features globally (not per vCPU)
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
75
82
76
Shameer Kolothum (1):
83
Philippe Mathieu-Daudé (4):
77
arm/virt: Add memory hot remove support
84
hw/arm/xlnx-zynqmp: Remove obsolete 'has_rpu' property
85
hw/i2c/npcm7xx_smbus: Simplify npcm7xx_smbus_init()
86
target/arm: Restrict v8M IDAU to TCG
87
target/arm/cpu: Update coding style to make checkpatch.pl happy
78
88
79
include/hw/i2c/arm_sbcon_i2c.h | 35 ++
89
Rebecca Cran (3):
80
target/arm/cpu.h | 2 +-
90
target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
81
target/arm/kvm_arm.h | 21 +-
91
target/arm: Enable FEAT_SSBS for "max" AARCH64 CPU
82
target/arm/translate.h | 8 +-
92
target/arm: Set ID_PFR2.SSBS to 1 for "max" 32-bit CPU
83
target/arm/neon-dp.decode | 106 ++++
84
hw/acpi/generic_event_device.c | 29 +
85
hw/arm/mps2-tz.c | 23 +-
86
hw/arm/mps2.c | 65 ++-
87
hw/arm/realview.c | 3 +-
88
hw/arm/versatilepb.c | 3 +-
89
hw/arm/vexpress.c | 3 +-
90
hw/arm/virt.c | 63 +-
91
hw/i2c/versatile_i2c.c | 38 +-
92
hw/watchdog/cmsdk-apb-watchdog.c | 1 +
93
target/arm/cpu.c | 2 +-
94
target/arm/cpu64.c | 10 +-
95
target/arm/kvm.c | 4 +-
96
target/arm/kvm64.c | 14 +-
97
target/arm/translate-a64.c | 20 +-
98
target/arm/translate-neon.inc.c | 1191 +++++++++++++++++++++++++++++++++++++-
99
target/arm/translate-vfp.inc.c | 7 +-
100
target/arm/translate.c | 1064 +---------------------------------
101
tests/qtest/arm-cpu-features.c | 38 +-
102
util/oslib-posix.c | 15 +
103
MAINTAINERS | 1 +
104
hw/arm/Kconfig | 8 +-
105
hw/watchdog/trace-events | 1 +
106
27 files changed, 1624 insertions(+), 1151 deletions(-)
107
create mode 100644 include/hw/i2c/arm_sbcon_i2c.h
108
93
94
Richard Henderson (1):
95
target/arm: Speed up aarch64 TBL/TBX
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: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
From 'Application Note AN385', chapter 3.14:
3
Cortex-A53 supports 40bits of address space. sbsa-ref's memory starts
4
above this limit.
4
5
5
The SMM implements a simple SBCon interface based on I2C.
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
6
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
There are 4 SBCon interfaces on the FPGA APB subsystem.
8
Acked-by: Leif Lindholm <leif@nuviainc.com>
8
9
Message-id: 20210216150122.3830863-2-marcin.juszkiewicz@linaro.org
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20200617072539.32686-13-f4bug@amsat.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
hw/arm/mps2.c | 8 ++++++++
12
hw/arm/sbsa-ref.c | 1 -
15
hw/arm/Kconfig | 1 +
13
1 file changed, 1 deletion(-)
16
2 files changed, 9 insertions(+)
17
14
18
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.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/hw/arm/mps2.c
17
--- a/hw/arm/sbsa-ref.c
21
+++ b/hw/arm/mps2.c
18
+++ b/hw/arm/sbsa-ref.c
22
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
23
#include "hw/misc/mps2-scc.h"
20
};
24
#include "hw/misc/mps2-fpgaio.h"
21
25
#include "hw/ssi/pl022.h"
22
static const char * const valid_cpus[] = {
26
+#include "hw/i2c/arm_sbcon_i2c.h"
23
- ARM_CPU_TYPE_NAME("cortex-a53"),
27
#include "hw/net/lan9118.h"
24
ARM_CPU_TYPE_NAME("cortex-a57"),
28
#include "net/net.h"
25
ARM_CPU_TYPE_NAME("cortex-a72"),
29
#include "hw/watchdog/cmsdk-apb-watchdog.h"
26
};
30
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
31
qdev_get_gpio_in(orgate_dev, j));
32
}
33
}
34
+ for (i = 0; i < 4; i++) {
35
+ static const hwaddr i2cbase[] = {0x40022000, /* Touch */
36
+ 0x40023000, /* Audio */
37
+ 0x40029000, /* Shield0 */
38
+ 0x4002a000}; /* Shield1 */
39
+ sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
40
+ }
41
42
/* In hardware this is a LAN9220; the LAN9118 is software compatible
43
* except that it doesn't support the checksum-offload feature.
44
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/arm/Kconfig
47
+++ b/hw/arm/Kconfig
48
@@ -XXX,XX +XXX,XX @@ config MPS2
49
select SPLIT_IRQ
50
select UNIMP
51
select CMSDK_APB_WATCHDOG
52
+ select VERSATILE_I2C
53
54
config FSL_IMX7
55
bool
56
--
27
--
57
2.20.1
28
2.20.1
58
29
59
30
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
Let add 'max' cpu while work goes on adding newer CPU types than
4
Message-id: 20200617072539.32686-14-f4bug@amsat.org
4
Cortex-A72. This allows us to check SVE etc support.
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
7
Acked-by: Leif Lindholm <leif@nuviainc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210216150122.3830863-3-marcin.juszkiewicz@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
hw/arm/mps2.c | 1 +
12
hw/arm/sbsa-ref.c | 1 +
9
1 file changed, 1 insertion(+)
13
1 file changed, 1 insertion(+)
10
14
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/mps2.c
17
--- a/hw/arm/sbsa-ref.c
14
+++ b/hw/arm/mps2.c
18
+++ b/hw/arm/sbsa-ref.c
15
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
16
0x4002a000}; /* Shield1 */
20
static const char * const valid_cpus[] = {
17
sysbus_create_simple(TYPE_ARM_SBCON_I2C, i2cbase[i], NULL);
21
ARM_CPU_TYPE_NAME("cortex-a57"),
18
}
22
ARM_CPU_TYPE_NAME("cortex-a72"),
19
+ create_unimplemented_device("i2s", 0x40024000, 0x400);
23
+ ARM_CPU_TYPE_NAME("max"),
20
24
};
21
/* In hardware this is a LAN9220; the LAN9118 is software compatible
25
22
* except that it doesn't support the checksum-offload feature.
26
static bool cpu_type_valid(const char *cpu)
23
--
27
--
24
2.20.1
28
2.20.1
25
29
26
30
diff view generated by jsdifflib
1
Since commit ba3e7926691ed3 it has been unnecessary for target code
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
to call gen_io_end() after an IO instruction in icount mode; it is
3
sufficient to call gen_io_start() before it and to force the end of
4
the TB.
5
2
6
Many now-unnecessary calls to gen_io_end() were removed in commit
3
Add support for FEAT_SSBS. SSBS (Speculative Store Bypass Safe) is an
7
9e9b10c6491153b, but some were missed or accidentally added later.
4
optional feature in ARMv8.0, and mandatory in ARMv8.5.
8
Remove unneeded calls from the arm target:
9
5
10
* the call in the handling of exception-return-via-LDM is
6
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
11
unnecessary, and the code is already forcing end-of-TB
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
* the call in the VFP access check code is more complicated:
8
Message-id: 20210216224543.16142-2-rebecca@nuviainc.com
13
we weren't ending the TB, so we need to add the code to
14
force that by setting DISAS_UPDATE
15
* the doc comment for ARM_CP_IO doesn't need to mention
16
gen_io_end() any more
17
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru>
22
Message-id: 20200619170324.12093-1-peter.maydell@linaro.org
23
---
10
---
24
target/arm/cpu.h | 2 +-
11
target/arm/cpu.h | 15 ++++++++++++++-
25
target/arm/translate-vfp.inc.c | 7 +++----
12
target/arm/internals.h | 6 ++++++
26
target/arm/translate.c | 3 ---
13
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++++++++
27
3 files changed, 4 insertions(+), 8 deletions(-)
14
target/arm/translate-a64.c | 12 ++++++++++++
15
4 files changed, 69 insertions(+), 1 deletion(-)
28
16
29
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
30
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/cpu.h
19
--- a/target/arm/cpu.h
32
+++ b/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
33
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
21
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
34
* migration or KVM state synchronization. (Typically this is for "registers"
22
#define SCTLR_TE (1U << 30) /* AArch32 only */
35
* which are actually used as instructions for cache maintenance and so on.)
23
#define SCTLR_EnIB (1U << 30) /* v8.3, AArch64 only */
36
* IO indicates that this register does I/O and therefore its accesses
24
#define SCTLR_EnIA (1U << 31) /* v8.3, AArch64 only */
37
- * need to be surrounded by gen_io_start()/gen_io_end(). In particular,
25
+#define SCTLR_DSSBS_32 (1U << 31) /* v8.5, AArch32 only */
38
+ * need to be marked with gen_io_start() and also end the TB. In particular,
26
#define SCTLR_BT0 (1ULL << 35) /* v8.5-BTI */
39
* registers which implement clocks or timers require this.
27
#define SCTLR_BT1 (1ULL << 36) /* v8.5-BTI */
40
* RAISES_EXC is for when the read or write hook might raise an exception;
28
#define SCTLR_ITFSB (1ULL << 37) /* v8.5-MemTag */
41
* the generated code will synchronize the CPU state before calling the hook
29
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
42
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
30
#define SCTLR_TCF (3ULL << 40) /* v8.5-MemTag */
31
#define SCTLR_ATA0 (1ULL << 42) /* v8.5-MemTag */
32
#define SCTLR_ATA (1ULL << 43) /* v8.5-MemTag */
33
-#define SCTLR_DSSBS (1ULL << 44) /* v8.5 */
34
+#define SCTLR_DSSBS_64 (1ULL << 44) /* v8.5, AArch64 only */
35
36
#define CPTR_TCPAC (1U << 31)
37
#define CPTR_TTA (1U << 20)
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;
56
}
57
58
+static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
59
+{
60
+ return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
61
+}
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
+}
74
+
75
/*
76
* Feature tests for "does this exist in either 32-bit or 64-bit?"
77
*/
78
diff --git a/target/arm/internals.h b/target/arm/internals.h
43
index XXXXXXX..XXXXXXX 100644
79
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/translate-vfp.inc.c
80
--- a/target/arm/internals.h
45
+++ b/target/arm/translate-vfp.inc.c
81
+++ b/target/arm/internals.h
46
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
82
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
47
if (s->v7m_lspact) {
83
if (isar_feature_aa32_dit(id)) {
48
/*
84
valid |= CPSR_DIT;
49
* Lazy state saving affects external memory and also the NVIC,
85
}
50
- * so we must mark it as an IO operation for icount.
86
+ if (isar_feature_aa32_ssbs(id)) {
51
+ * so we must mark it as an IO operation for icount (and cause
87
+ valid |= CPSR_SSBS;
52
+ * this to be the last insn in the TB).
88
+ }
53
*/
89
54
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
90
return valid;
55
+ s->base.is_jmp = DISAS_UPDATE;
91
}
56
gen_io_start();
92
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
57
}
93
if (isar_feature_aa64_dit(id)) {
58
gen_helper_v7m_preserve_fp_state(cpu_env);
94
valid |= PSTATE_DIT;
59
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
95
}
60
- gen_io_end();
96
+ if (isar_feature_aa64_ssbs(id)) {
61
- }
97
+ valid |= PSTATE_SSBS;
62
/*
98
+ }
63
* If the preserve_fp_state helper doesn't throw an exception
99
if (isar_feature_aa64_mte(id)) {
64
* then it will clear LSPACT; we don't need to repeat this for
100
valid |= PSTATE_TCO;
65
diff --git a/target/arm/translate.c b/target/arm/translate.c
101
}
102
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
103
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/translate.c
104
--- a/target/arm/helper.c
68
+++ b/target/arm/translate.c
105
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
106
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dit_reginfo = {
70
gen_io_start();
107
.readfn = aa64_dit_read, .writefn = aa64_dit_write
71
}
108
};
72
gen_helper_cpsr_write_eret(cpu_env, tmp);
109
73
- if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
110
+static uint64_t aa64_ssbs_read(CPUARMState *env, const ARMCPRegInfo *ri)
74
- gen_io_end();
111
+{
75
- }
112
+ return env->pstate & PSTATE_SSBS;
76
tcg_temp_free_i32(tmp);
113
+}
77
/* Must exit loop to check un-masked IRQs */
114
+
78
s->base.is_jmp = DISAS_EXIT;
115
+static void aa64_ssbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
116
+ uint64_t value)
117
+{
118
+ env->pstate = (env->pstate & ~PSTATE_SSBS) | (value & PSTATE_SSBS);
119
+}
120
+
121
+static const ARMCPRegInfo ssbs_reginfo = {
122
+ .name = "SSBS", .state = ARM_CP_STATE_AA64,
123
+ .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 6,
124
+ .type = ARM_CP_NO_RAW, .access = PL0_RW,
125
+ .readfn = aa64_ssbs_read, .writefn = aa64_ssbs_write
126
+};
127
+
128
static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
129
const ARMCPRegInfo *ri,
130
bool isread)
131
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
132
if (cpu_isar_feature(aa64_dit, cpu)) {
133
define_one_arm_cp_reg(cpu, &dit_reginfo);
134
}
135
+ if (cpu_isar_feature(aa64_ssbs, cpu)) {
136
+ define_one_arm_cp_reg(cpu, &ssbs_reginfo);
137
+ }
138
139
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
140
define_arm_cp_regs(cpu, vhe_reginfo);
141
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
142
env->uncached_cpsr &= ~(CPSR_IL | CPSR_J);
143
env->daif |= mask;
144
145
+ if (cpu_isar_feature(aa32_ssbs, env_archcpu(env))) {
146
+ if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_32) {
147
+ env->uncached_cpsr |= CPSR_SSBS;
148
+ } else {
149
+ env->uncached_cpsr &= ~CPSR_SSBS;
150
+ }
151
+ }
152
+
153
if (new_mode == ARM_CPU_MODE_HYP) {
154
env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0;
155
env->elr_el[2] = env->regs[15];
156
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
157
new_mode |= PSTATE_TCO;
158
}
159
160
+ if (cpu_isar_feature(aa64_ssbs, cpu)) {
161
+ if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_64) {
162
+ new_mode |= PSTATE_SSBS;
163
+ } else {
164
+ new_mode &= ~PSTATE_SSBS;
165
+ }
166
+ }
167
+
168
pstate_write(env, PSTATE_DAIF | new_mode);
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;
190
+
191
case 0x1a: /* DIT */
192
if (!dc_isar_feature(aa64_dit, s)) {
193
goto do_unallocated;
79
--
194
--
80
2.20.1
195
2.20.1
81
196
82
197
diff view generated by jsdifflib
New patch
1
From: Rebecca Cran <rebecca@nuviainc.com>
1
2
3
Set ID_AA64PFR1_EL1.SSBS to 2 and ID_PFR2.SSBS to 1.
4
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210216224543.16142-3-rebecca@nuviainc.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/cpu64.c | 5 +++++
11
1 file changed, 5 insertions(+)
12
13
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu64.c
16
+++ b/target/arm/cpu64.c
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
18
19
t = cpu->isar.id_aa64pfr1;
20
t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
21
+ t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2);
22
/*
23
* Begin with full support for MTE. This will be downgraded to MTE=0
24
* during realize if the board provides no tag memory, much like
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
26
u = FIELD_DP32(u, ID_PFR0, DIT, 1);
27
cpu->isar.id_pfr0 = u;
28
29
+ u = cpu->isar.id_pfr2;
30
+ u = FIELD_DP32(u, ID_PFR2, SSBS, 1);
31
+ cpu->isar.id_pfr2 = u;
32
+
33
u = cpu->isar.id_mmfr3;
34
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
35
cpu->isar.id_mmfr3 = u;
36
--
37
2.20.1
38
39
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Rebecca Cran <rebecca@nuviainc.com>
2
2
3
From 'Application Note AN385', chapter 3.9, SPI:
3
Enable FEAT_SSBS for the "max" 32-bit CPU.
4
4
5
The SMM implements five PL022 SPI modules.
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
6
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Two pairs of modules share the same OR-gated IRQ.
7
Message-id: 20210216224543.16142-4-rebecca@nuviainc.com
8
8
[PMM: fix typo causing compilation failure]
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20200617072539.32686-12-f4bug@amsat.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
10
---
14
hw/arm/mps2.c | 24 ++++++++++++++++++++++++
11
target/arm/cpu.c | 4 ++++
15
hw/arm/Kconfig | 6 +++---
12
1 file changed, 4 insertions(+)
16
2 files changed, 27 insertions(+), 3 deletions(-)
17
13
18
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/mps2.c
16
--- a/target/arm/cpu.c
21
+++ b/hw/arm/mps2.c
17
+++ b/target/arm/cpu.c
22
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
23
#include "hw/timer/cmsdk-apb-dualtimer.h"
19
t = cpu->isar.id_pfr0;
24
#include "hw/misc/mps2-scc.h"
20
t = FIELD_DP32(t, ID_PFR0, DIT, 1);
25
#include "hw/misc/mps2-fpgaio.h"
21
cpu->isar.id_pfr0 = t;
26
+#include "hw/ssi/pl022.h"
27
#include "hw/net/lan9118.h"
28
#include "net/net.h"
29
#include "hw/watchdog/cmsdk-apb-watchdog.h"
30
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
31
qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", 25000000);
32
sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
33
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0x40028000);
34
+ sysbus_create_simple(TYPE_PL022, 0x40025000, /* External ADC */
35
+ qdev_get_gpio_in(armv7m, 22));
36
+ for (i = 0; i < 2; i++) {
37
+ static const int spi_irqno[] = {11, 24};
38
+ static const hwaddr spibase[] = {0x40020000, /* APB */
39
+ 0x40021000, /* LCD */
40
+ 0x40026000, /* Shield0 */
41
+ 0x40027000}; /* Shield1 */
42
+ DeviceState *orgate_dev;
43
+ Object *orgate;
44
+ int j;
45
+
22
+
46
+ orgate = object_new(TYPE_OR_IRQ);
23
+ t = cpu->isar.id_pfr2;
47
+ object_property_set_int(orgate, 2, "num-lines", &error_fatal);
24
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
48
+ orgate_dev = DEVICE(orgate);
25
+ cpu->isar.id_pfr2 = t;
49
+ qdev_realize(orgate_dev, NULL, &error_fatal);
26
}
50
+ qdev_connect_gpio_out(orgate_dev, 0,
27
#endif
51
+ qdev_get_gpio_in(armv7m, spi_irqno[i]));
28
}
52
+ for (j = 0; j < 2; j++) {
53
+ sysbus_create_simple(TYPE_PL022, spibase[2 * i + j],
54
+ qdev_get_gpio_in(orgate_dev, j));
55
+ }
56
+ }
57
58
/* In hardware this is a LAN9220; the LAN9118 is software compatible
59
* except that it doesn't support the checksum-offload feature.
60
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/Kconfig
63
+++ b/hw/arm/Kconfig
64
@@ -XXX,XX +XXX,XX @@ config HIGHBANK
65
select ARM_TIMER # sp804
66
select ARM_V7M
67
select PL011 # UART
68
- select PL022 # Serial port
69
+ select PL022 # SPI
70
select PL031 # RTC
71
select PL061 # GPIO
72
select PL310 # cache controller
73
@@ -XXX,XX +XXX,XX @@ config STELLARIS
74
select CMSDK_APB_WATCHDOG
75
select I2C
76
select PL011 # UART
77
- select PL022 # Serial port
78
+ select PL022 # SPI
79
select PL061 # GPIO
80
select SSD0303 # OLED display
81
select SSD0323 # OLED display
82
@@ -XXX,XX +XXX,XX @@ config MPS2
83
select MPS2_FPGAIO
84
select MPS2_SCC
85
select OR_IRQ
86
- select PL022 # Serial port
87
+ select PL022 # SPI
88
select PL080 # DMA controller
89
select SPLIT_IRQ
90
select UNIMP
91
--
29
--
92
2.20.1
30
2.20.1
93
31
94
32
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Doug Evans <dje@google.com>
2
2
3
'ARM SBCon two-wire serial bus interface' is the official
3
This is a 10/100 ethernet device that has several features.
4
name describing the pair of registers used to bitbanging
4
Only the ones needed by the Linux driver have been implemented.
5
I2C in the Versatile boards.
5
See npcm7xx_emc.c for a list of unimplemented features.
6
6
7
Make the private VersatileI2CState structure as public
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
ArmSbconI2CState.
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
9
Add the TYPE_ARM_SBCON_I2C, alias to our current
9
Signed-off-by: Doug Evans <dje@google.com>
10
TYPE_VERSATILE_I2C model.
10
Message-id: 20210218212453.831406-2-dje@google.com
11
Rename the memory region description as 'arm_sbcon_i2c'.
12
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20200617072539.32686-5-f4bug@amsat.org
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
12
---
18
include/hw/i2c/arm_sbcon_i2c.h | 35 ++++++++++++++++++++++++++++++++++
13
include/hw/net/npcm7xx_emc.h | 286 ++++++++++++
19
hw/i2c/versatile_i2c.c | 17 +++++------------
14
hw/net/npcm7xx_emc.c | 857 +++++++++++++++++++++++++++++++++++
20
MAINTAINERS | 1 +
15
hw/net/meson.build | 1 +
21
3 files changed, 41 insertions(+), 12 deletions(-)
16
hw/net/trace-events | 17 +
22
create mode 100644 include/hw/i2c/arm_sbcon_i2c.h
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
23
20
24
diff --git a/include/hw/i2c/arm_sbcon_i2c.h b/include/hw/i2c/arm_sbcon_i2c.h
21
diff --git a/include/hw/net/npcm7xx_emc.h b/include/hw/net/npcm7xx_emc.h
25
new file mode 100644
22
new file mode 100644
26
index XXXXXXX..XXXXXXX
23
index XXXXXXX..XXXXXXX
27
--- /dev/null
24
--- /dev/null
28
+++ b/include/hw/i2c/arm_sbcon_i2c.h
25
+++ b/include/hw/net/npcm7xx_emc.h
29
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@
30
+/*
27
+/*
31
+ * ARM SBCon two-wire serial bus interface (I2C bitbang)
28
+ * Nuvoton NPCM7xx EMC Module
32
+ * a.k.a.
33
+ * ARM Versatile I2C controller
34
+ *
29
+ *
35
+ * Copyright (c) 2006-2007 CodeSourcery.
30
+ * Copyright 2020 Google LLC
36
+ * Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
37
+ * Copyright (C) 2020 Philippe Mathieu-Daudé <f4bug@amsat.org>
38
+ *
31
+ *
39
+ * SPDX-License-Identifier: GPL-2.0-or-later
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.
40
+ */
41
+ */
41
+#ifndef HW_I2C_ARM_SBCON_H
42
+
42
+#define HW_I2C_ARM_SBCON_H
43
+#ifndef NPCM7XX_EMC_H
43
+
44
+#define NPCM7XX_EMC_H
45
+
46
+#include "hw/irq.h"
44
+#include "hw/sysbus.h"
47
+#include "hw/sysbus.h"
45
+#include "hw/i2c/bitbang_i2c.h"
48
+#include "net/net.h"
46
+
49
+
47
+#define TYPE_VERSATILE_I2C "versatile_i2c"
50
+/* 32-bit register indices. */
48
+#define TYPE_ARM_SBCON_I2C TYPE_VERSATILE_I2C
51
+enum NPCM7xxPWMRegister {
49
+
52
+ /* Control registers. */
50
+#define ARM_SBCON_I2C(obj) \
53
+ REG_CAMCMR,
51
+ OBJECT_CHECK(ArmSbconI2CState, (obj), TYPE_ARM_SBCON_I2C)
54
+ REG_CAMEN,
52
+
55
+
53
+typedef struct ArmSbconI2CState {
56
+ /* There are 16 CAMn[ML] registers. */
57
+ REG_CAMM_BASE,
58
+ REG_CAML_BASE,
59
+ REG_CAMML_LAST = 0x21,
60
+
61
+ REG_TXDLSA = 0x22,
62
+ REG_RXDLSA,
63
+ REG_MCMDR,
64
+ REG_MIID,
65
+ REG_MIIDA,
66
+ REG_FFTCR,
67
+ REG_TSDR,
68
+ REG_RSDR,
69
+ REG_DMARFC,
70
+ REG_MIEN,
71
+
72
+ /* Status registers. */
73
+ REG_MISTA,
74
+ REG_MGSTA,
75
+ REG_MPCNT,
76
+ REG_MRPC,
77
+ REG_MRPCC,
78
+ REG_MREPC,
79
+ REG_DMARFS,
80
+ REG_CTXDSA,
81
+ REG_CTXBSA,
82
+ REG_CRXDSA,
83
+ REG_CRXBSA,
84
+
85
+ NPCM7XX_NUM_EMC_REGS,
86
+};
87
+
88
+/* REG_CAMCMR fields */
89
+/* Enable CAM Compare */
90
+#define REG_CAMCMR_ECMP (1 << 4)
91
+/* Complement CAM Compare */
92
+#define REG_CAMCMR_CCAM (1 << 3)
93
+/* Accept Broadcast Packet */
94
+#define REG_CAMCMR_ABP (1 << 2)
95
+/* Accept Multicast Packet */
96
+#define REG_CAMCMR_AMP (1 << 1)
97
+/* Accept Unicast Packet */
98
+#define REG_CAMCMR_AUP (1 << 0)
99
+
100
+/* REG_MCMDR fields */
101
+/* Software Reset */
102
+#define REG_MCMDR_SWR (1 << 24)
103
+/* Internal Loopback Select */
104
+#define REG_MCMDR_LBK (1 << 21)
105
+/* Operation Mode Select */
106
+#define REG_MCMDR_OPMOD (1 << 20)
107
+/* Enable MDC Clock Generation */
108
+#define REG_MCMDR_ENMDC (1 << 19)
109
+/* Full-Duplex Mode Select */
110
+#define REG_MCMDR_FDUP (1 << 18)
111
+/* Enable SQE Checking */
112
+#define REG_MCMDR_ENSEQ (1 << 17)
113
+/* Send PAUSE Frame */
114
+#define REG_MCMDR_SDPZ (1 << 16)
115
+/* No Defer */
116
+#define REG_MCMDR_NDEF (1 << 9)
117
+/* Frame Transmission On */
118
+#define REG_MCMDR_TXON (1 << 8)
119
+/* Strip CRC Checksum */
120
+#define REG_MCMDR_SPCRC (1 << 5)
121
+/* Accept CRC Error Packet */
122
+#define REG_MCMDR_AEP (1 << 4)
123
+/* Accept Control Packet */
124
+#define REG_MCMDR_ACP (1 << 3)
125
+/* Accept Runt Packet */
126
+#define REG_MCMDR_ARP (1 << 2)
127
+/* Accept Long Packet */
128
+#define REG_MCMDR_ALP (1 << 1)
129
+/* Frame Reception On */
130
+#define REG_MCMDR_RXON (1 << 0)
131
+
132
+/* REG_MIEN fields */
133
+/* Enable Transmit Descriptor Unavailable Interrupt */
134
+#define REG_MIEN_ENTDU (1 << 23)
135
+/* Enable Transmit Completion Interrupt */
136
+#define REG_MIEN_ENTXCP (1 << 18)
137
+/* Enable Transmit Interrupt */
138
+#define REG_MIEN_ENTXINTR (1 << 16)
139
+/* Enable Receive Descriptor Unavailable Interrupt */
140
+#define REG_MIEN_ENRDU (1 << 10)
141
+/* Enable Receive Good Interrupt */
142
+#define REG_MIEN_ENRXGD (1 << 4)
143
+/* Enable Receive Interrupt */
144
+#define REG_MIEN_ENRXINTR (1 << 0)
145
+
146
+/* REG_MISTA fields */
147
+/* TODO: Add error fields and support simulated errors? */
148
+/* Transmit Bus Error Interrupt */
149
+#define REG_MISTA_TXBERR (1 << 24)
150
+/* Transmit Descriptor Unavailable Interrupt */
151
+#define REG_MISTA_TDU (1 << 23)
152
+/* Transmit Completion Interrupt */
153
+#define REG_MISTA_TXCP (1 << 18)
154
+/* Transmit Interrupt */
155
+#define REG_MISTA_TXINTR (1 << 16)
156
+/* Receive Bus Error Interrupt */
157
+#define REG_MISTA_RXBERR (1 << 11)
158
+/* Receive Descriptor Unavailable Interrupt */
159
+#define REG_MISTA_RDU (1 << 10)
160
+/* DMA Early Notification Interrupt */
161
+#define REG_MISTA_DENI (1 << 9)
162
+/* Maximum Frame Length Interrupt */
163
+#define REG_MISTA_DFOI (1 << 8)
164
+/* Receive Good Interrupt */
165
+#define REG_MISTA_RXGD (1 << 4)
166
+/* Packet Too Long Interrupt */
167
+#define REG_MISTA_PTLE (1 << 3)
168
+/* Receive Interrupt */
169
+#define REG_MISTA_RXINTR (1 << 0)
170
+
171
+/* REG_MGSTA fields */
172
+/* Transmission Halted */
173
+#define REG_MGSTA_TXHA (1 << 11)
174
+/* Receive Halted */
175
+#define REG_MGSTA_RXHA (1 << 11)
176
+
177
+/* REG_DMARFC fields */
178
+/* Maximum Receive Frame Length */
179
+#define REG_DMARFC_RXMS(word) extract32((word), 0, 16)
180
+
181
+/* REG MIIDA fields */
182
+/* Busy Bit */
183
+#define REG_MIIDA_BUSY (1 << 17)
184
+
185
+/* Transmit and receive descriptors */
186
+typedef struct NPCM7xxEMCTxDesc NPCM7xxEMCTxDesc;
187
+typedef struct NPCM7xxEMCRxDesc NPCM7xxEMCRxDesc;
188
+
189
+struct NPCM7xxEMCTxDesc {
190
+ uint32_t flags;
191
+ uint32_t txbsa;
192
+ uint32_t status_and_length;
193
+ uint32_t ntxdsa;
194
+};
195
+
196
+struct NPCM7xxEMCRxDesc {
197
+ uint32_t status_and_length;
198
+ uint32_t rxbsa;
199
+ uint32_t reserved;
200
+ uint32_t nrxdsa;
201
+};
202
+
203
+/* NPCM7xxEMCTxDesc.flags values */
204
+/* Owner: 0 = cpu, 1 = emc */
205
+#define TX_DESC_FLAG_OWNER_MASK (1 << 31)
206
+/* Transmit interrupt enable */
207
+#define TX_DESC_FLAG_INTEN (1 << 2)
208
+/* CRC append */
209
+#define TX_DESC_FLAG_CRCAPP (1 << 1)
210
+/* Padding enable */
211
+#define TX_DESC_FLAG_PADEN (1 << 0)
212
+
213
+/* NPCM7xxEMCTxDesc.status_and_length values */
214
+/* Collision count */
215
+#define TX_DESC_STATUS_CCNT_SHIFT 28
216
+#define TX_DESC_STATUS_CCNT_BITSIZE 4
217
+/* SQE error */
218
+#define TX_DESC_STATUS_SQE (1 << 26)
219
+/* Transmission paused */
220
+#define TX_DESC_STATUS_PAU (1 << 25)
221
+/* P transmission halted */
222
+#define TX_DESC_STATUS_TXHA (1 << 24)
223
+/* Late collision */
224
+#define TX_DESC_STATUS_LC (1 << 23)
225
+/* Transmission abort */
226
+#define TX_DESC_STATUS_TXABT (1 << 22)
227
+/* No carrier sense */
228
+#define TX_DESC_STATUS_NCS (1 << 21)
229
+/* Defer exceed */
230
+#define TX_DESC_STATUS_EXDEF (1 << 20)
231
+/* Transmission complete */
232
+#define TX_DESC_STATUS_TXCP (1 << 19)
233
+/* Transmission deferred */
234
+#define TX_DESC_STATUS_DEF (1 << 17)
235
+/* Transmit interrupt */
236
+#define TX_DESC_STATUS_TXINTR (1 << 16)
237
+
238
+#define TX_DESC_PKT_LEN(word) extract32((word), 0, 16)
239
+
240
+/* Transmit buffer start address */
241
+#define TX_DESC_TXBSA(word) ((uint32_t) (word) & ~3u)
242
+
243
+/* Next transmit descriptor start address */
244
+#define TX_DESC_NTXDSA(word) ((uint32_t) (word) & ~3u)
245
+
246
+/* NPCM7xxEMCRxDesc.status_and_length values */
247
+/* Owner: 0b00 = cpu, 0b01 = undefined, 0b10 = emc, 0b11 = undefined */
248
+#define RX_DESC_STATUS_OWNER_SHIFT 30
249
+#define RX_DESC_STATUS_OWNER_BITSIZE 2
250
+#define RX_DESC_STATUS_OWNER_MASK (3 << RX_DESC_STATUS_OWNER_SHIFT)
251
+/* Runt packet */
252
+#define RX_DESC_STATUS_RP (1 << 22)
253
+/* Alignment error */
254
+#define RX_DESC_STATUS_ALIE (1 << 21)
255
+/* Frame reception complete */
256
+#define RX_DESC_STATUS_RXGD (1 << 20)
257
+/* Packet too long */
258
+#define RX_DESC_STATUS_PTLE (1 << 19)
259
+/* CRC error */
260
+#define RX_DESC_STATUS_CRCE (1 << 17)
261
+/* Receive interrupt */
262
+#define RX_DESC_STATUS_RXINTR (1 << 16)
263
+
264
+#define RX_DESC_PKT_LEN(word) extract32((word), 0, 16)
265
+
266
+/* Receive buffer start address */
267
+#define RX_DESC_RXBSA(word) ((uint32_t) (word) & ~3u)
268
+
269
+/* Next receive descriptor start address */
270
+#define RX_DESC_NRXDSA(word) ((uint32_t) (word) & ~3u)
271
+
272
+/* Minimum packet length, when TX_DESC_FLAG_PADEN is set. */
273
+#define MIN_PACKET_LENGTH 64
274
+
275
+struct NPCM7xxEMCState {
54
+ /*< private >*/
276
+ /*< private >*/
55
+ SysBusDevice parent_obj;
277
+ SysBusDevice parent;
56
+ /*< public >*/
278
+ /*< public >*/
57
+
279
+
58
+ MemoryRegion iomem;
280
+ MemoryRegion iomem;
59
+ bitbang_i2c_interface bitbang;
281
+
60
+ int out;
282
+ qemu_irq tx_irq;
61
+ int in;
283
+ qemu_irq rx_irq;
62
+} ArmSbconI2CState;
284
+
63
+
285
+ NICState *nic;
64
+#endif /* HW_I2C_ARM_SBCON_H */
286
+ NICConf conf;
65
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
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
+ }
760
+ default:
761
+ g_assert_not_reached();
762
+ }
763
+}
764
+
765
+static bool emc_receive_filter(NPCM7xxEMCState *emc, const uint8_t *buf,
766
+ size_t len)
767
+{
768
+ const char *fail_reason = NULL;
769
+ bool ok = emc_receive_filter1(emc, buf, len, &fail_reason);
770
+ if (!ok) {
771
+ trace_npcm7xx_emc_packet_filtered_out(fail_reason);
772
+ }
773
+ return ok;
774
+}
775
+
776
+static ssize_t emc_receive(NetClientState *nc, const uint8_t *buf, size_t len1)
777
+{
778
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(qemu_get_nic_opaque(nc));
779
+ const uint32_t len = len1;
780
+ size_t max_frame_len;
781
+ bool long_frame;
782
+ uint32_t desc_addr;
783
+ NPCM7xxEMCRxDesc rx_desc;
784
+ uint32_t crc;
785
+ uint8_t *crc_ptr;
786
+ uint32_t buf_addr;
787
+
788
+ trace_npcm7xx_emc_receiving_packet(len);
789
+
790
+ if (!emc_can_receive(nc)) {
791
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Unexpected packet\n", __func__);
792
+ return -1;
793
+ }
794
+
795
+ if (len < ETH_HLEN ||
796
+ /* Defensive programming: drop unsupportable large packets. */
797
+ len > 0xffff - CRC_LENGTH) {
798
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Dropped frame of %u bytes\n",
799
+ __func__, len);
800
+ return len;
801
+ }
802
+
803
+ /*
804
+ * DENI is set if EMC received the Length/Type field of the incoming
805
+ * packet, so it will be set regardless of what happens next.
806
+ */
807
+ emc_set_mista(emc, REG_MISTA_DENI);
808
+
809
+ if (!emc_receive_filter(emc, buf, len)) {
810
+ emc_update_rx_irq(emc);
811
+ return len;
812
+ }
813
+
814
+ /* Huge frames (> DMARFC) are dropped. */
815
+ max_frame_len = REG_DMARFC_RXMS(emc->regs[REG_DMARFC]);
816
+ if (len + CRC_LENGTH > max_frame_len) {
817
+ trace_npcm7xx_emc_packet_dropped(len);
818
+ emc_set_mista(emc, REG_MISTA_DFOI);
819
+ emc_update_rx_irq(emc);
820
+ return len;
821
+ }
822
+
823
+ /*
824
+ * Long Frames (> MAX_ETH_FRAME_SIZE) are also dropped, unless MCMDR.ALP
825
+ * is set.
826
+ */
827
+ long_frame = false;
828
+ if (len + CRC_LENGTH > MAX_ETH_FRAME_SIZE) {
829
+ if (emc->regs[REG_MCMDR] & REG_MCMDR_ALP) {
830
+ long_frame = true;
831
+ } else {
832
+ trace_npcm7xx_emc_packet_dropped(len);
833
+ emc_set_mista(emc, REG_MISTA_PTLE);
834
+ emc_update_rx_irq(emc);
835
+ return len;
836
+ }
837
+ }
838
+
839
+ desc_addr = RX_DESC_NRXDSA(emc->regs[REG_CRXDSA]);
840
+ if (emc_read_rx_desc(desc_addr, &rx_desc)) {
841
+ /* Error reading descriptor, already reported. */
842
+ emc_halt_rx(emc, REG_MISTA_RXBERR);
843
+ emc_update_rx_irq(emc);
844
+ return len;
845
+ }
846
+
847
+ /* Nothing we can do if we don't own the descriptor. */
848
+ if (!(rx_desc.status_and_length & RX_DESC_STATUS_OWNER_MASK)) {
849
+ trace_npcm7xx_emc_cpu_owned_desc(desc_addr);
850
+ emc_halt_rx(emc, REG_MISTA_RDU);
851
+ emc_update_rx_irq(emc);
852
+ return len;
853
+ }
854
+
855
+ crc = 0;
856
+ crc_ptr = (uint8_t *) &crc;
857
+ if (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC)) {
858
+ crc = cpu_to_be32(crc32(~0, buf, len));
859
+ }
860
+
861
+ /* Give the descriptor back regardless of what happens. */
862
+ rx_desc.status_and_length &= ~RX_DESC_STATUS_OWNER_MASK;
863
+
864
+ buf_addr = rx_desc.rxbsa;
865
+ emc->regs[REG_CRXBSA] = buf_addr;
866
+ if (dma_memory_write(&address_space_memory, buf_addr, buf, len) ||
867
+ (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC) &&
868
+ dma_memory_write(&address_space_memory, buf_addr + len, crc_ptr,
869
+ 4))) {
870
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Bus error writing packet\n",
871
+ __func__);
872
+ emc_set_mista(emc, REG_MISTA_RXBERR);
873
+ emc_set_next_rx_descriptor(emc, &rx_desc, desc_addr);
874
+ emc_update_rx_irq(emc);
875
+ trace_npcm7xx_emc_rx_done(emc->regs[REG_CRXDSA]);
876
+ return len;
877
+ }
878
+
879
+ trace_npcm7xx_emc_received_packet(len);
880
+
881
+ /* Note: We've already verified len+4 <= 0xffff. */
882
+ rx_desc.status_and_length = len;
883
+ if (!(emc->regs[REG_MCMDR] & REG_MCMDR_SPCRC)) {
884
+ rx_desc.status_and_length += 4;
885
+ }
886
+ rx_desc.status_and_length |= RX_DESC_STATUS_RXGD;
887
+ emc_set_mista(emc, REG_MISTA_RXGD);
888
+
889
+ if (emc->regs[REG_MISTA] & emc->regs[REG_MIEN] & REG_MISTA_RXINTR) {
890
+ rx_desc.status_and_length |= RX_DESC_STATUS_RXINTR;
891
+ }
892
+ if (long_frame) {
893
+ rx_desc.status_and_length |= RX_DESC_STATUS_PTLE;
894
+ }
895
+
896
+ emc_set_next_rx_descriptor(emc, &rx_desc, desc_addr);
897
+ emc_update_rx_irq(emc);
898
+ trace_npcm7xx_emc_rx_done(emc->regs[REG_CRXDSA]);
899
+ return len;
900
+}
901
+
902
+static void emc_try_receive_next_packet(NPCM7xxEMCState *emc)
903
+{
904
+ if (emc_can_receive(qemu_get_queue(emc->nic))) {
905
+ qemu_flush_queued_packets(qemu_get_queue(emc->nic));
906
+ }
907
+}
908
+
909
+static uint64_t npcm7xx_emc_read(void *opaque, hwaddr offset, unsigned size)
910
+{
911
+ NPCM7xxEMCState *emc = opaque;
912
+ uint32_t reg = offset / sizeof(uint32_t);
913
+ uint32_t result;
914
+
915
+ if (reg >= NPCM7XX_NUM_EMC_REGS) {
916
+ qemu_log_mask(LOG_GUEST_ERROR,
917
+ "%s: Invalid offset 0x%04" HWADDR_PRIx "\n",
918
+ __func__, offset);
919
+ return 0;
920
+ }
921
+
922
+ switch (reg) {
923
+ case REG_MIID:
924
+ /*
925
+ * We don't implement MII. For determinism, always return zero as
926
+ * writes record the last value written for debugging purposes.
927
+ */
928
+ qemu_log_mask(LOG_UNIMP, "%s: Read of MIID, returning 0\n", __func__);
929
+ result = 0;
930
+ break;
931
+ case REG_TSDR:
932
+ case REG_RSDR:
933
+ qemu_log_mask(LOG_GUEST_ERROR,
934
+ "%s: Read of write-only reg, %s/%d\n",
935
+ __func__, emc_reg_name(reg), reg);
936
+ return 0;
937
+ default:
938
+ result = emc->regs[reg];
939
+ break;
940
+ }
941
+
942
+ trace_npcm7xx_emc_reg_read(emc->emc_num, result, emc_reg_name(reg), reg);
943
+ return result;
944
+}
945
+
946
+static void npcm7xx_emc_write(void *opaque, hwaddr offset,
947
+ uint64_t v, unsigned size)
948
+{
949
+ NPCM7xxEMCState *emc = opaque;
950
+ uint32_t reg = offset / sizeof(uint32_t);
951
+ uint32_t value = v;
952
+
953
+ g_assert(size == sizeof(uint32_t));
954
+
955
+ if (reg >= NPCM7XX_NUM_EMC_REGS) {
956
+ qemu_log_mask(LOG_GUEST_ERROR,
957
+ "%s: Invalid offset 0x%04" HWADDR_PRIx "\n",
958
+ __func__, offset);
959
+ return;
960
+ }
961
+
962
+ trace_npcm7xx_emc_reg_write(emc->emc_num, emc_reg_name(reg), reg, value);
963
+
964
+ switch (reg) {
965
+ case REG_CAMCMR:
966
+ emc->regs[reg] = value;
967
+ break;
968
+ case REG_CAMEN:
969
+ /* Only CAM0 is supported, don't pretend otherwise. */
970
+ if (value & ~1) {
971
+ qemu_log_mask(LOG_GUEST_ERROR,
972
+ "%s: Only CAM0 is supported, cannot enable others"
973
+ ": 0x%x\n",
974
+ __func__, value);
975
+ }
976
+ emc->regs[reg] = value & 1;
977
+ break;
978
+ case REG_CAMM_BASE + 0:
979
+ emc->regs[reg] = value;
980
+ emc->conf.macaddr.a[0] = value >> 24;
981
+ emc->conf.macaddr.a[1] = value >> 16;
982
+ emc->conf.macaddr.a[2] = value >> 8;
983
+ emc->conf.macaddr.a[3] = value >> 0;
984
+ break;
985
+ case REG_CAML_BASE + 0:
986
+ emc->regs[reg] = value;
987
+ emc->conf.macaddr.a[4] = value >> 24;
988
+ emc->conf.macaddr.a[5] = value >> 16;
989
+ break;
990
+ case REG_MCMDR: {
991
+ uint32_t prev;
992
+ if (value & REG_MCMDR_SWR) {
993
+ emc_soft_reset(emc);
994
+ /* On h/w the reset happens over multiple cycles. For now KISS. */
995
+ break;
996
+ }
997
+ prev = emc->regs[reg];
998
+ emc->regs[reg] = value;
999
+ /* Update tx state. */
1000
+ if (!(prev & REG_MCMDR_TXON) &&
1001
+ (value & REG_MCMDR_TXON)) {
1002
+ emc->regs[REG_CTXDSA] = emc->regs[REG_TXDLSA];
1003
+ /*
1004
+ * Linux kernel turns TX on with CPU still holding descriptor,
1005
+ * which suggests we should wait for a write to TSDR before trying
1006
+ * to send a packet: so we don't send one here.
1007
+ */
1008
+ } else if ((prev & REG_MCMDR_TXON) &&
1009
+ !(value & REG_MCMDR_TXON)) {
1010
+ emc->regs[REG_MGSTA] |= REG_MGSTA_TXHA;
1011
+ }
1012
+ if (!(value & REG_MCMDR_TXON)) {
1013
+ emc_halt_tx(emc, 0);
1014
+ }
1015
+ /* Update rx state. */
1016
+ if (!(prev & REG_MCMDR_RXON) &&
1017
+ (value & REG_MCMDR_RXON)) {
1018
+ emc->regs[REG_CRXDSA] = emc->regs[REG_RXDLSA];
1019
+ } else if ((prev & REG_MCMDR_RXON) &&
1020
+ !(value & REG_MCMDR_RXON)) {
1021
+ emc->regs[REG_MGSTA] |= REG_MGSTA_RXHA;
1022
+ }
1023
+ if (!(value & REG_MCMDR_RXON)) {
1024
+ emc_halt_rx(emc, 0);
1025
+ }
1026
+ break;
1027
+ }
1028
+ case REG_TXDLSA:
1029
+ case REG_RXDLSA:
1030
+ case REG_DMARFC:
1031
+ case REG_MIID:
1032
+ emc->regs[reg] = value;
1033
+ break;
1034
+ case REG_MIEN:
1035
+ emc->regs[reg] = value;
1036
+ emc_update_irq_from_reg_change(emc);
1037
+ break;
1038
+ case REG_MISTA:
1039
+ /* Clear the bits that have 1 in "value". */
1040
+ emc->regs[reg] &= ~value;
1041
+ emc_update_irq_from_reg_change(emc);
1042
+ break;
1043
+ case REG_MGSTA:
1044
+ /* Clear the bits that have 1 in "value". */
1045
+ emc->regs[reg] &= ~value;
1046
+ break;
1047
+ case REG_TSDR:
1048
+ if (emc->regs[REG_MCMDR] & REG_MCMDR_TXON) {
1049
+ emc->tx_active = true;
1050
+ /* Keep trying to send packets until we run out. */
1051
+ while (emc->tx_active) {
1052
+ emc_try_send_next_packet(emc);
1053
+ }
1054
+ }
1055
+ break;
1056
+ case REG_RSDR:
1057
+ if (emc->regs[REG_MCMDR] & REG_MCMDR_RXON) {
1058
+ emc->rx_active = true;
1059
+ emc_try_receive_next_packet(emc);
1060
+ }
1061
+ break;
1062
+ case REG_MIIDA:
1063
+ emc->regs[reg] = value & ~REG_MIIDA_BUSY;
1064
+ break;
1065
+ case REG_MRPC:
1066
+ case REG_MRPCC:
1067
+ case REG_MREPC:
1068
+ case REG_CTXDSA:
1069
+ case REG_CTXBSA:
1070
+ case REG_CRXDSA:
1071
+ case REG_CRXBSA:
1072
+ qemu_log_mask(LOG_GUEST_ERROR,
1073
+ "%s: Write to read-only reg %s/%d\n",
1074
+ __func__, emc_reg_name(reg), reg);
1075
+ break;
1076
+ default:
1077
+ qemu_log_mask(LOG_UNIMP, "%s: Write to unimplemented reg %s/%d\n",
1078
+ __func__, emc_reg_name(reg), reg);
1079
+ break;
1080
+ }
1081
+}
1082
+
1083
+static const struct MemoryRegionOps npcm7xx_emc_ops = {
1084
+ .read = npcm7xx_emc_read,
1085
+ .write = npcm7xx_emc_write,
1086
+ .endianness = DEVICE_LITTLE_ENDIAN,
1087
+ .valid = {
1088
+ .min_access_size = 4,
1089
+ .max_access_size = 4,
1090
+ .unaligned = false,
1091
+ },
1092
+};
1093
+
1094
+static void emc_cleanup(NetClientState *nc)
1095
+{
1096
+ /* Nothing to do yet. */
1097
+}
1098
+
1099
+static NetClientInfo net_npcm7xx_emc_info = {
1100
+ .type = NET_CLIENT_DRIVER_NIC,
1101
+ .size = sizeof(NICState),
1102
+ .can_receive = emc_can_receive,
1103
+ .receive = emc_receive,
1104
+ .cleanup = emc_cleanup,
1105
+ .link_status_changed = emc_set_link,
1106
+};
1107
+
1108
+static void npcm7xx_emc_realize(DeviceState *dev, Error **errp)
1109
+{
1110
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);
1111
+ SysBusDevice *sbd = SYS_BUS_DEVICE(emc);
1112
+
1113
+ memory_region_init_io(&emc->iomem, OBJECT(emc), &npcm7xx_emc_ops, emc,
1114
+ TYPE_NPCM7XX_EMC, 4 * KiB);
1115
+ sysbus_init_mmio(sbd, &emc->iomem);
1116
+ sysbus_init_irq(sbd, &emc->tx_irq);
1117
+ sysbus_init_irq(sbd, &emc->rx_irq);
1118
+
1119
+ qemu_macaddr_default_if_unset(&emc->conf.macaddr);
1120
+ emc->nic = qemu_new_nic(&net_npcm7xx_emc_info, &emc->conf,
1121
+ object_get_typename(OBJECT(dev)), dev->id, emc);
1122
+ qemu_format_nic_info_str(qemu_get_queue(emc->nic), emc->conf.macaddr.a);
1123
+}
1124
+
1125
+static void npcm7xx_emc_unrealize(DeviceState *dev)
1126
+{
1127
+ NPCM7xxEMCState *emc = NPCM7XX_EMC(dev);
1128
+
1129
+ qemu_del_nic(emc->nic);
1130
+}
1131
+
1132
+static const VMStateDescription vmstate_npcm7xx_emc = {
1133
+ .name = TYPE_NPCM7XX_EMC,
1134
+ .version_id = 0,
1135
+ .minimum_version_id = 0,
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
66
index XXXXXXX..XXXXXXX 100644
1177
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/i2c/versatile_i2c.c
1178
--- a/hw/net/meson.build
68
+++ b/hw/i2c/versatile_i2c.c
1179
+++ b/hw/net/meson.build
69
@@ -XXX,XX +XXX,XX @@
1180
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_I82596_COMMON', if_true: files('i82596.c'))
70
/*
1181
softmmu_ss.add(when: 'CONFIG_SUNHME', if_true: files('sunhme.c'))
71
- * ARM Versatile I2C controller
1182
softmmu_ss.add(when: 'CONFIG_FTGMAC100', if_true: files('ftgmac100.c'))
72
+ * ARM SBCon two-wire serial bus interface (I2C bitbang)
1183
softmmu_ss.add(when: 'CONFIG_SUNGEM', if_true: files('sungem.c'))
73
+ * a.k.a. ARM Versatile I2C controller
1184
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c'))
74
*
1185
75
* Copyright (c) 2006-2007 CodeSourcery.
1186
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c'))
76
* Copyright (c) 2012 Oskar Andero <oskar.andero@gmail.com>
1187
softmmu_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
77
@@ -XXX,XX +XXX,XX @@
1188
diff --git a/hw/net/trace-events b/hw/net/trace-events
78
*/
79
80
#include "qemu/osdep.h"
81
-#include "hw/sysbus.h"
82
-#include "hw/i2c/bitbang_i2c.h"
83
+#include "hw/i2c/arm_sbcon_i2c.h"
84
#include "hw/registerfields.h"
85
#include "qemu/log.h"
86
#include "qemu/module.h"
87
88
-#define TYPE_VERSATILE_I2C "versatile_i2c"
89
#define VERSATILE_I2C(obj) \
90
OBJECT_CHECK(VersatileI2CState, (obj), TYPE_VERSATILE_I2C)
91
92
-typedef struct VersatileI2CState {
93
- SysBusDevice parent_obj;
94
+typedef ArmSbconI2CState VersatileI2CState;
95
96
- MemoryRegion iomem;
97
- bitbang_i2c_interface bitbang;
98
- int out;
99
- int in;
100
-} VersatileI2CState;
101
102
REG32(CONTROL_GET, 0)
103
REG32(CONTROL_SET, 0)
104
@@ -XXX,XX +XXX,XX @@ static void versatile_i2c_init(Object *obj)
105
bus = i2c_init_bus(dev, "i2c");
106
bitbang_i2c_init(&s->bitbang, bus);
107
memory_region_init_io(&s->iomem, obj, &versatile_i2c_ops, s,
108
- "versatile_i2c", 0x1000);
109
+ "arm_sbcon_i2c", 0x1000);
110
sysbus_init_mmio(sbd, &s->iomem);
111
}
112
113
diff --git a/MAINTAINERS b/MAINTAINERS
114
index XXXXXXX..XXXXXXX 100644
1189
index XXXXXXX..XXXXXXX 100644
115
--- a/MAINTAINERS
1190
--- a/hw/net/trace-events
116
+++ b/MAINTAINERS
1191
+++ b/hw/net/trace-events
117
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
1192
@@ -XXX,XX +XXX,XX @@ imx_fec_receive_last(int last) "rx frame flags 0x%04x"
118
L: qemu-arm@nongnu.org
1193
imx_enet_receive(size_t size) "len %zu"
119
S: Maintained
1194
imx_enet_receive_len(uint64_t addr, int len) "rx_bd 0x%"PRIx64" length %d"
120
F: hw/*/versatile*
1195
imx_enet_receive_last(int last) "rx frame flags 0x%04x"
121
+F: include/hw/i2c/arm_sbcon_i2c.h
1196
+
122
F: hw/misc/arm_sysctl.c
1197
+# npcm7xx_emc.c
123
F: docs/system/arm/versatile.rst
1198
+npcm7xx_emc_reset(int emc_num) "Resetting emc%d"
124
1199
+npcm7xx_emc_update_tx_irq(int level) "Setting tx irq to %d"
1200
+npcm7xx_emc_update_rx_irq(int level) "Setting rx irq to %d"
1201
+npcm7xx_emc_set_mista(uint32_t flags) "ORing 0x%x into MISTA"
1202
+npcm7xx_emc_cpu_owned_desc(uint32_t addr) "Can't process cpu-owned descriptor @0x%x"
1203
+npcm7xx_emc_sent_packet(uint32_t len) "Sent %u byte packet"
1204
+npcm7xx_emc_tx_done(uint32_t ctxdsa) "TX done, CTXDSA=0x%x"
1205
+npcm7xx_emc_can_receive(int can_receive) "Can receive: %d"
1206
+npcm7xx_emc_packet_filtered_out(const char* fail_reason) "Packet filtered out: %s"
1207
+npcm7xx_emc_packet_dropped(uint32_t len) "%u byte packet dropped"
1208
+npcm7xx_emc_receiving_packet(uint32_t len) "Receiving %u byte packet"
1209
+npcm7xx_emc_received_packet(uint32_t len) "Received %u byte packet"
1210
+npcm7xx_emc_rx_done(uint32_t crxdsa) "RX done, CRXDSA=0x%x"
1211
+npcm7xx_emc_reg_read(int emc_num, uint32_t result, const char *name, int regno) "emc%d: 0x%x = reg[%s/%d]"
1212
+npcm7xx_emc_reg_write(int emc_num, const char *name, int regno, uint32_t value) "emc%d: reg[%s/%d] = 0x%x"
125
--
1213
--
126
2.20.1
1214
2.20.1
127
1215
128
1216
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Doug Evans <dje@google.com>
2
2
3
Use self-explicit definitions instead of magic values.
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.
4
6
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
6
Message-id: 20200617072539.32686-4-f4bug@amsat.org
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Doug Evans <dje@google.com>
11
Message-id: 20210218212453.831406-3-dje@google.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
hw/i2c/versatile_i2c.c | 7 +++++--
14
docs/system/arm/nuvoton.rst | 3 ++-
11
1 file changed, 5 insertions(+), 2 deletions(-)
15
include/hw/arm/npcm7xx.h | 2 ++
16
hw/arm/npcm7xx.c | 50 +++++++++++++++++++++++++++++++++++--
17
3 files changed, 52 insertions(+), 3 deletions(-)
12
18
13
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
19
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/i2c/versatile_i2c.c
21
--- a/docs/system/arm/nuvoton.rst
16
+++ b/hw/i2c/versatile_i2c.c
22
+++ b/docs/system/arm/nuvoton.rst
17
@@ -XXX,XX +XXX,XX @@ REG32(CONTROL_GET, 0)
23
@@ -XXX,XX +XXX,XX @@ Supported devices
18
REG32(CONTROL_SET, 0)
24
* Analog to Digital Converter (ADC)
19
REG32(CONTROL_CLR, 4)
25
* Pulse Width Modulation (PWM)
20
26
* SMBus controller (SMBF)
21
+#define SCL BIT(0)
27
+ * Ethernet controller (EMC)
22
+#define SDA BIT(1)
28
29
Missing devices
30
---------------
31
@@ -XXX,XX +XXX,XX @@ Missing devices
32
* Shared memory (SHM)
33
* eSPI slave interface
34
35
- * Ethernet controllers (GMAC and EMC)
36
+ * Ethernet controller (GMAC)
37
* USB device (USBD)
38
* Peripheral SPI controller (PSPI)
39
* SD/MMC host
40
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/include/hw/arm/npcm7xx.h
43
+++ b/include/hw/arm/npcm7xx.h
44
@@ -XXX,XX +XXX,XX @@
45
#include "hw/misc/npcm7xx_gcr.h"
46
#include "hw/misc/npcm7xx_pwm.h"
47
#include "hw/misc/npcm7xx_rng.h"
48
+#include "hw/net/npcm7xx_emc.h"
49
#include "hw/nvram/npcm7xx_otp.h"
50
#include "hw/timer/npcm7xx_timer.h"
51
#include "hw/ssi/npcm7xx_fiu.h"
52
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
53
EHCISysBusState ehci;
54
OHCISysBusState ohci;
55
NPCM7xxFIUState fiu[2];
56
+ NPCM7xxEMCState emc[2];
57
} NPCM7xxState;
58
59
#define TYPE_NPCM7XX "npcm7xx"
60
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/npcm7xx.c
63
+++ b/hw/arm/npcm7xx.c
64
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
65
NPCM7XX_UART1_IRQ,
66
NPCM7XX_UART2_IRQ,
67
NPCM7XX_UART3_IRQ,
68
+ NPCM7XX_EMC1RX_IRQ = 15,
69
+ NPCM7XX_EMC1TX_IRQ,
70
NPCM7XX_TIMER0_IRQ = 32, /* Timer Module 0 */
71
NPCM7XX_TIMER1_IRQ,
72
NPCM7XX_TIMER2_IRQ,
73
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
74
NPCM7XX_SMBUS15_IRQ,
75
NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
76
NPCM7XX_PWM1_IRQ, /* PWM module 1 */
77
+ NPCM7XX_EMC2RX_IRQ = 114,
78
+ NPCM7XX_EMC2TX_IRQ,
79
NPCM7XX_GPIO0_IRQ = 116,
80
NPCM7XX_GPIO1_IRQ,
81
NPCM7XX_GPIO2_IRQ,
82
@@ -XXX,XX +XXX,XX @@ static const hwaddr npcm7xx_smbus_addr[] = {
83
0xf008f000,
84
};
85
86
+/* Register base address for each EMC Module */
87
+static const hwaddr npcm7xx_emc_addr[] = {
88
+ 0xf0825000,
89
+ 0xf0826000,
90
+};
23
+
91
+
24
static uint64_t versatile_i2c_read(void *opaque, hwaddr offset,
92
static const struct {
25
unsigned size)
93
hwaddr regs_addr;
26
{
94
uint32_t unconnected_pins;
27
@@ -XXX,XX +XXX,XX @@ static void versatile_i2c_write(void *opaque, hwaddr offset,
95
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
28
qemu_log_mask(LOG_GUEST_ERROR,
96
for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
29
"%s: Bad offset 0x%x\n", __func__, (int)offset);
97
object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
30
}
98
}
31
- bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SCL, (s->out & 1) != 0);
99
+
32
- s->in = bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SDA, (s->out & 2) != 0);
100
+ for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
33
+ bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SCL, (s->out & SCL) != 0);
101
+ object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
34
+ s->in = bitbang_i2c_set(&s->bitbang, BITBANG_I2C_SDA, (s->out & SDA) != 0);
102
+ }
35
}
103
}
36
104
37
static const MemoryRegionOps versatile_i2c_ops = {
105
static void npcm7xx_realize(DeviceState *dev, Error **errp)
106
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
107
sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
108
}
109
110
+ /*
111
+ * EMC Modules. Cannot fail.
112
+ * The mapping of the device to its netdev backend works as follows:
113
+ * emc[i] = nd_table[i]
114
+ * This works around the inability to specify the netdev property for the
115
+ * emc device: it's not pluggable and thus the -device option can't be
116
+ * used.
117
+ */
118
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_emc_addr) != ARRAY_SIZE(s->emc));
119
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->emc) != 2);
120
+ for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
121
+ s->emc[i].emc_num = i;
122
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->emc[i]);
123
+ if (nd_table[i].used) {
124
+ qemu_check_nic_model(&nd_table[i], TYPE_NPCM7XX_EMC);
125
+ qdev_set_nic_properties(DEVICE(sbd), &nd_table[i]);
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));
142
+ }
143
+
144
/*
145
* Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
146
* specified, but this is a programming error.
147
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
148
create_unimplemented_device("npcm7xx.vcd", 0xf0810000, 64 * KiB);
149
create_unimplemented_device("npcm7xx.ece", 0xf0820000, 8 * KiB);
150
create_unimplemented_device("npcm7xx.vdma", 0xf0822000, 8 * KiB);
151
- create_unimplemented_device("npcm7xx.emc1", 0xf0825000, 4 * KiB);
152
- create_unimplemented_device("npcm7xx.emc2", 0xf0826000, 4 * KiB);
153
create_unimplemented_device("npcm7xx.usbd[0]", 0xf0830000, 4 * KiB);
154
create_unimplemented_device("npcm7xx.usbd[1]", 0xf0831000, 4 * KiB);
155
create_unimplemented_device("npcm7xx.usbd[2]", 0xf0832000, 4 * KiB);
38
--
156
--
39
2.20.1
157
2.20.1
40
158
41
159
diff view generated by jsdifflib
1
From: David CARLIER <devnexen@gmail.com>
1
From: Doug Evans <dje@google.com>
2
2
3
From 3025a0ce3fdf7d3559fc35a52c659f635f5c750c Mon Sep 17 00:00:00 2001
3
Reviewed-by: Hao Wu <wuhaotsh@google.com>
4
From: David Carlier <devnexen@gmail.com>
4
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
5
Date: Tue, 26 May 2020 21:35:27 +0100
6
Subject: [PATCH] util/oslib-posix : qemu_init_exec_dir implementation for Mac
7
8
Using dyld API to get the full path of the current process.
9
10
Signed-off-by: David Carlier <devnexen@gmail.com>
11
Message-id: CA+XhMqxwC10XHVs4Z-JfE0-WLAU3ztDuU9QKVi31mjr59HWCxg@mail.gmail.com
12
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
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
9
---
15
util/oslib-posix.c | 15 +++++++++++++++
10
tests/qtest/npcm7xx_emc-test.c | 862 +++++++++++++++++++++++++++++++++
16
1 file changed, 15 insertions(+)
11
tests/qtest/meson.build | 3 +-
12
2 files changed, 864 insertions(+), 1 deletion(-)
13
create mode 100644 tests/qtest/npcm7xx_emc-test.c
17
14
18
diff --git a/util/oslib-posix.c b/util/oslib-posix.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
19
index XXXXXXX..XXXXXXX 100644
884
index XXXXXXX..XXXXXXX 100644
20
--- a/util/oslib-posix.c
885
--- a/tests/qtest/meson.build
21
+++ b/util/oslib-posix.c
886
+++ b/tests/qtest/meson.build
22
@@ -XXX,XX +XXX,XX @@
887
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
23
#include <lwp.h>
888
'npcm7xx_rng-test',
24
#endif
889
'npcm7xx_smbus-test',
25
890
'npcm7xx_timer-test',
26
+#ifdef __APPLE__
891
- 'npcm7xx_watchdog_timer-test']
27
+#include <mach-o/dyld.h>
892
+ 'npcm7xx_watchdog_timer-test'] + \
28
+#endif
893
+ (slirp.found() ? ['npcm7xx_emc-test'] : [])
29
+
894
qtests_arm = \
30
#include "qemu/mmap-alloc.h"
895
(config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
31
896
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
32
#ifdef CONFIG_DEBUG_STACK_USAGE
33
@@ -XXX,XX +XXX,XX @@ void qemu_init_exec_dir(const char *argv0)
34
p = buf;
35
}
36
}
37
+#elif defined(__APPLE__)
38
+ {
39
+ char fpath[PATH_MAX];
40
+ uint32_t len = sizeof(fpath);
41
+ if (_NSGetExecutablePath(fpath, &len) == 0) {
42
+ p = realpath(fpath, buf);
43
+ if (!p) {
44
+ return;
45
+ }
46
+ }
47
+ }
48
#endif
49
/* If we don't have any way of figuring out the actual executable
50
location then try argv[0]. */
51
--
897
--
52
2.20.1
898
2.20.1
53
899
54
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
To differenciate with the CMSDK APB peripheral region,
3
We hint the 'has_rpu' property is no longer required since commit
4
rename this region 'CMSDK AHB peripheral region'.
4
6908ec448b4 ("xlnx-zynqmp: Properly support the smp command line
5
option") which was released in QEMU v2.11.0.
6
7
Beside, this device is marked 'user_creatable = false', so the
8
only thing that could be setting the property is the board code
9
that creates the device.
10
11
Since the property is not user-facing, we can remove it without
12
going through the deprecation process.
5
13
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20200617072539.32686-8-f4bug@amsat.org
16
Message-id: 20210219144350.1979905-1-f4bug@amsat.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
18
---
11
hw/arm/mps2.c | 3 ++-
19
include/hw/arm/xlnx-zynqmp.h | 2 --
12
1 file changed, 2 insertions(+), 1 deletion(-)
20
hw/arm/xlnx-zynqmp.c | 6 ------
21
2 files changed, 8 deletions(-)
13
22
14
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
23
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
15
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/mps2.c
25
--- a/include/hw/arm/xlnx-zynqmp.h
17
+++ b/hw/arm/mps2.c
26
+++ b/include/hw/arm/xlnx-zynqmp.h
18
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
27
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
19
*/
28
bool secure;
20
create_unimplemented_device("CMSDK APB peripheral region @0x40000000",
29
/* Has the ARM Virtualization extensions? */
21
0x40000000, 0x00010000);
30
bool virt;
22
- create_unimplemented_device("CMSDK peripheral region @0x40010000",
31
- /* Has the RPU subsystem? */
23
+ create_unimplemented_device("CMSDK AHB peripheral region @0x40010000",
32
- bool has_rpu;
24
0x40010000, 0x00010000);
33
25
create_unimplemented_device("Extra peripheral region @0x40020000",
34
/* CAN bus. */
26
0x40020000, 0x00010000);
35
CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
27
+
36
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
28
create_unimplemented_device("RESERVED 4", 0x40030000, 0x001D0000);
37
index XXXXXXX..XXXXXXX 100644
29
create_unimplemented_device("VGA", 0x41000000, 0x0200000);
38
--- a/hw/arm/xlnx-zynqmp.c
30
39
+++ b/hw/arm/xlnx-zynqmp.c
40
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
41
}
42
}
43
44
- if (s->has_rpu) {
45
- info_report("The 'has_rpu' property is no longer required, to use the "
46
- "RPUs just use -smp 6.");
47
- }
48
-
49
xlnx_zynqmp_create_rpu(ms, s, boot_cpu, &err);
50
if (err) {
51
error_propagate(errp, err);
52
@@ -XXX,XX +XXX,XX @@ static Property xlnx_zynqmp_props[] = {
53
DEFINE_PROP_STRING("boot-cpu", XlnxZynqMPState, boot_cpu),
54
DEFINE_PROP_BOOL("secure", XlnxZynqMPState, secure, false),
55
DEFINE_PROP_BOOL("virtualization", XlnxZynqMPState, virt, false),
56
- DEFINE_PROP_BOOL("has_rpu", XlnxZynqMPState, has_rpu, false),
57
DEFINE_PROP_LINK("ddr-ram", XlnxZynqMPState, ddr_ram, TYPE_MEMORY_REGION,
58
MemoryRegion *),
59
DEFINE_PROP_LINK("canbus0", XlnxZynqMPState, canbus[0], TYPE_CAN_BUS,
31
--
60
--
32
2.20.1
61
2.20.1
33
62
34
63
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Some cpu features may be enabled and disabled for all configurations
3
Always perform one call instead of two for 16-byte operands.
4
that support the feature. Let's test that.
4
Use byte loads/stores directly into the vector register file
5
5
instead of extractions and deposits to a 64-bit local variable.
6
A recent regression[*] inspired adding these tests.
6
7
7
In order to easily receive pointers into the vector register file,
8
[*] '-cpu host,pmu=on' caused a segfault
8
convert the helper to the gvec out-of-line signature. Move the
9
9
helper into vec_helper.c, where it can make use of H1 and clear_tail.
10
Signed-off-by: Andrew Jones <drjones@redhat.com>
10
11
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200623090622.30365-2-philmd@redhat.com
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
13
Message-Id: <20200623082310.17577-1-drjones@redhat.com>
13
Tested-by: Alex Bennée <alex.bennee@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20210224230532.276878-1-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
16
---
17
tests/qtest/arm-cpu-features.c | 38 ++++++++++++++++++++++++++++++----
17
target/arm/helper-a64.h | 2 +-
18
1 file changed, 34 insertions(+), 4 deletions(-)
18
target/arm/helper-a64.c | 32 ---------------------
19
19
target/arm/translate-a64.c | 58 +++++---------------------------------
20
diff --git a/tests/qtest/arm-cpu-features.c b/tests/qtest/arm-cpu-features.c
20
target/arm/vec_helper.c | 48 +++++++++++++++++++++++++++++++
21
index XXXXXXX..XXXXXXX 100644
21
4 files changed, 56 insertions(+), 84 deletions(-)
22
--- a/tests/qtest/arm-cpu-features.c
22
23
+++ b/tests/qtest/arm-cpu-features.c
23
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
24
@@ -XXX,XX +XXX,XX @@ static bool resp_get_feature(QDict *resp, const char *feature)
24
index XXXXXXX..XXXXXXX 100644
25
qobject_unref(_resp); \
25
--- a/target/arm/helper-a64.h
26
})
26
+++ b/target/arm/helper-a64.h
27
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
28
-#define assert_feature(qts, cpu_type, feature, expected_value) \
28
DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr)
29
+#define resp_assert_feature(resp, feature, expected_value) \
29
DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr)
30
({ \
30
DEF_HELPER_3(vfp_cmped_a64, i64, f64, f64, ptr)
31
- QDict *_resp, *_props; \
31
-DEF_HELPER_FLAGS_5(simd_tbl, TCG_CALL_NO_RWG_SE, i64, env, i64, i64, i32, i32)
32
+ QDict *_props; \
32
+DEF_HELPER_FLAGS_4(simd_tblx, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
33
\
33
DEF_HELPER_FLAGS_3(vfp_mulxs, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
34
- _resp = do_query_no_props(qts, cpu_type); \
34
DEF_HELPER_FLAGS_3(vfp_mulxd, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
35
g_assert(_resp); \
35
DEF_HELPER_FLAGS_3(neon_ceq_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
36
g_assert(resp_has_props(_resp)); \
36
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
37
_props = resp_get_props(_resp); \
37
index XXXXXXX..XXXXXXX 100644
38
g_assert(qdict_get(_props, feature)); \
38
--- a/target/arm/helper-a64.c
39
g_assert(qdict_get_bool(_props, feature) == (expected_value)); \
39
+++ b/target/arm/helper-a64.c
40
+})
40
@@ -XXX,XX +XXX,XX @@ float64 HELPER(vfp_mulxd)(float64 a, float64 b, void *fpstp)
41
+
41
return float64_mul(a, b, fpst);
42
+#define assert_feature(qts, cpu_type, feature, expected_value) \
42
}
43
+({ \
43
44
+ QDict *_resp; \
44
-uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices,
45
+ \
45
- uint32_t rn, uint32_t numregs)
46
+ _resp = do_query_no_props(qts, cpu_type); \
46
-{
47
+ g_assert(_resp); \
47
- /* Helper function for SIMD TBL and TBX. We have to do the table
48
+ resp_assert_feature(_resp, feature, expected_value); \
48
- * lookup part for the 64 bits worth of indices we're passed in.
49
+ qobject_unref(_resp); \
49
- * result is the initial results vector (either zeroes for TBL
50
+})
50
- * or some guest values for TBX), rn the register number where
51
+
51
- * the table starts, and numregs the number of registers in the table.
52
+#define assert_set_feature(qts, cpu_type, feature, value) \
52
- * We return the results of the lookups.
53
+({ \
53
- */
54
+ const char *_fmt = (value) ? "{ %s: true }" : "{ %s: false }"; \
54
- int shift;
55
+ QDict *_resp; \
55
-
56
+ \
56
- for (shift = 0; shift < 64; shift += 8) {
57
+ _resp = do_query(qts, cpu_type, _fmt, feature); \
57
- int index = extract64(indices, shift, 8);
58
+ g_assert(_resp); \
58
- if (index < 16 * numregs) {
59
+ resp_assert_feature(_resp, feature, value); \
59
- /* Convert index (a byte offset into the virtual table
60
qobject_unref(_resp); \
60
- * which is a series of 128-bit vectors concatenated)
61
})
61
- * into the correct register element plus a bit offset
62
62
- * into that element, bearing in mind that the table
63
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion(const void *data)
63
- * can wrap around from V31 to V0.
64
assert_error(qts, "host", "The CPU type 'host' requires KVM", NULL);
64
- */
65
65
- int elt = (rn * 2 + (index >> 3)) % 64;
66
/* Test expected feature presence/absence for some cpu types */
66
- int bitidx = (index & 7) * 8;
67
- assert_has_feature_enabled(qts, "max", "pmu");
67
- uint64_t *q = aa64_vfp_qreg(env, elt >> 1);
68
assert_has_feature_enabled(qts, "cortex-a15", "pmu");
68
- uint64_t val = extract64(q[elt & 1], bitidx, 8);
69
assert_has_not_feature(qts, "cortex-a15", "aarch64");
69
-
70
70
- result = deposit64(result, shift, 8, val);
71
+ /* Enabling and disabling pmu should always work. */
71
- }
72
+ assert_has_feature_enabled(qts, "max", "pmu");
72
- }
73
+ assert_set_feature(qts, "max", "pmu", false);
73
- return result;
74
+ assert_set_feature(qts, "max", "pmu", true);
74
-}
75
+
75
-
76
assert_has_not_feature(qts, "max", "kvm-no-adjvtime");
76
/* 64bit/double versions of the neon float compare functions */
77
77
uint64_t HELPER(neon_ceq_f64)(float64 a, float64 b, void *fpstp)
78
if (g_str_equal(qtest_get_arch(), "aarch64")) {
78
{
79
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
79
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/arm/translate-a64.c
82
+++ b/target/arm/translate-a64.c
83
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
84
int rm = extract32(insn, 16, 5);
85
int rn = extract32(insn, 5, 5);
86
int rd = extract32(insn, 0, 5);
87
- int is_tblx = extract32(insn, 12, 1);
88
- int len = extract32(insn, 13, 2);
89
- TCGv_i64 tcg_resl, tcg_resh, tcg_idx;
90
- TCGv_i32 tcg_regno, tcg_numregs;
91
+ int is_tbx = extract32(insn, 12, 1);
92
+ int len = (extract32(insn, 13, 2) + 1) * 16;
93
94
if (op2 != 0) {
95
unallocated_encoding(s);
96
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
80
return;
97
return;
81
}
98
}
82
99
83
+ /* Enabling and disabling kvm-no-adjvtime should always work. */
100
- /* This does a table lookup: for every byte element in the input
84
assert_has_feature_disabled(qts, "host", "kvm-no-adjvtime");
101
- * we index into a table formed from up to four vector registers,
85
+ assert_set_feature(qts, "host", "kvm-no-adjvtime", true);
102
- * and then the output is the result of the lookups. Our helper
86
+ assert_set_feature(qts, "host", "kvm-no-adjvtime", false);
103
- * function does the lookup operation for a single 64 bit part of
87
104
- * the input.
88
if (g_str_equal(qtest_get_arch(), "aarch64")) {
105
- */
89
bool kvm_supports_sve;
106
- tcg_resl = tcg_temp_new_i64();
90
@@ -XXX,XX +XXX,XX @@ static void test_query_cpu_model_expansion_kvm(const void *data)
107
- tcg_resh = NULL;
91
char *error;
108
-
92
109
- if (is_tblx) {
93
assert_has_feature_enabled(qts, "host", "aarch64");
110
- read_vec_element(s, tcg_resl, rd, 0, MO_64);
94
+
111
- } else {
95
+ /* Enabling and disabling pmu should always work. */
112
- tcg_gen_movi_i64(tcg_resl, 0);
96
assert_has_feature_enabled(qts, "host", "pmu");
113
- }
97
+ assert_set_feature(qts, "host", "pmu", false);
114
-
98
+ assert_set_feature(qts, "host", "pmu", true);
115
- if (is_q) {
99
116
- tcg_resh = tcg_temp_new_i64();
100
assert_error(qts, "cortex-a15",
117
- if (is_tblx) {
101
"We cannot guarantee the CPU type 'cortex-a15' works "
118
- read_vec_element(s, tcg_resh, rd, 1, MO_64);
119
- } else {
120
- tcg_gen_movi_i64(tcg_resh, 0);
121
- }
122
- }
123
-
124
- tcg_idx = tcg_temp_new_i64();
125
- tcg_regno = tcg_const_i32(rn);
126
- tcg_numregs = tcg_const_i32(len + 1);
127
- read_vec_element(s, tcg_idx, rm, 0, MO_64);
128
- gen_helper_simd_tbl(tcg_resl, cpu_env, tcg_resl, tcg_idx,
129
- tcg_regno, tcg_numregs);
130
- if (is_q) {
131
- read_vec_element(s, tcg_idx, rm, 1, MO_64);
132
- gen_helper_simd_tbl(tcg_resh, cpu_env, tcg_resh, tcg_idx,
133
- tcg_regno, tcg_numregs);
134
- }
135
- tcg_temp_free_i64(tcg_idx);
136
- tcg_temp_free_i32(tcg_regno);
137
- tcg_temp_free_i32(tcg_numregs);
138
-
139
- write_vec_element(s, tcg_resl, rd, 0, MO_64);
140
- tcg_temp_free_i64(tcg_resl);
141
-
142
- if (is_q) {
143
- write_vec_element(s, tcg_resh, rd, 1, MO_64);
144
- tcg_temp_free_i64(tcg_resh);
145
- }
146
- clear_vec_high(s, is_q, rd);
147
+ tcg_gen_gvec_2_ptr(vec_full_reg_offset(s, rd),
148
+ vec_full_reg_offset(s, rm), cpu_env,
149
+ is_q ? 16 : 8, vec_full_reg_size(s),
150
+ (len << 6) | (is_tbx << 5) | rn,
151
+ gen_helper_simd_tblx);
152
}
153
154
/* ZIP/UZP/TRN
155
diff --git a/target/arm/vec_helper.c b/target/arm/vec_helper.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/vec_helper.c
158
+++ b/target/arm/vec_helper.c
159
@@ -XXX,XX +XXX,XX @@ DO_VRINT_RMODE(gvec_vrint_rm_h, helper_rinth, uint16_t)
160
DO_VRINT_RMODE(gvec_vrint_rm_s, helper_rints, uint32_t)
161
162
#undef DO_VRINT_RMODE
163
+
164
+#ifdef TARGET_AARCH64
165
+void HELPER(simd_tblx)(void *vd, void *vm, void *venv, uint32_t desc)
166
+{
167
+ const uint8_t *indices = vm;
168
+ CPUARMState *env = venv;
169
+ size_t oprsz = simd_oprsz(desc);
170
+ uint32_t rn = extract32(desc, SIMD_DATA_SHIFT, 5);
171
+ bool is_tbx = extract32(desc, SIMD_DATA_SHIFT + 5, 1);
172
+ uint32_t table_len = desc >> (SIMD_DATA_SHIFT + 6);
173
+ union {
174
+ uint8_t b[16];
175
+ uint64_t d[2];
176
+ } result;
177
+
178
+ /*
179
+ * We must construct the final result in a temp, lest the output
180
+ * overlaps the input table. For TBL, begin with zero; for TBX,
181
+ * begin with the original register contents. Note that we always
182
+ * copy 16 bytes here to avoid an extra branch; clearing the high
183
+ * bits of the register for oprsz == 8 is handled below.
184
+ */
185
+ if (is_tbx) {
186
+ memcpy(&result, vd, 16);
187
+ } else {
188
+ memset(&result, 0, 16);
189
+ }
190
+
191
+ for (size_t i = 0; i < oprsz; ++i) {
192
+ uint32_t index = indices[H1(i)];
193
+
194
+ if (index < table_len) {
195
+ /*
196
+ * Convert index (a byte offset into the virtual table
197
+ * which is a series of 128-bit vectors concatenated)
198
+ * into the correct register element, bearing in mind
199
+ * that the table can wrap around from V31 to V0.
200
+ */
201
+ const uint8_t *table = (const uint8_t *)
202
+ aa64_vfp_qreg(env, (rn + (index >> 4)) % 32);
203
+ result.b[H1(i)] = table[H1(index % 16)];
204
+ }
205
+ }
206
+
207
+ memcpy(vd, &result, 16);
208
+ clear_tail(vd, oprsz, simd_maxsz(desc));
209
+}
210
+#endif
102
--
211
--
103
2.20.1
212
2.20.1
104
213
105
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 self-explicit definitions instead of magic values.
3
The STATUS register will be reset to IDLE in
4
cnpcm7xx_smbus_enter_reset(), no need to preset
5
it in instance_init().
4
6
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20200617072539.32686-3-f4bug@amsat.org
8
Reviewed-by: Hao Wu <wuhaotsh@google.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20210228224813.312532-1-f4bug@amsat.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
hw/i2c/versatile_i2c.c | 14 ++++++++++----
12
hw/i2c/npcm7xx_smbus.c | 1 -
11
1 file changed, 10 insertions(+), 4 deletions(-)
13
1 file changed, 1 deletion(-)
12
14
13
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
15
diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/i2c/versatile_i2c.c
17
--- a/hw/i2c/npcm7xx_smbus.c
16
+++ b/hw/i2c/versatile_i2c.c
18
+++ b/hw/i2c/npcm7xx_smbus.c
17
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_init(Object *obj)
18
#include "qemu/osdep.h"
20
sysbus_init_mmio(sbd, &s->iomem);
19
#include "hw/sysbus.h"
21
20
#include "hw/i2c/bitbang_i2c.h"
22
s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
21
+#include "hw/registerfields.h"
23
- s->status = NPCM7XX_SMBUS_STATUS_IDLE;
22
#include "qemu/log.h"
24
}
23
#include "qemu/module.h"
25
24
26
static const VMStateDescription vmstate_npcm7xx_smbus = {
25
@@ -XXX,XX +XXX,XX @@ typedef struct VersatileI2CState {
26
int in;
27
} VersatileI2CState;
28
29
+REG32(CONTROL_GET, 0)
30
+REG32(CONTROL_SET, 0)
31
+REG32(CONTROL_CLR, 4)
32
+
33
static uint64_t versatile_i2c_read(void *opaque, hwaddr offset,
34
unsigned size)
35
{
36
VersatileI2CState *s = (VersatileI2CState *)opaque;
37
38
- if (offset == 0) {
39
+ switch (offset) {
40
+ case A_CONTROL_SET:
41
return (s->out & 1) | (s->in << 1);
42
- } else {
43
+ default:
44
qemu_log_mask(LOG_GUEST_ERROR,
45
"%s: Bad offset 0x%x\n", __func__, (int)offset);
46
return -1;
47
@@ -XXX,XX +XXX,XX @@ static void versatile_i2c_write(void *opaque, hwaddr offset,
48
VersatileI2CState *s = (VersatileI2CState *)opaque;
49
50
switch (offset) {
51
- case 0:
52
+ case A_CONTROL_SET:
53
s->out |= value & 3;
54
break;
55
- case 4:
56
+ case A_CONTROL_CLR:
57
s->out &= ~value;
58
break;
59
default:
60
--
27
--
61
2.20.1
28
2.20.1
62
29
63
30
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: schspa <schspa@gmail.com>
2
2
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
3
At the moment the following QEMU command line triggers an assertion
4
Message-id: 20200617072539.32686-7-f4bug@amsat.org
4
failure On xlnx-versal SOC:
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
11
12
qemu-system-aarch64: ../migration/savevm.c:860:
13
vmstate_register_with_alias_id:
14
Assertion `!se->compat || se->instance_id == 0' failed.
15
16
This problem was fixed on arm virt platform in commit f58b39d2d5b
17
("virtio-mmio: format transport base address in BusClass.get_dev_path")
18
19
It works perfectly on arm virt platform. but there is still there on
20
xlnx-versal SOC.
21
22
The main difference between arm virt and xlnx-versal is they use
23
different way to create virtio-mmio qdev. on arm virt, it calls
24
sysbus_create_simple("virtio-mmio", base, pic[irq]); which will call
25
sysbus_mmio_map internally and assign base address to subsys device
26
mmio correctly. but xlnx-versal's implements won't do this.
27
28
However, xlnx-versal can't switch to sysbus_create_simple() to create
29
virtio-mmio device. It's because xlnx-versal's cpu use
30
VersalVirt.soc.fpd.apu.mr as it's memory. which is subregion of
31
system_memory. sysbus_create_simple will add virtio to system_memory,
32
which can't be accessed by cpu.
33
34
Besides, xlnx-versal can't add sysbus_mmio_map api call too, because
35
this will add memory region to system_memory, and it can't be added
36
to VersalVirt.soc.fpd.apu.mr again.
37
38
We can solve this by assign correct base address offset on dev_path.
39
40
This path was test on aarch64 virt & xlnx-versal platform.
41
42
Signed-off-by: schspa <schspa@gmail.com>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
43
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
45
---
8
hw/arm/mps2.c | 5 ++++-
46
hw/virtio/virtio-mmio.c | 13 +++++++------
9
1 file changed, 4 insertions(+), 1 deletion(-)
47
1 file changed, 7 insertions(+), 6 deletions(-)
10
48
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
49
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
12
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/mps2.c
51
--- a/hw/virtio/virtio-mmio.c
14
+++ b/hw/arm/mps2.c
52
+++ b/hw/virtio/virtio-mmio.c
15
@@ -XXX,XX +XXX,XX @@ typedef struct {
53
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
16
MemoryRegion blockram_m2;
54
BusState *virtio_mmio_bus;
17
MemoryRegion blockram_m3;
55
VirtIOMMIOProxy *virtio_mmio_proxy;
18
MemoryRegion sram;
56
char *proxy_path;
19
+ /* FPGA APB subsystem */
57
- SysBusDevice *proxy_sbd;
20
MPS2SCC scc;
58
char *path;
21
+ /* CMSDK APB subsystem */
59
+ MemoryRegionSection section;
22
CMSDKAPBDualTimer dualtimer;
60
23
} MPS2MachineState;
61
virtio_mmio_bus = qdev_get_parent_bus(dev);
24
62
virtio_mmio_proxy = VIRTIO_MMIO(virtio_mmio_bus->parent);
25
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
63
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
26
g_assert_not_reached();
27
}
64
}
28
65
29
+ /* CMSDK APB subsystem */
66
/* Otherwise, we append the base address of the transport. */
30
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
67
- proxy_sbd = SYS_BUS_DEVICE(virtio_mmio_proxy);
31
cmsdk_apb_timer_create(0x40001000, qdev_get_gpio_in(armv7m, 9), SYSCLK_FRQ);
68
- assert(proxy_sbd->num_mmio == 1);
32
-
69
- assert(proxy_sbd->mmio[0].memory == &virtio_mmio_proxy->iomem);
33
object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
70
+ section = memory_region_find(&virtio_mmio_proxy->iomem, 0, 0x200);
34
TYPE_CMSDK_APB_DUALTIMER);
71
+ assert(section.mr);
35
qdev_prop_set_uint32(DEVICE(&mms->dualtimer), "pclk-frq", SYSCLK_FRQ);
72
36
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
73
if (proxy_path) {
37
qdev_get_gpio_in(armv7m, 10));
74
path = g_strdup_printf("%s/virtio-mmio@" TARGET_FMT_plx, proxy_path,
38
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
75
- proxy_sbd->mmio[0].addr);
39
76
+ section.offset_within_address_space);
40
+ /* FPGA APB subsystem */
77
} else {
41
object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
78
path = g_strdup_printf("virtio-mmio@" TARGET_FMT_plx,
42
sccdev = DEVICE(&mms->scc);
79
- proxy_sbd->mmio[0].addr);
43
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
80
+ section.offset_within_address_space);
81
}
82
+ memory_region_unref(section.mr);
83
+
84
g_free(proxy_path);
85
return path;
86
}
44
--
87
--
45
2.20.1
88
2.20.1
46
89
47
90
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Peter Collingbourne <pcc@google.com>
2
2
3
By using the TYPE_* definitions for devices, we can:
3
Section D6.7 of the ARM ARM states:
4
- quickly find where devices are used with 'git-grep'
5
- easily rename a device (one-line change).
6
4
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
For the purpose of determining Tag Check Fault handling, unprivileged
8
Message-id: 20200617072539.32686-6-f4bug@amsat.org
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>
23
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Message-id: 20210219201820.2672077-1-pcc@google.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
27
---
12
hw/arm/realview.c | 3 ++-
28
target/arm/helper.c | 2 +-
13
hw/arm/versatilepb.c | 3 ++-
29
target/arm/mte_helper.c | 13 +++++++++----
14
hw/arm/vexpress.c | 3 ++-
30
2 files changed, 10 insertions(+), 5 deletions(-)
15
3 files changed, 6 insertions(+), 3 deletions(-)
16
31
17
diff --git a/hw/arm/realview.c b/hw/arm/realview.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/hw/arm/realview.c
34
--- a/target/arm/helper.c
20
+++ b/hw/arm/realview.c
35
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
22
#include "hw/cpu/a9mpcore.h"
37
if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
23
#include "hw/intc/realview_gic.h"
38
&& tbid
24
#include "hw/irq.h"
39
&& !(env->pstate & PSTATE_TCO)
25
+#include "hw/i2c/arm_sbcon_i2c.h"
40
- && (sctlr & SCTLR_TCF)
26
41
+ && (sctlr & SCTLR_TCF0)
27
#define SMP_BOOT_ADDR 0xe0000000
42
&& allocation_tag_access_enabled(env, 0, sctlr)) {
28
#define SMP_BOOTREG_ADDR 0x10000030
43
flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
29
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
30
}
44
}
45
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/mte_helper.c
48
+++ b/target/arm/mte_helper.c
49
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
50
reg_el = regime_el(env, arm_mmu_idx);
51
sctlr = env->cp15.sctlr_el[reg_el];
52
53
- el = arm_current_el(env);
54
- if (el == 0) {
55
+ switch (arm_mmu_idx) {
56
+ case ARMMMUIdx_E10_0:
57
+ case ARMMMUIdx_E20_0:
58
+ el = 0;
59
tcf = extract64(sctlr, 38, 2);
60
- } else {
61
+ break;
62
+ default:
63
+ el = reg_el;
64
tcf = extract64(sctlr, 40, 2);
31
}
65
}
32
66
33
- dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
67
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
34
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, 0x10002000, NULL);
68
env->exception.vaddress = dirty_ptr;
35
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
69
36
i2c_create_slave(i2c, "ds1338", 0x68);
70
is_write = FIELD_EX32(desc, MTEDESC, WRITE);
37
71
- syn = syn_data_abort_no_iss(el != 0, 0, 0, 0, 0, is_write, 0x11);
38
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
72
+ syn = syn_data_abort_no_iss(arm_current_el(env) != 0, 0, 0, 0, 0,
39
index XXXXXXX..XXXXXXX 100644
73
+ is_write, 0x11);
40
--- a/hw/arm/versatilepb.c
74
raise_exception(env, EXCP_DATA_ABORT, syn, exception_target_el(env));
41
+++ b/hw/arm/versatilepb.c
75
/* noreturn, but fall through to the assert anyway */
42
@@ -XXX,XX +XXX,XX @@
43
#include "sysemu/sysemu.h"
44
#include "hw/pci/pci.h"
45
#include "hw/i2c/i2c.h"
46
+#include "hw/i2c/arm_sbcon_i2c.h"
47
#include "hw/irq.h"
48
#include "hw/boards.h"
49
#include "exec/address-spaces.h"
50
@@ -XXX,XX +XXX,XX @@ static void versatile_init(MachineState *machine, int board_id)
51
/* Add PL031 Real Time Clock. */
52
sysbus_create_simple("pl031", 0x101e8000, pic[10]);
53
54
- dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);
55
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, 0x10002000, NULL);
56
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
57
i2c_create_slave(i2c, "ds1338", 0x68);
58
59
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/vexpress.c
62
+++ b/hw/arm/vexpress.c
63
@@ -XXX,XX +XXX,XX @@
64
#include "hw/char/pl011.h"
65
#include "hw/cpu/a9mpcore.h"
66
#include "hw/cpu/a15mpcore.h"
67
+#include "hw/i2c/arm_sbcon_i2c.h"
68
69
#define VEXPRESS_BOARD_ID 0x8e0
70
#define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024)
71
@@ -XXX,XX +XXX,XX @@ static void vexpress_common_init(MachineState *machine)
72
sysbus_create_simple("sp804", map[VE_TIMER01], pic[2]);
73
sysbus_create_simple("sp804", map[VE_TIMER23], pic[3]);
74
75
- dev = sysbus_create_simple("versatile_i2c", map[VE_SERIALDVI], NULL);
76
+ dev = sysbus_create_simple(TYPE_VERSATILE_I2C, map[VE_SERIALDVI], NULL);
77
i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");
78
i2c_create_slave(i2c, "sii9022", 0x39);
79
76
80
--
77
--
81
2.20.1
78
2.20.1
82
79
83
80
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Register the GPIO peripherals as unimplemented to better
3
IDAU is specific to M-profile. KVM only supports A-profile.
4
follow their accesses, for example booting Zephyr:
4
Restrict this interface to TCG, as it is pointless (and
5
confusing) on a KVM-only build.
5
6
6
----------------
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
IN: arm_mps2_pinmux_init
8
0x00001160: f64f 0231 movw r2, #0xf831
9
0x00001164: 4b06 ldr r3, [pc, #0x18]
10
0x00001166: 2000 movs r0, #0
11
0x00001168: 619a str r2, [r3, #0x18]
12
0x0000116a: f24c 426f movw r2, #0xc46f
13
0x0000116e: f503 5380 add.w r3, r3, #0x1000
14
0x00001172: 619a str r2, [r3, #0x18]
15
0x00001174: f44f 529e mov.w r2, #0x13c0
16
0x00001178: f503 5380 add.w r3, r3, #0x1000
17
0x0000117c: 619a str r2, [r3, #0x18]
18
0x0000117e: 4770 bx lr
19
cmsdk-ahb-gpio: unimplemented device write (size 4, value 0xf831, offset 0x18)
20
cmsdk-ahb-gpio: unimplemented device write (size 4, value 0xc46f, offset 0x18)
21
cmsdk-ahb-gpio: unimplemented device write (size 4, value 0x13c0, offset 0x18)
22
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
25
Message-id: 20200617072539.32686-10-f4bug@amsat.org
10
Message-id: 20210221222617.2579610-2-f4bug@amsat.org
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
12
---
28
hw/arm/mps2.c | 8 ++++++--
13
target/arm/cpu.c | 7 -------
29
1 file changed, 6 insertions(+), 2 deletions(-)
14
target/arm/cpu_tcg.c | 8 ++++++++
15
2 files changed, 8 insertions(+), 7 deletions(-)
30
16
31
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
32
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/mps2.c
19
--- a/target/arm/cpu.c
34
+++ b/hw/arm/mps2.c
20
+++ b/target/arm/cpu.c
35
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
21
@@ -XXX,XX +XXX,XX @@ static const TypeInfo arm_cpu_type_info = {
36
MemoryRegion *system_memory = get_system_memory();
22
.class_init = arm_cpu_class_init,
37
MachineClass *mc = MACHINE_GET_CLASS(machine);
23
};
38
DeviceState *armv7m, *sccdev;
24
39
+ int i;
25
-static const TypeInfo idau_interface_type_info = {
40
26
- .name = TYPE_IDAU_INTERFACE,
41
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
27
- .parent = TYPE_INTERFACE,
42
error_report("This board can only be used with CPU %s",
28
- .class_size = sizeof(IDAUInterfaceClass),
43
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
29
-};
44
*/
30
-
45
Object *orgate;
31
static void arm_cpu_register_types(void)
46
DeviceState *orgate_dev;
32
{
47
- int i;
33
const size_t cpu_count = ARRAY_SIZE(arm_cpus);
48
34
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_register_types(void)
49
orgate = object_new(TYPE_OR_IRQ);
35
if (cpu_count) {
50
object_property_set_int(orgate, 6, "num-lines", &error_fatal);
36
size_t i;
51
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
37
52
*/
38
- type_register_static(&idau_interface_type_info);
53
Object *orgate;
39
for (i = 0; i < cpu_count; ++i) {
54
DeviceState *orgate_dev;
40
arm_cpu_register(&arm_cpus[i]);
55
- int i;
41
}
56
42
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
57
orgate = object_new(TYPE_OR_IRQ);
43
index XXXXXXX..XXXXXXX 100644
58
object_property_set_int(orgate, 10, "num-lines", &error_fatal);
44
--- a/target/arm/cpu_tcg.c
59
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
45
+++ b/target/arm/cpu_tcg.c
60
default:
46
@@ -XXX,XX +XXX,XX @@
61
g_assert_not_reached();
47
#include "hw/core/tcg-cpu-ops.h"
48
#endif /* CONFIG_TCG */
49
#include "internals.h"
50
+#include "target/arm/idau.h"
51
52
/* CPU models. These are not needed for the AArch64 linux-user build. */
53
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
54
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
55
{ .name = "pxa270-c5", .initfn = pxa270c5_initfn },
56
};
57
58
+static const TypeInfo idau_interface_type_info = {
59
+ .name = TYPE_IDAU_INTERFACE,
60
+ .parent = TYPE_INTERFACE,
61
+ .class_size = sizeof(IDAUInterfaceClass),
62
+};
63
+
64
static void arm_tcg_cpu_register_types(void)
65
{
66
size_t i;
67
68
+ type_register_static(&idau_interface_type_info);
69
for (i = 0; i < ARRAY_SIZE(arm_tcg_cpus); ++i) {
70
arm_cpu_register(&arm_tcg_cpus[i]);
62
}
71
}
63
+ for (i = 0; i < 4; i++) {
64
+ static const hwaddr gpiobase[] = {0x40010000, 0x40011000,
65
+ 0x40012000, 0x40013000};
66
+ create_unimplemented_device("cmsdk-ahb-gpio", gpiobase[i], 0x1000);
67
+ }
68
69
/* CMSDK APB subsystem */
70
cmsdk_apb_timer_create(0x40000000, qdev_get_gpio_in(armv7m, 8), SYSCLK_FRQ);
71
--
72
--
72
2.20.1
73
2.20.1
73
74
74
75
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
Add a trace event to see when a guest disable/enable the watchdog.
3
We will move this code in the next commit. Clean it up
4
first to avoid checkpatch.pl errors.
4
5
5
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20200617072539.32686-2-f4bug@amsat.org
7
Message-id: 20210221222617.2579610-3-f4bug@amsat.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
hw/watchdog/cmsdk-apb-watchdog.c | 1 +
11
target/arm/cpu.c | 12 ++++++++----
11
hw/watchdog/trace-events | 1 +
12
1 file changed, 8 insertions(+), 4 deletions(-)
12
2 files changed, 2 insertions(+)
13
13
14
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/watchdog/cmsdk-apb-watchdog.c
16
--- a/target/arm/cpu.c
17
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
17
+++ b/target/arm/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
18
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
19
break;
19
}
20
case A_WDOGLOCK:
20
21
s->lock = (value != WDOG_UNLOCK_VALUE);
21
static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
22
+ trace_cmsdk_apb_watchdog_lock(s->lock);
22
- /* power_control should be set to maximum latency. Again,
23
break;
23
+ /*
24
case A_WDOGITCR:
24
+ * power_control should be set to maximum latency. Again,
25
if (s->is_luminary) {
25
* default to 0 and set by private hook
26
diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events
26
*/
27
index XXXXXXX..XXXXXXX 100644
27
{ .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
28
--- a/hw/watchdog/trace-events
28
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
29
+++ b/hw/watchdog/trace-events
29
set_feature(&cpu->env, ARM_FEATURE_NEON);
30
@@ -XXX,XX +XXX,XX @@
30
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
31
cmsdk_apb_watchdog_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
31
set_feature(&cpu->env, ARM_FEATURE_EL3);
32
cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
32
- /* Note that A9 supports the MP extensions even for
33
cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset"
33
+ /*
34
+cmsdk_apb_watchdog_lock(uint32_t lock) "CMSDK APB watchdog: lock %" PRIu32
34
+ * Note that A9 supports the MP extensions even for
35
* A9UP and single-core A9MP (which are both different
36
* and valid configurations; we don't model A9UP).
37
*/
38
@@ -XXX,XX +XXX,XX @@ static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
39
{
40
MachineState *ms = MACHINE(qdev_get_machine());
41
42
- /* Linux wants the number of processors from here.
43
+ /*
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;
35
--
58
--
36
2.20.1
59
2.20.1
37
60
38
61
diff view generated by jsdifflib
1
Convert the Neon VREV64 insn from the 2-reg-misc grouping to decodetree.
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
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200616170844.13318-2-peter.maydell@linaro.org
8
Message-id: 20210215103215.4944-2-peter.maydell@linaro.org
6
---
9
---
7
target/arm/neon-dp.decode | 12 ++++++++
10
hw/arm/musicpal.c | 64 ++++++++++++++++++-----------------------------
8
target/arm/translate-neon.inc.c | 50 +++++++++++++++++++++++++++++++++
11
1 file changed, 24 insertions(+), 40 deletions(-)
9
target/arm/translate.c | 24 ++--------------
10
3 files changed, 64 insertions(+), 22 deletions(-)
11
12
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
15
--- a/hw/arm/musicpal.c
15
+++ b/target/arm/neon-dp.decode
16
+++ b/hw/arm/musicpal.c
16
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
17
@@ -XXX,XX +XXX,XX @@ static uint8_t scale_lcd_color(musicpal_lcd_state *s, uint8_t col)
17
vm=%vm_dp vd=%vd_dp size=1
18
}
18
VDUP_scalar 1111 001 1 1 . 11 index:1 100 .... 11 000 q:1 . 0 .... \
19
}
19
vm=%vm_dp vd=%vd_dp size=2
20
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)
34
+{
35
+ int dx, dy;
36
+ DisplaySurface *surface = qemu_console_surface(s->con);
37
+ uint32_t *pixel =
38
+ &((uint32_t *) surface_data(surface))[(y * 128 * 3 + x) * 3];
20
+
39
+
21
+ ##################################################################
40
+ for (dy = 0; dy < 3; dy++, pixel += 127 * 3) {
22
+ # 2-reg-misc grouping:
41
+ for (dx = 0; dx < 3; dx++, pixel++) {
23
+ # 1111 001 11 D 11 size:2 opc1:2 Vd:4 0 opc2:4 q:1 M 0 Vm:4
42
+ *pixel = col;
24
+ ##################################################################
43
+ }
25
+
44
+ }
26
+ &2misc vd vm q size
27
+
28
+ @2misc .... ... .. . .. size:2 .. .... . .... q:1 . . .... \
29
+ &2misc vm=%vm_dp vd=%vd_dp
30
+
31
+ VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
32
]
33
34
# Subgroup for size != 0b11
35
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/translate-neon.inc.c
38
+++ b/target/arm/translate-neon.inc.c
39
@@ -XXX,XX +XXX,XX @@ static bool trans_VDUP_scalar(DisasContext *s, arg_VDUP_scalar *a)
40
a->q ? 16 : 8, a->q ? 16 : 8);
41
return true;
42
}
45
}
43
+
46
-SET_LCD_PIXEL(8, uint8_t)
44
+static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
47
-SET_LCD_PIXEL(16, uint16_t)
45
+{
48
-SET_LCD_PIXEL(32, uint32_t)
46
+ int pass, half;
49
47
+
50
static void lcd_refresh(void *opaque)
48
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
51
{
49
+ return false;
52
musicpal_lcd_state *s = opaque;
50
+ }
53
- DisplaySurface *surface = qemu_console_surface(s->con);
51
+
54
int x, y, col;
52
+ /* UNDEF accesses to D16-D31 if they don't exist. */
55
53
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
56
- switch (surface_bits_per_pixel(surface)) {
54
+ ((a->vd | a->vm) & 0x10)) {
57
- case 0:
55
+ return false;
58
- return;
56
+ }
59
-#define LCD_REFRESH(depth, func) \
57
+
60
- case depth: \
58
+ if ((a->vd | a->vm) & a->q) {
61
- col = func(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff), \
59
+ return false;
62
- scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff), \
60
+ }
63
- scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff)); \
61
+
64
- for (x = 0; x < 128; x++) { \
62
+ if (a->size == 3) {
65
- for (y = 0; y < 64; y++) { \
63
+ return false;
66
- if (s->video_ram[x + (y/8)*128] & (1 << (y % 8))) { \
64
+ }
67
- glue(set_lcd_pixel, depth)(s, x, y, col); \
65
+
68
- } else { \
66
+ if (!vfp_access_check(s)) {
69
- glue(set_lcd_pixel, depth)(s, x, y, 0); \
67
+ return true;
70
- } \
68
+ }
71
- } \
69
+
72
- } \
70
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
73
- break;
71
+ TCGv_i32 tmp[2];
74
- LCD_REFRESH(8, rgb_to_pixel8)
72
+
75
- LCD_REFRESH(16, rgb_to_pixel16)
73
+ for (half = 0; half < 2; half++) {
76
- LCD_REFRESH(32, (is_surface_bgr(surface) ?
74
+ tmp[half] = neon_load_reg(a->vm, pass * 2 + half);
77
- rgb_to_pixel32bgr : rgb_to_pixel32))
75
+ switch (a->size) {
78
- default:
76
+ case 0:
79
- hw_error("unsupported colour depth %i\n",
77
+ tcg_gen_bswap32_i32(tmp[half], tmp[half]);
80
- surface_bits_per_pixel(surface));
78
+ break;
81
+ col = rgb_to_pixel32(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff),
79
+ case 1:
82
+ scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff),
80
+ gen_swap_half(tmp[half]);
83
+ scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff));
81
+ break;
84
+ for (x = 0; x < 128; x++) {
82
+ case 2:
85
+ for (y = 0; y < 64; y++) {
83
+ break;
86
+ if (s->video_ram[x + (y / 8) * 128] & (1 << (y % 8))) {
84
+ default:
87
+ set_lcd_pixel32(s, x, y, col);
85
+ g_assert_not_reached();
88
+ } else {
89
+ set_lcd_pixel32(s, x, y, 0);
86
+ }
90
+ }
87
+ }
91
+ }
88
+ neon_store_reg(a->vd, pass * 2, tmp[1]);
92
}
89
+ neon_store_reg(a->vd, pass * 2 + 1, tmp[0]);
93
90
+ }
94
dpy_gfx_update(s->con, 0, 0, 128*3, 64*3);
91
+ return true;
92
+}
93
diff --git a/target/arm/translate.c b/target/arm/translate.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/arm/translate.c
96
+++ b/target/arm/translate.c
97
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
98
}
99
switch (op) {
100
case NEON_2RM_VREV64:
101
- for (pass = 0; pass < (q ? 2 : 1); pass++) {
102
- tmp = neon_load_reg(rm, pass * 2);
103
- tmp2 = neon_load_reg(rm, pass * 2 + 1);
104
- switch (size) {
105
- case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
106
- case 1: gen_swap_half(tmp); break;
107
- case 2: /* no-op */ break;
108
- default: abort();
109
- }
110
- neon_store_reg(rd, pass * 2 + 1, tmp);
111
- if (size == 2) {
112
- neon_store_reg(rd, pass * 2, tmp2);
113
- } else {
114
- switch (size) {
115
- case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
116
- case 1: gen_swap_half(tmp2); break;
117
- default: abort();
118
- }
119
- neon_store_reg(rd, pass * 2, tmp2);
120
- }
121
- }
122
- break;
123
+ /* handled by decodetree */
124
+ return 1;
125
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
126
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
127
for (pass = 0; pass < q + 1; pass++) {
128
--
95
--
129
2.20.1
96
2.20.1
130
97
131
98
diff view generated by jsdifflib
1
Convert the VCVT instructions in the 2-reg-misc grouping to
1
For a long time now the UI layer has guaranteed that the console
2
decodetree.
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.
3
5
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-19-peter.maydell@linaro.org
8
Message-id: 20210215103215.4944-3-peter.maydell@linaro.org
7
---
9
---
8
target/arm/neon-dp.decode | 9 +++++
10
include/ui/console.h | 10 ----------
9
target/arm/translate-neon.inc.c | 70 +++++++++++++++++++++++++++++++++
11
hw/display/tc6393xb.c | 33 +--------------------------------
10
target/arm/translate.c | 70 ++++-----------------------------
12
2 files changed, 1 insertion(+), 42 deletions(-)
11
3 files changed, 87 insertions(+), 62 deletions(-)
12
13
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
diff --git a/include/ui/console.h b/include/ui/console.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
16
--- a/include/ui/console.h
16
+++ b/target/arm/neon-dp.decode
17
+++ b/include/ui/console.h
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
18
@@ -XXX,XX +XXX,XX @@ PixelFormat qemu_default_pixelformat(int bpp);
18
19
DisplaySurface *qemu_create_displaysurface(int width, int height);
19
VRINTP 1111 001 11 . 11 .. 10 .... 0 1111 . . 0 .... @2misc
20
void qemu_free_displaysurface(DisplaySurface *surface);
20
21
21
+ VCVTAS 1111 001 11 . 11 .. 11 .... 0 0000 . . 0 .... @2misc
22
-static inline int is_surface_bgr(DisplaySurface *surface)
22
+ VCVTAU 1111 001 11 . 11 .. 11 .... 0 0001 . . 0 .... @2misc
23
+ VCVTNS 1111 001 11 . 11 .. 11 .... 0 0010 . . 0 .... @2misc
24
+ VCVTNU 1111 001 11 . 11 .. 11 .... 0 0011 . . 0 .... @2misc
25
+ VCVTPS 1111 001 11 . 11 .. 11 .... 0 0100 . . 0 .... @2misc
26
+ VCVTPU 1111 001 11 . 11 .. 11 .... 0 0101 . . 0 .... @2misc
27
+ VCVTMS 1111 001 11 . 11 .. 11 .... 0 0110 . . 0 .... @2misc
28
+ VCVTMU 1111 001 11 . 11 .. 11 .... 0 0111 . . 0 .... @2misc
29
+
30
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
31
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
32
VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
33
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.inc.c
36
+++ b/target/arm/translate-neon.inc.c
37
@@ -XXX,XX +XXX,XX @@ DO_VRINT(VRINTA, FPROUNDING_TIEAWAY)
38
DO_VRINT(VRINTZ, FPROUNDING_ZERO)
39
DO_VRINT(VRINTM, FPROUNDING_NEGINF)
40
DO_VRINT(VRINTP, FPROUNDING_POSINF)
41
+
42
+static bool do_vcvt(DisasContext *s, arg_2misc *a, int rmode, bool is_signed)
43
+{
44
+ /*
45
+ * Handle a VCVT* operation by iterating 32 bits at a time,
46
+ * with a specified rounding mode in operation.
47
+ */
48
+ int pass;
49
+ TCGv_ptr fpst;
50
+ TCGv_i32 tcg_rmode, tcg_shift;
51
+
52
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
53
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
54
+ return false;
55
+ }
56
+
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
59
+ ((a->vd | a->vm) & 0x10)) {
60
+ return false;
61
+ }
62
+
63
+ if (a->size != 2) {
64
+ /* TODO: FP16 will be the size == 1 case */
65
+ return false;
66
+ }
67
+
68
+ if ((a->vd | a->vm) & a->q) {
69
+ return false;
70
+ }
71
+
72
+ if (!vfp_access_check(s)) {
73
+ return true;
74
+ }
75
+
76
+ fpst = get_fpstatus_ptr(1);
77
+ tcg_shift = tcg_const_i32(0);
78
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
79
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
80
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
81
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
82
+ if (is_signed) {
83
+ gen_helper_vfp_tosls(tmp, tmp, tcg_shift, fpst);
84
+ } else {
85
+ gen_helper_vfp_touls(tmp, tmp, tcg_shift, fpst);
86
+ }
87
+ neon_store_reg(a->vd, pass, tmp);
88
+ }
89
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
90
+ tcg_temp_free_i32(tcg_rmode);
91
+ tcg_temp_free_i32(tcg_shift);
92
+ tcg_temp_free_ptr(fpst);
93
+
94
+ return true;
95
+}
96
+
97
+#define DO_VCVT(INSN, RMODE, SIGNED) \
98
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
99
+ { \
100
+ return do_vcvt(s, a, RMODE, SIGNED); \
101
+ }
102
+
103
+DO_VCVT(VCVTAU, FPROUNDING_TIEAWAY, false)
104
+DO_VCVT(VCVTAS, FPROUNDING_TIEAWAY, true)
105
+DO_VCVT(VCVTNU, FPROUNDING_TIEEVEN, false)
106
+DO_VCVT(VCVTNS, FPROUNDING_TIEEVEN, true)
107
+DO_VCVT(VCVTPU, FPROUNDING_POSINF, false)
108
+DO_VCVT(VCVTPS, FPROUNDING_POSINF, true)
109
+DO_VCVT(VCVTMU, FPROUNDING_NEGINF, false)
110
+DO_VCVT(VCVTMS, FPROUNDING_NEGINF, true)
111
diff --git a/target/arm/translate.c b/target/arm/translate.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/target/arm/translate.c
114
+++ b/target/arm/translate.c
115
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
116
#define NEON_2RM_VCVT_SF 62
117
#define NEON_2RM_VCVT_UF 63
118
119
-static bool neon_2rm_is_v8_op(int op)
120
-{
23
-{
121
- /* Return true if this neon 2reg-misc op is ARMv8 and up */
24
- if (PIXMAN_FORMAT_BPP(surface->format) == 32 &&
122
- switch (op) {
25
- PIXMAN_FORMAT_TYPE(surface->format) == PIXMAN_TYPE_ABGR) {
123
- case NEON_2RM_VRINTN:
26
- return 1;
124
- case NEON_2RM_VRINTA:
27
- } else {
125
- case NEON_2RM_VRINTM:
28
- return 0;
126
- case NEON_2RM_VRINTP:
127
- case NEON_2RM_VRINTZ:
128
- case NEON_2RM_VRINTX:
129
- case NEON_2RM_VCVTAU:
130
- case NEON_2RM_VCVTAS:
131
- case NEON_2RM_VCVTNU:
132
- case NEON_2RM_VCVTNS:
133
- case NEON_2RM_VCVTPU:
134
- case NEON_2RM_VCVTPS:
135
- case NEON_2RM_VCVTMU:
136
- case NEON_2RM_VCVTMS:
137
- return true;
138
- default:
139
- return false;
140
- }
29
- }
141
-}
30
-}
142
-
31
-
143
/* Each entry in this array has bit n set if the insn allows
32
static inline int is_buffer_shared(DisplaySurface *surface)
144
* size value n (otherwise it will UNDEF). Since unallocated
33
{
145
* op values will have no bits set they always UNDEF.
34
return !(surface->flags & QEMU_ALLOCATED_FLAG);
146
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
35
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
147
if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
36
index XXXXXXX..XXXXXXX 100644
148
return 1;
37
--- a/hw/display/tc6393xb.c
149
}
38
+++ b/hw/display/tc6393xb.c
150
- if (neon_2rm_is_v8_op(op) &&
39
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
151
- !arm_dc_feature(s, ARM_FEATURE_V8)) {
40
(uint32_t) addr, value & 0xff);
152
- return 1;
41
}
153
- }
42
154
if (q && ((rm | rd) & 1)) {
43
-#define BITS 8
155
return 1;
44
-#include "tc6393xb_template.h"
156
}
45
-#define BITS 15
157
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
46
-#include "tc6393xb_template.h"
158
case NEON_2RM_VRINTM:
47
-#define BITS 16
159
case NEON_2RM_VRINTP:
48
-#include "tc6393xb_template.h"
160
case NEON_2RM_VRINTZ:
49
-#define BITS 24
161
+ case NEON_2RM_VCVTAU:
50
-#include "tc6393xb_template.h"
162
+ case NEON_2RM_VCVTAS:
51
#define BITS 32
163
+ case NEON_2RM_VCVTNU:
52
#include "tc6393xb_template.h"
164
+ case NEON_2RM_VCVTNS:
53
165
+ case NEON_2RM_VCVTPU:
54
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
166
+ case NEON_2RM_VCVTPS:
55
{
167
+ case NEON_2RM_VCVTMU:
56
- DisplaySurface *surface = qemu_console_surface(s->con);
168
+ case NEON_2RM_VCVTMS:
169
/* handled by decodetree */
170
return 1;
171
case NEON_2RM_VTRN:
172
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
173
}
174
neon_store_reg(rm, pass, tmp2);
175
break;
176
- case NEON_2RM_VCVTAU:
177
- case NEON_2RM_VCVTAS:
178
- case NEON_2RM_VCVTNU:
179
- case NEON_2RM_VCVTNS:
180
- case NEON_2RM_VCVTPU:
181
- case NEON_2RM_VCVTPS:
182
- case NEON_2RM_VCVTMU:
183
- case NEON_2RM_VCVTMS:
184
- {
185
- bool is_signed = !extract32(insn, 7, 1);
186
- TCGv_ptr fpst = get_fpstatus_ptr(1);
187
- TCGv_i32 tcg_rmode, tcg_shift;
188
- int rmode = fp_decode_rm[extract32(insn, 8, 2)];
189
-
57
-
190
- tcg_shift = tcg_const_i32(0);
58
- switch (surface_bits_per_pixel(surface)) {
191
- tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
59
- case 8:
192
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
60
- tc6393xb_draw_graphic8(s);
193
- cpu_env);
61
- break;
62
- case 15:
63
- tc6393xb_draw_graphic15(s);
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
- }
194
-
79
-
195
- if (is_signed) {
80
+ tc6393xb_draw_graphic32(s);
196
- gen_helper_vfp_tosls(tmp, tmp,
81
dpy_gfx_update_full(s->con);
197
- tcg_shift, fpst);
82
}
198
- } else {
83
199
- gen_helper_vfp_touls(tmp, tmp,
200
- tcg_shift, fpst);
201
- }
202
-
203
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
204
- cpu_env);
205
- tcg_temp_free_i32(tcg_rmode);
206
- tcg_temp_free_i32(tcg_shift);
207
- tcg_temp_free_ptr(fpst);
208
- break;
209
- }
210
default:
211
/* Reserved op values were caught by the
212
* neon_2rm_sizes[] check earlier.
213
--
84
--
214
2.20.1
85
2.20.1
215
86
216
87
diff view generated by jsdifflib
1
Convert the Neon VSWP insn to decodetree. Since the new implementation
1
Now the template header is included only for BITS==32, expand
2
doesn't have to share a pass-loop with the other 2-reg-misc operations
2
out all the macros that depended on the BITS setting.
3
we can implement the swap with 64-bit accesses rather than 32-bits
4
(which brings us into line with the pseudocode and is more efficient).
5
3
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200616170844.13318-20-peter.maydell@linaro.org
6
Message-id: 20210215103215.4944-4-peter.maydell@linaro.org
9
---
7
---
10
target/arm/neon-dp.decode | 2 ++
8
hw/display/tc6393xb_template.h | 35 ++++------------------------------
11
target/arm/translate-neon.inc.c | 41 +++++++++++++++++++++++++++++++++
9
1 file changed, 4 insertions(+), 31 deletions(-)
12
target/arm/translate.c | 5 +---
13
3 files changed, 44 insertions(+), 4 deletions(-)
14
10
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
11
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
13
--- a/hw/display/tc6393xb_template.h
18
+++ b/target/arm/neon-dp.decode
14
+++ b/hw/display/tc6393xb_template.h
19
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
15
@@ -XXX,XX +XXX,XX @@
20
VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
21
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
17
*/
22
18
23
+ VSWP 1111 001 11 . 11 .. 10 .... 0 0000 . . 0 .... @2misc
19
-#if BITS == 8
24
+
20
-# define SET_PIXEL(addr, color) (*(uint8_t *)addr = color)
25
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
21
-#elif BITS == 15 || BITS == 16
26
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
22
-# define SET_PIXEL(addr, color) (*(uint16_t *)addr = color)
27
23
-#elif BITS == 24
28
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
24
-# define SET_PIXEL(addr, color) \
29
index XXXXXXX..XXXXXXX 100644
25
- do { \
30
--- a/target/arm/translate-neon.inc.c
26
- addr[0] = color; \
31
+++ b/target/arm/translate-neon.inc.c
27
- addr[1] = (color) >> 8; \
32
@@ -XXX,XX +XXX,XX @@ DO_VCVT(VCVTPU, FPROUNDING_POSINF, false)
28
- addr[2] = (color) >> 16; \
33
DO_VCVT(VCVTPS, FPROUNDING_POSINF, true)
29
- } while (0)
34
DO_VCVT(VCVTMU, FPROUNDING_NEGINF, false)
30
-#elif BITS == 32
35
DO_VCVT(VCVTMS, FPROUNDING_NEGINF, true)
31
-# define SET_PIXEL(addr, color) (*(uint32_t *)addr = color)
36
+
32
-#else
37
+static bool trans_VSWP(DisasContext *s, arg_2misc *a)
33
-# error unknown bit depth
38
+{
34
-#endif
39
+ TCGv_i64 rm, rd;
35
-
40
+ int pass;
36
-
41
+
37
-static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
42
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
38
+static void tc6393xb_draw_graphic32(TC6393xbState *s)
43
+ return false;
39
{
44
+ }
40
DisplaySurface *surface = qemu_console_surface(s->con);
45
+
41
int i;
46
+ /* UNDEF accesses to D16-D31 if they don't exist. */
42
@@ -XXX,XX +XXX,XX @@ static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
47
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
43
data_buffer = s->vram_ptr;
48
+ ((a->vd | a->vm) & 0x10)) {
44
data_display = surface_data(surface);
49
+ return false;
45
for(i = 0; i < s->scr_height; i++) {
50
+ }
46
-#if (BITS == 16)
51
+
47
- memcpy(data_display, data_buffer, s->scr_width * 2);
52
+ if (a->size != 0) {
48
- data_buffer += s->scr_width;
53
+ return false;
49
- data_display += surface_stride(surface);
54
+ }
50
-#else
55
+
51
int j;
56
+ if ((a->vd | a->vm) & a->q) {
52
- for (j = 0; j < s->scr_width; j++, data_display += BITS / 8, data_buffer++) {
57
+ return false;
53
+ for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
58
+ }
54
uint16_t color = *data_buffer;
59
+
55
- uint32_t dest_color = glue(rgb_to_pixel, BITS)(
60
+ if (!vfp_access_check(s)) {
56
+ uint32_t dest_color = rgb_to_pixel32(
61
+ return true;
57
((color & 0xf800) * 0x108) >> 11,
62
+ }
58
((color & 0x7e0) * 0x41) >> 9,
63
+
59
((color & 0x1f) * 0x21) >> 2
64
+ rm = tcg_temp_new_i64();
60
);
65
+ rd = tcg_temp_new_i64();
61
- SET_PIXEL(data_display, dest_color);
66
+ for (pass = 0; pass < (a->q ? 2 : 1); pass++) {
62
+ *(uint32_t *)data_display = dest_color;
67
+ neon_load_reg64(rm, a->vm + pass);
63
}
68
+ neon_load_reg64(rd, a->vd + pass);
64
-#endif
69
+ neon_store_reg64(rm, a->vd + pass);
65
}
70
+ neon_store_reg64(rd, a->vm + pass);
66
}
71
+ }
67
-
72
+ tcg_temp_free_i64(rm);
68
-#undef BITS
73
+ tcg_temp_free_i64(rd);
69
-#undef SET_PIXEL
74
+
75
+ return true;
76
+}
77
diff --git a/target/arm/translate.c b/target/arm/translate.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/arm/translate.c
80
+++ b/target/arm/translate.c
81
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
82
case NEON_2RM_VCVTPS:
83
case NEON_2RM_VCVTMU:
84
case NEON_2RM_VCVTMS:
85
+ case NEON_2RM_VSWP:
86
/* handled by decodetree */
87
return 1;
88
case NEON_2RM_VTRN:
89
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
90
for (pass = 0; pass < (q ? 4 : 2); pass++) {
91
tmp = neon_load_reg(rm, pass);
92
switch (op) {
93
- case NEON_2RM_VSWP:
94
- tmp2 = neon_load_reg(rd, pass);
95
- neon_store_reg(rm, pass, tmp2);
96
- break;
97
case NEON_2RM_VTRN:
98
tmp2 = neon_load_reg(rd, pass);
99
switch (size) {
100
--
70
--
101
2.20.1
71
2.20.1
102
72
103
73
diff view generated by jsdifflib
1
Convert the Neon narrowing moves VMQNV, VQMOVN, VQMOVUN in the 2-reg-misc
1
The function tc6393xb_draw_graphic32() is called in exactly one place,
2
group to decodetree.
2
so just inline the function body at its callsite. This allows us to
3
drop the template header entirely.
4
5
The code move includes a single added space after 'for' to fix
6
the coding style.
3
7
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-5-peter.maydell@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/neon-dp.decode | 9 ++++
13
hw/display/tc6393xb_template.h | 45 ----------------------------------
9
target/arm/translate-neon.inc.c | 59 ++++++++++++++++++++++++
14
hw/display/tc6393xb.c | 23 ++++++++++++++---
10
target/arm/translate.c | 81 +--------------------------------
15
2 files changed, 19 insertions(+), 49 deletions(-)
11
3 files changed, 70 insertions(+), 79 deletions(-)
16
delete mode 100644 hw/display/tc6393xb_template.h
12
17
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
18
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
14
index XXXXXXX..XXXXXXX 100644
19
deleted file mode 100644
15
--- a/target/arm/neon-dp.decode
20
index XXXXXXX..XXXXXXX
16
+++ b/target/arm/neon-dp.decode
21
--- a/hw/display/tc6393xb_template.h
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
22
+++ /dev/null
18
23
@@ -XXX,XX +XXX,XX @@
19
@2misc .... ... .. . .. size:2 .. .... . .... q:1 . . .... \
24
-/*
20
&2misc vm=%vm_dp vd=%vd_dp
25
- * Toshiba TC6393XB I/O Controller.
21
+ @2misc_q0 .... ... .. . .. size:2 .. .... . .... . . . .... \
26
- * Found in Sharp Zaurus SL-6000 (tosa) or some
22
+ &2misc vm=%vm_dp vd=%vd_dp q=0
27
- * Toshiba e-Series PDAs.
23
28
- *
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
29
- * FB support code. Based on G364 fb emulator
25
30
- *
26
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
31
- * Copyright (c) 2007 Hervé Poussineau
27
32
- *
28
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
33
- * This program is free software; you can redistribute it and/or
29
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
34
- * modify it under the terms of the GNU General Public License as
30
+
35
- * published by the Free Software Foundation; either version 2 of
31
+ VMOVN 1111 001 11 . 11 .. 10 .... 0 0100 0 . 0 .... @2misc_q0
36
- * the License, or (at your option) any later version.
32
+ # VQMOVUN: unsigned result (source is always signed)
37
- *
33
+ VQMOVUN 1111 001 11 . 11 .. 10 .... 0 0100 1 . 0 .... @2misc_q0
38
- * This program is distributed in the hope that it will be useful,
34
+ # VQMOVN: signed result, source may be signed (_S) or unsigned (_U)
39
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
35
+ VQMOVN_S 1111 001 11 . 11 .. 10 .... 0 0101 0 . 0 .... @2misc_q0
40
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36
+ VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
41
- * GNU General Public License for more details.
37
]
42
- *
38
43
- * You should have received a copy of the GNU General Public License along
39
# Subgroup for size != 0b11
44
- * with this program; if not, see <http://www.gnu.org/licenses/>.
40
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
45
- */
41
index XXXXXXX..XXXXXXX 100644
46
-
42
--- a/target/arm/translate-neon.inc.c
47
-static void tc6393xb_draw_graphic32(TC6393xbState *s)
43
+++ b/target/arm/translate-neon.inc.c
44
@@ -XXX,XX +XXX,XX @@ static bool trans_VZIP(DisasContext *s, arg_2misc *a)
45
};
46
return do_zip_uzp(s, a, fn[a->q][a->size]);
47
}
48
+
49
+static bool do_vmovn(DisasContext *s, arg_2misc *a,
50
+ NeonGenNarrowEnvFn *narrowfn)
51
+{
52
+ TCGv_i64 rm;
53
+ TCGv_i32 rd0, rd1;
54
+
55
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
56
+ return false;
57
+ }
58
+
59
+ /* UNDEF accesses to D16-D31 if they don't exist. */
60
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
61
+ ((a->vd | a->vm) & 0x10)) {
62
+ return false;
63
+ }
64
+
65
+ if (a->vm & 1) {
66
+ return false;
67
+ }
68
+
69
+ if (!narrowfn) {
70
+ return false;
71
+ }
72
+
73
+ if (!vfp_access_check(s)) {
74
+ return true;
75
+ }
76
+
77
+ rm = tcg_temp_new_i64();
78
+ rd0 = tcg_temp_new_i32();
79
+ rd1 = tcg_temp_new_i32();
80
+
81
+ neon_load_reg64(rm, a->vm);
82
+ narrowfn(rd0, cpu_env, rm);
83
+ neon_load_reg64(rm, a->vm + 1);
84
+ narrowfn(rd1, cpu_env, rm);
85
+ neon_store_reg(a->vd, 0, rd0);
86
+ neon_store_reg(a->vd, 1, rd1);
87
+ tcg_temp_free_i64(rm);
88
+ return true;
89
+}
90
+
91
+#define DO_VMOVN(INSN, FUNC) \
92
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
93
+ { \
94
+ static NeonGenNarrowEnvFn * const narrowfn[] = { \
95
+ FUNC##8, \
96
+ FUNC##16, \
97
+ FUNC##32, \
98
+ NULL, \
99
+ }; \
100
+ return do_vmovn(s, a, narrowfn[a->size]); \
101
+ }
102
+
103
+DO_VMOVN(VMOVN, gen_neon_narrow_u)
104
+DO_VMOVN(VQMOVUN, gen_helper_neon_unarrow_sat)
105
+DO_VMOVN(VQMOVN_S, gen_helper_neon_narrow_sat_s)
106
+DO_VMOVN(VQMOVN_U, gen_helper_neon_narrow_sat_u)
107
diff --git a/target/arm/translate.c b/target/arm/translate.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/target/arm/translate.c
110
+++ b/target/arm/translate.c
111
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
112
tcg_temp_free_i32(rd);
113
}
114
115
-static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
116
-{
48
-{
117
- switch (size) {
49
- DisplaySurface *surface = qemu_console_surface(s->con);
118
- case 0: gen_helper_neon_narrow_u8(dest, src); break;
50
- int i;
119
- case 1: gen_helper_neon_narrow_u16(dest, src); break;
51
- uint16_t *data_buffer;
120
- case 2: tcg_gen_extrl_i64_i32(dest, src); break;
52
- uint8_t *data_display;
121
- default: abort();
122
- }
123
-}
124
-
53
-
125
-static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
54
- data_buffer = s->vram_ptr;
126
-{
55
- data_display = surface_data(surface);
127
- switch (size) {
56
- for(i = 0; i < s->scr_height; i++) {
128
- case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
57
- int j;
129
- case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
58
- for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
130
- case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
59
- uint16_t color = *data_buffer;
131
- default: abort();
60
- uint32_t dest_color = rgb_to_pixel32(
132
- }
61
- ((color & 0xf800) * 0x108) >> 11,
133
-}
62
- ((color & 0x7e0) * 0x41) >> 9,
134
-
63
- ((color & 0x1f) * 0x21) >> 2
135
-static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
64
- );
136
-{
65
- *(uint32_t *)data_display = dest_color;
137
- switch (size) {
138
- case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
139
- case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
140
- case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
141
- default: abort();
142
- }
143
-}
144
-
145
-static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
146
-{
147
- switch (size) {
148
- case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
149
- case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
150
- case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
151
- default: abort();
152
- }
153
-}
154
-
155
static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
156
{
157
if (u) {
158
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
159
tcg_temp_free_i32(src);
160
}
161
162
-static void gen_neon_narrow_op(int op, int u, int size,
163
- TCGv_i32 dest, TCGv_i64 src)
164
-{
165
- if (op) {
166
- if (u) {
167
- gen_neon_unarrow_sats(size, dest, src);
168
- } else {
169
- gen_neon_narrow(size, dest, src);
170
- }
171
- } else {
172
- if (u) {
173
- gen_neon_narrow_satu(size, dest, src);
174
- } else {
175
- gen_neon_narrow_sats(size, dest, src);
176
- }
66
- }
177
- }
67
- }
178
-}
68
-}
69
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/display/tc6393xb.c
72
+++ b/hw/display/tc6393xb.c
73
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
74
(uint32_t) addr, value & 0xff);
75
}
76
77
-#define BITS 32
78
-#include "tc6393xb_template.h"
179
-
79
-
180
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
80
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
181
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
81
{
182
* table A7-13.
82
- tc6393xb_draw_graphic32(s);
183
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
83
+ DisplaySurface *surface = qemu_console_surface(s->con);
184
!arm_dc_feature(s, ARM_FEATURE_V8)) {
84
+ int i;
185
return 1;
85
+ uint16_t *data_buffer;
186
}
86
+ uint8_t *data_display;
187
- if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
87
+
188
- q && ((rm | rd) & 1)) {
88
+ data_buffer = s->vram_ptr;
189
+ if (q && ((rm | rd) & 1)) {
89
+ data_display = surface_data(surface);
190
return 1;
90
+ for (i = 0; i < s->scr_height; i++) {
191
}
91
+ int j;
192
switch (op) {
92
+ for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
193
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
93
+ uint16_t color = *data_buffer;
194
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
94
+ uint32_t dest_color = rgb_to_pixel32(
195
case NEON_2RM_VUZP:
95
+ ((color & 0xf800) * 0x108) >> 11,
196
case NEON_2RM_VZIP:
96
+ ((color & 0x7e0) * 0x41) >> 9,
197
+ case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
97
+ ((color & 0x1f) * 0x21) >> 2
198
/* handled by decodetree */
98
+ );
199
return 1;
99
+ *(uint32_t *)data_display = dest_color;
200
case NEON_2RM_VTRN:
100
+ }
201
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
101
+ }
202
goto elementwise;
102
dpy_gfx_update_full(s->con);
203
}
103
}
204
break;
104
205
- case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
206
- /* also VQMOVUN; op field and mnemonics don't line up */
207
- if (rm & 1) {
208
- return 1;
209
- }
210
- tmp2 = NULL;
211
- for (pass = 0; pass < 2; pass++) {
212
- neon_load_reg64(cpu_V0, rm + pass);
213
- tmp = tcg_temp_new_i32();
214
- gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
215
- tmp, cpu_V0);
216
- if (pass == 0) {
217
- tmp2 = tmp;
218
- } else {
219
- neon_store_reg(rd, 0, tmp2);
220
- neon_store_reg(rd, 1, tmp);
221
- }
222
- }
223
- break;
224
case NEON_2RM_VSHLL:
225
if (q || (rd & 1)) {
226
return 1;
227
--
105
--
228
2.20.1
106
2.20.1
229
107
230
108
diff view generated by jsdifflib
1
Make gen_swap_half() take a source and destination TCGv_i32 rather
1
The omap_lcdc template header is already only included once, for
2
than modifying the input TCGv_i32; we're going to want to be able to
2
DEPTH==32, but it still has all the macro-driven parameterization
3
use it with the more flexible function signature, and this also
3
for other depths. Expand out all the macros in the header.
4
brings it into line with other functions like gen_rev16() and
5
gen_revsh().
6
4
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200616170844.13318-12-peter.maydell@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210215103215.4944-6-peter.maydell@linaro.org
10
---
9
---
11
target/arm/translate-neon.inc.c | 2 +-
10
hw/display/omap_lcd_template.h | 67 ++++++++++++++--------------------
12
target/arm/translate.c | 10 +++++-----
11
1 file changed, 28 insertions(+), 39 deletions(-)
13
2 files changed, 6 insertions(+), 6 deletions(-)
14
12
15
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
13
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-neon.inc.c
15
--- a/hw/display/omap_lcd_template.h
18
+++ b/target/arm/translate-neon.inc.c
16
+++ b/hw/display/omap_lcd_template.h
19
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
17
@@ -XXX,XX +XXX,XX @@
20
tcg_gen_bswap32_i32(tmp[half], tmp[half]);
18
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21
break;
19
*/
22
case 1:
20
23
- gen_swap_half(tmp[half]);
21
-#if DEPTH == 32
24
+ gen_swap_half(tmp[half], tmp[half]);
22
-# define BPP 4
25
break;
23
-# define PIXEL_TYPE uint32_t
26
case 2:
24
-#else
27
break;
25
-# error unsupport depth
28
diff --git a/target/arm/translate.c b/target/arm/translate.c
26
-#endif
29
index XXXXXXX..XXXXXXX 100644
27
-
30
--- a/target/arm/translate.c
28
/*
31
+++ b/target/arm/translate.c
29
* 2-bit colour
32
@@ -XXX,XX +XXX,XX @@ static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
30
*/
31
-static void glue(draw_line2_, DEPTH)(void *opaque,
32
- uint8_t *d, const uint8_t *s, int width, int deststep)
33
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
34
+ int width, int deststep)
35
{
36
uint16_t *pal = opaque;
37
uint8_t v, r, g, b;
38
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line2_, DEPTH)(void *opaque,
39
r = (pal[v & 3] >> 4) & 0xf0;
40
g = pal[v & 3] & 0xf0;
41
b = (pal[v & 3] << 4) & 0xf0;
42
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
43
- d += BPP;
44
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
45
+ d += 4;
46
v >>= 2;
47
r = (pal[v & 3] >> 4) & 0xf0;
48
g = pal[v & 3] & 0xf0;
49
b = (pal[v & 3] << 4) & 0xf0;
50
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
51
- d += BPP;
52
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
53
+ d += 4;
54
v >>= 2;
55
r = (pal[v & 3] >> 4) & 0xf0;
56
g = pal[v & 3] & 0xf0;
57
b = (pal[v & 3] << 4) & 0xf0;
58
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
59
- d += BPP;
60
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
61
+ d += 4;
62
v >>= 2;
63
r = (pal[v & 3] >> 4) & 0xf0;
64
g = pal[v & 3] & 0xf0;
65
b = (pal[v & 3] << 4) & 0xf0;
66
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
67
- d += BPP;
68
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
69
+ d += 4;
70
s ++;
71
width -= 4;
72
} while (width > 0);
73
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line2_, DEPTH)(void *opaque,
74
/*
75
* 4-bit colour
76
*/
77
-static void glue(draw_line4_, DEPTH)(void *opaque,
78
- uint8_t *d, const uint8_t *s, int width, int deststep)
79
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
80
+ int width, int deststep)
81
{
82
uint16_t *pal = opaque;
83
uint8_t v, r, g, b;
84
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line4_, DEPTH)(void *opaque,
85
r = (pal[v & 0xf] >> 4) & 0xf0;
86
g = pal[v & 0xf] & 0xf0;
87
b = (pal[v & 0xf] << 4) & 0xf0;
88
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
89
- d += BPP;
90
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
91
+ d += 4;
92
v >>= 4;
93
r = (pal[v & 0xf] >> 4) & 0xf0;
94
g = pal[v & 0xf] & 0xf0;
95
b = (pal[v & 0xf] << 4) & 0xf0;
96
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
97
- d += BPP;
98
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
99
+ d += 4;
100
s ++;
101
width -= 2;
102
} while (width > 0);
103
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line4_, DEPTH)(void *opaque,
104
/*
105
* 8-bit colour
106
*/
107
-static void glue(draw_line8_, DEPTH)(void *opaque,
108
- uint8_t *d, const uint8_t *s, int width, int deststep)
109
+static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
110
+ int width, int deststep)
111
{
112
uint16_t *pal = opaque;
113
uint8_t v, r, g, b;
114
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line8_, DEPTH)(void *opaque,
115
r = (pal[v] >> 4) & 0xf0;
116
g = pal[v] & 0xf0;
117
b = (pal[v] << 4) & 0xf0;
118
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
119
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
120
s ++;
121
- d += BPP;
122
+ d += 4;
123
} while (-- width != 0);
33
}
124
}
34
125
35
/* Swap low and high halfwords. */
126
/*
36
-static void gen_swap_half(TCGv_i32 var)
127
* 12-bit colour
37
+static void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
128
*/
129
-static void glue(draw_line12_, DEPTH)(void *opaque,
130
- uint8_t *d, const uint8_t *s, int width, int deststep)
131
+static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
132
+ int width, int deststep)
38
{
133
{
39
- tcg_gen_rotri_i32(var, var, 16);
134
uint16_t v;
40
+ tcg_gen_rotri_i32(dest, var, 16);
135
uint8_t r, g, b;
136
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line12_, DEPTH)(void *opaque,
137
r = (v >> 4) & 0xf0;
138
g = v & 0xf0;
139
b = (v << 4) & 0xf0;
140
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
141
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
142
s += 2;
143
- d += BPP;
144
+ d += 4;
145
} while (-- width != 0);
41
}
146
}
42
147
43
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
148
/*
44
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
149
* 16-bit colour
45
case NEON_2RM_VREV32:
150
*/
46
switch (size) {
151
-static void glue(draw_line16_, DEPTH)(void *opaque,
47
case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
152
- uint8_t *d, const uint8_t *s, int width, int deststep)
48
- case 1: gen_swap_half(tmp); break;
153
+static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
49
+ case 1: gen_swap_half(tmp, tmp); break;
154
+ int width, int deststep)
50
default: abort();
155
{
51
}
156
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
52
break;
157
memcpy(d, s, width * 2);
53
@@ -XXX,XX +XXX,XX @@ static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
158
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line16_, DEPTH)(void *opaque,
54
t1 = load_reg(s, a->rn);
159
r = (v >> 8) & 0xf8;
55
t2 = load_reg(s, a->rm);
160
g = (v >> 3) & 0xfc;
56
if (m_swap) {
161
b = (v << 3) & 0xf8;
57
- gen_swap_half(t2);
162
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
58
+ gen_swap_half(t2, t2);
163
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
59
}
164
s += 2;
60
gen_smul_dual(t1, t2);
165
- d += BPP;
61
166
+ d += 4;
62
@@ -XXX,XX +XXX,XX @@ static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
167
} while (-- width != 0);
63
t1 = load_reg(s, a->rn);
168
#endif
64
t2 = load_reg(s, a->rm);
169
}
65
if (m_swap) {
170
-
66
- gen_swap_half(t2);
171
-#undef DEPTH
67
+ gen_swap_half(t2, t2);
172
-#undef BPP
68
}
173
-#undef PIXEL_TYPE
69
gen_smul_dual(t1, t2);
70
71
--
174
--
72
2.20.1
175
2.20.1
73
176
74
177
diff view generated by jsdifflib
New patch
1
The draw_line16_32() function in the omap_lcdc template header
2
includes an ifdef for the case where HOST_WORDS_BIGENDIAN matches
3
TARGET_WORDS_BIGENDIAN. This is trying to optimise for "source
4
bitmap and destination bitmap format match", but it is broken,
5
because in this function the formats don't match: the source is
6
16-bit colour and the destination is 32-bit colour, so a memcpy()
7
will produce corrupted graphics output. Drop the bogus ifdef.
1
8
9
This bug was introduced in commit ea644cf343129, when we dropped
10
support for DEPTH values other than 32 from the template header.
11
The old #if line was
12
#if DEPTH == 16 && defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
13
and this was mistakenly changed to
14
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
15
rather than deleting the #if as now having an always-false condition.
16
17
Fixes: ea644cf343129
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20210215103215.4944-7-peter.maydell@linaro.org
22
---
23
hw/display/omap_lcd_template.h | 4 ----
24
1 file changed, 4 deletions(-)
25
26
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/display/omap_lcd_template.h
29
+++ b/hw/display/omap_lcd_template.h
30
@@ -XXX,XX +XXX,XX @@ static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
31
static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
32
int width, int deststep)
33
{
34
-#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
35
- memcpy(d, s, width * 2);
36
-#else
37
uint16_t v;
38
uint8_t r, g, b;
39
40
@@ -XXX,XX +XXX,XX @@ static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
41
s += 2;
42
d += 4;
43
} while (-- width != 0);
44
-#endif
45
}
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
1
Convert the fp-compare-with-zero insns in the Neon 2-reg-misc group to
1
Fix some minor coding style issues in the template header,
2
decodetree.
2
so checkpatch doesn't complain when we move the code.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-17-peter.maydell@linaro.org
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215103215.4944-8-peter.maydell@linaro.org
7
---
8
---
8
target/arm/neon-dp.decode | 6 ++++
9
hw/display/omap_lcd_template.h | 6 +++---
9
target/arm/translate-neon.inc.c | 28 ++++++++++++++++++
10
1 file changed, 3 insertions(+), 3 deletions(-)
10
target/arm/translate.c | 50 ++++-----------------------------
11
3 files changed, 39 insertions(+), 45 deletions(-)
12
11
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
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/target/arm/neon-dp.decode
14
--- a/hw/display/omap_lcd_template.h
16
+++ b/target/arm/neon-dp.decode
15
+++ b/hw/display/omap_lcd_template.h
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
16
@@ -XXX,XX +XXX,XX @@ static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
18
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
17
b = (pal[v & 3] << 4) & 0xf0;
19
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
18
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
20
19
d += 4;
21
+ VCGT0_F 1111 001 11 . 11 .. 01 .... 0 1000 . . 0 .... @2misc
20
- s ++;
22
+ VCGE0_F 1111 001 11 . 11 .. 01 .... 0 1001 . . 0 .... @2misc
21
+ s++;
23
+ VCEQ0_F 1111 001 11 . 11 .. 01 .... 0 1010 . . 0 .... @2misc
22
width -= 4;
24
+ VCLE0_F 1111 001 11 . 11 .. 01 .... 0 1011 . . 0 .... @2misc
23
} while (width > 0);
25
+ VCLT0_F 1111 001 11 . 11 .. 01 .... 0 1100 . . 0 .... @2misc
26
+
27
VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
28
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
29
30
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-neon.inc.c
33
+++ b/target/arm/translate-neon.inc.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VRINTX(DisasContext *s, arg_2misc *a)
35
}
36
return do_2misc_fp(s, a, gen_helper_rints_exact);
37
}
24
}
38
+
25
@@ -XXX,XX +XXX,XX @@ static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
39
+#define WRAP_FP_CMP0_FWD(WRAPNAME, FUNC) \
26
b = (pal[v & 0xf] << 4) & 0xf0;
40
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m, TCGv_ptr fpst) \
27
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
41
+ { \
28
d += 4;
42
+ TCGv_i32 zero = tcg_const_i32(0); \
29
- s ++;
43
+ FUNC(d, m, zero, fpst); \
30
+ s++;
44
+ tcg_temp_free_i32(zero); \
31
width -= 2;
45
+ }
32
} while (width > 0);
46
+#define WRAP_FP_CMP0_REV(WRAPNAME, FUNC) \
33
}
47
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m, TCGv_ptr fpst) \
34
@@ -XXX,XX +XXX,XX @@ static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
48
+ { \
35
g = pal[v] & 0xf0;
49
+ TCGv_i32 zero = tcg_const_i32(0); \
36
b = (pal[v] << 4) & 0xf0;
50
+ FUNC(d, zero, m, fpst); \
37
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
51
+ tcg_temp_free_i32(zero); \
38
- s ++;
52
+ }
39
+ s++;
53
+
40
d += 4;
54
+#define DO_FP_CMP0(INSN, FUNC, REV) \
41
} while (-- width != 0);
55
+ WRAP_FP_CMP0_##REV(gen_##INSN, FUNC) \
42
}
56
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
57
+ { \
58
+ return do_2misc_fp(s, a, gen_##INSN); \
59
+ }
60
+
61
+DO_FP_CMP0(VCGT0_F, gen_helper_neon_cgt_f32, FWD)
62
+DO_FP_CMP0(VCGE0_F, gen_helper_neon_cge_f32, FWD)
63
+DO_FP_CMP0(VCEQ0_F, gen_helper_neon_ceq_f32, FWD)
64
+DO_FP_CMP0(VCLE0_F, gen_helper_neon_cge_f32, REV)
65
+DO_FP_CMP0(VCLT0_F, gen_helper_neon_cgt_f32, REV)
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/arm/translate.c
69
+++ b/target/arm/translate.c
70
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
71
case NEON_2RM_VCVT_SF:
72
case NEON_2RM_VCVT_UF:
73
case NEON_2RM_VRINTX:
74
+ case NEON_2RM_VCGT0_F:
75
+ case NEON_2RM_VCGE0_F:
76
+ case NEON_2RM_VCEQ0_F:
77
+ case NEON_2RM_VCLE0_F:
78
+ case NEON_2RM_VCLT0_F:
79
/* handled by decodetree */
80
return 1;
81
case NEON_2RM_VTRN:
82
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
83
for (pass = 0; pass < (q ? 4 : 2); pass++) {
84
tmp = neon_load_reg(rm, pass);
85
switch (op) {
86
- case NEON_2RM_VCGT0_F:
87
- {
88
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
89
- tmp2 = tcg_const_i32(0);
90
- gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
91
- tcg_temp_free_i32(tmp2);
92
- tcg_temp_free_ptr(fpstatus);
93
- break;
94
- }
95
- case NEON_2RM_VCGE0_F:
96
- {
97
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
98
- tmp2 = tcg_const_i32(0);
99
- gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
100
- tcg_temp_free_i32(tmp2);
101
- tcg_temp_free_ptr(fpstatus);
102
- break;
103
- }
104
- case NEON_2RM_VCEQ0_F:
105
- {
106
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
107
- tmp2 = tcg_const_i32(0);
108
- gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
109
- tcg_temp_free_i32(tmp2);
110
- tcg_temp_free_ptr(fpstatus);
111
- break;
112
- }
113
- case NEON_2RM_VCLE0_F:
114
- {
115
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
116
- tmp2 = tcg_const_i32(0);
117
- gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
118
- tcg_temp_free_i32(tmp2);
119
- tcg_temp_free_ptr(fpstatus);
120
- break;
121
- }
122
- case NEON_2RM_VCLT0_F:
123
- {
124
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
125
- tmp2 = tcg_const_i32(0);
126
- gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
127
- tcg_temp_free_i32(tmp2);
128
- tcg_temp_free_ptr(fpstatus);
129
- break;
130
- }
131
case NEON_2RM_VSWP:
132
tmp2 = neon_load_reg(rd, pass);
133
neon_store_reg(rm, pass, tmp2);
134
--
43
--
135
2.20.1
44
2.20.1
136
45
137
46
diff view generated by jsdifflib
1
Convert the Neon 2-reg-misc insns which are implemented with
1
We only include the template header once, so just inline it into the
2
simple calls to functions that take the input, output and
2
source file for the device.
3
fpstatus pointer.
4
3
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200616170844.13318-16-peter.maydell@linaro.org
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215103215.4944-9-peter.maydell@linaro.org
8
---
8
---
9
target/arm/translate.h | 1 +
9
hw/display/omap_lcd_template.h | 154 ---------------------------------
10
target/arm/neon-dp.decode | 8 +++++
10
hw/display/omap_lcdc.c | 127 ++++++++++++++++++++++++++-
11
target/arm/translate-neon.inc.c | 62 +++++++++++++++++++++++++++++++++
11
2 files changed, 125 insertions(+), 156 deletions(-)
12
target/arm/translate.c | 56 ++++-------------------------
12
delete mode 100644 hw/display/omap_lcd_template.h
13
4 files changed, 78 insertions(+), 49 deletions(-)
14
13
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
14
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
15
deleted file mode 100644
16
index XXXXXXX..XXXXXXX
17
--- a/hw/display/omap_lcd_template.h
18
+++ /dev/null
19
@@ -XXX,XX +XXX,XX @@
20
-/*
21
- * QEMU OMAP LCD Emulator templates
22
- *
23
- * Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
24
- *
25
- * Redistribution and use in source and binary forms, with or without
26
- * modification, are permitted provided that the following conditions
27
- * are met:
28
- *
29
- * 1. Redistributions of source code must retain the above copyright
30
- * notice, this list of conditions and the following disclaimer.
31
- * 2. Redistributions in binary form must reproduce the above copyright
32
- * notice, this list of conditions and the following disclaimer in
33
- * the documentation and/or other materials provided with the
34
- * distribution.
35
- *
36
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
37
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
38
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
39
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
40
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
41
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
42
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
43
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
44
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
46
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
- */
48
-
49
-/*
50
- * 2-bit colour
51
- */
52
-static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
53
- int width, int deststep)
54
-{
55
- uint16_t *pal = opaque;
56
- uint8_t v, r, g, b;
57
-
58
- do {
59
- v = ldub_p((void *) s);
60
- r = (pal[v & 3] >> 4) & 0xf0;
61
- g = pal[v & 3] & 0xf0;
62
- b = (pal[v & 3] << 4) & 0xf0;
63
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
64
- d += 4;
65
- v >>= 2;
66
- r = (pal[v & 3] >> 4) & 0xf0;
67
- g = pal[v & 3] & 0xf0;
68
- b = (pal[v & 3] << 4) & 0xf0;
69
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
70
- d += 4;
71
- v >>= 2;
72
- r = (pal[v & 3] >> 4) & 0xf0;
73
- g = pal[v & 3] & 0xf0;
74
- b = (pal[v & 3] << 4) & 0xf0;
75
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
76
- d += 4;
77
- v >>= 2;
78
- r = (pal[v & 3] >> 4) & 0xf0;
79
- g = pal[v & 3] & 0xf0;
80
- b = (pal[v & 3] << 4) & 0xf0;
81
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
82
- d += 4;
83
- s++;
84
- width -= 4;
85
- } while (width > 0);
86
-}
87
-
88
-/*
89
- * 4-bit colour
90
- */
91
-static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
92
- int width, int deststep)
93
-{
94
- uint16_t *pal = opaque;
95
- uint8_t v, r, g, b;
96
-
97
- do {
98
- v = ldub_p((void *) s);
99
- r = (pal[v & 0xf] >> 4) & 0xf0;
100
- g = pal[v & 0xf] & 0xf0;
101
- b = (pal[v & 0xf] << 4) & 0xf0;
102
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
103
- d += 4;
104
- v >>= 4;
105
- r = (pal[v & 0xf] >> 4) & 0xf0;
106
- g = pal[v & 0xf] & 0xf0;
107
- b = (pal[v & 0xf] << 4) & 0xf0;
108
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
109
- d += 4;
110
- s++;
111
- width -= 2;
112
- } while (width > 0);
113
-}
114
-
115
-/*
116
- * 8-bit colour
117
- */
118
-static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
119
- int width, int deststep)
120
-{
121
- uint16_t *pal = opaque;
122
- uint8_t v, r, g, b;
123
-
124
- do {
125
- v = ldub_p((void *) s);
126
- r = (pal[v] >> 4) & 0xf0;
127
- g = pal[v] & 0xf0;
128
- b = (pal[v] << 4) & 0xf0;
129
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
130
- s++;
131
- d += 4;
132
- } while (-- width != 0);
133
-}
134
-
135
-/*
136
- * 12-bit colour
137
- */
138
-static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
139
- int width, int deststep)
140
-{
141
- uint16_t v;
142
- uint8_t r, g, b;
143
-
144
- do {
145
- v = lduw_le_p((void *) s);
146
- r = (v >> 4) & 0xf0;
147
- g = v & 0xf0;
148
- b = (v << 4) & 0xf0;
149
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
150
- s += 2;
151
- d += 4;
152
- } while (-- width != 0);
153
-}
154
-
155
-/*
156
- * 16-bit colour
157
- */
158
-static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
159
- int width, int deststep)
160
-{
161
- uint16_t v;
162
- uint8_t r, g, b;
163
-
164
- do {
165
- v = lduw_le_p((void *) s);
166
- r = (v >> 8) & 0xf8;
167
- g = (v >> 3) & 0xfc;
168
- b = (v << 3) & 0xf8;
169
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
170
- s += 2;
171
- d += 4;
172
- } while (-- width != 0);
173
-}
174
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
16
index XXXXXXX..XXXXXXX 100644
175
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
176
--- a/hw/display/omap_lcdc.c
18
+++ b/target/arm/translate.h
177
+++ b/hw/display/omap_lcdc.c
19
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
178
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
20
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
179
21
typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
180
#define draw_line_func drawfn
22
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
181
23
+typedef void NeonGenOneSingleOpFn(TCGv_i32, TCGv_i32, TCGv_ptr);
182
-#define DEPTH 32
24
typedef void NeonGenTwoSingleOpFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
183
-#include "omap_lcd_template.h"
25
typedef void NeonGenTwoDoubleOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
184
+/*
26
typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
185
+ * 2-bit colour
27
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
186
+ */
28
index XXXXXXX..XXXXXXX 100644
187
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
29
--- a/target/arm/neon-dp.decode
188
+ int width, int deststep)
30
+++ b/target/arm/neon-dp.decode
189
+{
31
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
190
+ uint16_t *pal = opaque;
32
SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
191
+ uint8_t v, r, g, b;
33
SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
192
+
34
193
+ do {
35
+ VRINTX 1111 001 11 . 11 .. 10 .... 0 1001 . . 0 .... @2misc
194
+ v = ldub_p((void *) s);
36
+
195
+ r = (pal[v & 3] >> 4) & 0xf0;
37
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
196
+ g = pal[v & 3] & 0xf0;
38
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
197
+ b = (pal[v & 3] << 4) & 0xf0;
39
198
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
40
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
199
+ d += 4;
41
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
200
+ v >>= 2;
42
+ VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
201
+ r = (pal[v & 3] >> 4) & 0xf0;
43
+ VRSQRTE_F 1111 001 11 . 11 .. 11 .... 0 1011 . . 0 .... @2misc
202
+ g = pal[v & 3] & 0xf0;
44
+ VCVT_FS 1111 001 11 . 11 .. 11 .... 0 1100 . . 0 .... @2misc
203
+ b = (pal[v & 3] << 4) & 0xf0;
45
+ VCVT_FU 1111 001 11 . 11 .. 11 .... 0 1101 . . 0 .... @2misc
204
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
46
+ VCVT_SF 1111 001 11 . 11 .. 11 .... 0 1110 . . 0 .... @2misc
205
+ d += 4;
47
+ VCVT_UF 1111 001 11 . 11 .. 11 .... 0 1111 . . 0 .... @2misc
206
+ v >>= 2;
48
]
207
+ r = (pal[v & 3] >> 4) & 0xf0;
49
208
+ g = pal[v & 3] & 0xf0;
50
# Subgroup for size != 0b11
209
+ b = (pal[v & 3] << 4) & 0xf0;
51
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
210
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
52
index XXXXXXX..XXXXXXX 100644
211
+ d += 4;
53
--- a/target/arm/translate-neon.inc.c
212
+ v >>= 2;
54
+++ b/target/arm/translate-neon.inc.c
213
+ r = (pal[v & 3] >> 4) & 0xf0;
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VQNEG(DisasContext *s, arg_2misc *a)
214
+ g = pal[v & 3] & 0xf0;
56
};
215
+ b = (pal[v & 3] << 4) & 0xf0;
57
return do_2misc(s, a, fn[a->size]);
216
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
58
}
217
+ d += 4;
59
+
218
+ s++;
60
+static bool do_2misc_fp(DisasContext *s, arg_2misc *a,
219
+ width -= 4;
61
+ NeonGenOneSingleOpFn *fn)
220
+ } while (width > 0);
62
+{
221
+}
63
+ int pass;
222
+
64
+ TCGv_ptr fpst;
223
+/*
65
+
224
+ * 4-bit colour
66
+ /* Handle a 2-reg-misc operation by iterating 32 bits at a time */
225
+ */
67
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
226
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
68
+ return false;
227
+ int width, int deststep)
69
+ }
228
+{
70
+
229
+ uint16_t *pal = opaque;
71
+ /* UNDEF accesses to D16-D31 if they don't exist. */
230
+ uint8_t v, r, g, b;
72
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
231
+
73
+ ((a->vd | a->vm) & 0x10)) {
232
+ do {
74
+ return false;
233
+ v = ldub_p((void *) s);
75
+ }
234
+ r = (pal[v & 0xf] >> 4) & 0xf0;
76
+
235
+ g = pal[v & 0xf] & 0xf0;
77
+ if (a->size != 2) {
236
+ b = (pal[v & 0xf] << 4) & 0xf0;
78
+ /* TODO: FP16 will be the size == 1 case */
237
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
79
+ return false;
238
+ d += 4;
80
+ }
239
+ v >>= 4;
81
+
240
+ r = (pal[v & 0xf] >> 4) & 0xf0;
82
+ if ((a->vd | a->vm) & a->q) {
241
+ g = pal[v & 0xf] & 0xf0;
83
+ return false;
242
+ b = (pal[v & 0xf] << 4) & 0xf0;
84
+ }
243
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
85
+
244
+ d += 4;
86
+ if (!vfp_access_check(s)) {
245
+ s++;
87
+ return true;
246
+ width -= 2;
88
+ }
247
+ } while (width > 0);
89
+
248
+}
90
+ fpst = get_fpstatus_ptr(1);
249
+
91
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
250
+/*
92
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
251
+ * 8-bit colour
93
+ fn(tmp, tmp, fpst);
252
+ */
94
+ neon_store_reg(a->vd, pass, tmp);
253
+static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
95
+ }
254
+ int width, int deststep)
96
+ tcg_temp_free_ptr(fpst);
255
+{
97
+
256
+ uint16_t *pal = opaque;
98
+ return true;
257
+ uint8_t v, r, g, b;
99
+}
258
+
100
+
259
+ do {
101
+#define DO_2MISC_FP(INSN, FUNC) \
260
+ v = ldub_p((void *) s);
102
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
261
+ r = (pal[v] >> 4) & 0xf0;
103
+ { \
262
+ g = pal[v] & 0xf0;
104
+ return do_2misc_fp(s, a, FUNC); \
263
+ b = (pal[v] << 4) & 0xf0;
105
+ }
264
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
106
+
265
+ s++;
107
+DO_2MISC_FP(VRECPE_F, gen_helper_recpe_f32)
266
+ d += 4;
108
+DO_2MISC_FP(VRSQRTE_F, gen_helper_rsqrte_f32)
267
+ } while (-- width != 0);
109
+DO_2MISC_FP(VCVT_FS, gen_helper_vfp_sitos)
268
+}
110
+DO_2MISC_FP(VCVT_FU, gen_helper_vfp_uitos)
269
+
111
+DO_2MISC_FP(VCVT_SF, gen_helper_vfp_tosizs)
270
+/*
112
+DO_2MISC_FP(VCVT_UF, gen_helper_vfp_touizs)
271
+ * 12-bit colour
113
+
272
+ */
114
+static bool trans_VRINTX(DisasContext *s, arg_2misc *a)
273
+static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
115
+{
274
+ int width, int deststep)
116
+ if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
275
+{
117
+ return false;
276
+ uint16_t v;
118
+ }
277
+ uint8_t r, g, b;
119
+ return do_2misc_fp(s, a, gen_helper_rints_exact);
278
+
120
+}
279
+ do {
121
diff --git a/target/arm/translate.c b/target/arm/translate.c
280
+ v = lduw_le_p((void *) s);
122
index XXXXXXX..XXXXXXX 100644
281
+ r = (v >> 4) & 0xf0;
123
--- a/target/arm/translate.c
282
+ g = v & 0xf0;
124
+++ b/target/arm/translate.c
283
+ b = (v << 4) & 0xf0;
125
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
284
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
126
case NEON_2RM_VRSQRTE:
285
+ s += 2;
127
case NEON_2RM_VQABS:
286
+ d += 4;
128
case NEON_2RM_VQNEG:
287
+ } while (-- width != 0);
129
+ case NEON_2RM_VRECPE_F:
288
+}
130
+ case NEON_2RM_VRSQRTE_F:
289
+
131
+ case NEON_2RM_VCVT_FS:
290
+/*
132
+ case NEON_2RM_VCVT_FU:
291
+ * 16-bit colour
133
+ case NEON_2RM_VCVT_SF:
292
+ */
134
+ case NEON_2RM_VCVT_UF:
293
+static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
135
+ case NEON_2RM_VRINTX:
294
+ int width, int deststep)
136
/* handled by decodetree */
295
+{
137
return 1;
296
+ uint16_t v;
138
case NEON_2RM_VTRN:
297
+ uint8_t r, g, b;
139
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
298
+
140
tcg_temp_free_i32(tcg_rmode);
299
+ do {
141
break;
300
+ v = lduw_le_p((void *) s);
142
}
301
+ r = (v >> 8) & 0xf8;
143
- case NEON_2RM_VRINTX:
302
+ g = (v >> 3) & 0xfc;
144
- {
303
+ b = (v << 3) & 0xf8;
145
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
304
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
146
- gen_helper_rints_exact(tmp, tmp, fpstatus);
305
+ s += 2;
147
- tcg_temp_free_ptr(fpstatus);
306
+ d += 4;
148
- break;
307
+ } while (-- width != 0);
149
- }
308
+}
150
case NEON_2RM_VCVTAU:
309
151
case NEON_2RM_VCVTAS:
310
static void omap_update_display(void *opaque)
152
case NEON_2RM_VCVTNU:
311
{
153
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
154
tcg_temp_free_ptr(fpst);
155
break;
156
}
157
- case NEON_2RM_VRECPE_F:
158
- {
159
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
160
- gen_helper_recpe_f32(tmp, tmp, fpstatus);
161
- tcg_temp_free_ptr(fpstatus);
162
- break;
163
- }
164
- case NEON_2RM_VRSQRTE_F:
165
- {
166
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
167
- gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
168
- tcg_temp_free_ptr(fpstatus);
169
- break;
170
- }
171
- case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
172
- {
173
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
174
- gen_helper_vfp_sitos(tmp, tmp, fpstatus);
175
- tcg_temp_free_ptr(fpstatus);
176
- break;
177
- }
178
- case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
179
- {
180
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
181
- gen_helper_vfp_uitos(tmp, tmp, fpstatus);
182
- tcg_temp_free_ptr(fpstatus);
183
- break;
184
- }
185
- case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
186
- {
187
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
188
- gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
189
- tcg_temp_free_ptr(fpstatus);
190
- break;
191
- }
192
- case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
193
- {
194
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
195
- gen_helper_vfp_touizs(tmp, tmp, fpstatus);
196
- tcg_temp_free_ptr(fpstatus);
197
- break;
198
- }
199
default:
200
/* Reserved op values were caught by the
201
* neon_2rm_sizes[] check earlier.
202
--
312
--
203
2.20.1
313
2.20.1
204
314
205
315
diff view generated by jsdifflib
1
Convert the Neon VQABS and VQNEG insns to decodetree.
1
The macro draw_line_func is used only once; just expand it.
2
Since these are the only ones which need cpu_env passing to
3
the helper, we wrap the helper rather than creating a whole
4
new do_2misc_env() function.
5
2
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200616170844.13318-15-peter.maydell@linaro.org
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210215103215.4944-10-peter.maydell@linaro.org
9
---
7
---
10
target/arm/neon-dp.decode | 3 +++
8
hw/display/omap_lcdc.c | 4 +---
11
target/arm/translate-neon.inc.c | 35 +++++++++++++++++++++++++++++++++
9
1 file changed, 1 insertion(+), 3 deletions(-)
12
target/arm/translate.c | 30 ++--------------------------
13
3 files changed, 40 insertions(+), 28 deletions(-)
14
10
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
11
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
13
--- a/hw/display/omap_lcdc.c
18
+++ b/target/arm/neon-dp.decode
14
+++ b/hw/display/omap_lcdc.c
19
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
15
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
20
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
16
qemu_irq_lower(s->irq);
21
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
22
23
+ VQABS 1111 001 11 . 11 .. 00 .... 0 1110 . . 0 .... @2misc
24
+ VQNEG 1111 001 11 . 11 .. 00 .... 0 1111 . . 0 .... @2misc
25
+
26
VCGT0 1111 001 11 . 11 .. 01 .... 0 0000 . . 0 .... @2misc
27
VCGE0 1111 001 11 . 11 .. 01 .... 0 0001 . . 0 .... @2misc
28
VCEQ0 1111 001 11 . 11 .. 01 .... 0 0010 . . 0 .... @2misc
29
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/translate-neon.inc.c
32
+++ b/target/arm/translate-neon.inc.c
33
@@ -XXX,XX +XXX,XX @@ static bool trans_VRSQRTE(DisasContext *s, arg_2misc *a)
34
}
35
return do_2misc(s, a, gen_helper_rsqrte_u32);
36
}
17
}
37
+
18
38
+#define WRAP_1OP_ENV_FN(WRAPNAME, FUNC) \
19
-#define draw_line_func drawfn
39
+ static void WRAPNAME(TCGv_i32 d, TCGv_i32 m) \
20
-
40
+ { \
21
/*
41
+ FUNC(d, cpu_env, m); \
22
* 2-bit colour
42
+ }
23
*/
43
+
24
@@ -XXX,XX +XXX,XX @@ static void omap_update_display(void *opaque)
44
+WRAP_1OP_ENV_FN(gen_VQABS_s8, gen_helper_neon_qabs_s8)
25
{
45
+WRAP_1OP_ENV_FN(gen_VQABS_s16, gen_helper_neon_qabs_s16)
26
struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
46
+WRAP_1OP_ENV_FN(gen_VQABS_s32, gen_helper_neon_qabs_s32)
27
DisplaySurface *surface;
47
+WRAP_1OP_ENV_FN(gen_VQNEG_s8, gen_helper_neon_qneg_s8)
28
- draw_line_func draw_line;
48
+WRAP_1OP_ENV_FN(gen_VQNEG_s16, gen_helper_neon_qneg_s16)
29
+ drawfn draw_line;
49
+WRAP_1OP_ENV_FN(gen_VQNEG_s32, gen_helper_neon_qneg_s32)
30
int size, height, first, last;
50
+
31
int width, linesize, step, bpp, frame_offset;
51
+static bool trans_VQABS(DisasContext *s, arg_2misc *a)
32
hwaddr frame_base;
52
+{
53
+ static NeonGenOneOpFn * const fn[] = {
54
+ gen_VQABS_s8,
55
+ gen_VQABS_s16,
56
+ gen_VQABS_s32,
57
+ NULL,
58
+ };
59
+ return do_2misc(s, a, fn[a->size]);
60
+}
61
+
62
+static bool trans_VQNEG(DisasContext *s, arg_2misc *a)
63
+{
64
+ static NeonGenOneOpFn * const fn[] = {
65
+ gen_VQNEG_s8,
66
+ gen_VQNEG_s16,
67
+ gen_VQNEG_s32,
68
+ NULL,
69
+ };
70
+ return do_2misc(s, a, fn[a->size]);
71
+}
72
diff --git a/target/arm/translate.c b/target/arm/translate.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/translate.c
75
+++ b/target/arm/translate.c
76
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
77
case NEON_2RM_VNEG_F:
78
case NEON_2RM_VRECPE:
79
case NEON_2RM_VRSQRTE:
80
+ case NEON_2RM_VQABS:
81
+ case NEON_2RM_VQNEG:
82
/* handled by decodetree */
83
return 1;
84
case NEON_2RM_VTRN:
85
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
86
for (pass = 0; pass < (q ? 4 : 2); pass++) {
87
tmp = neon_load_reg(rm, pass);
88
switch (op) {
89
- case NEON_2RM_VQABS:
90
- switch (size) {
91
- case 0:
92
- gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
93
- break;
94
- case 1:
95
- gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
96
- break;
97
- case 2:
98
- gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
99
- break;
100
- default: abort();
101
- }
102
- break;
103
- case NEON_2RM_VQNEG:
104
- switch (size) {
105
- case 0:
106
- gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
107
- break;
108
- case 1:
109
- gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
110
- break;
111
- case 2:
112
- gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
113
- break;
114
- default: abort();
115
- }
116
- break;
117
case NEON_2RM_VCGT0_F:
118
{
119
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
120
--
33
--
121
2.20.1
34
2.20.1
122
35
123
36
diff view generated by jsdifflib
New patch
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().
1
8
9
Drop the never-used BGR-handling code, and assert that we have
10
a 32-bit surface rather than just doing nothing if it isn't.
11
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
16
---
17
hw/display/tcx.c | 31 ++++++++-----------------------
18
1 file changed, 8 insertions(+), 23 deletions(-)
19
20
diff --git a/hw/display/tcx.c b/hw/display/tcx.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/display/tcx.c
23
+++ b/hw/display/tcx.c
24
@@ -XXX,XX +XXX,XX @@ static int tcx_check_dirty(TCXState *s, DirtyBitmapSnapshot *snap,
25
26
static void update_palette_entries(TCXState *s, int start, int end)
27
{
28
- DisplaySurface *surface = qemu_console_surface(s->con);
29
int i;
30
31
for (i = start; i < end; i++) {
32
- if (is_surface_bgr(surface)) {
33
- s->palette[i] = rgb_to_pixel32bgr(s->r[i], s->g[i], s->b[i]);
34
- } else {
35
- s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
36
- }
37
+ s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
38
}
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) {
84
- return;
85
- }
86
+ assert(surface_bits_per_pixel(surface) == 32);
87
88
page = 0;
89
y_start = -1;
90
@@ -XXX,XX +XXX,XX @@ static void tcx24_update_display(void *opaque)
91
uint8_t *d, *s;
92
uint32_t *cptr, *s24;
93
94
- if (surface_bits_per_pixel(surface) != 32) {
95
- return;
96
- }
97
+ assert(surface_bits_per_pixel(surface) == 32);
98
99
page = 0;
100
y_start = -1;
101
--
102
2.20.1
103
104
diff view generated by jsdifflib
New patch
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.
1
4
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
9
---
10
hw/arm/mps2-tz.c | 10 ++++++----
11
1 file changed, 6 insertions(+), 4 deletions(-)
12
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
16
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
18
MachineClass parent;
19
MPS2TZFPGAType fpga_type;
20
uint32_t scc_id;
21
+ uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
22
const char *armsse_type;
23
};
24
25
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
26
27
OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
28
29
-/* Main SYSCLK frequency in Hz */
30
-#define SYSCLK_FRQ 20000000
31
/* Slow 32Khz S32KCLK frequency in Hz */
32
#define S32KCLK_FRQ (32 * 1000)
33
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
35
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
36
const char *name, hwaddr size)
37
{
38
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
39
CMSDKAPBUART *uart = opaque;
40
int i = uart - &mms->uart[0];
41
int rxirqno = i * 2;
42
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
43
44
object_initialize_child(OBJECT(mms), name, uart, TYPE_CMSDK_APB_UART);
45
qdev_prop_set_chr(DEVICE(uart), "chardev", serial_hd(i));
46
- qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", SYSCLK_FRQ);
47
+ qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
48
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
49
s = SYS_BUS_DEVICE(uart);
50
sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
51
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
52
53
/* These clocks don't need migration because they are fixed-frequency */
54
mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
55
- clock_set_hz(mms->sysclk, SYSCLK_FRQ);
56
+ clock_set_hz(mms->sysclk, mmc->sysclk_frq);
57
mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
58
clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
59
60
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
61
mmc->fpga_type = FPGA_AN505;
62
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
63
mmc->scc_id = 0x41045050;
64
+ mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
65
mmc->armsse_type = TYPE_IOTKIT;
66
}
67
68
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
69
mmc->fpga_type = FPGA_AN521;
70
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
71
mmc->scc_id = 0x41045210;
72
+ mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
73
mmc->armsse_type = TYPE_SSE200;
74
}
75
76
--
77
2.20.1
78
79
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.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
We already model the CMSDK APB watchdog device, let's use it!
7
With a variable-length property array, the SCC no longer specifies
8
default values for the OSCCLKs, so we must set them explicitly in the
9
board code. This defaults are actually incorrect for the an521 and
10
an505; we will correct this bug in a following patch.
4
11
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
12
This is a migration compatibility break for all the mps boards.
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
7
Message-id: 20200617072539.32686-9-f4bug@amsat.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20210215115138.20465-3-peter.maydell@linaro.org
10
---
18
---
11
hw/arm/mps2.c | 7 +++++++
19
include/hw/misc/mps2-scc.h | 7 +++----
12
hw/arm/Kconfig | 1 +
20
hw/arm/mps2-tz.c | 5 +++++
13
2 files changed, 8 insertions(+)
21
hw/arm/mps2.c | 5 +++++
22
hw/misc/mps2-scc.c | 24 +++++++++++++-----------
23
4 files changed, 26 insertions(+), 15 deletions(-)
14
24
25
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/misc/mps2-scc.h
28
+++ b/include/hw/misc/mps2-scc.h
29
@@ -XXX,XX +XXX,XX @@
30
#define TYPE_MPS2_SCC "mps2-scc"
31
OBJECT_DECLARE_SIMPLE_TYPE(MPS2SCC, MPS2_SCC)
32
33
-#define NUM_OSCCLK 3
34
-
35
struct MPS2SCC {
36
/*< private >*/
37
SysBusDevice parent_obj;
38
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
39
uint32_t dll;
40
uint32_t aid;
41
uint32_t id;
42
- uint32_t oscclk[NUM_OSCCLK];
43
- uint32_t oscclk_reset[NUM_OSCCLK];
44
+ uint32_t num_oscclk;
45
+ uint32_t *oscclk;
46
+ uint32_t *oscclk_reset;
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
}
15
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
66
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
16
index XXXXXXX..XXXXXXX 100644
67
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2.c
68
--- a/hw/arm/mps2.c
18
+++ b/hw/arm/mps2.c
69
+++ b/hw/arm/mps2.c
19
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
70
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
20
sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
71
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
21
qdev_get_gpio_in(armv7m, 10));
72
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
22
sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0x40002000);
73
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
23
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
74
+ /* All these FPGA images have the same OSCCLK configuration */
24
+ TYPE_CMSDK_APB_WATCHDOG);
75
+ qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
25
+ qdev_prop_set_uint32(DEVICE(&mms->watchdog), "wdogclk-frq", SYSCLK_FRQ);
76
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
26
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
77
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
27
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
78
+ qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
28
+ qdev_get_gpio_in_named(armv7m, "NMI", 0));
79
sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
29
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0x40008000);
80
sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
30
81
object_initialize_child(OBJECT(mms), "fpgaio",
31
/* FPGA APB subsystem */
82
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
32
object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
33
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
34
index XXXXXXX..XXXXXXX 100644
83
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/arm/Kconfig
84
--- a/hw/misc/mps2-scc.c
36
+++ b/hw/arm/Kconfig
85
+++ b/hw/misc/mps2-scc.c
37
@@ -XXX,XX +XXX,XX @@ config MPS2
86
@@ -XXX,XX +XXX,XX @@ static bool scc_cfg_write(MPS2SCC *s, unsigned function,
38
select PL080 # DMA controller
87
{
39
select SPLIT_IRQ
88
trace_mps2_scc_cfg_write(function, device, value);
40
select UNIMP
89
41
+ select CMSDK_APB_WATCHDOG
90
- if (function != 1 || device >= NUM_OSCCLK) {
42
91
+ if (function != 1 || device >= s->num_oscclk) {
43
config FSL_IMX7
92
qemu_log_mask(LOG_GUEST_ERROR,
44
bool
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
}
117
+
118
+ s->oscclk = g_new0(uint32_t, s->num_oscclk);
119
}
120
121
static const VMStateDescription mps2_scc_vmstate = {
122
.name = "mps2-scc",
123
- .version_id = 1,
124
- .minimum_version_id = 1,
125
+ .version_id = 2,
126
+ .minimum_version_id = 2,
127
.fields = (VMStateField[]) {
128
VMSTATE_UINT32(cfg0, MPS2SCC),
129
VMSTATE_UINT32(cfg1, MPS2SCC),
130
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
131
VMSTATE_UINT32(cfgctrl, MPS2SCC),
132
VMSTATE_UINT32(cfgstat, MPS2SCC),
133
VMSTATE_UINT32(dll, MPS2SCC),
134
- VMSTATE_UINT32_ARRAY(oscclk, MPS2SCC, NUM_OSCCLK),
135
+ VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
136
+ 0, vmstate_info_uint32, uint32_t),
137
VMSTATE_END_OF_LIST()
138
}
139
};
140
@@ -XXX,XX +XXX,XX @@ static Property mps2_scc_properties[] = {
141
DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0),
142
DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
143
DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0),
144
- /* These are the initial settings for the source clocks on the board.
145
+ /*
146
+ * These are the initial settings for the source clocks on the board.
147
* In hardware they can be configured via a config file read by the
148
* motherboard configuration controller to suit the FPGA image.
149
- * These default values are used by most of the standard FPGA images.
150
*/
151
- DEFINE_PROP_UINT32("oscclk0", MPS2SCC, oscclk_reset[0], 50000000),
152
- DEFINE_PROP_UINT32("oscclk1", MPS2SCC, oscclk_reset[1], 24576000),
153
- DEFINE_PROP_UINT32("oscclk2", MPS2SCC, oscclk_reset[2], 25000000),
154
+ DEFINE_PROP_ARRAY("oscclk", MPS2SCC, num_oscclk, oscclk_reset,
155
+ qdev_prop_uint32, uint32_t),
156
DEFINE_PROP_END_OF_LIST(),
157
};
158
45
--
159
--
46
2.20.1
160
2.20.1
47
161
48
162
diff view generated by jsdifflib
New patch
1
We were previously using the default OSCCLK settings, which are
2
correct for the older MPS2 boards (mps2-an385, mps2-an386,
3
mps2-an500, mps2-an511), but wrong for the mps2-an505 and mps2-511
4
implemented in mps2-tz.c. Now we're setting the values explicitly we
5
can fix them to be correct.
1
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210215115138.20465-4-peter.maydell@linaro.org
11
---
12
hw/arm/mps2-tz.c | 4 ++--
13
1 file changed, 2 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
18
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
20
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
21
/* This will need to be per-FPGA image eventually */
22
qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
23
- qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
24
- qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
25
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 40000000);
26
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24580000);
27
qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
28
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
29
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
New patch
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.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-5-peter.maydell@linaro.org
9
---
10
hw/arm/mps2-tz.c | 23 ++++++++++++++++++-----
11
1 file changed, 18 insertions(+), 5 deletions(-)
12
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
16
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
18
MPS2TZFPGAType fpga_type;
19
uint32_t scc_id;
20
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
21
+ uint32_t len_oscclk;
22
+ const uint32_t *oscclk;
23
const char *armsse_type;
24
};
25
26
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
27
/* Slow 32Khz S32KCLK frequency in Hz */
28
#define S32KCLK_FRQ (32 * 1000)
29
30
+static const uint32_t an505_oscclk[] = {
31
+ 40000000,
32
+ 24580000,
33
+ 25000000,
34
+};
35
+
36
/* Create an alias of an entire original MemoryRegion @orig
37
* located at @base in the memory map.
38
*/
39
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
40
MPS2SCC *scc = opaque;
41
DeviceState *sccdev;
42
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
43
+ uint32_t i;
44
45
object_initialize_child(OBJECT(mms), "scc", scc, TYPE_MPS2_SCC);
46
sccdev = DEVICE(scc);
47
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
48
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
49
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
50
- /* This will need to be per-FPGA image eventually */
51
- qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
52
- qdev_prop_set_uint32(sccdev, "oscclk[0]", 40000000);
53
- qdev_prop_set_uint32(sccdev, "oscclk[1]", 24580000);
54
- qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
55
+ qdev_prop_set_uint32(sccdev, "len-oscclk", mmc->len_oscclk);
56
+ for (i = 0; i < mmc->len_oscclk; i++) {
57
+ g_autofree char *propname = g_strdup_printf("oscclk[%u]", i);
58
+ qdev_prop_set_uint32(sccdev, propname, mmc->oscclk[i]);
59
+ }
60
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
61
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
62
}
63
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
64
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
65
mmc->scc_id = 0x41045050;
66
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
67
+ mmc->oscclk = an505_oscclk;
68
+ mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
69
mmc->armsse_type = TYPE_IOTKIT;
70
}
71
72
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
73
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
74
mmc->scc_id = 0x41045210;
75
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
76
+ mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
77
+ mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
78
mmc->armsse_type = TYPE_SSE200;
79
}
80
81
--
82
2.20.1
83
84
diff view generated by jsdifflib
1
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
1
The MPS2 board has 2 LEDs, but the MPS3 board has 10 LEDs. The
2
FPGAIO device is similar on both sets of boards, but the LED0
3
register has correspondingly more bits that have an effect. Add a
4
device property for number of LEDs.
2
5
3
This adds support for memory(pc-dimm) hot remove on arm/virt that
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
uses acpi ged device.
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210215115138.20465-6-peter.maydell@linaro.org
10
---
11
include/hw/misc/mps2-fpgaio.h | 5 ++++-
12
hw/misc/mps2-fpgaio.c | 31 +++++++++++++++++++++++--------
13
2 files changed, 27 insertions(+), 9 deletions(-)
5
14
6
NVDIMM hot removal is not yet supported.
15
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
7
8
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
9
Message-id: 20200622124157.20360-1-shameerali.kolothum.thodi@huawei.com
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
Tested-by: Eric Auger <eric.auger@redhat.com>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/acpi/generic_event_device.c | 29 ++++++++++++++++
15
hw/arm/virt.c | 62 ++++++++++++++++++++++++++++++++--
16
2 files changed, 89 insertions(+), 2 deletions(-)
17
18
diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/acpi/generic_event_device.c
17
--- a/include/hw/misc/mps2-fpgaio.h
21
+++ b/hw/acpi/generic_event_device.c
18
+++ b/include/hw/misc/mps2-fpgaio.h
22
@@ -XXX,XX +XXX,XX @@ static void acpi_ged_device_plug_cb(HotplugHandler *hotplug_dev,
19
@@ -XXX,XX +XXX,XX @@
20
#define TYPE_MPS2_FPGAIO "mps2-fpgaio"
21
OBJECT_DECLARE_SIMPLE_TYPE(MPS2FPGAIO, MPS2_FPGAIO)
22
23
+#define MPS2FPGAIO_MAX_LEDS 32
24
+
25
struct MPS2FPGAIO {
26
/*< private >*/
27
SysBusDevice parent_obj;
28
29
/*< public >*/
30
MemoryRegion iomem;
31
- LEDState *led[2];
32
+ LEDState *led[MPS2FPGAIO_MAX_LEDS];
33
+ uint32_t num_leds;
34
35
uint32_t led0;
36
uint32_t prescale;
37
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/misc/mps2-fpgaio.c
40
+++ b/hw/misc/mps2-fpgaio.c
41
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value,
42
43
switch (offset) {
44
case A_LED0:
45
- s->led0 = value & 0x3;
46
- led_set_state(s->led[0], value & 0x01);
47
- led_set_state(s->led[1], value & 0x02);
48
+ if (s->num_leds != 0) {
49
+ uint32_t i;
50
+
51
+ s->led0 = value & MAKE_64BIT_MASK(0, s->num_leds);
52
+ for (i = 0; i < s->num_leds; i++) {
53
+ led_set_state(s->led[i], value & (1 << i));
54
+ }
55
+ }
56
break;
57
case A_PRESCALE:
58
resync_counter(s);
59
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_reset(DeviceState *dev)
60
s->pscntr = 0;
61
s->pscntr_sync_ticks = now;
62
63
- for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
64
+ for (size_t i = 0; i < s->num_leds; i++) {
65
device_cold_reset(DEVICE(s->led[i]));
23
}
66
}
24
}
67
}
25
68
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_init(Object *obj)
26
+static void acpi_ged_unplug_request_cb(HotplugHandler *hotplug_dev,
69
static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
27
+ DeviceState *dev, Error **errp)
28
+{
29
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
30
+
31
+ if ((object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
32
+ !(object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)))) {
33
+ acpi_memory_unplug_request_cb(hotplug_dev, &s->memhp_state, dev, errp);
34
+ } else {
35
+ error_setg(errp, "acpi: device unplug request for unsupported device"
36
+ " type: %s", object_get_typename(OBJECT(dev)));
37
+ }
38
+}
39
+
40
+static void acpi_ged_unplug_cb(HotplugHandler *hotplug_dev,
41
+ DeviceState *dev, Error **errp)
42
+{
43
+ AcpiGedState *s = ACPI_GED(hotplug_dev);
44
+
45
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
46
+ acpi_memory_unplug_cb(&s->memhp_state, dev, errp);
47
+ } else {
48
+ error_setg(errp, "acpi: device unplug for unsupported device"
49
+ " type: %s", object_get_typename(OBJECT(dev)));
50
+ }
51
+}
52
+
53
static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)
54
{
70
{
55
AcpiGedState *s = ACPI_GED(adev);
71
MPS2FPGAIO *s = MPS2_FPGAIO(dev);
56
@@ -XXX,XX +XXX,XX @@ static void acpi_ged_class_init(ObjectClass *class, void *data)
72
+ uint32_t i;
57
dc->vmsd = &vmstate_acpi_ged;
73
58
74
- s->led[0] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
59
hc->plug = acpi_ged_device_plug_cb;
75
- LED_COLOR_GREEN, "USERLED0");
60
+ hc->unplug_request = acpi_ged_unplug_request_cb;
76
- s->led[1] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
61
+ hc->unplug = acpi_ged_unplug_cb;
77
- LED_COLOR_GREEN, "USERLED1");
62
78
+ if (s->num_leds > MPS2FPGAIO_MAX_LEDS) {
63
adevc->send_event = acpi_ged_send_event;
79
+ error_setg(errp, "num-leds cannot be greater than %d",
64
}
80
+ MPS2FPGAIO_MAX_LEDS);
65
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
81
+ return;
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/virt.c
68
+++ b/hw/arm/virt.c
69
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
70
}
71
}
72
73
+static void virt_dimm_unplug_request(HotplugHandler *hotplug_dev,
74
+ DeviceState *dev, Error **errp)
75
+{
76
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
77
+ Error *local_err = NULL;
78
+
79
+ if (!vms->acpi_dev) {
80
+ error_setg(&local_err,
81
+ "memory hotplug is not enabled: missing acpi-ged device");
82
+ goto out;
83
+ }
82
+ }
84
+
83
+
85
+ if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {
84
+ for (i = 0; i < s->num_leds; i++) {
86
+ error_setg(&local_err,
85
+ g_autofree char *ledname = g_strdup_printf("USERLED%d", i);
87
+ "nvdimm device hot unplug is not supported yet.");
86
+ s->led[i] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
88
+ goto out;
87
+ LED_COLOR_GREEN, ledname);
89
+ }
90
+
91
+ hotplug_handler_unplug_request(HOTPLUG_HANDLER(vms->acpi_dev), dev,
92
+ &local_err);
93
+out:
94
+ error_propagate(errp, local_err);
95
+}
96
+
97
+static void virt_dimm_unplug(HotplugHandler *hotplug_dev,
98
+ DeviceState *dev, Error **errp)
99
+{
100
+ VirtMachineState *vms = VIRT_MACHINE(hotplug_dev);
101
+ Error *local_err = NULL;
102
+
103
+ hotplug_handler_unplug(HOTPLUG_HANDLER(vms->acpi_dev), dev, &local_err);
104
+ if (local_err) {
105
+ goto out;
106
+ }
107
+
108
+ pc_dimm_unplug(PC_DIMM(dev), MACHINE(vms));
109
+ qdev_unrealize(dev);
110
+
111
+out:
112
+ error_propagate(errp, local_err);
113
+}
114
+
115
static void virt_machine_device_unplug_request_cb(HotplugHandler *hotplug_dev,
116
DeviceState *dev, Error **errp)
117
{
118
- error_setg(errp, "device unplug request for unsupported device"
119
- " type: %s", object_get_typename(OBJECT(dev)));
120
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
121
+ virt_dimm_unplug_request(hotplug_dev, dev, errp);
122
+ } else {
123
+ error_setg(errp, "device unplug request for unsupported device"
124
+ " type: %s", object_get_typename(OBJECT(dev)));
125
+ }
126
+}
127
+
128
+static void virt_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
129
+ DeviceState *dev, Error **errp)
130
+{
131
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {
132
+ virt_dimm_unplug(hotplug_dev, dev, errp);
133
+ } else {
134
+ error_setg(errp, "virt: device unplug for unsupported device"
135
+ " type: %s", object_get_typename(OBJECT(dev)));
136
+ }
88
+ }
137
}
89
}
138
90
139
static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
91
static bool mps2_fpgaio_counters_needed(void *opaque)
140
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
92
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_fpgaio_vmstate = {
141
hc->pre_plug = virt_machine_device_pre_plug_cb;
93
static Property mps2_fpgaio_properties[] = {
142
hc->plug = virt_machine_device_plug_cb;
94
/* Frequency of the prescale counter */
143
hc->unplug_request = virt_machine_device_unplug_request_cb;
95
DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000),
144
+ hc->unplug = virt_machine_device_unplug_cb;
96
+ /* Number of LEDs controlled by LED0 register */
145
mc->numa_mem_supported = true;
97
+ DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
146
mc->nvdimm_supported = true;
98
DEFINE_PROP_END_OF_LIST(),
147
mc->auto_enable_numa_with_memhp = true;
99
};
100
148
--
101
--
149
2.20.1
102
2.20.1
150
103
151
104
diff view generated by jsdifflib
New patch
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.
1
4
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
9
---
10
include/hw/misc/mps2-fpgaio.h | 1 +
11
hw/misc/mps2-fpgaio.c | 10 ++++++++++
12
2 files changed, 11 insertions(+)
13
14
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/misc/mps2-fpgaio.h
17
+++ b/include/hw/misc/mps2-fpgaio.h
18
@@ -XXX,XX +XXX,XX @@ struct MPS2FPGAIO {
19
MemoryRegion iomem;
20
LEDState *led[MPS2FPGAIO_MAX_LEDS];
21
uint32_t num_leds;
22
+ bool has_switches;
23
24
uint32_t led0;
25
uint32_t prescale;
26
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/misc/mps2-fpgaio.c
29
+++ b/hw/misc/mps2-fpgaio.c
30
@@ -XXX,XX +XXX,XX @@ REG32(CLK100HZ, 0x14)
31
REG32(COUNTER, 0x18)
32
REG32(PRESCALE, 0x1c)
33
REG32(PSCNTR, 0x20)
34
+REG32(SWITCH, 0x28)
35
REG32(MISC, 0x4c)
36
37
static uint32_t counter_from_tickoff(int64_t now, int64_t tick_offset, int frq)
38
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_fpgaio_read(void *opaque, hwaddr offset, unsigned size)
39
resync_counter(s);
40
r = s->pscntr;
41
break;
42
+ case A_SWITCH:
43
+ if (!s->has_switches) {
44
+ goto bad_offset;
45
+ }
46
+ /* User-togglable board switches. We don't model that, so report 0. */
47
+ r = 0;
48
+ break;
49
default:
50
+ bad_offset:
51
qemu_log_mask(LOG_GUEST_ERROR,
52
"MPS2 FPGAIO read: bad offset %x\n", (int) offset);
53
r = 0;
54
@@ -XXX,XX +XXX,XX @@ static Property mps2_fpgaio_properties[] = {
55
DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000),
56
/* Number of LEDs controlled by LED0 register */
57
DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
58
+ DEFINE_PROP_BOOL("has-switches", MPS2FPGAIO, has_switches, false),
59
DEFINE_PROP_END_OF_LIST(),
60
};
61
62
--
63
2.20.1
64
65
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.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
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Message-id: 20200617072539.32686-11-f4bug@amsat.org
5
Reviewed-by: Peter Maydell <peter.maydell@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: 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
7
---
10
---
8
hw/arm/mps2.c | 9 +++++++++
11
hw/arm/mps2-tz.c | 9 +++++++++
9
1 file changed, 9 insertions(+)
12
1 file changed, 9 insertions(+)
10
13
11
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
14
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
12
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/mps2.c
16
--- a/hw/arm/mps2-tz.c
14
+++ b/hw/arm/mps2.c
17
+++ b/hw/arm/mps2-tz.c
15
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
16
#include "hw/timer/cmsdk-apb-timer.h"
19
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
17
#include "hw/timer/cmsdk-apb-dualtimer.h"
20
uint32_t len_oscclk;
18
#include "hw/misc/mps2-scc.h"
21
const uint32_t *oscclk;
19
+#include "hw/misc/mps2-fpgaio.h"
22
+ uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
20
#include "hw/net/lan9118.h"
23
+ bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
21
#include "net/net.h"
24
const char *armsse_type;
22
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
25
};
23
26
24
typedef enum MPS2FPGAType {
27
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
25
FPGA_AN385,
28
const char *name, hwaddr size)
26
@@ -XXX,XX +XXX,XX @@ typedef struct {
29
{
27
MemoryRegion sram;
30
MPS2FPGAIO *fpgaio = opaque;
28
/* FPGA APB subsystem */
31
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
29
MPS2SCC scc;
32
30
+ MPS2FPGAIO fpgaio;
33
object_initialize_child(OBJECT(mms), "fpgaio", fpgaio, TYPE_MPS2_FPGAIO);
31
/* CMSDK APB subsystem */
34
+ qdev_prop_set_uint32(DEVICE(fpgaio), "num-leds", mmc->fpgaio_num_leds);
32
CMSDKAPBDualTimer dualtimer;
35
+ qdev_prop_set_bit(DEVICE(fpgaio), "has-switches", mmc->fpgaio_has_switches);
33
+ CMSDKAPBWatchdog watchdog;
36
sysbus_realize(SYS_BUS_DEVICE(fpgaio), &error_fatal);
34
} MPS2MachineState;
37
return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
35
38
}
36
#define TYPE_MPS2_MACHINE "mps2"
39
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
37
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
40
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
38
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
41
mmc->oscclk = an505_oscclk;
39
sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
42
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
40
sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
43
+ mmc->fpgaio_num_leds = 2;
41
+ object_initialize_child(OBJECT(mms), "fpgaio",
44
+ mmc->fpgaio_has_switches = false;
42
+ &mms->fpgaio, TYPE_MPS2_FPGAIO);
45
mmc->armsse_type = TYPE_IOTKIT;
43
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", 25000000);
46
}
44
+ sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
47
45
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0x40028000);
48
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
46
49
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
47
/* In hardware this is a LAN9220; the LAN9118 is software compatible
50
mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
48
* except that it doesn't support the checksum-offload feature.
51
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
52
+ mmc->fpgaio_num_leds = 2;
53
+ mmc->fpgaio_has_switches = false;
54
mmc->armsse_type = TYPE_SSE200;
55
}
56
49
--
57
--
50
2.20.1
58
2.20.1
51
59
52
60
diff view generated by jsdifflib
1
All the other typedefs like these spell "Op" with a lowercase 'p';
1
In the mps2-tz board code, we handle devices whose interrupt lines
2
remane the NeonGenTwoSingleOPFn and NeonGenTwoDoubleOPFn typedefs to
2
must be wired to all CPUs by creating IRQ splitter devices for the
3
match.
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.
5
6
We can avoid making an explicit check on the board type constant by
7
instead creating and using the IRQ splitters for any board with more
8
than 1 CPU. This avoids having to add extra cases to the
9
conditionals every time we add new boards.
4
10
5
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>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20200616170844.13318-11-peter.maydell@linaro.org
14
Message-id: 20210215115138.20465-9-peter.maydell@linaro.org
8
---
15
---
9
target/arm/translate.h | 4 ++--
16
hw/arm/mps2-tz.c | 19 +++++++++----------
10
target/arm/translate-a64.c | 4 ++--
17
1 file changed, 9 insertions(+), 10 deletions(-)
11
target/arm/translate-neon.inc.c | 2 +-
12
3 files changed, 5 insertions(+), 5 deletions(-)
13
18
14
diff --git a/target/arm/translate.h b/target/arm/translate.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/translate.h
21
--- a/hw/arm/mps2-tz.c
17
+++ b/target/arm/translate.h
22
+++ b/hw/arm/mps2-tz.c
18
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
23
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
19
typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
24
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
20
typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
25
{
21
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
26
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
22
-typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
27
- MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
23
-typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
28
+ MachineClass *mc = MACHINE_GET_CLASS(mms);
24
+typedef void NeonGenTwoSingleOpFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
29
25
+typedef void NeonGenTwoDoubleOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
30
assert(irqno < MPS2TZ_NUMIRQ);
26
typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
31
27
typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
32
- switch (mmc->fpga_type) {
28
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
33
- case FPGA_AN505:
29
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
34
- return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
30
index XXXXXXX..XXXXXXX 100644
35
- case FPGA_AN521:
31
--- a/target/arm/translate-a64.c
36
+ if (mc->max_cpus > 1) {
32
+++ b/target/arm/translate-a64.c
37
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
33
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
38
- default:
34
TCGv_i64 tcg_op = tcg_temp_new_i64();
39
- g_assert_not_reached();
35
TCGv_i64 tcg_zero = tcg_const_i64(0);
40
+ } else {
36
TCGv_i64 tcg_res = tcg_temp_new_i64();
41
+ return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
37
- NeonGenTwoDoubleOPFn *genfn;
42
}
38
+ NeonGenTwoDoubleOpFn *genfn;
39
bool swap = false;
40
int pass;
41
42
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_fcmp_zero(DisasContext *s, int opcode,
43
TCGv_i32 tcg_op = tcg_temp_new_i32();
44
TCGv_i32 tcg_zero = tcg_const_i32(0);
45
TCGv_i32 tcg_res = tcg_temp_new_i32();
46
- NeonGenTwoSingleOPFn *genfn;
47
+ NeonGenTwoSingleOpFn *genfn;
48
bool swap = false;
49
int pass, maxpasses;
50
51
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate-neon.inc.c
54
+++ b/target/arm/translate-neon.inc.c
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL_U_2sh(DisasContext *s, arg_2reg_shift *a)
56
}
43
}
57
44
58
static bool do_fp_2sh(DisasContext *s, arg_2reg_shift *a,
45
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
59
- NeonGenTwoSingleOPFn *fn)
46
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
60
+ NeonGenTwoSingleOpFn *fn)
47
61
{
48
/*
62
/* FP operations in 2-reg-and-shift group */
49
- * The AN521 needs us to create splitters to feed the IRQ inputs
63
TCGv_i32 tmp, shiftv;
50
- * for each CPU in the SSE-200 from each device in the board.
51
+ * If this board has more than one CPU, then we need to create splitters
52
+ * to feed the IRQ inputs for each CPU in the SSE from each device in the
53
+ * board. If there is only one CPU, we can just wire the device IRQ
54
+ * directly to the SSE's IRQ input.
55
*/
56
- if (mmc->fpga_type == FPGA_AN521) {
57
+ if (mc->max_cpus > 1) {
58
for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
59
char *name = g_strdup_printf("mps2-irq-splitter%d", i);
60
SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
64
--
61
--
65
2.20.1
62
2.20.1
66
63
67
64
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
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
Cc: Cornelia Huck <cohuck@redhat.com>
4
Since the difference is small (92 on the current boards and 95 on the
4
Signed-off-by: Andrew Jones <drjones@redhat.com>
5
new one) we don't dynamically allocate the cpu_irq_splitter[] array
5
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
6
but leave it as a fixed length array whose size is the maximum needed
6
Message-id: 20200616140803.25515-1-drjones@redhat.com
7
for any of the boards.
8
7
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
8
---
13
---
9
hw/arm/virt.c | 1 +
14
hw/arm/mps2-tz.c | 15 ++++++++++-----
10
1 file changed, 1 insertion(+)
15
1 file changed, 10 insertions(+), 5 deletions(-)
11
16
12
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/virt.c
19
--- a/hw/arm/mps2-tz.c
15
+++ b/hw/arm/virt.c
20
+++ b/hw/arm/mps2-tz.c
16
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(5, 1)
21
@@ -XXX,XX +XXX,XX @@
17
static void virt_machine_5_0_options(MachineClass *mc)
22
#include "hw/qdev-clock.h"
23
#include "qom/object.h"
24
25
-#define MPS2TZ_NUMIRQ 92
26
+#define MPS2TZ_NUMIRQ_MAX 92
27
28
typedef enum MPS2TZFPGAType {
29
FPGA_AN505,
30
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
31
const uint32_t *oscclk;
32
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
33
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
34
+ int numirq; /* Number of external interrupts */
35
const char *armsse_type;
36
};
37
38
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
39
SplitIRQ sec_resp_splitter;
40
qemu_or_irq uart_irq_orgate;
41
DeviceState *lan9118;
42
- SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ];
43
+ SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
44
Clock *sysclk;
45
Clock *s32kclk;
46
};
47
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
18
{
48
{
19
virt_machine_5_1_options(mc);
49
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
20
+ compat_props_add(mc->compat_props, hw_compat_5_0, hw_compat_5_0_len);
50
MachineClass *mc = MACHINE_GET_CLASS(mms);
51
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
52
53
- assert(irqno < MPS2TZ_NUMIRQ);
54
+ assert(irqno < mmc->numirq);
55
56
if (mc->max_cpus > 1) {
57
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
58
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
59
iotkitdev = DEVICE(&mms->iotkit);
60
object_property_set_link(OBJECT(&mms->iotkit), "memory",
61
OBJECT(system_memory), &error_abort);
62
- qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", MPS2TZ_NUMIRQ);
63
+ qdev_prop_set_uint32(iotkitdev, "EXP_NUMIRQ", mmc->numirq);
64
qdev_connect_clock_in(iotkitdev, "MAINCLK", mms->sysclk);
65
qdev_connect_clock_in(iotkitdev, "S32KCLK", mms->s32kclk);
66
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
67
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
68
* board. If there is only one CPU, we can just wire the device IRQ
69
* directly to the SSE's IRQ input.
70
*/
71
+ assert(mmc->numirq <= MPS2TZ_NUMIRQ_MAX);
72
if (mc->max_cpus > 1) {
73
- for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
74
+ for (i = 0; i < mmc->numirq; i++) {
75
char *name = g_strdup_printf("mps2-irq-splitter%d", i);
76
SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
77
78
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
79
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
80
mmc->fpgaio_num_leds = 2;
81
mmc->fpgaio_has_switches = false;
82
+ mmc->numirq = 92;
83
mmc->armsse_type = TYPE_IOTKIT;
21
}
84
}
22
DEFINE_VIRT_MACHINE(5, 0)
85
86
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
87
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
88
mmc->fpgaio_num_leds = 2;
89
mmc->fpgaio_has_switches = false;
90
+ mmc->numirq = 92;
91
mmc->armsse_type = TYPE_SSE200;
92
}
23
93
24
--
94
--
25
2.20.1
95
2.20.1
26
96
27
97
diff view generated by jsdifflib
1
Convert the VREV32 and VREV16 insns in the Neon 2-reg-misc group
1
The AN524 version of the SCC interface has different behaviour for
2
to decodetree.
2
some of the CFG registers; implement it.
3
4
Each board in this family can have minor differences in the meaning
5
of the CFG registers, so rather than trying to specify all the
6
possible semantics via individual device properties, we make the
7
behaviour conditional on the part-number field of the SCC_ID register
8
which the board code already passes us.
9
10
For the AN524, the differences are:
11
* CFG3 is reserved rather than being board switches
12
* CFG5 is a new register ("ACLK Frequency in Hz")
13
* CFG6 is a new register ("Clock divider for BRAM")
14
15
We implement both of the new registers as reads-as-written.
3
16
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-13-peter.maydell@linaro.org
19
Message-id: 20210215115138.20465-11-peter.maydell@linaro.org
7
---
20
---
8
target/arm/translate.h | 1 +
21
include/hw/misc/mps2-scc.h | 3 ++
9
target/arm/neon-dp.decode | 2 ++
22
hw/misc/mps2-scc.c | 71 ++++++++++++++++++++++++++++++++++++--
10
target/arm/translate-neon.inc.c | 55 +++++++++++++++++++++++++++++++++
23
2 files changed, 72 insertions(+), 2 deletions(-)
11
target/arm/translate.c | 12 ++-----
12
4 files changed, 60 insertions(+), 10 deletions(-)
13
24
14
diff --git a/target/arm/translate.h b/target/arm/translate.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/translate.h
27
--- a/include/hw/misc/mps2-scc.h
17
+++ b/target/arm/translate.h
28
+++ b/include/hw/misc/mps2-scc.h
18
@@ -XXX,XX +XXX,XX @@ typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
29
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
19
uint32_t, uint32_t, uint32_t);
30
20
31
uint32_t cfg0;
21
/* Function prototype for gen_ functions for calling Neon helpers */
32
uint32_t cfg1;
22
+typedef void NeonGenOneOpFn(TCGv_i32, TCGv_i32);
33
+ uint32_t cfg2;
23
typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
34
uint32_t cfg4;
24
typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
35
+ uint32_t cfg5;
25
typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
36
+ uint32_t cfg6;
26
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
37
uint32_t cfgdata_rtn;
38
uint32_t cfgdata_out;
39
uint32_t cfgctrl;
40
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
27
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/neon-dp.decode
42
--- a/hw/misc/mps2-scc.c
29
+++ b/target/arm/neon-dp.decode
43
+++ b/hw/misc/mps2-scc.c
30
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
44
@@ -XXX,XX +XXX,XX @@
31
&2misc vm=%vm_dp vd=%vd_dp q=1
45
32
46
REG32(CFG0, 0)
33
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
47
REG32(CFG1, 4)
34
+ VREV32 1111 001 11 . 11 .. 00 .... 0 0001 . . 0 .... @2misc
48
+REG32(CFG2, 8)
35
+ VREV16 1111 001 11 . 11 .. 00 .... 0 0010 . . 0 .... @2misc
49
REG32(CFG3, 0xc)
36
50
REG32(CFG4, 0x10)
37
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
51
+REG32(CFG5, 0x14)
38
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
52
+REG32(CFG6, 0x18)
39
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
53
REG32(CFGDATA_RTN, 0xa0)
40
index XXXXXXX..XXXXXXX 100644
54
REG32(CFGDATA_OUT, 0xa4)
41
--- a/target/arm/translate-neon.inc.c
55
REG32(CFGCTRL, 0xa8)
42
+++ b/target/arm/translate-neon.inc.c
56
@@ -XXX,XX +XXX,XX @@ REG32(DLL, 0x100)
43
@@ -XXX,XX +XXX,XX @@ DO_2M_CRYPTO(AESIMC, aa32_aes, 0)
57
REG32(AID, 0xFF8)
44
DO_2M_CRYPTO(SHA1H, aa32_sha1, 2)
58
REG32(ID, 0xFFC)
45
DO_2M_CRYPTO(SHA1SU1, aa32_sha1, 2)
59
46
DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
60
+static int scc_partno(MPS2SCC *s)
47
+
48
+static bool do_2misc(DisasContext *s, arg_2misc *a, NeonGenOneOpFn *fn)
49
+{
61
+{
50
+ int pass;
62
+ /* Return the partno field of the SCC_ID (0x524, 0x511, etc) */
51
+
63
+ return extract32(s->id, 4, 8);
52
+ /* Handle a 2-reg-misc operation by iterating 32 bits at a time */
53
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
54
+ return false;
55
+ }
56
+
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
59
+ ((a->vd | a->vm) & 0x10)) {
60
+ return false;
61
+ }
62
+
63
+ if (!fn) {
64
+ return false;
65
+ }
66
+
67
+ if ((a->vd | a->vm) & a->q) {
68
+ return false;
69
+ }
70
+
71
+ if (!vfp_access_check(s)) {
72
+ return true;
73
+ }
74
+
75
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
76
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
77
+ fn(tmp, tmp);
78
+ neon_store_reg(a->vd, pass, tmp);
79
+ }
80
+
81
+ return true;
82
+}
64
+}
83
+
65
+
84
+static bool trans_VREV32(DisasContext *s, arg_2misc *a)
66
/* Handle a write via the SYS_CFG channel to the specified function/device.
85
+{
67
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
86
+ static NeonGenOneOpFn * const fn[] = {
68
*/
87
+ tcg_gen_bswap32_i32,
69
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
88
+ gen_swap_half,
70
case A_CFG1:
89
+ NULL,
71
r = s->cfg1;
90
+ NULL,
72
break;
91
+ };
73
+ case A_CFG2:
92
+ return do_2misc(s, a, fn[a->size]);
74
+ if (scc_partno(s) != 0x524) {
93
+}
75
+ /* CFG2 reserved on other boards */
94
+
76
+ goto bad_offset;
95
+static bool trans_VREV16(DisasContext *s, arg_2misc *a)
77
+ }
96
+{
78
+ r = s->cfg2;
97
+ if (a->size != 0) {
79
+ break;
98
+ return false;
80
case A_CFG3:
99
+ }
81
+ if (scc_partno(s) == 0x524) {
100
+ return do_2misc(s, a, gen_rev16);
82
+ /* CFG3 reserved on AN524 */
101
+}
83
+ goto bad_offset;
102
diff --git a/target/arm/translate.c b/target/arm/translate.c
84
+ }
103
index XXXXXXX..XXXXXXX 100644
85
/* These are user-settable DIP switches on the board. We don't
104
--- a/target/arm/translate.c
86
* model that, so just return zeroes.
105
+++ b/target/arm/translate.c
87
*/
106
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
88
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
107
case NEON_2RM_AESE: case NEON_2RM_AESMC:
89
case A_CFG4:
108
case NEON_2RM_SHA1H:
90
r = s->cfg4;
109
case NEON_2RM_SHA1SU1:
91
break;
110
+ case NEON_2RM_VREV32:
92
+ case A_CFG5:
111
+ case NEON_2RM_VREV16:
93
+ if (scc_partno(s) != 0x524) {
112
/* handled by decodetree */
94
+ /* CFG5 reserved on other boards */
113
return 1;
95
+ goto bad_offset;
114
case NEON_2RM_VTRN:
96
+ }
115
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
97
+ r = s->cfg5;
116
for (pass = 0; pass < (q ? 4 : 2); pass++) {
98
+ break;
117
tmp = neon_load_reg(rm, pass);
99
+ case A_CFG6:
118
switch (op) {
100
+ if (scc_partno(s) != 0x524) {
119
- case NEON_2RM_VREV32:
101
+ /* CFG6 reserved on other boards */
120
- switch (size) {
102
+ goto bad_offset;
121
- case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
103
+ }
122
- case 1: gen_swap_half(tmp, tmp); break;
104
+ r = s->cfg6;
123
- default: abort();
105
+ break;
124
- }
106
case A_CFGDATA_RTN:
125
- break;
107
r = s->cfgdata_rtn;
126
- case NEON_2RM_VREV16:
108
break;
127
- gen_rev16(tmp, tmp);
109
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
128
- break;
110
r = s->id;
129
case NEON_2RM_VCLS:
111
break;
130
switch (size) {
112
default:
131
case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
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),
132
--
184
--
133
2.20.1
185
2.20.1
134
186
135
187
diff view generated by jsdifflib
1
The NeonGenOneOpFn typedef breaks with the pattern of the other
1
On the MPS2 boards, the first 32 interrupt lines are entirely
2
NeonGen*Fn typedefs, because it is a TCGv_i64 -> TCGv_i64 operation
2
internal to the SSE; interrupt lines for devices outside the SSE
3
but it does not have '64' in its name. Rename it to NeonGenOne64OpFn,
3
start at 32. In the application notes that document each FPGA image,
4
so that the old name is available for a TCGv_i32 -> TCGv_i32 operation
4
the interrupt wiring is documented from the point of view of the CPU,
5
(which we will need in a subsequent commit).
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.
8
9
Within our implementation, because the external interrupts must be
10
connected to the EXP_IRQ[0...n] lines of the SSE object, we made the
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.
6
22
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20200616170844.13318-10-peter.maydell@linaro.org
25
Message-id: 20210215115138.20465-12-peter.maydell@linaro.org
10
---
26
---
11
target/arm/translate.h | 2 +-
27
hw/arm/mps2-tz.c | 24 +++++++++++++++++-------
12
target/arm/translate-a64.c | 4 ++--
28
1 file changed, 17 insertions(+), 7 deletions(-)
13
2 files changed, 3 insertions(+), 3 deletions(-)
14
29
15
diff --git a/target/arm/translate.h b/target/arm/translate.h
30
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.h
32
--- a/hw/arm/mps2-tz.c
18
+++ b/target/arm/translate.h
33
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
34
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
20
typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
35
21
typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
36
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
22
typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
37
{
23
-typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
38
- /* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
24
+typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
39
+ /*
25
typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
40
+ * Return a qemu_irq which will signal IRQ n to all CPUs in the
26
typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
41
+ * SSE. The irqno should be as the CPU sees it, so the first
27
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
42
+ * external-to-the-SSE interrupt is 32.
28
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
43
+ */
29
index XXXXXXX..XXXXXXX 100644
44
MachineClass *mc = MACHINE_GET_CLASS(mms);
30
--- a/target/arm/translate-a64.c
45
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
31
+++ b/target/arm/translate-a64.c
46
32
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_pairwise(DisasContext *s, int opcode, bool u,
47
- assert(irqno < mmc->numirq);
33
} else {
48
+ assert(irqno >= 32 && irqno < (mmc->numirq + 32));
34
for (pass = 0; pass < maxpass; pass++) {
49
+
35
TCGv_i64 tcg_op = tcg_temp_new_i64();
50
+ /*
36
- NeonGenOneOpFn *genfn;
51
+ * Convert from "CPU irq number" (as listed in the FPGA image
37
- static NeonGenOneOpFn * const fns[2][2] = {
52
+ * documentation) to the SSE external-interrupt number.
38
+ NeonGenOne64OpFn *genfn;
53
+ */
39
+ static NeonGenOne64OpFn * const fns[2][2] = {
54
+ irqno -= 32;
40
{ gen_helper_neon_addlp_s8, gen_helper_neon_addlp_u8 },
55
41
{ gen_helper_neon_addlp_s16, gen_helper_neon_addlp_u16 },
56
if (mc->max_cpus > 1) {
42
};
57
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
58
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
59
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
60
CMSDKAPBUART *uart = opaque;
61
int i = uart - &mms->uart[0];
62
- int rxirqno = i * 2;
63
- int txirqno = i * 2 + 1;
64
- int combirqno = i + 10;
65
+ int rxirqno = i * 2 + 32;
66
+ int txirqno = i * 2 + 33;
67
+ int combirqno = i + 42;
68
SysBusDevice *s;
69
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
70
71
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
72
73
s = SYS_BUS_DEVICE(mms->lan9118);
74
sysbus_realize_and_unref(s, &error_fatal);
75
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 16));
76
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 48));
77
return sysbus_mmio_get_region(s, 0);
78
}
79
80
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
81
&error_fatal);
82
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
83
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
84
- get_sse_irq_in(mms, 15));
85
+ get_sse_irq_in(mms, 47));
86
87
/* Most of the devices in the FPGA are behind Peripheral Protection
88
* Controllers. The required order for initializing things is:
43
--
89
--
44
2.20.1
90
2.20.1
45
91
46
92
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@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
Since commit d70c996df23f, when enabling the PMU we get:
8
This commit adds the framework to allow PPCPortInfo structures to
9
specify interrupt numbers. We add an array of interrupt numbers to
10
the PPCPortInfo struct, and pass it through to the make_* helpers.
11
The following commit will change the make_* helpers over to using the
12
framework.
4
13
5
$ qemu-system-aarch64 -cpu host,pmu=on -M virt,accel=kvm,gic-version=3
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Segmentation fault (core dumped)
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
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(-)
7
20
8
Thread 1 "qemu-system-aar" received signal SIGSEGV, Segmentation fault.
21
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
9
0x0000aaaaaae356d0 in kvm_ioctl (s=0x0, type=44547) at accel/kvm/kvm-all.c:2588
10
2588 ret = ioctl(s->fd, type, arg);
11
(gdb) bt
12
#0 0x0000aaaaaae356d0 in kvm_ioctl (s=0x0, type=44547) at accel/kvm/kvm-all.c:2588
13
#1 0x0000aaaaaae31568 in kvm_check_extension (s=0x0, extension=126) at accel/kvm/kvm-all.c:916
14
#2 0x0000aaaaaafce254 in kvm_arm_pmu_supported (cpu=0xaaaaac214ab0) at target/arm/kvm.c:213
15
#3 0x0000aaaaaafc0f94 in arm_set_pmu (obj=0xaaaaac214ab0, value=true, errp=0xffffffffe438) at target/arm/cpu.c:1111
16
#4 0x0000aaaaab5533ac in property_set_bool (obj=0xaaaaac214ab0, v=0xaaaaac223a80, name=0xaaaaac11a970 "pmu", opaque=0xaaaaac222730, errp=0xffffffffe438) at qom/object.c:2170
17
#5 0x0000aaaaab5512f0 in object_property_set (obj=0xaaaaac214ab0, v=0xaaaaac223a80, name=0xaaaaac11a970 "pmu", errp=0xffffffffe438) at qom/object.c:1328
18
#6 0x0000aaaaab551e10 in object_property_parse (obj=0xaaaaac214ab0, string=0xaaaaac11b4c0 "on", name=0xaaaaac11a970 "pmu", errp=0xffffffffe438) at qom/object.c:1561
19
#7 0x0000aaaaab54ee8c in object_apply_global_props (obj=0xaaaaac214ab0, props=0xaaaaac018e20, errp=0xaaaaabd6fd88 <error_fatal>) at qom/object.c:407
20
#8 0x0000aaaaab1dd5a4 in qdev_prop_set_globals (dev=0xaaaaac214ab0) at hw/core/qdev-properties.c:1218
21
#9 0x0000aaaaab1d9fac in device_post_init (obj=0xaaaaac214ab0) at hw/core/qdev.c:1050
22
...
23
#15 0x0000aaaaab54f310 in object_initialize_with_type (obj=0xaaaaac214ab0, size=52208, type=0xaaaaabe237f0) at qom/object.c:512
24
#16 0x0000aaaaab54fa24 in object_new_with_type (type=0xaaaaabe237f0) at qom/object.c:687
25
#17 0x0000aaaaab54fa80 in object_new (typename=0xaaaaabe23970 "host-arm-cpu") at qom/object.c:702
26
#18 0x0000aaaaaaf04a74 in machvirt_init (machine=0xaaaaac0a8550) at hw/arm/virt.c:1770
27
#19 0x0000aaaaab1e8720 in machine_run_board_init (machine=0xaaaaac0a8550) at hw/core/machine.c:1138
28
#20 0x0000aaaaaaf95394 in qemu_init (argc=5, argv=0xffffffffea58, envp=0xffffffffea88) at softmmu/vl.c:4348
29
#21 0x0000aaaaaada3f74 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at softmmu/main.c:48
30
31
This is because in frame #2, cpu->kvm_state is still NULL
32
(the vCPU is not yet realized).
33
34
KVM has a hard requirement of all cores supporting the same
35
feature set. We only need to check if the accelerator supports
36
a feature, not each vCPU individually.
37
38
Fix by removing the 'CPUState *cpu' argument from the
39
kvm_arm_<FEATURE>_supported() functions.
40
41
Fixes: d70c996df23f ('Use CPUState::kvm_state in kvm_arm_pmu_supported')
42
Reported-by: Haibo Xu <haibo.xu@linaro.org>
43
Reviewed-by: Andrew Jones <drjones@redhat.com>
44
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
45
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
46
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
47
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
48
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
49
---
50
target/arm/kvm_arm.h | 21 +++++++++------------
51
target/arm/cpu.c | 2 +-
52
target/arm/cpu64.c | 10 +++++-----
53
target/arm/kvm.c | 4 ++--
54
target/arm/kvm64.c | 14 +++++---------
55
5 files changed, 22 insertions(+), 29 deletions(-)
56
57
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
58
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
59
--- a/target/arm/kvm_arm.h
23
--- a/hw/arm/mps2-tz.c
60
+++ b/target/arm/kvm_arm.h
24
+++ b/hw/arm/mps2-tz.c
61
@@ -XXX,XX +XXX,XX @@ void kvm_arm_add_vcpu_properties(Object *obj);
25
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
62
26
* needs to be plugged into the downstream end of the PPC port.
63
/**
64
* kvm_arm_aarch32_supported:
65
- * @cs: CPUState
66
*
67
- * Returns: true if the KVM VCPU can enable AArch32 mode
68
+ * Returns: true if KVM can enable AArch32 mode
69
* and false otherwise.
70
*/
27
*/
71
-bool kvm_arm_aarch32_supported(CPUState *cs);
28
typedef MemoryRegion *MakeDevFn(MPS2TZMachineState *mms, void *opaque,
72
+bool kvm_arm_aarch32_supported(void);
29
- const char *name, hwaddr size);
73
30
+ const char *name, hwaddr size,
74
/**
31
+ const int *irqs);
75
* kvm_arm_pmu_supported:
32
76
- * @cs: CPUState
33
typedef struct PPCPortInfo {
77
*
34
const char *name;
78
- * Returns: true if the KVM VCPU can enable its PMU
35
@@ -XXX,XX +XXX,XX @@ typedef struct PPCPortInfo {
79
+ * Returns: true if KVM can enable the PMU
36
void *opaque;
80
* and false otherwise.
37
hwaddr addr;
81
*/
38
hwaddr size;
82
-bool kvm_arm_pmu_supported(CPUState *cs);
39
+ int irqs[3]; /* currently no device needs more IRQ lines than this */
83
+bool kvm_arm_pmu_supported(void);
40
} PPCPortInfo;
84
41
85
/**
42
typedef struct PPCInfo {
86
* kvm_arm_sve_supported:
43
@@ -XXX,XX +XXX,XX @@ typedef struct PPCInfo {
87
- * @cs: CPUState
44
} PPCInfo;
88
*
45
89
- * Returns true if the KVM VCPU can enable SVE and false otherwise.
46
static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
90
+ * Returns true if KVM can enable SVE and false otherwise.
47
- void *opaque,
91
*/
48
- const char *name, hwaddr size)
92
-bool kvm_arm_sve_supported(CPUState *cs);
49
+ void *opaque,
93
+bool kvm_arm_sve_supported(void);
50
+ const char *name, hwaddr size,
94
51
+ const int *irqs)
95
/**
96
* kvm_arm_get_max_vm_ipa_size:
97
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
98
99
static inline void kvm_arm_add_vcpu_properties(Object *obj) {}
100
101
-static inline bool kvm_arm_aarch32_supported(CPUState *cs)
102
+static inline bool kvm_arm_aarch32_supported(void)
103
{
52
{
104
return false;
53
/* Initialize, configure and realize a TYPE_UNIMPLEMENTED_DEVICE,
54
* and return a pointer to its MemoryRegion.
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
105
}
56
}
106
57
107
-static inline bool kvm_arm_pmu_supported(CPUState *cs)
58
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
108
+static inline bool kvm_arm_pmu_supported(void)
59
- const char *name, hwaddr size)
60
+ const char *name, hwaddr size,
61
+ const int *irqs)
109
{
62
{
110
return false;
63
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
64
CMSDKAPBUART *uart = opaque;
65
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
111
}
66
}
112
67
113
-static inline bool kvm_arm_sve_supported(CPUState *cs)
68
static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
114
+static inline bool kvm_arm_sve_supported(void)
69
- const char *name, hwaddr size)
70
+ const char *name, hwaddr size,
71
+ const int *irqs)
115
{
72
{
116
return false;
73
MPS2SCC *scc = opaque;
74
DeviceState *sccdev;
75
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
117
}
76
}
118
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
77
119
index XXXXXXX..XXXXXXX 100644
78
static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
120
--- a/target/arm/cpu.c
79
- const char *name, hwaddr size)
121
+++ b/target/arm/cpu.c
80
+ const char *name, hwaddr size,
122
@@ -XXX,XX +XXX,XX @@ static void arm_set_pmu(Object *obj, bool value, Error **errp)
81
+ const int *irqs)
123
ARMCPU *cpu = ARM_CPU(obj);
82
{
124
83
MPS2FPGAIO *fpgaio = opaque;
125
if (value) {
84
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
126
- if (kvm_enabled() && !kvm_arm_pmu_supported(CPU(cpu))) {
85
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
127
+ if (kvm_enabled() && !kvm_arm_pmu_supported()) {
128
error_setg(errp, "'pmu' feature not supported by KVM on this host");
129
return;
130
}
131
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/cpu64.c
134
+++ b/target/arm/cpu64.c
135
@@ -XXX,XX +XXX,XX @@ void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
136
137
/* Collect the set of vector lengths supported by KVM. */
138
bitmap_zero(kvm_supported, ARM_MAX_VQ);
139
- if (kvm_enabled() && kvm_arm_sve_supported(CPU(cpu))) {
140
+ if (kvm_enabled() && kvm_arm_sve_supported()) {
141
kvm_arm_sve_get_vls(CPU(cpu), kvm_supported);
142
} else if (kvm_enabled()) {
143
assert(!cpu_isar_feature(aa64_sve, cpu));
144
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
145
return;
146
}
147
148
- if (kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
149
+ if (kvm_enabled() && !kvm_arm_sve_supported()) {
150
error_setg(errp, "cannot set sve-max-vq");
151
error_append_hint(errp, "SVE not supported by KVM on this host\n");
152
return;
153
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve_vq(Object *obj, Visitor *v, const char *name,
154
return;
155
}
156
157
- if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
158
+ if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
159
error_setg(errp, "cannot enable %s", name);
160
error_append_hint(errp, "SVE not supported by KVM on this host\n");
161
return;
162
@@ -XXX,XX +XXX,XX @@ static void cpu_arm_set_sve(Object *obj, Visitor *v, const char *name,
163
return;
164
}
165
166
- if (value && kvm_enabled() && !kvm_arm_sve_supported(CPU(cpu))) {
167
+ if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
168
error_setg(errp, "'sve' feature not supported by KVM on this host");
169
return;
170
}
171
@@ -XXX,XX +XXX,XX @@ static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp)
172
* uniform execution state like do_interrupt.
173
*/
174
if (value == false) {
175
- if (!kvm_enabled() || !kvm_arm_aarch32_supported(CPU(cpu))) {
176
+ if (!kvm_enabled() || !kvm_arm_aarch32_supported()) {
177
error_setg(errp, "'aarch64' feature cannot be disabled "
178
"unless KVM is enabled and 32-bit EL1 "
179
"is supported");
180
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
181
index XXXXXXX..XXXXXXX 100644
182
--- a/target/arm/kvm.c
183
+++ b/target/arm/kvm.c
184
@@ -XXX,XX +XXX,XX @@ void kvm_arm_add_vcpu_properties(Object *obj)
185
}
186
}
86
}
187
87
188
-bool kvm_arm_pmu_supported(CPUState *cpu)
88
static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
189
+bool kvm_arm_pmu_supported(void)
89
- const char *name, hwaddr size)
90
+ const char *name, hwaddr size,
91
+ const int *irqs)
190
{
92
{
191
- return kvm_check_extension(cpu->kvm_state, KVM_CAP_ARM_PMU_V3);
93
SysBusDevice *s;
192
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3);
94
NICInfo *nd = &nd_table[0];
95
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
193
}
96
}
194
97
195
int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
98
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
196
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
99
- const char *name, hwaddr size)
197
index XXXXXXX..XXXXXXX 100644
100
+ const char *name, hwaddr size,
198
--- a/target/arm/kvm64.c
101
+ const int *irqs)
199
+++ b/target/arm/kvm64.c
102
{
200
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf)
103
TZMPC *mpc = opaque;
201
return true;
104
int i = mpc - &mms->ssram_mpc[0];
105
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
202
}
106
}
203
107
204
-bool kvm_arm_aarch32_supported(CPUState *cpu)
108
static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
205
+bool kvm_arm_aarch32_supported(void)
109
- const char *name, hwaddr size)
110
+ const char *name, hwaddr size,
111
+ const int *irqs)
206
{
112
{
207
- KVMState *s = KVM_STATE(current_accel());
113
PL080State *dma = opaque;
208
-
114
int i = dma - &mms->dma[0];
209
- return kvm_check_extension(s, KVM_CAP_ARM_EL1_32BIT);
115
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
210
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_EL1_32BIT);
211
}
116
}
212
117
213
-bool kvm_arm_sve_supported(CPUState *cpu)
118
static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
214
+bool kvm_arm_sve_supported(void)
119
- const char *name, hwaddr size)
120
+ const char *name, hwaddr size,
121
+ const int *irqs)
215
{
122
{
216
- KVMState *s = KVM_STATE(current_accel());
123
/*
217
-
124
* The AN505 has five PL022 SPI controllers.
218
- return kvm_check_extension(s, KVM_CAP_ARM_SVE);
125
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
219
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_SVE);
220
}
126
}
221
127
222
QEMU_BUILD_BUG_ON(KVM_ARM64_SVE_VQ_MIN != 1);
128
static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
223
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
129
- const char *name, hwaddr size)
224
env->features &= ~(1ULL << ARM_FEATURE_PMU);
130
+ const char *name, hwaddr size,
225
}
131
+ const int *irqs)
226
if (cpu_isar_feature(aa64_sve, cpu)) {
132
{
227
- assert(kvm_arm_sve_supported(cs));
133
ArmSbconI2CState *i2c = opaque;
228
+ assert(kvm_arm_sve_supported());
134
SysBusDevice *s;
229
cpu->kvm_init_features[0] |= 1 << KVM_ARM_VCPU_SVE;
135
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
230
}
136
continue;
231
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);
232
--
145
--
233
2.20.1
146
2.20.1
234
147
235
148
diff view generated by jsdifflib
1
Convert the pairwise ops VPADDL and VPADAL in the 2-reg-misc grouping
1
Move the specification of the IRQ information for the uart, ethernet,
2
to decodetree.
2
dma and spi devices to the data structures. (The other devices
3
3
handled by the PPCPortInfo structures don't have any interrupt lines
4
At this point we can get rid of the weird CPU_V001 #define that was
4
we need to wire up.)
5
used to avoid having to explicitly list all the arguments being
6
passed to some TCG gen/helper functions.
7
5
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200616170844.13318-3-peter.maydell@linaro.org
8
Message-id: 20210215115138.20465-14-peter.maydell@linaro.org
11
---
9
---
12
target/arm/neon-dp.decode | 6 ++
10
hw/arm/mps2-tz.c | 52 +++++++++++++++++++++++-------------------------
13
target/arm/translate-neon.inc.c | 149 ++++++++++++++++++++++++++++++++
11
1 file changed, 25 insertions(+), 27 deletions(-)
14
target/arm/translate.c | 35 +-------
15
3 files changed, 157 insertions(+), 33 deletions(-)
16
12
17
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/neon-dp.decode
15
--- a/hw/arm/mps2-tz.c
20
+++ b/target/arm/neon-dp.decode
16
+++ b/hw/arm/mps2-tz.c
21
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
17
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
22
&2misc vm=%vm_dp vd=%vd_dp
18
const char *name, hwaddr size,
23
19
const int *irqs)
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
20
{
25
+
21
+ /* The irq[] array is tx, rx, combined, in that order */
26
+ VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
22
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
27
+ VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
23
CMSDKAPBUART *uart = opaque;
28
+
24
int i = uart - &mms->uart[0];
29
+ VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
25
- int rxirqno = i * 2 + 32;
30
+ VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
26
- int txirqno = i * 2 + 33;
31
]
27
- int combirqno = i + 42;
32
28
SysBusDevice *s;
33
# Subgroup for size != 0b11
29
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
34
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
30
35
index XXXXXXX..XXXXXXX 100644
31
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
36
--- a/target/arm/translate-neon.inc.c
32
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
37
+++ b/target/arm/translate-neon.inc.c
33
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
38
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV64(DisasContext *s, arg_VREV64 *a)
34
s = SYS_BUS_DEVICE(uart);
39
}
35
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
40
return true;
36
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, rxirqno));
37
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
38
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
39
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
40
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
41
- sysbus_connect_irq(s, 4, get_sse_irq_in(mms, combirqno));
42
+ sysbus_connect_irq(s, 4, get_sse_irq_in(mms, irqs[2]));
43
return sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0);
41
}
44
}
42
+
45
43
+static bool do_2misc_pairwise(DisasContext *s, arg_2misc *a,
46
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
44
+ NeonGenWidenFn *widenfn,
47
45
+ NeonGenTwo64OpFn *opfn,
48
s = SYS_BUS_DEVICE(mms->lan9118);
46
+ NeonGenTwo64OpFn *accfn)
49
sysbus_realize_and_unref(s, &error_fatal);
47
+{
50
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 48));
48
+ /*
51
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
49
+ * Pairwise long operations: widen both halves of the pair,
52
return sysbus_mmio_get_region(s, 0);
50
+ * combine the pairs with the opfn, and then possibly accumulate
51
+ * into the destination with the accfn.
52
+ */
53
+ int pass;
54
+
55
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
56
+ return false;
57
+ }
58
+
59
+ /* UNDEF accesses to D16-D31 if they don't exist. */
60
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
61
+ ((a->vd | a->vm) & 0x10)) {
62
+ return false;
63
+ }
64
+
65
+ if ((a->vd | a->vm) & a->q) {
66
+ return false;
67
+ }
68
+
69
+ if (!widenfn) {
70
+ return false;
71
+ }
72
+
73
+ if (!vfp_access_check(s)) {
74
+ return true;
75
+ }
76
+
77
+ for (pass = 0; pass < a->q + 1; pass++) {
78
+ TCGv_i32 tmp;
79
+ TCGv_i64 rm0_64, rm1_64, rd_64;
80
+
81
+ rm0_64 = tcg_temp_new_i64();
82
+ rm1_64 = tcg_temp_new_i64();
83
+ rd_64 = tcg_temp_new_i64();
84
+ tmp = neon_load_reg(a->vm, pass * 2);
85
+ widenfn(rm0_64, tmp);
86
+ tcg_temp_free_i32(tmp);
87
+ tmp = neon_load_reg(a->vm, pass * 2 + 1);
88
+ widenfn(rm1_64, tmp);
89
+ tcg_temp_free_i32(tmp);
90
+ opfn(rd_64, rm0_64, rm1_64);
91
+ tcg_temp_free_i64(rm0_64);
92
+ tcg_temp_free_i64(rm1_64);
93
+
94
+ if (accfn) {
95
+ TCGv_i64 tmp64 = tcg_temp_new_i64();
96
+ neon_load_reg64(tmp64, a->vd + pass);
97
+ accfn(rd_64, tmp64, rd_64);
98
+ tcg_temp_free_i64(tmp64);
99
+ }
100
+ neon_store_reg64(rd_64, a->vd + pass);
101
+ tcg_temp_free_i64(rd_64);
102
+ }
103
+ return true;
104
+}
105
+
106
+static bool trans_VPADDL_S(DisasContext *s, arg_2misc *a)
107
+{
108
+ static NeonGenWidenFn * const widenfn[] = {
109
+ gen_helper_neon_widen_s8,
110
+ gen_helper_neon_widen_s16,
111
+ tcg_gen_ext_i32_i64,
112
+ NULL,
113
+ };
114
+ static NeonGenTwo64OpFn * const opfn[] = {
115
+ gen_helper_neon_paddl_u16,
116
+ gen_helper_neon_paddl_u32,
117
+ tcg_gen_add_i64,
118
+ NULL,
119
+ };
120
+
121
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], NULL);
122
+}
123
+
124
+static bool trans_VPADDL_U(DisasContext *s, arg_2misc *a)
125
+{
126
+ static NeonGenWidenFn * const widenfn[] = {
127
+ gen_helper_neon_widen_u8,
128
+ gen_helper_neon_widen_u16,
129
+ tcg_gen_extu_i32_i64,
130
+ NULL,
131
+ };
132
+ static NeonGenTwo64OpFn * const opfn[] = {
133
+ gen_helper_neon_paddl_u16,
134
+ gen_helper_neon_paddl_u32,
135
+ tcg_gen_add_i64,
136
+ NULL,
137
+ };
138
+
139
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size], NULL);
140
+}
141
+
142
+static bool trans_VPADAL_S(DisasContext *s, arg_2misc *a)
143
+{
144
+ static NeonGenWidenFn * const widenfn[] = {
145
+ gen_helper_neon_widen_s8,
146
+ gen_helper_neon_widen_s16,
147
+ tcg_gen_ext_i32_i64,
148
+ NULL,
149
+ };
150
+ static NeonGenTwo64OpFn * const opfn[] = {
151
+ gen_helper_neon_paddl_u16,
152
+ gen_helper_neon_paddl_u32,
153
+ tcg_gen_add_i64,
154
+ NULL,
155
+ };
156
+ static NeonGenTwo64OpFn * const accfn[] = {
157
+ gen_helper_neon_addl_u16,
158
+ gen_helper_neon_addl_u32,
159
+ tcg_gen_add_i64,
160
+ NULL,
161
+ };
162
+
163
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size],
164
+ accfn[a->size]);
165
+}
166
+
167
+static bool trans_VPADAL_U(DisasContext *s, arg_2misc *a)
168
+{
169
+ static NeonGenWidenFn * const widenfn[] = {
170
+ gen_helper_neon_widen_u8,
171
+ gen_helper_neon_widen_u16,
172
+ tcg_gen_extu_i32_i64,
173
+ NULL,
174
+ };
175
+ static NeonGenTwo64OpFn * const opfn[] = {
176
+ gen_helper_neon_paddl_u16,
177
+ gen_helper_neon_paddl_u32,
178
+ tcg_gen_add_i64,
179
+ NULL,
180
+ };
181
+ static NeonGenTwo64OpFn * const accfn[] = {
182
+ gen_helper_neon_addl_u16,
183
+ gen_helper_neon_addl_u32,
184
+ tcg_gen_add_i64,
185
+ NULL,
186
+ };
187
+
188
+ return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size],
189
+ accfn[a->size]);
190
+}
191
diff --git a/target/arm/translate.c b/target/arm/translate.c
192
index XXXXXXX..XXXXXXX 100644
193
--- a/target/arm/translate.c
194
+++ b/target/arm/translate.c
195
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
196
gen_rfe(s, pc, load_cpu_field(spsr));
197
}
53
}
198
54
199
-#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
200
-
56
const char *name, hwaddr size,
201
static int gen_neon_unzip(int rd, int rm, int size, int q)
57
const int *irqs)
202
{
58
{
203
TCGv_ptr pd, pm;
59
+ /* The irq[] array is DMACINTR, DMACINTERR, DMACINTTC, in that order */
204
@@ -XXX,XX +XXX,XX @@ static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
60
PL080State *dma = opaque;
205
tcg_temp_free_i32(src);
61
int i = dma - &mms->dma[0];
62
SysBusDevice *s;
63
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
64
65
s = SYS_BUS_DEVICE(dma);
66
/* Wire up DMACINTR, DMACINTERR, DMACINTTC */
67
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 58 + i * 3));
68
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, 56 + i * 3));
69
- sysbus_connect_irq(s, 2, get_sse_irq_in(mms, 57 + i * 3));
70
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
71
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
72
+ sysbus_connect_irq(s, 2, get_sse_irq_in(mms, irqs[2]));
73
74
g_free(mscname);
75
return sysbus_mmio_get_region(s, 0);
76
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
77
* lines are set via the "MISC" register in the MPS2 FPGAIO device.
78
*/
79
PL022State *spi = opaque;
80
- int i = spi - &mms->spi[0];
81
SysBusDevice *s;
82
83
object_initialize_child(OBJECT(mms), name, spi, TYPE_PL022);
84
sysbus_realize(SYS_BUS_DEVICE(spi), &error_fatal);
85
s = SYS_BUS_DEVICE(spi);
86
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 51 + i));
87
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
88
return sysbus_mmio_get_region(s, 0);
206
}
89
}
207
90
208
-static inline void gen_neon_addl(int size)
91
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
209
-{
92
}, {
210
- switch (size) {
93
.name = "apb_ppcexp1",
211
- case 0: gen_helper_neon_addl_u16(CPU_V001); break;
94
.ports = {
212
- case 1: gen_helper_neon_addl_u32(CPU_V001); break;
95
- { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000 },
213
- case 2: tcg_gen_add_i64(CPU_V001); break;
96
- { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000 },
214
- default: abort();
97
- { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000 },
215
- }
98
- { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000 },
216
-}
99
- { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000 },
217
-
100
- { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000 },
218
static void gen_neon_narrow_op(int op, int u, int size,
101
- { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000 },
219
TCGv_i32 dest, TCGv_i64 src)
102
- { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
220
{
103
- { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
221
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
104
- { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
222
}
105
+ { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000, { 51 } },
223
switch (op) {
106
+ { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000, { 52 } },
224
case NEON_2RM_VREV64:
107
+ { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000, { 53 } },
225
- /* handled by decodetree */
108
+ { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000, { 54 } },
226
- return 1;
109
+ { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000, { 55 } },
227
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
110
+ { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000, { 32, 33, 42 } },
228
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
111
+ { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000, { 34, 35, 43 } },
229
- for (pass = 0; pass < q + 1; pass++) {
112
+ { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000, { 36, 37, 44 } },
230
- tmp = neon_load_reg(rm, pass * 2);
113
+ { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000, { 38, 39, 45 } },
231
- gen_neon_widen(cpu_V0, tmp, size, op & 1);
114
+ { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000, { 40, 41, 46 } },
232
- tmp = neon_load_reg(rm, pass * 2 + 1);
115
{ "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
233
- gen_neon_widen(cpu_V1, tmp, size, op & 1);
116
{ "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
234
- switch (size) {
117
{ "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
235
- case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
118
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
236
- case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
119
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x40101000, 0x1000 },
237
- case 2: tcg_gen_add_i64(CPU_V001); break;
120
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x40102000, 0x1000 },
238
- default: abort();
121
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x40103000, 0x1000 },
239
- }
122
- { "eth", make_eth_dev, NULL, 0x42000000, 0x100000 },
240
- if (op >= NEON_2RM_VPADAL) {
123
+ { "eth", make_eth_dev, NULL, 0x42000000, 0x100000, { 48 } },
241
- /* Accumulate. */
124
},
242
- neon_load_reg64(cpu_V1, rd + pass);
125
}, {
243
- gen_neon_addl(size);
126
.name = "ahb_ppcexp1",
244
- }
127
.ports = {
245
- neon_store_reg64(cpu_V0, rd + pass);
128
- { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000 },
246
- }
129
- { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000 },
247
- break;
130
- { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000 },
248
+ /* handled by decodetree */
131
- { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000 },
249
+ return 1;
132
+ { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000, { 58, 56, 57 } },
250
case NEON_2RM_VTRN:
133
+ { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000, { 61, 59, 60 } },
251
if (size == 2) {
134
+ { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000, { 64, 62, 63 } },
252
int n;
135
+ { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000, { 67, 65, 66 } },
136
},
137
},
138
};
253
--
139
--
254
2.20.1
140
2.20.1
255
141
256
142
diff view generated by jsdifflib
1
Convert the Neon-2-reg misc crypto ops (AESE, AESMC, SHA1H, SHA1SU1)
1
We create an OR gate to wire together the overflow IRQs for all the
2
to decodetree.
2
UARTs on the board; this has to have twice the number of inputs as
3
there are UARTs, since each UART feeds it a TX overflow and an RX
4
overflow interrupt line. Replace the hardcoded '10' with a
5
calculation based on the size of the uart[] array in the
6
MPS2TZMachineState. (We rely on OR gate inputs that are never wired
7
up or asserted being treated as always-zero.)
3
8
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-9-peter.maydell@linaro.org
11
Message-id: 20210215115138.20465-15-peter.maydell@linaro.org
7
---
12
---
8
target/arm/neon-dp.decode | 12 ++++++++
13
hw/arm/mps2-tz.c | 11 ++++++++---
9
target/arm/translate-neon.inc.c | 42 ++++++++++++++++++++++++++
14
1 file changed, 8 insertions(+), 3 deletions(-)
10
target/arm/translate.c | 52 +++------------------------------
11
3 files changed, 58 insertions(+), 48 deletions(-)
12
15
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
16
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
18
--- a/hw/arm/mps2-tz.c
16
+++ b/target/arm/neon-dp.decode
19
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
20
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
18
&2misc vm=%vm_dp vd=%vd_dp
21
*/
19
@2misc_q0 .... ... .. . .. size:2 .. .... . .... . . . .... \
22
memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
20
&2misc vm=%vm_dp vd=%vd_dp q=0
23
21
+ @2misc_q1 .... ... .. . .. size:2 .. .... . .... . . . .... \
24
- /* The overflow IRQs for all UARTs are ORed together.
22
+ &2misc vm=%vm_dp vd=%vd_dp q=1
25
+ /*
23
26
+ * The overflow IRQs for all UARTs are ORed together.
24
VREV64 1111 001 11 . 11 .. 00 .... 0 0000 . . 0 .... @2misc
27
* Tx, Rx and "combined" IRQs are sent to the NVIC separately.
25
28
- * Create the OR gate for this.
26
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
29
+ * Create the OR gate for this: it has one input for the TX overflow
27
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
30
+ * and one for the RX overflow for each UART we might have.
28
31
+ * (If the board has fewer than the maximum possible number of UARTs
29
+ AESE 1111 001 11 . 11 .. 00 .... 0 0110 0 . 0 .... @2misc_q1
32
+ * those inputs are never wired up and are treated as always-zero.)
30
+ AESD 1111 001 11 . 11 .. 00 .... 0 0110 1 . 0 .... @2misc_q1
33
*/
31
+ AESMC 1111 001 11 . 11 .. 00 .... 0 0111 0 . 0 .... @2misc_q1
34
object_initialize_child(OBJECT(mms), "uart-irq-orgate",
32
+ AESIMC 1111 001 11 . 11 .. 00 .... 0 0111 1 . 0 .... @2misc_q1
35
&mms->uart_irq_orgate, TYPE_OR_IRQ);
33
+
36
- object_property_set_int(OBJECT(&mms->uart_irq_orgate), "num-lines", 10,
34
VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
37
+ object_property_set_int(OBJECT(&mms->uart_irq_orgate), "num-lines",
35
38
+ 2 * ARRAY_SIZE(mms->uart),
36
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
39
&error_fatal);
37
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
40
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
38
VCLE0 1111 001 11 . 11 .. 01 .... 0 0011 . . 0 .... @2misc
41
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
39
VCLT0 1111 001 11 . 11 .. 01 .... 0 0100 . . 0 .... @2misc
40
41
+ SHA1H 1111 001 11 . 11 .. 01 .... 0 0101 1 . 0 .... @2misc_q1
42
+
43
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
44
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
45
46
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
47
48
VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
49
50
+ SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
51
+ SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
52
+
53
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
54
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
55
]
56
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-neon.inc.c
59
+++ b/target/arm/translate-neon.inc.c
60
@@ -XXX,XX +XXX,XX @@ static bool trans_VMVN(DisasContext *s, arg_2misc *a)
61
}
62
return do_2misc_vec(s, a, tcg_gen_gvec_not);
63
}
64
+
65
+#define WRAP_2M_3_OOL_FN(WRAPNAME, FUNC, DATA) \
66
+ static void WRAPNAME(unsigned vece, uint32_t rd_ofs, \
67
+ uint32_t rm_ofs, uint32_t oprsz, \
68
+ uint32_t maxsz) \
69
+ { \
70
+ tcg_gen_gvec_3_ool(rd_ofs, rd_ofs, rm_ofs, oprsz, maxsz, \
71
+ DATA, FUNC); \
72
+ }
73
+
74
+#define WRAP_2M_2_OOL_FN(WRAPNAME, FUNC, DATA) \
75
+ static void WRAPNAME(unsigned vece, uint32_t rd_ofs, \
76
+ uint32_t rm_ofs, uint32_t oprsz, \
77
+ uint32_t maxsz) \
78
+ { \
79
+ tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, oprsz, maxsz, DATA, FUNC); \
80
+ }
81
+
82
+WRAP_2M_3_OOL_FN(gen_AESE, gen_helper_crypto_aese, 0)
83
+WRAP_2M_3_OOL_FN(gen_AESD, gen_helper_crypto_aese, 1)
84
+WRAP_2M_2_OOL_FN(gen_AESMC, gen_helper_crypto_aesmc, 0)
85
+WRAP_2M_2_OOL_FN(gen_AESIMC, gen_helper_crypto_aesmc, 1)
86
+WRAP_2M_2_OOL_FN(gen_SHA1H, gen_helper_crypto_sha1h, 0)
87
+WRAP_2M_2_OOL_FN(gen_SHA1SU1, gen_helper_crypto_sha1su1, 0)
88
+WRAP_2M_2_OOL_FN(gen_SHA256SU0, gen_helper_crypto_sha256su0, 0)
89
+
90
+#define DO_2M_CRYPTO(INSN, FEATURE, SIZE) \
91
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
92
+ { \
93
+ if (!dc_isar_feature(FEATURE, s) || a->size != SIZE) { \
94
+ return false; \
95
+ } \
96
+ return do_2misc_vec(s, a, gen_##INSN); \
97
+ }
98
+
99
+DO_2M_CRYPTO(AESE, aa32_aes, 0)
100
+DO_2M_CRYPTO(AESD, aa32_aes, 0)
101
+DO_2M_CRYPTO(AESMC, aa32_aes, 0)
102
+DO_2M_CRYPTO(AESIMC, aa32_aes, 0)
103
+DO_2M_CRYPTO(SHA1H, aa32_sha1, 2)
104
+DO_2M_CRYPTO(SHA1SU1, aa32_sha1, 2)
105
+DO_2M_CRYPTO(SHA256SU0, aa32_sha2, 2)
106
diff --git a/target/arm/translate.c b/target/arm/translate.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/target/arm/translate.c
109
+++ b/target/arm/translate.c
110
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
111
{
112
int op;
113
int q;
114
- int rd, rm, rd_ofs, rm_ofs;
115
+ int rd, rm;
116
int size;
117
int pass;
118
int u;
119
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
120
VFP_DREG_D(rd, insn);
121
VFP_DREG_M(rm, insn);
122
size = (insn >> 20) & 3;
123
- rd_ofs = neon_reg_offset(rd, 0);
124
- rm_ofs = neon_reg_offset(rm, 0);
125
126
if ((insn & (1 << 23)) == 0) {
127
/* Three register same length: handled by decodetree */
128
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
129
case NEON_2RM_VCLE0:
130
case NEON_2RM_VCGE0:
131
case NEON_2RM_VCLT0:
132
+ case NEON_2RM_AESE: case NEON_2RM_AESMC:
133
+ case NEON_2RM_SHA1H:
134
+ case NEON_2RM_SHA1SU1:
135
/* handled by decodetree */
136
return 1;
137
case NEON_2RM_VTRN:
138
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
139
goto elementwise;
140
}
141
break;
142
- case NEON_2RM_AESE: case NEON_2RM_AESMC:
143
- if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
144
- return 1;
145
- }
146
- /*
147
- * Bit 6 is the lowest opcode bit; it distinguishes
148
- * between encryption (AESE/AESMC) and decryption
149
- * (AESD/AESIMC).
150
- */
151
- if (op == NEON_2RM_AESE) {
152
- tcg_gen_gvec_3_ool(vfp_reg_offset(true, rd),
153
- vfp_reg_offset(true, rd),
154
- vfp_reg_offset(true, rm),
155
- 16, 16, extract32(insn, 6, 1),
156
- gen_helper_crypto_aese);
157
- } else {
158
- tcg_gen_gvec_2_ool(vfp_reg_offset(true, rd),
159
- vfp_reg_offset(true, rm),
160
- 16, 16, extract32(insn, 6, 1),
161
- gen_helper_crypto_aesmc);
162
- }
163
- break;
164
- case NEON_2RM_SHA1H:
165
- if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
166
- return 1;
167
- }
168
- tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
169
- gen_helper_crypto_sha1h);
170
- break;
171
- case NEON_2RM_SHA1SU1:
172
- if ((rm | rd) & 1) {
173
- return 1;
174
- }
175
- /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
176
- if (q) {
177
- if (!dc_isar_feature(aa32_sha2, s)) {
178
- return 1;
179
- }
180
- } else if (!dc_isar_feature(aa32_sha1, s)) {
181
- return 1;
182
- }
183
- tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
184
- q ? gen_helper_crypto_sha256su0
185
- : gen_helper_crypto_sha1su1);
186
- break;
187
188
default:
189
elementwise:
190
--
42
--
191
2.20.1
43
2.20.1
192
44
193
45
diff view generated by jsdifflib
1
The functions neon_element_offset(), neon_load_element(),
1
The AN505 and AN521 have the same device layout, but the AN524 is
2
neon_load_element64(), neon_store_element() and
2
somewhat different. Allow for more than one PPCInfo array, which can
3
neon_store_element64() are used only in the translate-neon.inc.c
3
be selected based on the board type.
4
file, so move their definitions there.
5
6
Since the .inc.c file is #included in translate.c this doesn't make
7
much difference currently, but it's a more logical place to put the
8
functions and it might be helpful if we ever decide to try to make
9
the .inc.c files genuinely separate compilation units.
10
4
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20200616170844.13318-22-peter.maydell@linaro.org
7
Message-id: 20210215115138.20465-16-peter.maydell@linaro.org
14
---
8
---
15
target/arm/translate-neon.inc.c | 101 ++++++++++++++++++++++++++++++++
9
hw/arm/mps2-tz.c | 16 ++++++++++++++--
16
target/arm/translate.c | 101 --------------------------------
10
1 file changed, 14 insertions(+), 2 deletions(-)
17
2 files changed, 101 insertions(+), 101 deletions(-)
18
11
19
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-neon.inc.c
14
--- a/hw/arm/mps2-tz.c
22
+++ b/target/arm/translate-neon.inc.c
15
+++ b/hw/arm/mps2-tz.c
23
@@ -XXX,XX +XXX,XX @@ static inline int rsub_8(DisasContext *s, int x)
16
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
24
#include "decode-neon-ls.inc.c"
17
MemoryRegion *system_memory = get_system_memory();
25
#include "decode-neon-shared.inc.c"
18
DeviceState *iotkitdev;
26
19
DeviceState *dev_splitter;
27
+/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
20
+ const PPCInfo *ppcs;
28
+ * where 0 is the least significant end of the register.
21
+ int num_ppcs;
29
+ */
22
int i;
30
+static inline long
23
31
+neon_element_offset(int reg, int element, MemOp size)
24
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
32
+{
25
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
33
+ int element_size = 1 << size;
26
* + wire up the PPC's control lines to the IoTKit object
34
+ int ofs = element * element_size;
27
*/
35
+#ifdef HOST_WORDS_BIGENDIAN
28
36
+ /* Calculate the offset assuming fully little-endian,
29
- const PPCInfo ppcs[] = { {
37
+ * then XOR to account for the order of the 8-byte units.
30
+ const PPCInfo an505_ppcs[] = { {
38
+ */
31
.name = "apb_ppcexp0",
39
+ if (element_size < 8) {
32
.ports = {
40
+ ofs ^= 8 - element_size;
33
{ "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
41
+ }
34
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
42
+#endif
35
},
43
+ return neon_reg_offset(reg, 0) + ofs;
36
};
44
+}
37
45
+
38
- for (i = 0; i < ARRAY_SIZE(ppcs); i++) {
46
+static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
39
+ switch (mmc->fpga_type) {
47
+{
40
+ case FPGA_AN505:
48
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
41
+ case FPGA_AN521:
49
+
42
+ ppcs = an505_ppcs;
50
+ switch (mop) {
43
+ num_ppcs = ARRAY_SIZE(an505_ppcs);
51
+ case MO_UB:
52
+ tcg_gen_ld8u_i32(var, cpu_env, offset);
53
+ break;
54
+ case MO_UW:
55
+ tcg_gen_ld16u_i32(var, cpu_env, offset);
56
+ break;
57
+ case MO_UL:
58
+ tcg_gen_ld_i32(var, cpu_env, offset);
59
+ break;
44
+ break;
60
+ default:
45
+ default:
61
+ g_assert_not_reached();
46
+ g_assert_not_reached();
62
+ }
47
+ }
63
+}
64
+
48
+
65
+static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop)
49
+ for (i = 0; i < num_ppcs; i++) {
66
+{
50
const PPCInfo *ppcinfo = &ppcs[i];
67
+ long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
51
TZPPC *ppc = &mms->ppc[i];
68
+
52
DeviceState *ppcdev;
69
+ switch (mop) {
70
+ case MO_UB:
71
+ tcg_gen_ld8u_i64(var, cpu_env, offset);
72
+ break;
73
+ case MO_UW:
74
+ tcg_gen_ld16u_i64(var, cpu_env, offset);
75
+ break;
76
+ case MO_UL:
77
+ tcg_gen_ld32u_i64(var, cpu_env, offset);
78
+ break;
79
+ case MO_Q:
80
+ tcg_gen_ld_i64(var, cpu_env, offset);
81
+ break;
82
+ default:
83
+ g_assert_not_reached();
84
+ }
85
+}
86
+
87
+static void neon_store_element(int reg, int ele, MemOp size, TCGv_i32 var)
88
+{
89
+ long offset = neon_element_offset(reg, ele, size);
90
+
91
+ switch (size) {
92
+ case MO_8:
93
+ tcg_gen_st8_i32(var, cpu_env, offset);
94
+ break;
95
+ case MO_16:
96
+ tcg_gen_st16_i32(var, cpu_env, offset);
97
+ break;
98
+ case MO_32:
99
+ tcg_gen_st_i32(var, cpu_env, offset);
100
+ break;
101
+ default:
102
+ g_assert_not_reached();
103
+ }
104
+}
105
+
106
+static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var)
107
+{
108
+ long offset = neon_element_offset(reg, ele, size);
109
+
110
+ switch (size) {
111
+ case MO_8:
112
+ tcg_gen_st8_i64(var, cpu_env, offset);
113
+ break;
114
+ case MO_16:
115
+ tcg_gen_st16_i64(var, cpu_env, offset);
116
+ break;
117
+ case MO_32:
118
+ tcg_gen_st32_i64(var, cpu_env, offset);
119
+ break;
120
+ case MO_64:
121
+ tcg_gen_st_i64(var, cpu_env, offset);
122
+ break;
123
+ default:
124
+ g_assert_not_reached();
125
+ }
126
+}
127
+
128
static bool trans_VCMLA(DisasContext *s, arg_VCMLA *a)
129
{
130
int opr_sz;
131
diff --git a/target/arm/translate.c b/target/arm/translate.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/translate.c
134
+++ b/target/arm/translate.c
135
@@ -XXX,XX +XXX,XX @@ neon_reg_offset (int reg, int n)
136
return vfp_reg_offset(0, sreg);
137
}
138
139
-/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
140
- * where 0 is the least significant end of the register.
141
- */
142
-static inline long
143
-neon_element_offset(int reg, int element, MemOp size)
144
-{
145
- int element_size = 1 << size;
146
- int ofs = element * element_size;
147
-#ifdef HOST_WORDS_BIGENDIAN
148
- /* Calculate the offset assuming fully little-endian,
149
- * then XOR to account for the order of the 8-byte units.
150
- */
151
- if (element_size < 8) {
152
- ofs ^= 8 - element_size;
153
- }
154
-#endif
155
- return neon_reg_offset(reg, 0) + ofs;
156
-}
157
-
158
static TCGv_i32 neon_load_reg(int reg, int pass)
159
{
160
TCGv_i32 tmp = tcg_temp_new_i32();
161
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 neon_load_reg(int reg, int pass)
162
return tmp;
163
}
164
165
-static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
166
-{
167
- long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
168
-
169
- switch (mop) {
170
- case MO_UB:
171
- tcg_gen_ld8u_i32(var, cpu_env, offset);
172
- break;
173
- case MO_UW:
174
- tcg_gen_ld16u_i32(var, cpu_env, offset);
175
- break;
176
- case MO_UL:
177
- tcg_gen_ld_i32(var, cpu_env, offset);
178
- break;
179
- default:
180
- g_assert_not_reached();
181
- }
182
-}
183
-
184
-static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop)
185
-{
186
- long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
187
-
188
- switch (mop) {
189
- case MO_UB:
190
- tcg_gen_ld8u_i64(var, cpu_env, offset);
191
- break;
192
- case MO_UW:
193
- tcg_gen_ld16u_i64(var, cpu_env, offset);
194
- break;
195
- case MO_UL:
196
- tcg_gen_ld32u_i64(var, cpu_env, offset);
197
- break;
198
- case MO_Q:
199
- tcg_gen_ld_i64(var, cpu_env, offset);
200
- break;
201
- default:
202
- g_assert_not_reached();
203
- }
204
-}
205
-
206
static void neon_store_reg(int reg, int pass, TCGv_i32 var)
207
{
208
tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
209
tcg_temp_free_i32(var);
210
}
211
212
-static void neon_store_element(int reg, int ele, MemOp size, TCGv_i32 var)
213
-{
214
- long offset = neon_element_offset(reg, ele, size);
215
-
216
- switch (size) {
217
- case MO_8:
218
- tcg_gen_st8_i32(var, cpu_env, offset);
219
- break;
220
- case MO_16:
221
- tcg_gen_st16_i32(var, cpu_env, offset);
222
- break;
223
- case MO_32:
224
- tcg_gen_st_i32(var, cpu_env, offset);
225
- break;
226
- default:
227
- g_assert_not_reached();
228
- }
229
-}
230
-
231
-static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var)
232
-{
233
- long offset = neon_element_offset(reg, ele, size);
234
-
235
- switch (size) {
236
- case MO_8:
237
- tcg_gen_st8_i64(var, cpu_env, offset);
238
- break;
239
- case MO_16:
240
- tcg_gen_st16_i64(var, cpu_env, offset);
241
- break;
242
- case MO_32:
243
- tcg_gen_st32_i64(var, cpu_env, offset);
244
- break;
245
- case MO_64:
246
- tcg_gen_st_i64(var, cpu_env, offset);
247
- break;
248
- default:
249
- g_assert_not_reached();
250
- }
251
-}
252
-
253
static inline void neon_load_reg64(TCGv_i64 var, int reg)
254
{
255
tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
256
--
53
--
257
2.20.1
54
2.20.1
258
55
259
56
diff view generated by jsdifflib
1
Convert the remaining ops in the Neon 2-reg-misc group which
1
The AN505 and AN521 have the same layout of RAM; the AN524 does not.
2
can be implemented simply with our do_2misc() helper.
2
Replace the current hard-coding of where the RAM is and which parts
3
of it are behind which MPCs with a data-driven approach.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-14-peter.maydell@linaro.org
7
Message-id: 20210215115138.20465-17-peter.maydell@linaro.org
7
---
8
---
8
target/arm/neon-dp.decode | 10 +++++
9
hw/arm/mps2-tz.c | 175 +++++++++++++++++++++++++++++++++++++----------
9
target/arm/translate-neon.inc.c | 69 +++++++++++++++++++++++++++++++++
10
1 file changed, 138 insertions(+), 37 deletions(-)
10
target/arm/translate.c | 38 ++++--------------
11
11
3 files changed, 86 insertions(+), 31 deletions(-)
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
14
--- a/hw/arm/mps2-tz.c
16
+++ b/target/arm/neon-dp.decode
15
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
16
@@ -XXX,XX +XXX,XX @@
18
AESMC 1111 001 11 . 11 .. 00 .... 0 0111 0 . 0 .... @2misc_q1
17
#include "qom/object.h"
19
AESIMC 1111 001 11 . 11 .. 00 .... 0 0111 1 . 0 .... @2misc_q1
18
20
19
#define MPS2TZ_NUMIRQ_MAX 92
21
+ VCLS 1111 001 11 . 11 .. 00 .... 0 1000 . . 0 .... @2misc
20
+#define MPS2TZ_RAM_MAX 4
22
+ VCLZ 1111 001 11 . 11 .. 00 .... 0 1001 . . 0 .... @2misc
21
23
+ VCNT 1111 001 11 . 11 .. 00 .... 0 1010 . . 0 .... @2misc
22
typedef enum MPS2TZFPGAType {
24
+
23
FPGA_AN505,
25
VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
24
FPGA_AN521,
26
25
} MPS2TZFPGAType;
27
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
26
28
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
27
+/*
29
VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
28
+ * Define the layout of RAM in a board, including which parts are
30
VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
29
+ * behind which MPCs.
31
30
+ * mrindex specifies the index into mms->ram[] to use for the backing RAM;
32
+ VABS_F 1111 001 11 . 11 .. 01 .... 0 1110 . . 0 .... @2misc
31
+ * -1 means "use the system RAM".
33
+ VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
32
+ */
34
+
33
+typedef struct RAMInfo {
35
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
34
+ const char *name;
36
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
35
+ uint32_t base;
37
36
+ uint32_t size;
38
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
37
+ int mpc; /* MPC number, -1 for "not behind an MPC" */
39
38
+ int mrindex;
40
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
39
+ int flags;
41
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
40
+} RAMInfo;
42
+
41
+
43
+ VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
42
+/*
44
+ VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
43
+ * Flag values:
45
]
44
+ * IS_ALIAS: this RAM area is an alias to the upstream end of the
46
45
+ * MPC specified by its .mpc value
47
# Subgroup for size != 0b11
46
+ */
48
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
47
+#define IS_ALIAS 1
49
index XXXXXXX..XXXXXXX 100644
48
+
50
--- a/target/arm/translate-neon.inc.c
49
struct MPS2TZMachineClass {
51
+++ b/target/arm/translate-neon.inc.c
50
MachineClass parent;
52
@@ -XXX,XX +XXX,XX @@ static bool trans_VREV16(DisasContext *s, arg_2misc *a)
51
MPS2TZFPGAType fpga_type;
53
}
52
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
54
return do_2misc(s, a, gen_rev16);
53
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
55
}
54
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
56
+
55
int numirq; /* Number of external interrupts */
57
+static bool trans_VCLS(DisasContext *s, arg_2misc *a)
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)
58
+{
117
+{
59
+ static NeonGenOneOpFn * const fn[] = {
118
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
60
+ gen_helper_neon_cls_s8,
119
+ const RAMInfo *p;
61
+ gen_helper_neon_cls_s16,
120
+
62
+ gen_helper_neon_cls_s32,
121
+ for (p = mmc->raminfo; p->name; p++) {
63
+ NULL,
122
+ if (p->mpc == mpc && !(p->flags & IS_ALIAS)) {
64
+ };
123
+ return p;
65
+ return do_2misc(s, a, fn[a->size]);
124
+ }
125
+ }
126
+ /* if raminfo array doesn't have an entry for each MPC this is a bug */
127
+ g_assert_not_reached();
66
+}
128
+}
67
+
129
+
68
+static void do_VCLZ_32(TCGv_i32 rd, TCGv_i32 rm)
130
+static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
131
+ const RAMInfo *raminfo)
69
+{
132
+{
70
+ tcg_gen_clzi_i32(rd, rm, 32);
133
+ /* Return an initialized MemoryRegion for the RAMInfo. */
134
+ MemoryRegion *ram;
135
+
136
+ if (raminfo->mrindex < 0) {
137
+ /* Means this RAMInfo is for QEMU's "system memory" */
138
+ MachineState *machine = MACHINE(mms);
139
+ return machine->ram;
140
+ }
141
+
142
+ assert(raminfo->mrindex < MPS2TZ_RAM_MAX);
143
+ ram = &mms->ram[raminfo->mrindex];
144
+
145
+ memory_region_init_ram(ram, NULL, raminfo->name,
146
+ raminfo->size, &error_fatal);
147
+ return ram;
71
+}
148
+}
72
+
149
+
73
+static bool trans_VCLZ(DisasContext *s, arg_2misc *a)
150
/* Create an alias of an entire original MemoryRegion @orig
151
* located at @base in the memory map.
152
*/
153
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
154
const int *irqs)
155
{
156
TZMPC *mpc = opaque;
157
- int i = mpc - &mms->ssram_mpc[0];
158
- MemoryRegion *ssram = &mms->ssram[i];
159
+ int i = mpc - &mms->mpc[0];
160
MemoryRegion *upstream;
161
- char *mpcname = g_strdup_printf("%s-mpc", name);
162
- static uint32_t ramsize[] = { 0x00400000, 0x00200000, 0x00200000 };
163
- static uint32_t rambase[] = { 0x00000000, 0x28000000, 0x28200000 };
164
+ const RAMInfo *raminfo = find_raminfo_for_mpc(mms, i);
165
+ MemoryRegion *ram = mr_for_raminfo(mms, raminfo);
166
167
- memory_region_init_ram(ssram, NULL, name, ramsize[i], &error_fatal);
168
-
169
- object_initialize_child(OBJECT(mms), mpcname, mpc, TYPE_TZ_MPC);
170
- object_property_set_link(OBJECT(mpc), "downstream", OBJECT(ssram),
171
+ object_initialize_child(OBJECT(mms), name, mpc, TYPE_TZ_MPC);
172
+ object_property_set_link(OBJECT(mpc), "downstream", OBJECT(ram),
173
&error_fatal);
174
sysbus_realize(SYS_BUS_DEVICE(mpc), &error_fatal);
175
/* Map the upstream end of the MPC into system memory */
176
upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
177
- memory_region_add_subregion(get_system_memory(), rambase[i], upstream);
178
+ memory_region_add_subregion(get_system_memory(), raminfo->base, upstream);
179
/* and connect its interrupt to the IoTKit */
180
qdev_connect_gpio_out_named(DEVICE(mpc), "irq", 0,
181
qdev_get_gpio_in_named(DEVICE(&mms->iotkit),
182
"mpcexp_status", i));
183
184
- /* The first SSRAM is a special case as it has an alias; accesses to
185
- * the alias region at 0x00400000 must also go to the MPC upstream.
186
- */
187
- if (i == 0) {
188
- make_ram_alias(&mms->ssram1_m, "mps.ssram1_m", upstream, 0x00400000);
189
- }
190
-
191
- g_free(mpcname);
192
/* Return the register interface MR for our caller to map behind the PPC */
193
return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
194
}
195
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
196
return sysbus_mmio_get_region(s, 0);
197
}
198
199
+static void create_non_mpc_ram(MPS2TZMachineState *mms)
74
+{
200
+{
75
+ static NeonGenOneOpFn * const fn[] = {
201
+ /*
76
+ gen_helper_neon_clz_u8,
202
+ * Handle the RAMs which are either not behind MPCs or which are
77
+ gen_helper_neon_clz_u16,
203
+ * aliases to another MPC.
78
+ do_VCLZ_32,
204
+ */
79
+ NULL,
205
+ const RAMInfo *p;
80
+ };
206
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
81
+ return do_2misc(s, a, fn[a->size]);
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
+ }
82
+}
219
+}
83
+
220
+
84
+static bool trans_VCNT(DisasContext *s, arg_2misc *a)
221
static void mps2tz_common_init(MachineState *machine)
85
+{
222
{
86
+ if (a->size != 0) {
223
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
87
+ return false;
224
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
88
+ }
225
qdev_connect_gpio_out_named(iotkitdev, "sec_resp_cfg", 0,
89
+ return do_2misc(s, a, gen_helper_neon_cnt_u8);
226
qdev_get_gpio_in(dev_splitter, 0));
90
+}
227
91
+
228
- /* The IoTKit sets up much of the memory layout, including
92
+static bool trans_VABS_F(DisasContext *s, arg_2misc *a)
229
+ /*
93
+{
230
+ * The IoTKit sets up much of the memory layout, including
94
+ if (a->size != 2) {
231
* the aliases between secure and non-secure regions in the
95
+ return false;
232
- * address space. The FPGA itself contains:
96
+ }
233
- *
97
+ /* TODO: FP16 : size == 1 */
234
- * 0x00000000..0x003fffff SSRAM1
98
+ return do_2misc(s, a, gen_helper_vfp_abss);
235
- * 0x00400000..0x007fffff alias of SSRAM1
99
+}
236
- * 0x28000000..0x283fffff 4MB SSRAM2 + SSRAM3
100
+
237
- * 0x40100000..0x4fffffff AHB Master Expansion 1 interface devices
101
+static bool trans_VNEG_F(DisasContext *s, arg_2misc *a)
238
- * 0x80000000..0x80ffffff 16MB PSRAM
102
+{
239
- */
103
+ if (a->size != 2) {
240
-
104
+ return false;
241
- /* The FPGA images have an odd combination of different RAMs,
105
+ }
242
+ * address space, and also most of the devices in the system.
106
+ /* TODO: FP16 : size == 1 */
243
+ * The FPGA itself contains various RAMs and some additional devices.
107
+ return do_2misc(s, a, gen_helper_vfp_negs);
244
+ * The FPGA images have an odd combination of different RAMs,
108
+}
245
* because in hardware they are different implementations and
109
+
246
* connected to different buses, giving varying performance/size
110
+static bool trans_VRECPE(DisasContext *s, arg_2misc *a)
247
* tradeoffs. For QEMU they're all just RAM, though. We arbitrarily
111
+{
248
- * call the 16MB our "system memory", as it's the largest lump.
112
+ if (a->size != 2) {
249
+ * call the largest lump our "system memory".
113
+ return false;
250
*/
114
+ }
251
- memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
115
+ return do_2misc(s, a, gen_helper_recpe_u32);
252
116
+}
253
/*
117
+
254
* The overflow IRQs for all UARTs are ORed together.
118
+static bool trans_VRSQRTE(DisasContext *s, arg_2misc *a)
255
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
119
+{
256
const PPCInfo an505_ppcs[] = { {
120
+ if (a->size != 2) {
257
.name = "apb_ppcexp0",
121
+ return false;
258
.ports = {
122
+ }
259
- { "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
123
+ return do_2misc(s, a, gen_helper_rsqrte_u32);
260
- { "ssram-1", make_mpc, &mms->ssram_mpc[1], 0x58008000, 0x1000 },
124
+}
261
- { "ssram-2", make_mpc, &mms->ssram_mpc[2], 0x58009000, 0x1000 },
125
diff --git a/target/arm/translate.c b/target/arm/translate.c
262
+ { "ssram-0-mpc", make_mpc, &mms->mpc[0], 0x58007000, 0x1000 },
126
index XXXXXXX..XXXXXXX 100644
263
+ { "ssram-1-mpc", make_mpc, &mms->mpc[1], 0x58008000, 0x1000 },
127
--- a/target/arm/translate.c
264
+ { "ssram-2-mpc", make_mpc, &mms->mpc[2], 0x58009000, 0x1000 },
128
+++ b/target/arm/translate.c
265
},
129
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
266
}, {
130
case NEON_2RM_SHA1SU1:
267
.name = "apb_ppcexp1",
131
case NEON_2RM_VREV32:
268
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
132
case NEON_2RM_VREV16:
269
133
+ case NEON_2RM_VCLS:
270
create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000);
134
+ case NEON_2RM_VCLZ:
271
135
+ case NEON_2RM_VCNT:
272
+ create_non_mpc_ram(mms);
136
+ case NEON_2RM_VABS_F:
273
+
137
+ case NEON_2RM_VNEG_F:
274
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
138
+ case NEON_2RM_VRECPE:
275
}
139
+ case NEON_2RM_VRSQRTE:
276
140
/* handled by decodetree */
277
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
141
return 1;
278
mmc->fpgaio_num_leds = 2;
142
case NEON_2RM_VTRN:
279
mmc->fpgaio_has_switches = false;
143
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
280
mmc->numirq = 92;
144
for (pass = 0; pass < (q ? 4 : 2); pass++) {
281
+ mmc->raminfo = an505_raminfo;
145
tmp = neon_load_reg(rm, pass);
282
mmc->armsse_type = TYPE_IOTKIT;
146
switch (op) {
283
}
147
- case NEON_2RM_VCLS:
284
148
- switch (size) {
285
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
149
- case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
286
mmc->fpgaio_num_leds = 2;
150
- case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
287
mmc->fpgaio_has_switches = false;
151
- case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
288
mmc->numirq = 92;
152
- default: abort();
289
+ mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
153
- }
290
mmc->armsse_type = TYPE_SSE200;
154
- break;
291
}
155
- case NEON_2RM_VCLZ:
292
156
- switch (size) {
157
- case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
158
- case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
159
- case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
160
- default: abort();
161
- }
162
- break;
163
- case NEON_2RM_VCNT:
164
- gen_helper_neon_cnt_u8(tmp, tmp);
165
- break;
166
case NEON_2RM_VQABS:
167
switch (size) {
168
case 0:
169
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
170
tcg_temp_free_ptr(fpstatus);
171
break;
172
}
173
- case NEON_2RM_VABS_F:
174
- gen_helper_vfp_abss(tmp, tmp);
175
- break;
176
- case NEON_2RM_VNEG_F:
177
- gen_helper_vfp_negs(tmp, tmp);
178
- break;
179
case NEON_2RM_VSWP:
180
tmp2 = neon_load_reg(rd, pass);
181
neon_store_reg(rm, pass, tmp2);
182
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
183
tcg_temp_free_ptr(fpst);
184
break;
185
}
186
- case NEON_2RM_VRECPE:
187
- gen_helper_recpe_u32(tmp, tmp);
188
- break;
189
- case NEON_2RM_VRSQRTE:
190
- gen_helper_rsqrte_u32(tmp, tmp);
191
- break;
192
case NEON_2RM_VRECPE_F:
193
{
194
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
195
--
293
--
196
2.20.1
294
2.20.1
197
295
198
296
diff view generated by jsdifflib
1
Convert the Neon VTRN insn to decodetree. This is the last insn in the
1
Instead of hardcoding the MachineClass default_ram_size and
2
Neon data-processing group, so we can remove all the now-unused old
2
default_ram_id fields, set them on class creation by finding the
3
decoder framework.
3
entry in the RAMInfo array which is marked as being the QEMU system
4
4
RAM.
5
It's possible that there's a more efficient implementation of
6
VTRN, but for this conversion we just copy the existing approach.
7
5
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20200616170844.13318-21-peter.maydell@linaro.org
8
Message-id: 20210215115138.20465-18-peter.maydell@linaro.org
11
---
9
---
12
target/arm/neon-dp.decode | 2 +-
10
hw/arm/mps2-tz.c | 24 ++++++++++++++++++++++--
13
target/arm/translate-neon.inc.c | 90 ++++++++
11
1 file changed, 22 insertions(+), 2 deletions(-)
14
target/arm/translate.c | 363 +-------------------------------
15
3 files changed, 93 insertions(+), 362 deletions(-)
16
12
17
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/neon-dp.decode
15
--- a/hw/arm/mps2-tz.c
20
+++ b/target/arm/neon-dp.decode
16
+++ b/hw/arm/mps2-tz.c
21
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
17
@@ -XXX,XX +XXX,XX @@ static void mps2tz_class_init(ObjectClass *oc, void *data)
22
VNEG_F 1111 001 11 . 11 .. 01 .... 0 1111 . . 0 .... @2misc
18
23
19
mc->init = mps2tz_common_init;
24
VSWP 1111 001 11 . 11 .. 10 .... 0 0000 . . 0 .... @2misc
20
iic->check = mps2_tz_idau_check;
25
-
21
- mc->default_ram_size = 16 * MiB;
26
+ VTRN 1111 001 11 . 11 .. 10 .... 0 0001 . . 0 .... @2misc
22
- mc->default_ram_id = "mps.ram";
27
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
28
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
29
30
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-neon.inc.c
33
+++ b/target/arm/translate-neon.inc.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VSWP(DisasContext *s, arg_2misc *a)
35
36
return true;
37
}
38
+static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
39
+{
40
+ TCGv_i32 rd, tmp;
41
+
42
+ rd = tcg_temp_new_i32();
43
+ tmp = tcg_temp_new_i32();
44
+
45
+ tcg_gen_shli_i32(rd, t0, 8);
46
+ tcg_gen_andi_i32(rd, rd, 0xff00ff00);
47
+ tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
48
+ tcg_gen_or_i32(rd, rd, tmp);
49
+
50
+ tcg_gen_shri_i32(t1, t1, 8);
51
+ tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
52
+ tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
53
+ tcg_gen_or_i32(t1, t1, tmp);
54
+ tcg_gen_mov_i32(t0, rd);
55
+
56
+ tcg_temp_free_i32(tmp);
57
+ tcg_temp_free_i32(rd);
58
+}
23
+}
59
+
24
+
60
+static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
25
+static void mps2tz_set_default_ram_info(MPS2TZMachineClass *mmc)
61
+{
26
+{
62
+ TCGv_i32 rd, tmp;
27
+ /*
28
+ * Set mc->default_ram_size and default_ram_id from the
29
+ * information in mmc->raminfo.
30
+ */
31
+ MachineClass *mc = MACHINE_CLASS(mmc);
32
+ const RAMInfo *p;
63
+
33
+
64
+ rd = tcg_temp_new_i32();
34
+ for (p = mmc->raminfo; p->name; p++) {
65
+ tmp = tcg_temp_new_i32();
35
+ if (p->mrindex < 0) {
66
+
36
+ /* Found the entry for "system memory" */
67
+ tcg_gen_shli_i32(rd, t0, 16);
37
+ mc->default_ram_size = p->size;
68
+ tcg_gen_andi_i32(tmp, t1, 0xffff);
38
+ mc->default_ram_id = p->name;
69
+ tcg_gen_or_i32(rd, rd, tmp);
39
+ return;
70
+ tcg_gen_shri_i32(t1, t1, 16);
71
+ tcg_gen_andi_i32(tmp, t0, 0xffff0000);
72
+ tcg_gen_or_i32(t1, t1, tmp);
73
+ tcg_gen_mov_i32(t0, rd);
74
+
75
+ tcg_temp_free_i32(tmp);
76
+ tcg_temp_free_i32(rd);
77
+}
78
+
79
+static bool trans_VTRN(DisasContext *s, arg_2misc *a)
80
+{
81
+ TCGv_i32 tmp, tmp2;
82
+ int pass;
83
+
84
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
85
+ return false;
86
+ }
87
+
88
+ /* UNDEF accesses to D16-D31 if they don't exist. */
89
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
90
+ ((a->vd | a->vm) & 0x10)) {
91
+ return false;
92
+ }
93
+
94
+ if ((a->vd | a->vm) & a->q) {
95
+ return false;
96
+ }
97
+
98
+ if (a->size == 3) {
99
+ return false;
100
+ }
101
+
102
+ if (!vfp_access_check(s)) {
103
+ return true;
104
+ }
105
+
106
+ if (a->size == 2) {
107
+ for (pass = 0; pass < (a->q ? 4 : 2); pass += 2) {
108
+ tmp = neon_load_reg(a->vm, pass);
109
+ tmp2 = neon_load_reg(a->vd, pass + 1);
110
+ neon_store_reg(a->vm, pass, tmp2);
111
+ neon_store_reg(a->vd, pass + 1, tmp);
112
+ }
113
+ } else {
114
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
115
+ tmp = neon_load_reg(a->vm, pass);
116
+ tmp2 = neon_load_reg(a->vd, pass);
117
+ if (a->size == 0) {
118
+ gen_neon_trn_u8(tmp, tmp2);
119
+ } else {
120
+ gen_neon_trn_u16(tmp, tmp2);
121
+ }
122
+ neon_store_reg(a->vm, pass, tmp2);
123
+ neon_store_reg(a->vd, pass, tmp);
124
+ }
40
+ }
125
+ }
41
+ }
126
+ return true;
42
+ g_assert_not_reached();
127
+}
128
diff --git a/target/arm/translate.c b/target/arm/translate.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/target/arm/translate.c
131
+++ b/target/arm/translate.c
132
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
133
gen_rfe(s, pc, load_cpu_field(spsr));
134
}
43
}
135
44
136
-static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
45
static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
137
-{
46
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
138
- TCGv_i32 rd, tmp;
47
mmc->numirq = 92;
139
-
48
mmc->raminfo = an505_raminfo;
140
- rd = tcg_temp_new_i32();
49
mmc->armsse_type = TYPE_IOTKIT;
141
- tmp = tcg_temp_new_i32();
50
+ mps2tz_set_default_ram_info(mmc);
142
-
143
- tcg_gen_shli_i32(rd, t0, 8);
144
- tcg_gen_andi_i32(rd, rd, 0xff00ff00);
145
- tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
146
- tcg_gen_or_i32(rd, rd, tmp);
147
-
148
- tcg_gen_shri_i32(t1, t1, 8);
149
- tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
150
- tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
151
- tcg_gen_or_i32(t1, t1, tmp);
152
- tcg_gen_mov_i32(t0, rd);
153
-
154
- tcg_temp_free_i32(tmp);
155
- tcg_temp_free_i32(rd);
156
-}
157
-
158
-static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
159
-{
160
- TCGv_i32 rd, tmp;
161
-
162
- rd = tcg_temp_new_i32();
163
- tmp = tcg_temp_new_i32();
164
-
165
- tcg_gen_shli_i32(rd, t0, 16);
166
- tcg_gen_andi_i32(tmp, t1, 0xffff);
167
- tcg_gen_or_i32(rd, rd, tmp);
168
- tcg_gen_shri_i32(t1, t1, 16);
169
- tcg_gen_andi_i32(tmp, t0, 0xffff0000);
170
- tcg_gen_or_i32(t1, t1, tmp);
171
- tcg_gen_mov_i32(t0, rd);
172
-
173
- tcg_temp_free_i32(tmp);
174
- tcg_temp_free_i32(rd);
175
-}
176
-
177
-/* Symbolic constants for op fields for Neon 2-register miscellaneous.
178
- * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
179
- * table A7-13.
180
- */
181
-#define NEON_2RM_VREV64 0
182
-#define NEON_2RM_VREV32 1
183
-#define NEON_2RM_VREV16 2
184
-#define NEON_2RM_VPADDL 4
185
-#define NEON_2RM_VPADDL_U 5
186
-#define NEON_2RM_AESE 6 /* Includes AESD */
187
-#define NEON_2RM_AESMC 7 /* Includes AESIMC */
188
-#define NEON_2RM_VCLS 8
189
-#define NEON_2RM_VCLZ 9
190
-#define NEON_2RM_VCNT 10
191
-#define NEON_2RM_VMVN 11
192
-#define NEON_2RM_VPADAL 12
193
-#define NEON_2RM_VPADAL_U 13
194
-#define NEON_2RM_VQABS 14
195
-#define NEON_2RM_VQNEG 15
196
-#define NEON_2RM_VCGT0 16
197
-#define NEON_2RM_VCGE0 17
198
-#define NEON_2RM_VCEQ0 18
199
-#define NEON_2RM_VCLE0 19
200
-#define NEON_2RM_VCLT0 20
201
-#define NEON_2RM_SHA1H 21
202
-#define NEON_2RM_VABS 22
203
-#define NEON_2RM_VNEG 23
204
-#define NEON_2RM_VCGT0_F 24
205
-#define NEON_2RM_VCGE0_F 25
206
-#define NEON_2RM_VCEQ0_F 26
207
-#define NEON_2RM_VCLE0_F 27
208
-#define NEON_2RM_VCLT0_F 28
209
-#define NEON_2RM_VABS_F 30
210
-#define NEON_2RM_VNEG_F 31
211
-#define NEON_2RM_VSWP 32
212
-#define NEON_2RM_VTRN 33
213
-#define NEON_2RM_VUZP 34
214
-#define NEON_2RM_VZIP 35
215
-#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
216
-#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
217
-#define NEON_2RM_VSHLL 38
218
-#define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
219
-#define NEON_2RM_VRINTN 40
220
-#define NEON_2RM_VRINTX 41
221
-#define NEON_2RM_VRINTA 42
222
-#define NEON_2RM_VRINTZ 43
223
-#define NEON_2RM_VCVT_F16_F32 44
224
-#define NEON_2RM_VRINTM 45
225
-#define NEON_2RM_VCVT_F32_F16 46
226
-#define NEON_2RM_VRINTP 47
227
-#define NEON_2RM_VCVTAU 48
228
-#define NEON_2RM_VCVTAS 49
229
-#define NEON_2RM_VCVTNU 50
230
-#define NEON_2RM_VCVTNS 51
231
-#define NEON_2RM_VCVTPU 52
232
-#define NEON_2RM_VCVTPS 53
233
-#define NEON_2RM_VCVTMU 54
234
-#define NEON_2RM_VCVTMS 55
235
-#define NEON_2RM_VRECPE 56
236
-#define NEON_2RM_VRSQRTE 57
237
-#define NEON_2RM_VRECPE_F 58
238
-#define NEON_2RM_VRSQRTE_F 59
239
-#define NEON_2RM_VCVT_FS 60
240
-#define NEON_2RM_VCVT_FU 61
241
-#define NEON_2RM_VCVT_SF 62
242
-#define NEON_2RM_VCVT_UF 63
243
-
244
-/* Each entry in this array has bit n set if the insn allows
245
- * size value n (otherwise it will UNDEF). Since unallocated
246
- * op values will have no bits set they always UNDEF.
247
- */
248
-static const uint8_t neon_2rm_sizes[] = {
249
- [NEON_2RM_VREV64] = 0x7,
250
- [NEON_2RM_VREV32] = 0x3,
251
- [NEON_2RM_VREV16] = 0x1,
252
- [NEON_2RM_VPADDL] = 0x7,
253
- [NEON_2RM_VPADDL_U] = 0x7,
254
- [NEON_2RM_AESE] = 0x1,
255
- [NEON_2RM_AESMC] = 0x1,
256
- [NEON_2RM_VCLS] = 0x7,
257
- [NEON_2RM_VCLZ] = 0x7,
258
- [NEON_2RM_VCNT] = 0x1,
259
- [NEON_2RM_VMVN] = 0x1,
260
- [NEON_2RM_VPADAL] = 0x7,
261
- [NEON_2RM_VPADAL_U] = 0x7,
262
- [NEON_2RM_VQABS] = 0x7,
263
- [NEON_2RM_VQNEG] = 0x7,
264
- [NEON_2RM_VCGT0] = 0x7,
265
- [NEON_2RM_VCGE0] = 0x7,
266
- [NEON_2RM_VCEQ0] = 0x7,
267
- [NEON_2RM_VCLE0] = 0x7,
268
- [NEON_2RM_VCLT0] = 0x7,
269
- [NEON_2RM_SHA1H] = 0x4,
270
- [NEON_2RM_VABS] = 0x7,
271
- [NEON_2RM_VNEG] = 0x7,
272
- [NEON_2RM_VCGT0_F] = 0x4,
273
- [NEON_2RM_VCGE0_F] = 0x4,
274
- [NEON_2RM_VCEQ0_F] = 0x4,
275
- [NEON_2RM_VCLE0_F] = 0x4,
276
- [NEON_2RM_VCLT0_F] = 0x4,
277
- [NEON_2RM_VABS_F] = 0x4,
278
- [NEON_2RM_VNEG_F] = 0x4,
279
- [NEON_2RM_VSWP] = 0x1,
280
- [NEON_2RM_VTRN] = 0x7,
281
- [NEON_2RM_VUZP] = 0x7,
282
- [NEON_2RM_VZIP] = 0x7,
283
- [NEON_2RM_VMOVN] = 0x7,
284
- [NEON_2RM_VQMOVN] = 0x7,
285
- [NEON_2RM_VSHLL] = 0x7,
286
- [NEON_2RM_SHA1SU1] = 0x4,
287
- [NEON_2RM_VRINTN] = 0x4,
288
- [NEON_2RM_VRINTX] = 0x4,
289
- [NEON_2RM_VRINTA] = 0x4,
290
- [NEON_2RM_VRINTZ] = 0x4,
291
- [NEON_2RM_VCVT_F16_F32] = 0x2,
292
- [NEON_2RM_VRINTM] = 0x4,
293
- [NEON_2RM_VCVT_F32_F16] = 0x2,
294
- [NEON_2RM_VRINTP] = 0x4,
295
- [NEON_2RM_VCVTAU] = 0x4,
296
- [NEON_2RM_VCVTAS] = 0x4,
297
- [NEON_2RM_VCVTNU] = 0x4,
298
- [NEON_2RM_VCVTNS] = 0x4,
299
- [NEON_2RM_VCVTPU] = 0x4,
300
- [NEON_2RM_VCVTPS] = 0x4,
301
- [NEON_2RM_VCVTMU] = 0x4,
302
- [NEON_2RM_VCVTMS] = 0x4,
303
- [NEON_2RM_VRECPE] = 0x4,
304
- [NEON_2RM_VRSQRTE] = 0x4,
305
- [NEON_2RM_VRECPE_F] = 0x4,
306
- [NEON_2RM_VRSQRTE_F] = 0x4,
307
- [NEON_2RM_VCVT_FS] = 0x4,
308
- [NEON_2RM_VCVT_FU] = 0x4,
309
- [NEON_2RM_VCVT_SF] = 0x4,
310
- [NEON_2RM_VCVT_UF] = 0x4,
311
-};
312
-
313
static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
314
uint32_t opr_sz, uint32_t max_sz,
315
gen_helper_gvec_3_ptr *fn)
316
@@ -XXX,XX +XXX,XX @@ void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
317
tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
318
}
51
}
319
52
320
-/* Translate a NEON data processing instruction. Return nonzero if the
53
static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
321
- instruction is invalid.
54
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
322
- We process data in a mixture of 32-bit and 64-bit chunks.
55
mmc->numirq = 92;
323
- Mostly we use 32-bit chunks so we can use normal scalar instructions. */
56
mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
324
-
57
mmc->armsse_type = TYPE_SSE200;
325
-static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
58
+ mps2tz_set_default_ram_info(mmc);
326
-{
59
}
327
- int op;
60
328
- int q;
61
static const TypeInfo mps2tz_info = {
329
- int rd, rm;
330
- int size;
331
- int pass;
332
- int u;
333
- TCGv_i32 tmp, tmp2;
334
-
335
- if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
336
- return 1;
337
- }
338
-
339
- /* FIXME: this access check should not take precedence over UNDEF
340
- * for invalid encodings; we will generate incorrect syndrome information
341
- * for attempts to execute invalid vfp/neon encodings with FP disabled.
342
- */
343
- if (s->fp_excp_el) {
344
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
345
- syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
346
- return 0;
347
- }
348
-
349
- if (!s->vfp_enabled)
350
- return 1;
351
- q = (insn & (1 << 6)) != 0;
352
- u = (insn >> 24) & 1;
353
- VFP_DREG_D(rd, insn);
354
- VFP_DREG_M(rm, insn);
355
- size = (insn >> 20) & 3;
356
-
357
- if ((insn & (1 << 23)) == 0) {
358
- /* Three register same length: handled by decodetree */
359
- return 1;
360
- } else if (insn & (1 << 4)) {
361
- /* Two registers and shift or reg and imm: handled by decodetree */
362
- return 1;
363
- } else { /* (insn & 0x00800010 == 0x00800000) */
364
- if (size != 3) {
365
- /*
366
- * Three registers of different lengths, or two registers and
367
- * a scalar: handled by decodetree
368
- */
369
- return 1;
370
- } else { /* size == 3 */
371
- if (!u) {
372
- /* Extract: handled by decodetree */
373
- return 1;
374
- } else if ((insn & (1 << 11)) == 0) {
375
- /* Two register misc. */
376
- op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
377
- size = (insn >> 18) & 3;
378
- /* UNDEF for unknown op values and bad op-size combinations */
379
- if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
380
- return 1;
381
- }
382
- if (q && ((rm | rd) & 1)) {
383
- return 1;
384
- }
385
- switch (op) {
386
- case NEON_2RM_VREV64:
387
- case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
388
- case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
389
- case NEON_2RM_VUZP:
390
- case NEON_2RM_VZIP:
391
- case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
392
- case NEON_2RM_VSHLL:
393
- case NEON_2RM_VCVT_F16_F32:
394
- case NEON_2RM_VCVT_F32_F16:
395
- case NEON_2RM_VMVN:
396
- case NEON_2RM_VNEG:
397
- case NEON_2RM_VABS:
398
- case NEON_2RM_VCEQ0:
399
- case NEON_2RM_VCGT0:
400
- case NEON_2RM_VCLE0:
401
- case NEON_2RM_VCGE0:
402
- case NEON_2RM_VCLT0:
403
- case NEON_2RM_AESE: case NEON_2RM_AESMC:
404
- case NEON_2RM_SHA1H:
405
- case NEON_2RM_SHA1SU1:
406
- case NEON_2RM_VREV32:
407
- case NEON_2RM_VREV16:
408
- case NEON_2RM_VCLS:
409
- case NEON_2RM_VCLZ:
410
- case NEON_2RM_VCNT:
411
- case NEON_2RM_VABS_F:
412
- case NEON_2RM_VNEG_F:
413
- case NEON_2RM_VRECPE:
414
- case NEON_2RM_VRSQRTE:
415
- case NEON_2RM_VQABS:
416
- case NEON_2RM_VQNEG:
417
- case NEON_2RM_VRECPE_F:
418
- case NEON_2RM_VRSQRTE_F:
419
- case NEON_2RM_VCVT_FS:
420
- case NEON_2RM_VCVT_FU:
421
- case NEON_2RM_VCVT_SF:
422
- case NEON_2RM_VCVT_UF:
423
- case NEON_2RM_VRINTX:
424
- case NEON_2RM_VCGT0_F:
425
- case NEON_2RM_VCGE0_F:
426
- case NEON_2RM_VCEQ0_F:
427
- case NEON_2RM_VCLE0_F:
428
- case NEON_2RM_VCLT0_F:
429
- case NEON_2RM_VRINTN:
430
- case NEON_2RM_VRINTA:
431
- case NEON_2RM_VRINTM:
432
- case NEON_2RM_VRINTP:
433
- case NEON_2RM_VRINTZ:
434
- case NEON_2RM_VCVTAU:
435
- case NEON_2RM_VCVTAS:
436
- case NEON_2RM_VCVTNU:
437
- case NEON_2RM_VCVTNS:
438
- case NEON_2RM_VCVTPU:
439
- case NEON_2RM_VCVTPS:
440
- case NEON_2RM_VCVTMU:
441
- case NEON_2RM_VCVTMS:
442
- case NEON_2RM_VSWP:
443
- /* handled by decodetree */
444
- return 1;
445
- case NEON_2RM_VTRN:
446
- if (size == 2) {
447
- int n;
448
- for (n = 0; n < (q ? 4 : 2); n += 2) {
449
- tmp = neon_load_reg(rm, n);
450
- tmp2 = neon_load_reg(rd, n + 1);
451
- neon_store_reg(rm, n, tmp2);
452
- neon_store_reg(rd, n + 1, tmp);
453
- }
454
- } else {
455
- goto elementwise;
456
- }
457
- break;
458
-
459
- default:
460
- elementwise:
461
- for (pass = 0; pass < (q ? 4 : 2); pass++) {
462
- tmp = neon_load_reg(rm, pass);
463
- switch (op) {
464
- case NEON_2RM_VTRN:
465
- tmp2 = neon_load_reg(rd, pass);
466
- switch (size) {
467
- case 0: gen_neon_trn_u8(tmp, tmp2); break;
468
- case 1: gen_neon_trn_u16(tmp, tmp2); break;
469
- default: abort();
470
- }
471
- neon_store_reg(rm, pass, tmp2);
472
- break;
473
- default:
474
- /* Reserved op values were caught by the
475
- * neon_2rm_sizes[] check earlier.
476
- */
477
- abort();
478
- }
479
- neon_store_reg(rd, pass, tmp);
480
- }
481
- break;
482
- }
483
- } else {
484
- /* VTBL, VTBX, VDUP: handled by decodetree */
485
- return 1;
486
- }
487
- }
488
- }
489
- return 0;
490
-}
491
-
492
static int disas_coproc_insn(DisasContext *s, uint32_t insn)
493
{
494
int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
495
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
496
}
497
/* fall back to legacy decoder */
498
499
- if (((insn >> 25) & 7) == 1) {
500
- /* NEON Data processing. */
501
- if (disas_neon_data_insn(s, insn)) {
502
- goto illegal_op;
503
- }
504
- return;
505
- }
506
if ((insn & 0x0e000f00) == 0x0c000100) {
507
if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
508
/* iWMMXt register transfer. */
509
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
510
break;
511
}
512
if (((insn >> 24) & 3) == 3) {
513
- /* Translate into the equivalent ARM encoding. */
514
- insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
515
- if (disas_neon_data_insn(s, insn)) {
516
- goto illegal_op;
517
- }
518
+ /* Neon DP, but failed disas_neon_dp() */
519
+ goto illegal_op;
520
} else if (((insn >> 8) & 0xe) == 10) {
521
/* VFP, but failed disas_vfp. */
522
goto illegal_op;
523
--
62
--
524
2.20.1
63
2.20.1
525
64
526
65
diff view generated by jsdifflib
1
Convert the VSHLL insn in the 2-reg-misc Neon group to decodetree.
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
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20200616170844.13318-6-peter.maydell@linaro.org
6
Message-id: 20210215115138.20465-19-peter.maydell@linaro.org
6
---
7
---
7
target/arm/neon-dp.decode | 2 ++
8
hw/arm/mps2-tz.c | 6 ++++++
8
target/arm/translate-neon.inc.c | 52 +++++++++++++++++++++++++++++++++
9
1 file changed, 6 insertions(+)
9
target/arm/translate.c | 35 +---------------------
10
3 files changed, 55 insertions(+), 34 deletions(-)
11
10
12
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
11
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
13
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/neon-dp.decode
13
--- a/hw/arm/mps2-tz.c
15
+++ b/target/arm/neon-dp.decode
14
+++ b/hw/arm/mps2-tz.c
16
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
15
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
17
# VQMOVN: signed result, source may be signed (_S) or unsigned (_U)
16
* Flag values:
18
VQMOVN_S 1111 001 11 . 11 .. 10 .... 0 0101 0 . 0 .... @2misc_q0
17
* IS_ALIAS: this RAM area is an alias to the upstream end of the
19
VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
18
* MPC specified by its .mpc value
20
+
19
+ * IS_ROM: this RAM area is read-only
21
+ VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
20
*/
22
]
21
#define IS_ALIAS 1
23
22
+#define IS_ROM 2
24
# Subgroup for size != 0b11
23
25
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
24
struct MPS2TZMachineClass {
26
index XXXXXXX..XXXXXXX 100644
25
MachineClass parent;
27
--- a/target/arm/translate-neon.inc.c
26
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
28
+++ b/target/arm/translate-neon.inc.c
27
if (raminfo->mrindex < 0) {
29
@@ -XXX,XX +XXX,XX @@ DO_VMOVN(VMOVN, gen_neon_narrow_u)
28
/* Means this RAMInfo is for QEMU's "system memory" */
30
DO_VMOVN(VQMOVUN, gen_helper_neon_unarrow_sat)
29
MachineState *machine = MACHINE(mms);
31
DO_VMOVN(VQMOVN_S, gen_helper_neon_narrow_sat_s)
30
+ assert(!(raminfo->flags & IS_ROM));
32
DO_VMOVN(VQMOVN_U, gen_helper_neon_narrow_sat_u)
31
return machine->ram;
33
+
32
}
34
+static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
33
35
+{
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
36
+ TCGv_i32 rm0, rm1;
35
37
+ TCGv_i64 rd;
36
memory_region_init_ram(ram, NULL, raminfo->name,
38
+ static NeonGenWidenFn * const widenfns[] = {
37
raminfo->size, &error_fatal);
39
+ gen_helper_neon_widen_u8,
38
+ if (raminfo->flags & IS_ROM) {
40
+ gen_helper_neon_widen_u16,
39
+ memory_region_set_readonly(ram, true);
41
+ tcg_gen_extu_i32_i64,
42
+ NULL,
43
+ };
44
+ NeonGenWidenFn *widenfn = widenfns[a->size];
45
+
46
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
47
+ return false;
48
+ }
40
+ }
49
+
41
return ram;
50
+ /* UNDEF accesses to D16-D31 if they don't exist. */
51
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
52
+ ((a->vd | a->vm) & 0x10)) {
53
+ return false;
54
+ }
55
+
56
+ if (a->vd & 1) {
57
+ return false;
58
+ }
59
+
60
+ if (!widenfn) {
61
+ return false;
62
+ }
63
+
64
+ if (!vfp_access_check(s)) {
65
+ return true;
66
+ }
67
+
68
+ rd = tcg_temp_new_i64();
69
+
70
+ rm0 = neon_load_reg(a->vm, 0);
71
+ rm1 = neon_load_reg(a->vm, 1);
72
+
73
+ widenfn(rd, rm0);
74
+ tcg_gen_shli_i64(rd, rd, 8 << a->size);
75
+ neon_store_reg64(rd, a->vd);
76
+ widenfn(rd, rm1);
77
+ tcg_gen_shli_i64(rd, rd, 8 << a->size);
78
+ neon_store_reg64(rd, a->vd + 1);
79
+
80
+ tcg_temp_free_i64(rd);
81
+ tcg_temp_free_i32(rm0);
82
+ tcg_temp_free_i32(rm1);
83
+ return true;
84
+}
85
diff --git a/target/arm/translate.c b/target/arm/translate.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/translate.c
88
+++ b/target/arm/translate.c
89
@@ -XXX,XX +XXX,XX @@ static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
90
tcg_temp_free_i32(rd);
91
}
42
}
92
43
93
-static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
94
-{
95
- if (u) {
96
- switch (size) {
97
- case 0: gen_helper_neon_widen_u8(dest, src); break;
98
- case 1: gen_helper_neon_widen_u16(dest, src); break;
99
- case 2: tcg_gen_extu_i32_i64(dest, src); break;
100
- default: abort();
101
- }
102
- } else {
103
- switch (size) {
104
- case 0: gen_helper_neon_widen_s8(dest, src); break;
105
- case 1: gen_helper_neon_widen_s16(dest, src); break;
106
- case 2: tcg_gen_ext_i32_i64(dest, src); break;
107
- default: abort();
108
- }
109
- }
110
- tcg_temp_free_i32(src);
111
-}
112
-
113
/* Symbolic constants for op fields for Neon 2-register miscellaneous.
114
* The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
115
* table A7-13.
116
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
117
case NEON_2RM_VUZP:
118
case NEON_2RM_VZIP:
119
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
120
+ case NEON_2RM_VSHLL:
121
/* handled by decodetree */
122
return 1;
123
case NEON_2RM_VTRN:
124
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
125
goto elementwise;
126
}
127
break;
128
- case NEON_2RM_VSHLL:
129
- if (q || (rd & 1)) {
130
- return 1;
131
- }
132
- tmp = neon_load_reg(rm, 0);
133
- tmp2 = neon_load_reg(rm, 1);
134
- for (pass = 0; pass < 2; pass++) {
135
- if (pass == 1)
136
- tmp = tmp2;
137
- gen_neon_widen(cpu_V0, tmp, size, 1);
138
- tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
139
- neon_store_reg64(cpu_V0, rd + pass);
140
- }
141
- break;
142
case NEON_2RM_VCVT_F16_F32:
143
{
144
TCGv_ptr fpst;
145
--
44
--
146
2.20.1
45
2.20.1
147
46
148
47
diff view generated by jsdifflib
1
Convert to decodetree the insns in the Neon 2-reg-misc grouping which
1
The armv7m_load_kernel() function takes a mem_size argument which it
2
we implement using gvec.
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).
5
6
Instead of hardcoding this value, find the RAMInfo corresponding to
7
the 0 address and extract its size.
3
8
4
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>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-8-peter.maydell@linaro.org
12
Message-id: 20210215115138.20465-20-peter.maydell@linaro.org
7
---
13
---
8
target/arm/neon-dp.decode | 11 +++++++
14
hw/arm/mps2-tz.c | 17 ++++++++++++++++-
9
target/arm/translate-neon.inc.c | 55 +++++++++++++++++++++++++++++++++
15
1 file changed, 16 insertions(+), 1 deletion(-)
10
target/arm/translate.c | 35 +++++----------------
11
3 files changed, 74 insertions(+), 27 deletions(-)
12
16
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
19
--- a/hw/arm/mps2-tz.c
16
+++ b/target/arm/neon-dp.decode
20
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
21
@@ -XXX,XX +XXX,XX @@ static void create_non_mpc_ram(MPS2TZMachineState *mms)
18
VPADDL_S 1111 001 11 . 11 .. 00 .... 0 0100 . . 0 .... @2misc
22
}
19
VPADDL_U 1111 001 11 . 11 .. 00 .... 0 0101 . . 0 .... @2misc
23
}
20
24
21
+ VMVN 1111 001 11 . 11 .. 00 .... 0 1011 . . 0 .... @2misc
25
+static uint32_t boot_ram_size(MPS2TZMachineState *mms)
26
+{
27
+ /* Return the size of the RAM block at guest address zero */
28
+ const RAMInfo *p;
29
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
22
+
30
+
23
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
31
+ for (p = mmc->raminfo; p->name; p++) {
24
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
32
+ if (p->base == 0) {
25
33
+ return p->size;
26
+ VCGT0 1111 001 11 . 11 .. 01 .... 0 0000 . . 0 .... @2misc
34
+ }
27
+ VCGE0 1111 001 11 . 11 .. 01 .... 0 0001 . . 0 .... @2misc
28
+ VCEQ0 1111 001 11 . 11 .. 01 .... 0 0010 . . 0 .... @2misc
29
+ VCLE0 1111 001 11 . 11 .. 01 .... 0 0011 . . 0 .... @2misc
30
+ VCLT0 1111 001 11 . 11 .. 01 .... 0 0100 . . 0 .... @2misc
31
+
32
+ VABS 1111 001 11 . 11 .. 01 .... 0 0110 . . 0 .... @2misc
33
+ VNEG 1111 001 11 . 11 .. 01 .... 0 0111 . . 0 .... @2misc
34
+
35
VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
36
VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
37
38
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/arm/translate-neon.inc.c
41
+++ b/target/arm/translate-neon.inc.c
42
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
43
44
return true;
45
}
46
+
47
+static bool do_2misc_vec(DisasContext *s, arg_2misc *a, GVecGen2Fn *fn)
48
+{
49
+ int vec_size = a->q ? 16 : 8;
50
+ int rd_ofs = neon_reg_offset(a->vd, 0);
51
+ int rm_ofs = neon_reg_offset(a->vm, 0);
52
+
53
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
54
+ return false;
55
+ }
35
+ }
56
+
36
+ g_assert_not_reached();
57
+ /* UNDEF accesses to D16-D31 if they don't exist. */
58
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
59
+ ((a->vd | a->vm) & 0x10)) {
60
+ return false;
61
+ }
62
+
63
+ if (a->size == 3) {
64
+ return false;
65
+ }
66
+
67
+ if ((a->vd | a->vm) & a->q) {
68
+ return false;
69
+ }
70
+
71
+ if (!vfp_access_check(s)) {
72
+ return true;
73
+ }
74
+
75
+ fn(a->size, rd_ofs, rm_ofs, vec_size, vec_size);
76
+
77
+ return true;
78
+}
37
+}
79
+
38
+
80
+#define DO_2MISC_VEC(INSN, FN) \
39
static void mps2tz_common_init(MachineState *machine)
81
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
40
{
82
+ { \
41
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
83
+ return do_2misc_vec(s, a, FN); \
42
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
84
+ }
43
85
+
44
create_non_mpc_ram(mms);
86
+DO_2MISC_VEC(VNEG, tcg_gen_gvec_neg)
45
87
+DO_2MISC_VEC(VABS, tcg_gen_gvec_abs)
46
- armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
88
+DO_2MISC_VEC(VCEQ0, gen_gvec_ceq0)
47
+ armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
89
+DO_2MISC_VEC(VCGT0, gen_gvec_cgt0)
48
+ boot_ram_size(mms));
90
+DO_2MISC_VEC(VCLE0, gen_gvec_cle0)
49
}
91
+DO_2MISC_VEC(VCGE0, gen_gvec_cge0)
50
92
+DO_2MISC_VEC(VCLT0, gen_gvec_clt0)
51
static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
93
+
94
+static bool trans_VMVN(DisasContext *s, arg_2misc *a)
95
+{
96
+ if (a->size != 0) {
97
+ return false;
98
+ }
99
+ return do_2misc_vec(s, a, tcg_gen_gvec_not);
100
+}
101
diff --git a/target/arm/translate.c b/target/arm/translate.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/target/arm/translate.c
104
+++ b/target/arm/translate.c
105
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
106
int size;
107
int pass;
108
int u;
109
- int vec_size;
110
TCGv_i32 tmp, tmp2;
111
112
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
113
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
114
VFP_DREG_D(rd, insn);
115
VFP_DREG_M(rm, insn);
116
size = (insn >> 20) & 3;
117
- vec_size = q ? 16 : 8;
118
rd_ofs = neon_reg_offset(rd, 0);
119
rm_ofs = neon_reg_offset(rm, 0);
120
121
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
122
case NEON_2RM_VSHLL:
123
case NEON_2RM_VCVT_F16_F32:
124
case NEON_2RM_VCVT_F32_F16:
125
+ case NEON_2RM_VMVN:
126
+ case NEON_2RM_VNEG:
127
+ case NEON_2RM_VABS:
128
+ case NEON_2RM_VCEQ0:
129
+ case NEON_2RM_VCGT0:
130
+ case NEON_2RM_VCLE0:
131
+ case NEON_2RM_VCGE0:
132
+ case NEON_2RM_VCLT0:
133
/* handled by decodetree */
134
return 1;
135
case NEON_2RM_VTRN:
136
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
137
q ? gen_helper_crypto_sha256su0
138
: gen_helper_crypto_sha1su1);
139
break;
140
- case NEON_2RM_VMVN:
141
- tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
142
- break;
143
- case NEON_2RM_VNEG:
144
- tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
145
- break;
146
- case NEON_2RM_VABS:
147
- tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
148
- break;
149
-
150
- case NEON_2RM_VCEQ0:
151
- gen_gvec_ceq0(size, rd_ofs, rm_ofs, vec_size, vec_size);
152
- break;
153
- case NEON_2RM_VCGT0:
154
- gen_gvec_cgt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
155
- break;
156
- case NEON_2RM_VCLE0:
157
- gen_gvec_cle0(size, rd_ofs, rm_ofs, vec_size, vec_size);
158
- break;
159
- case NEON_2RM_VCGE0:
160
- gen_gvec_cge0(size, rd_ofs, rm_ofs, vec_size, vec_size);
161
- break;
162
- case NEON_2RM_VCLT0:
163
- gen_gvec_clt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
164
- break;
165
166
default:
167
elementwise:
168
--
52
--
169
2.20.1
53
2.20.1
170
54
171
55
diff view generated by jsdifflib
1
Convert the Neon VZIP and VUZP insns in the 2-reg-misc group to
1
Add support for the mps3-an524 board; this is an SSE-200 based FPGA
2
decodetree.
2
image, like the existing mps2-an521. It has a usefully larger amount
3
of RAM, and a PL031 RTC, as well as some more minor differences.
4
5
In real hardware this image runs on a newer generation of the FPGA
6
board, the MPS3 rather than the older MPS2. Architecturally the two
7
boards are similar, so we implement the MPS3 boards in the mps2-tz.c
8
file as variations of the existing MPS2 boards.
3
9
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-4-peter.maydell@linaro.org
12
Message-id: 20210215115138.20465-21-peter.maydell@linaro.org
7
---
13
---
8
target/arm/neon-dp.decode | 3 ++
14
hw/arm/mps2-tz.c | 139 +++++++++++++++++++++++++++++++++++++++++++++--
9
target/arm/translate-neon.inc.c | 74 ++++++++++++++++++++++++++
15
1 file changed, 135 insertions(+), 4 deletions(-)
10
target/arm/translate.c | 92 +--------------------------------
16
11
3 files changed, 79 insertions(+), 90 deletions(-)
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
12
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/neon-dp.decode
19
--- a/hw/arm/mps2-tz.c
16
+++ b/target/arm/neon-dp.decode
20
+++ b/hw/arm/mps2-tz.c
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
21
@@ -XXX,XX +XXX,XX @@
18
22
* This source file covers the following FPGA images, for TrustZone cores:
19
VPADAL_S 1111 001 11 . 11 .. 00 .... 0 1100 . . 0 .... @2misc
23
* "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
20
VPADAL_U 1111 001 11 . 11 .. 00 .... 0 1101 . . 0 .... @2misc
24
* "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
21
+
25
+ * "mps2-an524" -- Dual Cortex-M33 as documented in Application Note AN524
22
+ VUZP 1111 001 11 . 11 .. 10 .... 0 0010 . . 0 .... @2misc
26
*
23
+ VZIP 1111 001 11 . 11 .. 10 .... 0 0011 . . 0 .... @2misc
27
* Links to the TRM for the board itself and to the various Application
24
]
28
* Notes which document the FPGA images can be found here:
25
29
@@ -XXX,XX +XXX,XX @@
26
# Subgroup for size != 0b11
30
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
31
* Application Note AN521:
28
index XXXXXXX..XXXXXXX 100644
32
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
29
--- a/target/arm/translate-neon.inc.c
33
+ * Application Note AN524:
30
+++ b/target/arm/translate-neon.inc.c
34
+ * https://developer.arm.com/documentation/dai0524/latest/
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VPADAL_U(DisasContext *s, arg_2misc *a)
35
*
32
return do_2misc_pairwise(s, a, widenfn[a->size], opfn[a->size],
36
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
33
accfn[a->size]);
37
* (ARM ECM0601256) for the details of some of the device layout:
38
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
39
- * Similarly, the AN521 uses the SSE-200, and the SSE-200 TRM defines
40
+ * Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
41
* most of the device layout:
42
* http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
43
*
44
@@ -XXX,XX +XXX,XX @@
45
#include "hw/qdev-clock.h"
46
#include "qom/object.h"
47
48
-#define MPS2TZ_NUMIRQ_MAX 92
49
+#define MPS2TZ_NUMIRQ_MAX 95
50
#define MPS2TZ_RAM_MAX 4
51
52
typedef enum MPS2TZFPGAType {
53
FPGA_AN505,
54
FPGA_AN521,
55
+ FPGA_AN524,
56
} MPS2TZFPGAType;
57
58
/*
59
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
60
TZPPC ppc[5];
61
TZMPC mpc[3];
62
PL022State spi[5];
63
- ArmSbconI2CState i2c[4];
64
+ ArmSbconI2CState i2c[5];
65
UnimplementedDeviceState i2s_audio;
66
UnimplementedDeviceState gpio[4];
67
UnimplementedDeviceState gfx;
68
+ UnimplementedDeviceState cldc;
69
+ UnimplementedDeviceState rtc;
70
PL080State dma[4];
71
TZMSC msc[4];
72
- CMSDKAPBUART uart[5];
73
+ CMSDKAPBUART uart[6];
74
SplitIRQ sec_resp_splitter;
75
qemu_or_irq uart_irq_orgate;
76
DeviceState *lan9118;
77
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
78
#define TYPE_MPS2TZ_MACHINE "mps2tz"
79
#define TYPE_MPS2TZ_AN505_MACHINE MACHINE_TYPE_NAME("mps2-an505")
80
#define TYPE_MPS2TZ_AN521_MACHINE MACHINE_TYPE_NAME("mps2-an521")
81
+#define TYPE_MPS3TZ_AN524_MACHINE MACHINE_TYPE_NAME("mps3-an524")
82
83
OBJECT_DECLARE_TYPE(MPS2TZMachineState, MPS2TZMachineClass, MPS2TZ_MACHINE)
84
85
@@ -XXX,XX +XXX,XX @@ static const uint32_t an505_oscclk[] = {
86
25000000,
87
};
88
89
+static const uint32_t an524_oscclk[] = {
90
+ 24000000,
91
+ 32000000,
92
+ 50000000,
93
+ 50000000,
94
+ 24576000,
95
+ 23750000,
96
+};
97
+
98
static const RAMInfo an505_raminfo[] = { {
99
.name = "ssram-0",
100
.base = 0x00000000,
101
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an505_raminfo[] = { {
102
},
103
};
104
105
+static const RAMInfo an524_raminfo[] = { {
106
+ .name = "bram",
107
+ .base = 0x00000000,
108
+ .size = 512 * KiB,
109
+ .mpc = 0,
110
+ .mrindex = 0,
111
+ }, {
112
+ .name = "sram",
113
+ .base = 0x20000000,
114
+ .size = 32 * 4 * KiB,
115
+ .mpc = 1,
116
+ .mrindex = 1,
117
+ }, {
118
+ /* We don't model QSPI flash yet; for now expose it as simple ROM */
119
+ .name = "QSPI",
120
+ .base = 0x28000000,
121
+ .size = 8 * MiB,
122
+ .mpc = 1,
123
+ .mrindex = 2,
124
+ .flags = IS_ROM,
125
+ }, {
126
+ .name = "DDR",
127
+ .base = 0x60000000,
128
+ .size = 2 * GiB,
129
+ .mpc = 2,
130
+ .mrindex = -1,
131
+ }, {
132
+ .name = NULL,
133
+ },
134
+};
135
+
136
static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
137
{
138
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
139
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
140
},
141
};
142
143
+ const PPCInfo an524_ppcs[] = { {
144
+ .name = "apb_ppcexp0",
145
+ .ports = {
146
+ { "bram-mpc", make_mpc, &mms->mpc[0], 0x58007000, 0x1000 },
147
+ { "qspi-mpc", make_mpc, &mms->mpc[1], 0x58008000, 0x1000 },
148
+ { "ddr-mpc", make_mpc, &mms->mpc[2], 0x58009000, 0x1000 },
149
+ },
150
+ }, {
151
+ .name = "apb_ppcexp1",
152
+ .ports = {
153
+ { "i2c0", make_i2c, &mms->i2c[0], 0x41200000, 0x1000 },
154
+ { "i2c1", make_i2c, &mms->i2c[1], 0x41201000, 0x1000 },
155
+ { "spi0", make_spi, &mms->spi[0], 0x41202000, 0x1000, { 52 } },
156
+ { "spi1", make_spi, &mms->spi[1], 0x41203000, 0x1000, { 53 } },
157
+ { "spi2", make_spi, &mms->spi[2], 0x41204000, 0x1000, { 54 } },
158
+ { "i2c2", make_i2c, &mms->i2c[2], 0x41205000, 0x1000 },
159
+ { "i2c3", make_i2c, &mms->i2c[3], 0x41206000, 0x1000 },
160
+ { /* port 7 reserved */ },
161
+ { "i2c4", make_i2c, &mms->i2c[4], 0x41208000, 0x1000 },
162
+ },
163
+ }, {
164
+ .name = "apb_ppcexp2",
165
+ .ports = {
166
+ { "scc", make_scc, &mms->scc, 0x41300000, 0x1000 },
167
+ { "i2s-audio", make_unimp_dev, &mms->i2s_audio,
168
+ 0x41301000, 0x1000 },
169
+ { "fpgaio", make_fpgaio, &mms->fpgaio, 0x41302000, 0x1000 },
170
+ { "uart0", make_uart, &mms->uart[0], 0x41303000, 0x1000, { 32, 33, 42 } },
171
+ { "uart1", make_uart, &mms->uart[1], 0x41304000, 0x1000, { 34, 35, 43 } },
172
+ { "uart2", make_uart, &mms->uart[2], 0x41305000, 0x1000, { 36, 37, 44 } },
173
+ { "uart3", make_uart, &mms->uart[3], 0x41306000, 0x1000, { 38, 39, 45 } },
174
+ { "uart4", make_uart, &mms->uart[4], 0x41307000, 0x1000, { 40, 41, 46 } },
175
+ { "uart5", make_uart, &mms->uart[5], 0x41308000, 0x1000, { 124, 125, 126 } },
176
+
177
+ { /* port 9 reserved */ },
178
+ { "clcd", make_unimp_dev, &mms->cldc, 0x4130a000, 0x1000 },
179
+ { "rtc", make_unimp_dev, &mms->rtc, 0x4130b000, 0x1000 },
180
+ },
181
+ }, {
182
+ .name = "ahb_ppcexp0",
183
+ .ports = {
184
+ { "gpio0", make_unimp_dev, &mms->gpio[0], 0x41100000, 0x1000 },
185
+ { "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
186
+ { "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
187
+ { "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
188
+ { "eth", make_eth_dev, NULL, 0x41400000, 0x100000, { 48 } },
189
+ },
190
+ },
191
+ };
192
+
193
switch (mmc->fpga_type) {
194
case FPGA_AN505:
195
case FPGA_AN521:
196
ppcs = an505_ppcs;
197
num_ppcs = ARRAY_SIZE(an505_ppcs);
198
break;
199
+ case FPGA_AN524:
200
+ ppcs = an524_ppcs;
201
+ num_ppcs = ARRAY_SIZE(an524_ppcs);
202
+ break;
203
default:
204
g_assert_not_reached();
205
}
206
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
207
mps2tz_set_default_ram_info(mmc);
34
}
208
}
35
+
209
36
+typedef void ZipFn(TCGv_ptr, TCGv_ptr);
210
+static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
37
+
38
+static bool do_zip_uzp(DisasContext *s, arg_2misc *a,
39
+ ZipFn *fn)
40
+{
211
+{
41
+ TCGv_ptr pd, pm;
212
+ MachineClass *mc = MACHINE_CLASS(oc);
42
+
213
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
43
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
214
+
44
+ return false;
215
+ mc->desc = "ARM MPS3 with AN524 FPGA image for dual Cortex-M33";
45
+ }
216
+ mc->default_cpus = 2;
46
+
217
+ mc->min_cpus = mc->default_cpus;
47
+ /* UNDEF accesses to D16-D31 if they don't exist. */
218
+ mc->max_cpus = mc->default_cpus;
48
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
219
+ mmc->fpga_type = FPGA_AN524;
49
+ ((a->vd | a->vm) & 0x10)) {
220
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
50
+ return false;
221
+ mmc->scc_id = 0x41045240;
51
+ }
222
+ mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
52
+
223
+ mmc->oscclk = an524_oscclk;
53
+ if ((a->vd | a->vm) & a->q) {
224
+ mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
54
+ return false;
225
+ mmc->fpgaio_num_leds = 10;
55
+ }
226
+ mmc->fpgaio_has_switches = true;
56
+
227
+ mmc->numirq = 95;
57
+ if (!fn) {
228
+ mmc->raminfo = an524_raminfo;
58
+ /* Bad size or size/q combination */
229
+ mmc->armsse_type = TYPE_SSE200;
59
+ return false;
230
+ mps2tz_set_default_ram_info(mmc);
60
+ }
61
+
62
+ if (!vfp_access_check(s)) {
63
+ return true;
64
+ }
65
+
66
+ pd = vfp_reg_ptr(true, a->vd);
67
+ pm = vfp_reg_ptr(true, a->vm);
68
+ fn(pd, pm);
69
+ tcg_temp_free_ptr(pd);
70
+ tcg_temp_free_ptr(pm);
71
+ return true;
72
+}
231
+}
73
+
232
+
74
+static bool trans_VUZP(DisasContext *s, arg_2misc *a)
233
static const TypeInfo mps2tz_info = {
75
+{
234
.name = TYPE_MPS2TZ_MACHINE,
76
+ static ZipFn * const fn[2][4] = {
235
.parent = TYPE_MACHINE,
77
+ {
236
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mps2tz_an521_info = {
78
+ gen_helper_neon_unzip8,
237
.class_init = mps2tz_an521_class_init,
79
+ gen_helper_neon_unzip16,
238
};
80
+ NULL,
239
81
+ NULL,
240
+static const TypeInfo mps3tz_an524_info = {
82
+ }, {
241
+ .name = TYPE_MPS3TZ_AN524_MACHINE,
83
+ gen_helper_neon_qunzip8,
242
+ .parent = TYPE_MPS2TZ_MACHINE,
84
+ gen_helper_neon_qunzip16,
243
+ .class_init = mps3tz_an524_class_init,
85
+ gen_helper_neon_qunzip32,
244
+};
86
+ NULL,
245
+
87
+ }
246
static void mps2tz_machine_init(void)
88
+ };
247
{
89
+ return do_zip_uzp(s, a, fn[a->q][a->size]);
248
type_register_static(&mps2tz_info);
90
+}
249
type_register_static(&mps2tz_an505_info);
91
+
250
type_register_static(&mps2tz_an521_info);
92
+static bool trans_VZIP(DisasContext *s, arg_2misc *a)
251
+ type_register_static(&mps3tz_an524_info);
93
+{
94
+ static ZipFn * const fn[2][4] = {
95
+ {
96
+ gen_helper_neon_zip8,
97
+ gen_helper_neon_zip16,
98
+ NULL,
99
+ NULL,
100
+ }, {
101
+ gen_helper_neon_qzip8,
102
+ gen_helper_neon_qzip16,
103
+ gen_helper_neon_qzip32,
104
+ NULL,
105
+ }
106
+ };
107
+ return do_zip_uzp(s, a, fn[a->q][a->size]);
108
+}
109
diff --git a/target/arm/translate.c b/target/arm/translate.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/target/arm/translate.c
112
+++ b/target/arm/translate.c
113
@@ -XXX,XX +XXX,XX @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
114
gen_rfe(s, pc, load_cpu_field(spsr));
115
}
252
}
116
253
117
-static int gen_neon_unzip(int rd, int rm, int size, int q)
254
type_init(mps2tz_machine_init);
118
-{
119
- TCGv_ptr pd, pm;
120
-
121
- if (!q && size == 2) {
122
- return 1;
123
- }
124
- pd = vfp_reg_ptr(true, rd);
125
- pm = vfp_reg_ptr(true, rm);
126
- if (q) {
127
- switch (size) {
128
- case 0:
129
- gen_helper_neon_qunzip8(pd, pm);
130
- break;
131
- case 1:
132
- gen_helper_neon_qunzip16(pd, pm);
133
- break;
134
- case 2:
135
- gen_helper_neon_qunzip32(pd, pm);
136
- break;
137
- default:
138
- abort();
139
- }
140
- } else {
141
- switch (size) {
142
- case 0:
143
- gen_helper_neon_unzip8(pd, pm);
144
- break;
145
- case 1:
146
- gen_helper_neon_unzip16(pd, pm);
147
- break;
148
- default:
149
- abort();
150
- }
151
- }
152
- tcg_temp_free_ptr(pd);
153
- tcg_temp_free_ptr(pm);
154
- return 0;
155
-}
156
-
157
-static int gen_neon_zip(int rd, int rm, int size, int q)
158
-{
159
- TCGv_ptr pd, pm;
160
-
161
- if (!q && size == 2) {
162
- return 1;
163
- }
164
- pd = vfp_reg_ptr(true, rd);
165
- pm = vfp_reg_ptr(true, rm);
166
- if (q) {
167
- switch (size) {
168
- case 0:
169
- gen_helper_neon_qzip8(pd, pm);
170
- break;
171
- case 1:
172
- gen_helper_neon_qzip16(pd, pm);
173
- break;
174
- case 2:
175
- gen_helper_neon_qzip32(pd, pm);
176
- break;
177
- default:
178
- abort();
179
- }
180
- } else {
181
- switch (size) {
182
- case 0:
183
- gen_helper_neon_zip8(pd, pm);
184
- break;
185
- case 1:
186
- gen_helper_neon_zip16(pd, pm);
187
- break;
188
- default:
189
- abort();
190
- }
191
- }
192
- tcg_temp_free_ptr(pd);
193
- tcg_temp_free_ptr(pm);
194
- return 0;
195
-}
196
-
197
static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
198
{
199
TCGv_i32 rd, tmp;
200
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
201
case NEON_2RM_VREV64:
202
case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
203
case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
204
+ case NEON_2RM_VUZP:
205
+ case NEON_2RM_VZIP:
206
/* handled by decodetree */
207
return 1;
208
case NEON_2RM_VTRN:
209
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
210
goto elementwise;
211
}
212
break;
213
- case NEON_2RM_VUZP:
214
- if (gen_neon_unzip(rd, rm, size, q)) {
215
- return 1;
216
- }
217
- break;
218
- case NEON_2RM_VZIP:
219
- if (gen_neon_zip(rd, rm, size, q)) {
220
- return 1;
221
- }
222
- break;
223
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
224
/* also VQMOVUN; op field and mnemonics don't line up */
225
if (rm & 1) {
226
--
255
--
227
2.20.1
256
2.20.1
228
257
229
258
diff view generated by jsdifflib
1
Convert the Neon 2-reg-misc VRINT insns to decodetree.
1
The AN524 has a USB controller (an ISP1763); we don't have a model of
2
Giving these insns their own do_vrint() function allows us
2
it but we should provide a stub "unimplemented-device" for it. This
3
to change the rounding mode just once at the start and end
3
is slightly complicated because the USB controller shares a PPC port
4
rather than doing it for every element in the vector.
4
with the ethernet controller.
5
6
Implement a make_* function which provides creates a container
7
MemoryRegion with both the ethernet controller and an
8
unimplemented-device stub for the USB controller.
5
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>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20200616170844.13318-18-peter.maydell@linaro.org
13
Message-id: 20210215115138.20465-22-peter.maydell@linaro.org
9
---
14
---
10
target/arm/neon-dp.decode | 8 +++++
15
hw/arm/mps2-tz.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
11
target/arm/translate-neon.inc.c | 61 +++++++++++++++++++++++++++++++++
16
1 file changed, 47 insertions(+), 1 deletion(-)
12
target/arm/translate.c | 31 +++--------------
13
3 files changed, 74 insertions(+), 26 deletions(-)
14
17
15
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
18
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/neon-dp.decode
20
--- a/hw/arm/mps2-tz.c
18
+++ b/target/arm/neon-dp.decode
21
+++ b/hw/arm/mps2-tz.c
19
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
22
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
20
SHA1SU1 1111 001 11 . 11 .. 10 .... 0 0111 0 . 0 .... @2misc_q1
23
21
SHA256SU0 1111 001 11 . 11 .. 10 .... 0 0111 1 . 0 .... @2misc_q1
24
ARMSSE iotkit;
22
25
MemoryRegion ram[MPS2TZ_RAM_MAX];
23
+ VRINTN 1111 001 11 . 11 .. 10 .... 0 1000 . . 0 .... @2misc
26
+ MemoryRegion eth_usb_container;
24
VRINTX 1111 001 11 . 11 .. 10 .... 0 1001 . . 0 .... @2misc
25
+ VRINTA 1111 001 11 . 11 .. 10 .... 0 1010 . . 0 .... @2misc
26
+ VRINTZ 1111 001 11 . 11 .. 10 .... 0 1011 . . 0 .... @2misc
27
28
VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
29
+
27
+
30
+ VRINTM 1111 001 11 . 11 .. 10 .... 0 1101 . . 0 .... @2misc
28
MPS2SCC scc;
31
+
29
MPS2FPGAIO fpgaio;
32
VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
30
TZPPC ppc[5];
33
31
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
34
+ VRINTP 1111 001 11 . 11 .. 10 .... 0 1111 . . 0 .... @2misc
32
UnimplementedDeviceState gfx;
35
+
33
UnimplementedDeviceState cldc;
36
VRECPE 1111 001 11 . 11 .. 11 .... 0 1000 . . 0 .... @2misc
34
UnimplementedDeviceState rtc;
37
VRSQRTE 1111 001 11 . 11 .. 11 .... 0 1001 . . 0 .... @2misc
35
+ UnimplementedDeviceState usb;
38
VRECPE_F 1111 001 11 . 11 .. 11 .... 0 1010 . . 0 .... @2misc
36
PL080State dma[4];
39
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
37
TZMSC msc[4];
40
index XXXXXXX..XXXXXXX 100644
38
CMSDKAPBUART uart[6];
41
--- a/target/arm/translate-neon.inc.c
39
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
42
+++ b/target/arm/translate-neon.inc.c
40
return sysbus_mmio_get_region(s, 0);
43
@@ -XXX,XX +XXX,XX @@ DO_FP_CMP0(VCGE0_F, gen_helper_neon_cge_f32, FWD)
41
}
44
DO_FP_CMP0(VCEQ0_F, gen_helper_neon_ceq_f32, FWD)
42
45
DO_FP_CMP0(VCLE0_F, gen_helper_neon_cge_f32, REV)
43
+static MemoryRegion *make_eth_usb(MPS2TZMachineState *mms, void *opaque,
46
DO_FP_CMP0(VCLT0_F, gen_helper_neon_cgt_f32, REV)
44
+ const char *name, hwaddr size,
47
+
45
+ const int *irqs)
48
+static bool do_vrint(DisasContext *s, arg_2misc *a, int rmode)
49
+{
46
+{
50
+ /*
47
+ /*
51
+ * Handle a VRINT* operation by iterating 32 bits at a time,
48
+ * The AN524 makes the ethernet and USB share a PPC port.
52
+ * with a specified rounding mode in operation.
49
+ * irqs[] is the ethernet IRQ.
53
+ */
50
+ */
54
+ int pass;
51
+ SysBusDevice *s;
55
+ TCGv_ptr fpst;
52
+ NICInfo *nd = &nd_table[0];
56
+ TCGv_i32 tcg_rmode;
57
+
53
+
58
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
54
+ memory_region_init(&mms->eth_usb_container, OBJECT(mms),
59
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
55
+ "mps2-tz-eth-usb-container", 0x200000);
60
+ return false;
61
+ }
62
+
56
+
63
+ /* UNDEF accesses to D16-D31 if they don't exist. */
57
+ /*
64
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
58
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
65
+ ((a->vd | a->vm) & 0x10)) {
59
+ * except that it doesn't support the checksum-offload feature.
66
+ return false;
60
+ */
67
+ }
61
+ qemu_check_nic_model(nd, "lan9118");
62
+ mms->lan9118 = qdev_new(TYPE_LAN9118);
63
+ qdev_set_nic_properties(mms->lan9118, nd);
68
+
64
+
69
+ if (a->size != 2) {
65
+ s = SYS_BUS_DEVICE(mms->lan9118);
70
+ /* TODO: FP16 will be the size == 1 case */
66
+ sysbus_realize_and_unref(s, &error_fatal);
71
+ return false;
67
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
72
+ }
73
+
68
+
74
+ if ((a->vd | a->vm) & a->q) {
69
+ memory_region_add_subregion(&mms->eth_usb_container,
75
+ return false;
70
+ 0, sysbus_mmio_get_region(s, 0));
76
+ }
77
+
71
+
78
+ if (!vfp_access_check(s)) {
72
+ /* The USB OTG controller is an ISP1763; we don't have a model of it. */
79
+ return true;
73
+ object_initialize_child(OBJECT(mms), "usb-otg",
80
+ }
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);
81
+
79
+
82
+ fpst = get_fpstatus_ptr(1);
80
+ memory_region_add_subregion(&mms->eth_usb_container,
83
+ tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
81
+ 0x100000, sysbus_mmio_get_region(s, 0));
84
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
85
+ for (pass = 0; pass < (a->q ? 4 : 2); pass++) {
86
+ TCGv_i32 tmp = neon_load_reg(a->vm, pass);
87
+ gen_helper_rints(tmp, tmp, fpst);
88
+ neon_store_reg(a->vd, pass, tmp);
89
+ }
90
+ gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode, cpu_env);
91
+ tcg_temp_free_i32(tcg_rmode);
92
+ tcg_temp_free_ptr(fpst);
93
+
82
+
94
+ return true;
83
+ return &mms->eth_usb_container;
95
+}
84
+}
96
+
85
+
97
+#define DO_VRINT(INSN, RMODE) \
86
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
98
+ static bool trans_##INSN(DisasContext *s, arg_2misc *a) \
87
const char *name, hwaddr size,
99
+ { \
88
const int *irqs)
100
+ return do_vrint(s, a, RMODE); \
89
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
101
+ }
90
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
102
+
91
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
103
+DO_VRINT(VRINTN, FPROUNDING_TIEEVEN)
92
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
104
+DO_VRINT(VRINTA, FPROUNDING_TIEAWAY)
93
- { "eth", make_eth_dev, NULL, 0x41400000, 0x100000, { 48 } },
105
+DO_VRINT(VRINTZ, FPROUNDING_ZERO)
94
+ { "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 48 } },
106
+DO_VRINT(VRINTM, FPROUNDING_NEGINF)
95
},
107
+DO_VRINT(VRINTP, FPROUNDING_POSINF)
96
},
108
diff --git a/target/arm/translate.c b/target/arm/translate.c
97
};
109
index XXXXXXX..XXXXXXX 100644
110
--- a/target/arm/translate.c
111
+++ b/target/arm/translate.c
112
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
113
case NEON_2RM_VCEQ0_F:
114
case NEON_2RM_VCLE0_F:
115
case NEON_2RM_VCLT0_F:
116
+ case NEON_2RM_VRINTN:
117
+ case NEON_2RM_VRINTA:
118
+ case NEON_2RM_VRINTM:
119
+ case NEON_2RM_VRINTP:
120
+ case NEON_2RM_VRINTZ:
121
/* handled by decodetree */
122
return 1;
123
case NEON_2RM_VTRN:
124
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
125
}
126
neon_store_reg(rm, pass, tmp2);
127
break;
128
- case NEON_2RM_VRINTN:
129
- case NEON_2RM_VRINTA:
130
- case NEON_2RM_VRINTM:
131
- case NEON_2RM_VRINTP:
132
- case NEON_2RM_VRINTZ:
133
- {
134
- TCGv_i32 tcg_rmode;
135
- TCGv_ptr fpstatus = get_fpstatus_ptr(1);
136
- int rmode;
137
-
138
- if (op == NEON_2RM_VRINTZ) {
139
- rmode = FPROUNDING_ZERO;
140
- } else {
141
- rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
142
- }
143
-
144
- tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
145
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
146
- cpu_env);
147
- gen_helper_rints(tmp, tmp, fpstatus);
148
- gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
149
- cpu_env);
150
- tcg_temp_free_ptr(fpstatus);
151
- tcg_temp_free_i32(tcg_rmode);
152
- break;
153
- }
154
case NEON_2RM_VCVTAU:
155
case NEON_2RM_VCVTAS:
156
case NEON_2RM_VCVTNU:
157
--
98
--
158
2.20.1
99
2.20.1
159
100
160
101
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.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
From 'Application Note AN521', chapter 4.7:
4
5
The SMM implements four SBCon serial modules:
6
7
One SBCon module for use by the Color LCD touch interface.
8
One SBCon module to configure the audio controller.
9
Two general purpose SBCon modules, that connect to the
10
Expansion headers J7 and J8, are intended for use with the
11
V2C-Shield1 which provide an I2C interface on the headers.
12
13
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Message-id: 20200617072539.32686-15-f4bug@amsat.org
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
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
17
---
8
---
18
hw/arm/mps2-tz.c | 23 ++++++++++++++++++-----
9
hw/arm/mps2-tz.c | 22 ++++++++++++++++++++--
19
1 file changed, 18 insertions(+), 5 deletions(-)
10
1 file changed, 20 insertions(+), 2 deletions(-)
20
11
21
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
22
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/mps2-tz.c
14
--- a/hw/arm/mps2-tz.c
24
+++ b/hw/arm/mps2-tz.c
15
+++ b/hw/arm/mps2-tz.c
25
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
17
#include "hw/misc/tz-msc.h"
26
#include "hw/arm/armsse.h"
18
#include "hw/arm/armsse.h"
27
#include "hw/dma/pl080.h"
19
#include "hw/dma/pl080.h"
20
+#include "hw/rtc/pl031.h"
28
#include "hw/ssi/pl022.h"
21
#include "hw/ssi/pl022.h"
29
+#include "hw/i2c/arm_sbcon_i2c.h"
22
#include "hw/i2c/arm_sbcon_i2c.h"
30
#include "hw/net/lan9118.h"
23
#include "hw/net/lan9118.h"
31
#include "net/net.h"
24
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
32
#include "hw/core/split-irq.h"
33
@@ -XXX,XX +XXX,XX @@ typedef struct {
34
TZPPC ppc[5];
35
TZMPC ssram_mpc[3];
36
PL022State spi[5];
37
- UnimplementedDeviceState i2c[4];
38
+ ArmSbconI2CState i2c[4];
39
UnimplementedDeviceState i2s_audio;
40
UnimplementedDeviceState gpio[4];
25
UnimplementedDeviceState gpio[4];
41
UnimplementedDeviceState gfx;
26
UnimplementedDeviceState gfx;
42
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
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,
43
return sysbus_mmio_get_region(s, 0);
35
return sysbus_mmio_get_region(s, 0);
44
}
36
}
45
37
46
+static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
38
+static MemoryRegion *make_rtc(MPS2TZMachineState *mms, void *opaque,
47
+ const char *name, hwaddr size)
39
+ const char *name, hwaddr size,
40
+ const int *irqs)
48
+{
41
+{
49
+ ArmSbconI2CState *i2c = opaque;
42
+ PL031State *pl031 = opaque;
50
+ SysBusDevice *s;
43
+ SysBusDevice *s;
51
+
44
+
52
+ object_initialize_child(OBJECT(mms), name, i2c, TYPE_ARM_SBCON_I2C);
45
+ object_initialize_child(OBJECT(mms), name, pl031, TYPE_PL031);
53
+ s = SYS_BUS_DEVICE(i2c);
46
+ s = SYS_BUS_DEVICE(pl031);
54
+ sysbus_realize(s, &error_fatal);
47
+ sysbus_realize(s, &error_fatal);
48
+ /*
49
+ * The board docs don't give an IRQ number for the PL031, so
50
+ * presumably it is not connected.
51
+ */
55
+ return sysbus_mmio_get_region(s, 0);
52
+ return sysbus_mmio_get_region(s, 0);
56
+}
53
+}
57
+
54
+
58
static void mps2tz_common_init(MachineState *machine)
55
static void create_non_mpc_ram(MPS2TZMachineState *mms)
59
{
56
{
60
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
57
/*
61
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
58
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
62
{ "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
59
63
{ "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
60
{ /* port 9 reserved */ },
64
{ "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
61
{ "clcd", make_unimp_dev, &mms->cldc, 0x4130a000, 0x1000 },
65
- { "i2c0", make_unimp_dev, &mms->i2c[0], 0x40207000, 0x1000 },
62
- { "rtc", make_unimp_dev, &mms->rtc, 0x4130b000, 0x1000 },
66
- { "i2c1", make_unimp_dev, &mms->i2c[1], 0x40208000, 0x1000 },
63
+ { "rtc", make_rtc, &mms->rtc, 0x4130b000, 0x1000 },
67
- { "i2c2", make_unimp_dev, &mms->i2c[2], 0x4020c000, 0x1000 },
68
- { "i2c3", make_unimp_dev, &mms->i2c[3], 0x4020d000, 0x1000 },
69
+ { "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
70
+ { "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
71
+ { "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
72
+ { "i2c3", make_i2c, &mms->i2c[3], 0x4020d000, 0x1000 },
73
},
64
},
74
}, {
65
}, {
75
.name = "apb_ppcexp2",
66
.name = "ahb_ppcexp0",
76
--
67
--
77
2.20.1
68
2.20.1
78
69
79
70
diff view generated by jsdifflib
1
In commit cfdb2c0c95ae9205b0 ("target/arm: Vectorize SABA/UABA") we
1
Add brief documentation of the new mps3-an524 board.
2
replaced the old handling of SABA/UABA with a vectorized implementation
3
which returns early rather than falling into the loop-ever-elements
4
code. We forgot to delete the part of the old looping code that
5
did the accumulate step, and Coverity correctly warns (CID 1428955)
6
that this code is now dead. Delete it.
7
2
8
Fixes: cfdb2c0c95ae9205b0
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20200619171547.29780-1-peter.maydell@linaro.org
6
Message-id: 20210215115138.20465-24-peter.maydell@linaro.org
13
---
7
---
14
target/arm/translate-a64.c | 12 ------------
8
docs/system/arm/mps2.rst | 24 ++++++++++++++++++------
15
1 file changed, 12 deletions(-)
9
1 file changed, 18 insertions(+), 6 deletions(-)
16
10
17
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
11
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate-a64.c
13
--- a/docs/system/arm/mps2.rst
20
+++ b/target/arm/translate-a64.c
14
+++ b/docs/system/arm/mps2.rst
21
@@ -XXX,XX +XXX,XX @@ static void disas_simd_3same_int(DisasContext *s, uint32_t insn)
15
@@ -XXX,XX +XXX,XX @@
22
genfn(tcg_res, tcg_op1, tcg_op2);
16
-Arm MPS2 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``)
23
}
17
-================================================================================================================
24
18
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
25
- if (opcode == 0xf) {
19
+=========================================================================================================================================
26
- /* SABA, UABA: accumulating ops */
20
27
- static NeonGenTwoOpFn * const fns[3] = {
21
These board models all use Arm M-profile CPUs.
28
- gen_helper_neon_add_u8,
22
29
- gen_helper_neon_add_u16,
23
-The Arm MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
30
- tcg_gen_add_i32,
24
-FPGA but is otherwise the same as the 2). Since the CPU itself
31
- };
25
-and most of the devices are in the FPGA, the details of the board
32
-
26
-as seen by the guest depend significantly on the FPGA image.
33
- read_vec_element_i32(s, tcg_op1, rd, pass, MO_32);
27
+The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
34
- fns[size](tcg_res, tcg_op1, tcg_res);
28
+bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
35
- }
29
+FPGA again, can handle 4GB of RAM and has a USB controller and QSPI flash).
36
-
30
+
37
write_vec_element_i32(s, tcg_res, rd, pass, MO_32);
31
+Since the CPU itself and most of the devices are in the FPGA, the
38
32
+details of the board as seen by the guest depend significantly on the
39
tcg_temp_free_i32(tcg_res);
33
+FPGA image.
34
35
QEMU models the following FPGA images:
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
40
--
59
--
41
2.20.1
60
2.20.1
42
61
43
62
diff view generated by jsdifflib
1
Convert the Neon insns in the 2-reg-misc group which are
1
Update old infocenter.arm.com URLs to the equivalent developer.arm.com
2
VCVT between f32 and f16 to decodetree.
2
ones (the old URLs should redirect, but we might as well avoid the
3
redirection notice, and the new URLs are pleasantly shorter).
4
5
This commit covers the links to the MPS2 board TRM, the various
6
Application Notes, the IoTKit and SSE-200 documents.
3
7
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20200616170844.13318-7-peter.maydell@linaro.org
10
Message-id: 20210215115138.20465-25-peter.maydell@linaro.org
7
---
11
---
8
target/arm/neon-dp.decode | 3 ++
12
include/hw/arm/armsse.h | 4 ++--
9
target/arm/translate-neon.inc.c | 96 +++++++++++++++++++++++++++++++++
13
include/hw/misc/armsse-cpuid.h | 2 +-
10
target/arm/translate.c | 65 ++--------------------
14
include/hw/misc/armsse-mhu.h | 2 +-
11
3 files changed, 102 insertions(+), 62 deletions(-)
15
include/hw/misc/iotkit-secctl.h | 2 +-
12
16
include/hw/misc/iotkit-sysctl.h | 2 +-
13
diff --git a/target/arm/neon-dp.decode b/target/arm/neon-dp.decode
17
include/hw/misc/iotkit-sysinfo.h | 2 +-
14
index XXXXXXX..XXXXXXX 100644
18
include/hw/misc/mps2-fpgaio.h | 2 +-
15
--- a/target/arm/neon-dp.decode
19
hw/arm/mps2-tz.c | 11 +++++------
16
+++ b/target/arm/neon-dp.decode
20
hw/misc/armsse-cpuid.c | 2 +-
17
@@ -XXX,XX +XXX,XX @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm
21
hw/misc/armsse-mhu.c | 2 +-
18
VQMOVN_U 1111 001 11 . 11 .. 10 .... 0 0101 1 . 0 .... @2misc_q0
22
hw/misc/iotkit-sysctl.c | 2 +-
19
23
hw/misc/iotkit-sysinfo.c | 2 +-
20
VSHLL 1111 001 11 . 11 .. 10 .... 0 0110 0 . 0 .... @2misc_q0
24
hw/misc/mps2-fpgaio.c | 2 +-
21
+
25
hw/misc/mps2-scc.c | 2 +-
22
+ VCVT_F16_F32 1111 001 11 . 11 .. 10 .... 0 1100 0 . 0 .... @2misc_q0
26
14 files changed, 19 insertions(+), 20 deletions(-)
23
+ VCVT_F32_F16 1111 001 11 . 11 .. 10 .... 0 1110 0 . 0 .... @2misc_q0
27
24
]
28
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
25
29
index XXXXXXX..XXXXXXX 100644
26
# Subgroup for size != 0b11
30
--- a/include/hw/arm/armsse.h
27
diff --git a/target/arm/translate-neon.inc.c b/target/arm/translate-neon.inc.c
31
+++ b/include/hw/arm/armsse.h
28
index XXXXXXX..XXXXXXX 100644
32
@@ -XXX,XX +XXX,XX @@
29
--- a/target/arm/translate-neon.inc.c
33
* hardware, which include the IoT Kit and the SSE-050, SSE-100 and
30
+++ b/target/arm/translate-neon.inc.c
34
* SSE-200. Currently we model:
31
@@ -XXX,XX +XXX,XX @@ static bool trans_VSHLL(DisasContext *s, arg_2misc *a)
35
* - the Arm IoT Kit which is documented in
32
tcg_temp_free_i32(rm1);
36
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
33
return true;
37
+ * https://developer.arm.com/documentation/ecm0601256/latest
34
}
38
* - the SSE-200 which is documented in
35
+
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
36
+static bool trans_VCVT_F16_F32(DisasContext *s, arg_2misc *a)
40
+ * https://developer.arm.com/documentation/101104/latest/
37
+{
41
*
38
+ TCGv_ptr fpst;
42
* The IoTKit contains:
39
+ TCGv_i32 ahp, tmp, tmp2, tmp3;
43
* a Cortex-M33
40
+
44
diff --git a/include/hw/misc/armsse-cpuid.h b/include/hw/misc/armsse-cpuid.h
41
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
45
index XXXXXXX..XXXXXXX 100644
42
+ !dc_isar_feature(aa32_fp16_spconv, s)) {
46
--- a/include/hw/misc/armsse-cpuid.h
43
+ return false;
47
+++ b/include/hw/misc/armsse-cpuid.h
44
+ }
48
@@ -XXX,XX +XXX,XX @@
45
+
49
/*
46
+ /* UNDEF accesses to D16-D31 if they don't exist. */
50
* This is a model of the "CPU_IDENTITY" register block which is part of the
47
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
51
* Arm SSE-200 and documented in
48
+ ((a->vd | a->vm) & 0x10)) {
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
49
+ return false;
53
+ * https://developer.arm.com/documentation/101104/latest/
50
+ }
54
*
51
+
55
* QEMU interface:
52
+ if ((a->vm & 1) || (a->size != 1)) {
56
* + QOM property "CPUID": the value to use for the CPUID register
53
+ return false;
57
diff --git a/include/hw/misc/armsse-mhu.h b/include/hw/misc/armsse-mhu.h
54
+ }
58
index XXXXXXX..XXXXXXX 100644
55
+
59
--- a/include/hw/misc/armsse-mhu.h
56
+ if (!vfp_access_check(s)) {
60
+++ b/include/hw/misc/armsse-mhu.h
57
+ return true;
61
@@ -XXX,XX +XXX,XX @@
58
+ }
62
/*
59
+
63
* This is a model of the Message Handling Unit (MHU) which is part of the
60
+ fpst = get_fpstatus_ptr(true);
64
* Arm SSE-200 and documented in
61
+ ahp = get_ahp_flag();
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
62
+ tmp = neon_load_reg(a->vm, 0);
66
+ * https://developer.arm.com/documentation/101104/latest/
63
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
67
*
64
+ tmp2 = neon_load_reg(a->vm, 1);
68
* QEMU interface:
65
+ gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
69
* + sysbus MMIO region 0: the system information register bank
66
+ tcg_gen_shli_i32(tmp2, tmp2, 16);
70
diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
67
+ tcg_gen_or_i32(tmp2, tmp2, tmp);
71
index XXXXXXX..XXXXXXX 100644
68
+ tcg_temp_free_i32(tmp);
72
--- a/include/hw/misc/iotkit-secctl.h
69
+ tmp = neon_load_reg(a->vm, 2);
73
+++ b/include/hw/misc/iotkit-secctl.h
70
+ gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
74
@@ -XXX,XX +XXX,XX @@
71
+ tmp3 = neon_load_reg(a->vm, 3);
75
72
+ neon_store_reg(a->vd, 0, tmp2);
76
/* This is a model of the security controller which is part of the
73
+ gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
77
* Arm IoT Kit and documented in
74
+ tcg_gen_shli_i32(tmp3, tmp3, 16);
78
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
75
+ tcg_gen_or_i32(tmp3, tmp3, tmp);
79
+ * https://developer.arm.com/documentation/ecm0601256/latest
76
+ neon_store_reg(a->vd, 1, tmp3);
80
*
77
+ tcg_temp_free_i32(tmp);
81
* QEMU interface:
78
+ tcg_temp_free_i32(ahp);
82
* + sysbus MMIO region 0 is the "secure privilege control block" registers
79
+ tcg_temp_free_ptr(fpst);
83
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
80
+
84
index XXXXXXX..XXXXXXX 100644
81
+ return true;
85
--- a/include/hw/misc/iotkit-sysctl.h
82
+}
86
+++ b/include/hw/misc/iotkit-sysctl.h
83
+
87
@@ -XXX,XX +XXX,XX @@
84
+static bool trans_VCVT_F32_F16(DisasContext *s, arg_2misc *a)
88
/*
85
+{
89
* This is a model of the "system control element" which is part of the
86
+ TCGv_ptr fpst;
90
* Arm IoTKit and documented in
87
+ TCGv_i32 ahp, tmp, tmp2, tmp3;
91
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
88
+
92
+ * https://developer.arm.com/documentation/ecm0601256/latest
89
+ if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
93
* Specifically, it implements the "system information block" and
90
+ !dc_isar_feature(aa32_fp16_spconv, s)) {
94
* "system control register" blocks.
91
+ return false;
95
*
92
+ }
96
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
93
+
97
index XXXXXXX..XXXXXXX 100644
94
+ /* UNDEF accesses to D16-D31 if they don't exist. */
98
--- a/include/hw/misc/iotkit-sysinfo.h
95
+ if (!dc_isar_feature(aa32_simd_r32, s) &&
99
+++ b/include/hw/misc/iotkit-sysinfo.h
96
+ ((a->vd | a->vm) & 0x10)) {
100
@@ -XXX,XX +XXX,XX @@
97
+ return false;
101
/*
98
+ }
102
* This is a model of the "system information block" which is part of the
99
+
103
* Arm IoTKit and documented in
100
+ if ((a->vd & 1) || (a->size != 1)) {
104
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
101
+ return false;
105
+ * https://developer.arm.com/documentation/ecm0601256/latest
102
+ }
106
* QEMU interface:
103
+
107
* + QOM property "SYS_VERSION": value to use for SYS_VERSION register
104
+ if (!vfp_access_check(s)) {
108
* + QOM property "SYS_CONFIG": value to use for SYS_CONFIG register
105
+ return true;
109
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
106
+ }
110
index XXXXXXX..XXXXXXX 100644
107
+
111
--- a/include/hw/misc/mps2-fpgaio.h
108
+ fpst = get_fpstatus_ptr(true);
112
+++ b/include/hw/misc/mps2-fpgaio.h
109
+ ahp = get_ahp_flag();
113
@@ -XXX,XX +XXX,XX @@
110
+ tmp3 = tcg_temp_new_i32();
114
/* This is a model of the FPGAIO register block in the AN505
111
+ tmp = neon_load_reg(a->vm, 0);
115
* FPGA image for the MPS2 dev board; it is documented in the
112
+ tmp2 = neon_load_reg(a->vm, 1);
116
* application note:
113
+ tcg_gen_ext16u_i32(tmp3, tmp);
117
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
114
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
118
+ * https://developer.arm.com/documentation/dai0505/latest/
115
+ neon_store_reg(a->vd, 0, tmp3);
119
*
116
+ tcg_gen_shri_i32(tmp, tmp, 16);
120
* QEMU interface:
117
+ gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
121
* + sysbus MMIO region 0: the register bank
118
+ neon_store_reg(a->vd, 1, tmp);
122
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
119
+ tmp3 = tcg_temp_new_i32();
123
index XXXXXXX..XXXXXXX 100644
120
+ tcg_gen_ext16u_i32(tmp3, tmp2);
124
--- a/hw/arm/mps2-tz.c
121
+ gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
125
+++ b/hw/arm/mps2-tz.c
122
+ neon_store_reg(a->vd, 2, tmp3);
126
@@ -XXX,XX +XXX,XX @@
123
+ tcg_gen_shri_i32(tmp2, tmp2, 16);
127
* https://developer.arm.com/products/system-design/development-boards/fpga-prototyping-boards/mps2
124
+ gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
128
*
125
+ neon_store_reg(a->vd, 3, tmp2);
129
* Board TRM:
126
+ tcg_temp_free_i32(ahp);
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
127
+ tcg_temp_free_ptr(fpst);
131
+ * https://developer.arm.com/documentation/100112/latest/
128
+
132
* Application Note AN505:
129
+ return true;
133
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
130
+}
134
+ * https://developer.arm.com/documentation/dai0505/latest/
131
diff --git a/target/arm/translate.c b/target/arm/translate.c
135
* Application Note AN521:
132
index XXXXXXX..XXXXXXX 100644
136
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
133
--- a/target/arm/translate.c
137
+ * https://developer.arm.com/documentation/dai0521/latest/
134
+++ b/target/arm/translate.c
138
* Application Note AN524:
135
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
139
* https://developer.arm.com/documentation/dai0524/latest/
136
int pass;
140
*
137
int u;
141
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
138
int vec_size;
142
* (ARM ECM0601256) for the details of some of the device layout:
139
- TCGv_i32 tmp, tmp2, tmp3;
143
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
140
+ TCGv_i32 tmp, tmp2;
144
+ * https://developer.arm.com/documentation/ecm0601256/latest
141
145
* Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
142
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
146
* most of the device layout:
143
return 1;
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
144
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
148
- *
145
case NEON_2RM_VZIP:
149
+ * https://developer.arm.com/documentation/101104/latest/
146
case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
150
*/
147
case NEON_2RM_VSHLL:
151
148
+ case NEON_2RM_VCVT_F16_F32:
152
#include "qemu/osdep.h"
149
+ case NEON_2RM_VCVT_F32_F16:
153
diff --git a/hw/misc/armsse-cpuid.c b/hw/misc/armsse-cpuid.c
150
/* handled by decodetree */
154
index XXXXXXX..XXXXXXX 100644
151
return 1;
155
--- a/hw/misc/armsse-cpuid.c
152
case NEON_2RM_VTRN:
156
+++ b/hw/misc/armsse-cpuid.c
153
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
157
@@ -XXX,XX +XXX,XX @@
154
goto elementwise;
158
/*
155
}
159
* This is a model of the "CPU_IDENTITY" register block which is part of the
156
break;
160
* Arm SSE-200 and documented in
157
- case NEON_2RM_VCVT_F16_F32:
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
158
- {
162
+ * https://developer.arm.com/documentation/101104/latest/
159
- TCGv_ptr fpst;
163
*
160
- TCGv_i32 ahp;
164
* It consists of one read-only CPUID register (set by QOM property), plus the
161
-
165
* usual ID registers.
162
- if (!dc_isar_feature(aa32_fp16_spconv, s) ||
166
diff --git a/hw/misc/armsse-mhu.c b/hw/misc/armsse-mhu.c
163
- q || (rm & 1)) {
167
index XXXXXXX..XXXXXXX 100644
164
- return 1;
168
--- a/hw/misc/armsse-mhu.c
165
- }
169
+++ b/hw/misc/armsse-mhu.c
166
- fpst = get_fpstatus_ptr(true);
170
@@ -XXX,XX +XXX,XX @@
167
- ahp = get_ahp_flag();
171
/*
168
- tmp = neon_load_reg(rm, 0);
172
* This is a model of the Message Handling Unit (MHU) which is part of the
169
- gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
173
* Arm SSE-200 and documented in
170
- tmp2 = neon_load_reg(rm, 1);
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
171
- gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
175
+ * https://developer.arm.com/documentation/101104/latest/
172
- tcg_gen_shli_i32(tmp2, tmp2, 16);
176
*/
173
- tcg_gen_or_i32(tmp2, tmp2, tmp);
177
174
- tcg_temp_free_i32(tmp);
178
#include "qemu/osdep.h"
175
- tmp = neon_load_reg(rm, 2);
179
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
176
- gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
180
index XXXXXXX..XXXXXXX 100644
177
- tmp3 = neon_load_reg(rm, 3);
181
--- a/hw/misc/iotkit-sysctl.c
178
- neon_store_reg(rd, 0, tmp2);
182
+++ b/hw/misc/iotkit-sysctl.c
179
- gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
183
@@ -XXX,XX +XXX,XX @@
180
- tcg_gen_shli_i32(tmp3, tmp3, 16);
184
/*
181
- tcg_gen_or_i32(tmp3, tmp3, tmp);
185
* This is a model of the "system control element" which is part of the
182
- neon_store_reg(rd, 1, tmp3);
186
* Arm IoTKit and documented in
183
- tcg_temp_free_i32(tmp);
187
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
184
- tcg_temp_free_i32(ahp);
188
+ * https://developer.arm.com/documentation/ecm0601256/latest
185
- tcg_temp_free_ptr(fpst);
189
* Specifically, it implements the "system control register" blocks.
186
- break;
190
*/
187
- }
191
188
- case NEON_2RM_VCVT_F32_F16:
192
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
189
- {
193
index XXXXXXX..XXXXXXX 100644
190
- TCGv_ptr fpst;
194
--- a/hw/misc/iotkit-sysinfo.c
191
- TCGv_i32 ahp;
195
+++ b/hw/misc/iotkit-sysinfo.c
192
- if (!dc_isar_feature(aa32_fp16_spconv, s) ||
196
@@ -XXX,XX +XXX,XX @@
193
- q || (rd & 1)) {
197
/*
194
- return 1;
198
* This is a model of the "system information block" which is part of the
195
- }
199
* Arm IoTKit and documented in
196
- fpst = get_fpstatus_ptr(true);
200
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
197
- ahp = get_ahp_flag();
201
+ * https://developer.arm.com/documentation/ecm0601256/latest
198
- tmp3 = tcg_temp_new_i32();
202
* It consists of 2 read-only version/config registers, plus the
199
- tmp = neon_load_reg(rm, 0);
203
* usual ID registers.
200
- tmp2 = neon_load_reg(rm, 1);
204
*/
201
- tcg_gen_ext16u_i32(tmp3, tmp);
205
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
202
- gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
206
index XXXXXXX..XXXXXXX 100644
203
- neon_store_reg(rd, 0, tmp3);
207
--- a/hw/misc/mps2-fpgaio.c
204
- tcg_gen_shri_i32(tmp, tmp, 16);
208
+++ b/hw/misc/mps2-fpgaio.c
205
- gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
209
@@ -XXX,XX +XXX,XX @@
206
- neon_store_reg(rd, 1, tmp);
210
/* This is a model of the "FPGA system control and I/O" block found
207
- tmp3 = tcg_temp_new_i32();
211
* in the AN505 FPGA image for the MPS2 devboard.
208
- tcg_gen_ext16u_i32(tmp3, tmp2);
212
* It is documented in AN505:
209
- gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
213
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
210
- neon_store_reg(rd, 2, tmp3);
214
+ * https://developer.arm.com/documentation/dai0505/latest/
211
- tcg_gen_shri_i32(tmp2, tmp2, 16);
215
*/
212
- gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
216
213
- neon_store_reg(rd, 3, tmp2);
217
#include "qemu/osdep.h"
214
- tcg_temp_free_i32(ahp);
218
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
215
- tcg_temp_free_ptr(fpst);
219
index XXXXXXX..XXXXXXX 100644
216
- break;
220
--- a/hw/misc/mps2-scc.c
217
- }
221
+++ b/hw/misc/mps2-scc.c
218
case NEON_2RM_AESE: case NEON_2RM_AESMC:
222
@@ -XXX,XX +XXX,XX @@
219
if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
223
* found in the FPGA images of MPS2 development boards.
220
return 1;
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
221
--
231
--
222
2.20.1
232
2.20.1
223
233
224
234
diff view generated by jsdifflib