1
target-arm queue: I have a lot more still in my to-review
1
First arm pullreq for 6.1 cycle. The big stuff here is RTH's alignment series.
2
queue, but my rule of thumb is when I get to 50 patches or
3
so to send out what I have.
4
2
5
thanks
3
thanks
6
-- PMM
4
-- PMM
7
5
8
The following changes since commit 9a7beaad3dbba982f7a461d676b55a5c3851d312:
6
The following changes since commit ccdf06c1db192152ac70a1dd974c624f566cb7d4:
9
7
10
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20210304' into staging (2021-03-05 10:47:46 +0000)
8
Open 6.1 development tree (2021-04-30 11:15:40 +0100)
11
9
12
are available in the Git repository at:
10
are available in the Git repository at:
13
11
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210305
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210430
15
13
16
for you to fetch changes up to 2c669ff88ec6733420a000103a2b8b9e93df4945:
14
for you to fetch changes up to a6091108aa44e9017af4ca13c43f55a629e3744c:
17
15
18
hw/arm/mps2: Update old infocenter.arm.com URLs (2021-03-05 15:17:38 +0000)
16
hw/pci-host/gpex: Don't fault for unmapped parts of MMIO and PIO windows (2021-04-30 11:16:52 +0100)
19
17
20
----------------------------------------------------------------
18
----------------------------------------------------------------
21
* sbsa-ref: remove cortex-a53 from list of supported cpus
19
target-arm queue:
22
* sbsa-ref: add 'max' to list of allowed cpus
20
* hw/pci-host/gpex: Don't fault for unmapped parts of MMIO and PIO windows
23
* target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
21
* hw: add compat machines for 6.1
24
* npcm7xx: add EMC model
22
* Fault misaligned accesses where the architecture requires it
25
* xlnx-zynqmp: Remove obsolete 'has_rpu' property
23
* Fix some corner cases of MTE faults (notably with misaligned accesses)
26
* target/arm: Speed up aarch64 TBL/TBX
24
* Make Thumb store insns UNDEF for Rn==1111
27
* virtio-mmio: improve virtio-mmio get_dev_path alog
25
* hw/arm/smmuv3: Support 16K translation granule
28
* target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
29
* target/arm: Restrict v8M IDAU to TCG
30
* target/arm/cpu: Update coding style to make checkpatch.pl happy
31
* musicpal, tc6393xb, omap_lcdc, tcx: drop dead code for non-32-bit-RGB surfaces
32
* Add new board: mps3-an524
33
26
34
----------------------------------------------------------------
27
----------------------------------------------------------------
35
Doug Evans (3):
28
Cornelia Huck (1):
36
hw/net: Add npcm7xx emc model
29
hw: add compat machines for 6.1
37
hw/arm: Add npcm7xx emc model
38
tests/qtests: Add npcm7xx emc model test
39
30
40
Marcin Juszkiewicz (2):
31
Kunkun Jiang (1):
41
sbsa-ref: remove cortex-a53 from list of supported cpus
32
hw/arm/smmuv3: Support 16K translation granule
42
sbsa-ref: add 'max' to list of allowed cpus
43
33
44
Peter Collingbourne (1):
34
Peter Maydell (2):
45
target/arm: Use TCF0 and TFSRE0 for unprivileged tag checks
35
target/arm: Make Thumb store insns UNDEF for Rn==1111
36
hw/pci-host/gpex: Don't fault for unmapped parts of MMIO and PIO windows
46
37
47
Peter Maydell (34):
38
Richard Henderson (39):
48
hw/arm/musicpal: Remove dead code for non-32-bit-RGB surfaces
39
target/arm: Fix mte_checkN
49
hw/display/tc6393xb: Remove dead code for handling non-32bpp surfaces
40
target/arm: Split out mte_probe_int
50
hw/display/tc6393xb: Expand out macros in template header
41
target/arm: Fix unaligned checks for mte_check1, mte_probe1
51
hw/display/tc6393xb: Inline tc6393xb_draw_graphic32() at its callsite
42
test/tcg/aarch64: Add mte-5
52
hw/display/omap_lcdc: Expand out macros in template header
43
target/arm: Replace MTEDESC ESIZE+TSIZE with SIZEM1
53
hw/display/omap_lcdc: Drop broken bigendian ifdef
44
target/arm: Merge mte_check1, mte_checkN
54
hw/display/omap_lcdc: Fix coding style issues in template header
45
target/arm: Rename mte_probe1 to mte_probe
55
hw/display/omap_lcdc: Inline template header into C file
46
target/arm: Simplify sve mte checking
56
hw/display/omap_lcdc: Delete unnecessary macro
47
target/arm: Remove log2_esize parameter to gen_mte_checkN
57
hw/display/tcx: Drop unnecessary code for handling BGR format outputs
48
target/arm: Fix decode of align in VLDST_single
58
hw/arm/mps2-tz: Make SYSCLK frequency board-specific
49
target/arm: Rename TBFLAG_A32, SCTLR_B
59
hw/misc/mps2-scc: Support configurable number of OSCCLK values
50
target/arm: Rename TBFLAG_ANY, PSTATE_SS
60
hw/arm/mps2-tz: Correct the OSCCLK settings for mps2-an505 and mps2-an511
51
target/arm: Add wrapper macros for accessing tbflags
61
hw/arm/mps2-tz: Make the OSCCLK settings be configurable per-board
52
target/arm: Introduce CPUARMTBFlags
62
hw/misc/mps2-fpgaio: Make number of LEDs configurable by board
53
target/arm: Move mode specific TB flags to tb->cs_base
63
hw/misc/mps2-fpgaio: Support SWITCH register
54
target/arm: Move TBFLAG_AM32 bits to the top
64
hw/arm/mps2-tz: Make FPGAIO switch and LED config per-board
55
target/arm: Move TBFLAG_ANY bits to the bottom
65
hw/arm/mps2-tz: Condition IRQ splitting on number of CPUs, not board type
56
target/arm: Add ALIGN_MEM to TBFLAG_ANY
66
hw/arm/mps2-tz: Make number of IRQs board-specific
57
target/arm: Adjust gen_aa32_{ld, st}_i32 for align+endianness
67
hw/misc/mps2-scc: Implement CFG_REG5 and CFG_REG6 for MPS3 AN524
58
target/arm: Merge gen_aa32_frob64 into gen_aa32_ld_i64
68
hw/arm/mps2-tz: Correct wrong interrupt numbers for DMA and SPI
59
target/arm: Fix SCTLR_B test for TCGv_i64 load/store
69
hw/arm/mps2-tz: Allow PPCPortInfo structures to specify device interrupts
60
target/arm: Adjust gen_aa32_{ld, st}_i64 for align+endianness
70
hw/arm/mps2-tz: Move device IRQ info to data structures
61
target/arm: Enforce word alignment for LDRD/STRD
71
hw/arm/mps2-tz: Size the uart-irq-orgate based on the number of UARTs
62
target/arm: Enforce alignment for LDA/LDAH/STL/STLH
72
hw/arm/mps2-tz: Allow boards to have different PPCInfo data
63
target/arm: Enforce alignment for LDM/STM
73
hw/arm/mps2-tz: Make RAM arrangement board-specific
64
target/arm: Enforce alignment for RFE
74
hw/arm/mps2-tz: Set MachineClass default_ram info from RAMInfo data
65
target/arm: Enforce alignment for SRS
75
hw/arm/mps2-tz: Support ROMs as well as RAMs
66
target/arm: Enforce alignment for VLDM/VSTM
76
hw/arm/mps2-tz: Get armv7m_load_kernel() size argument from RAMInfo
67
target/arm: Enforce alignment for VLDR/VSTR
77
hw/arm/mps2-tz: Add new mps3-an524 board
68
target/arm: Enforce alignment for VLDn (all lanes)
78
hw/arm/mps2-tz: Stub out USB controller for mps3-an524
69
target/arm: Enforce alignment for VLDn/VSTn (multiple)
79
hw/arm/mps2-tz: Provide PL031 RTC on mps3-an524
70
target/arm: Enforce alignment for VLDn/VSTn (single)
80
docs/system/arm/mps2.rst: Document the new mps3-an524 board
71
target/arm: Use finalize_memop for aa64 gpr load/store
81
hw/arm/mps2: Update old infocenter.arm.com URLs
72
target/arm: Use finalize_memop for aa64 fpr load/store
73
target/arm: Enforce alignment for aa64 load-acq/store-rel
74
target/arm: Use MemOp for size + endian in aa64 vector ld/st
75
target/arm: Enforce alignment for aa64 vector LDn/STn (multiple)
76
target/arm: Enforce alignment for aa64 vector LDn/STn (single)
77
target/arm: Enforce alignment for sve LD1R
82
78
83
Philippe Mathieu-Daudé (4):
79
include/hw/boards.h | 3 +
84
hw/arm/xlnx-zynqmp: Remove obsolete 'has_rpu' property
80
include/hw/i386/pc.h | 3 +
85
hw/i2c/npcm7xx_smbus: Simplify npcm7xx_smbus_init()
81
include/hw/pci-host/gpex.h | 4 +
86
target/arm: Restrict v8M IDAU to TCG
82
target/arm/cpu.h | 105 ++++++++++-----
87
target/arm/cpu: Update coding style to make checkpatch.pl happy
83
target/arm/helper-a64.h | 3 +-
84
target/arm/internals.h | 11 +-
85
target/arm/translate-a64.h | 2 +-
86
target/arm/translate.h | 38 ++++++
87
target/arm/neon-ls.decode | 4 +-
88
hw/arm/smmuv3.c | 6 +-
89
hw/arm/virt.c | 7 +-
90
hw/core/machine.c | 5 +
91
hw/i386/pc.c | 3 +
92
hw/i386/pc_piix.c | 14 +-
93
hw/i386/pc_q35.c | 13 +-
94
hw/pci-host/gpex.c | 56 +++++++-
95
hw/ppc/spapr.c | 17 ++-
96
hw/s390x/s390-virtio-ccw.c | 14 +-
97
target/arm/helper-a64.c | 2 +-
98
target/arm/helper.c | 162 ++++++++++++----------
99
target/arm/mte_helper.c | 185 ++++++++++---------------
100
target/arm/sve_helper.c | 100 +++++---------
101
target/arm/translate-a64.c | 236 ++++++++++++++++----------------
102
target/arm/translate-sve.c | 11 +-
103
target/arm/translate.c | 274 ++++++++++++++++++++++----------------
104
tests/tcg/aarch64/mte-5.c | 44 ++++++
105
target/arm/translate-neon.c.inc | 117 ++++++++++++----
106
target/arm/translate-vfp.c.inc | 20 +--
107
tests/tcg/aarch64/Makefile.target | 2 +-
108
29 files changed, 878 insertions(+), 583 deletions(-)
109
create mode 100644 tests/tcg/aarch64/mte-5.c
88
110
89
Rebecca Cran (3):
90
target/arm: Add support for FEAT_SSBS, Speculative Store Bypass Safe
91
target/arm: Enable FEAT_SSBS for "max" AARCH64 CPU
92
target/arm: Set ID_PFR2.SSBS to 1 for "max" 32-bit CPU
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
Update old infocenter.arm.com URLs to the equivalent developer.arm.com
1
From: Kunkun Jiang <jiangkunkun@huawei.com>
2
ones (the old URLs should redirect, but we might as well avoid the
3
redirection notice, and the new URLs are pleasantly shorter).
4
2
5
This commit covers the links to the MPS2 board TRM, the various
3
The driver can query some bits in SMMUv3 IDR5 to learn which
6
Application Notes, the IoTKit and SSE-200 documents.
4
translation granules are supported. Arm recommends that SMMUv3
5
implementations support at least 4K and 64K granules. But in
6
the vSMMUv3, there seems to be no reason not to support 16K
7
translation granule. In addition, if 16K is not supported,
8
vSVA will failed to be enabled in the future for 16K guest
9
kernel. So it'd better to support it.
7
10
11
Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
12
Reviewed-by: Eric Auger <eric.auger@redhat.com>
13
Tested-by: Eric Auger <eric.auger@redhat.com>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210215115138.20465-25-peter.maydell@linaro.org
11
---
15
---
12
include/hw/arm/armsse.h | 4 ++--
16
hw/arm/smmuv3.c | 6 ++++--
13
include/hw/misc/armsse-cpuid.h | 2 +-
17
1 file changed, 4 insertions(+), 2 deletions(-)
14
include/hw/misc/armsse-mhu.h | 2 +-
15
include/hw/misc/iotkit-secctl.h | 2 +-
16
include/hw/misc/iotkit-sysctl.h | 2 +-
17
include/hw/misc/iotkit-sysinfo.h | 2 +-
18
include/hw/misc/mps2-fpgaio.h | 2 +-
19
hw/arm/mps2-tz.c | 11 +++++------
20
hw/misc/armsse-cpuid.c | 2 +-
21
hw/misc/armsse-mhu.c | 2 +-
22
hw/misc/iotkit-sysctl.c | 2 +-
23
hw/misc/iotkit-sysinfo.c | 2 +-
24
hw/misc/mps2-fpgaio.c | 2 +-
25
hw/misc/mps2-scc.c | 2 +-
26
14 files changed, 19 insertions(+), 20 deletions(-)
27
18
28
diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h
19
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
29
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/armsse.h
21
--- a/hw/arm/smmuv3.c
31
+++ b/include/hw/arm/armsse.h
22
+++ b/hw/arm/smmuv3.c
32
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ static void smmuv3_init_regs(SMMUv3State *s)
33
* hardware, which include the IoT Kit and the SSE-050, SSE-100 and
24
s->idr[3] = FIELD_DP32(s->idr[3], IDR3, RIL, 1);
34
* SSE-200. Currently we model:
25
s->idr[3] = FIELD_DP32(s->idr[3], IDR3, HAD, 1);
35
* - the Arm IoT Kit which is documented in
26
36
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
27
- /* 4K and 64K granule support */
37
+ * https://developer.arm.com/documentation/ecm0601256/latest
28
+ /* 4K, 16K and 64K granule support */
38
* - the SSE-200 which is documented in
29
s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN4K, 1);
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
30
+ s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN16K, 1);
40
+ * https://developer.arm.com/documentation/101104/latest/
31
s->idr[5] = FIELD_DP32(s->idr[5], IDR5, GRAN64K, 1);
41
*
32
s->idr[5] = FIELD_DP32(s->idr[5], IDR5, OAS, SMMU_IDR5_OAS); /* 44 bits */
42
* The IoTKit contains:
33
43
* a Cortex-M33
34
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
44
diff --git a/include/hw/misc/armsse-cpuid.h b/include/hw/misc/armsse-cpuid.h
35
45
index XXXXXXX..XXXXXXX 100644
36
tg = CD_TG(cd, i);
46
--- a/include/hw/misc/armsse-cpuid.h
37
tt->granule_sz = tg2granule(tg, i);
47
+++ b/include/hw/misc/armsse-cpuid.h
38
- if ((tt->granule_sz != 12 && tt->granule_sz != 16) || CD_ENDI(cd)) {
48
@@ -XXX,XX +XXX,XX @@
39
+ if ((tt->granule_sz != 12 && tt->granule_sz != 14 &&
49
/*
40
+ tt->granule_sz != 16) || CD_ENDI(cd)) {
50
* This is a model of the "CPU_IDENTITY" register block which is part of the
41
goto bad_cd;
51
* Arm SSE-200 and documented in
42
}
52
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
53
+ * https://developer.arm.com/documentation/101104/latest/
54
*
55
* QEMU interface:
56
* + QOM property "CPUID": the value to use for the CPUID register
57
diff --git a/include/hw/misc/armsse-mhu.h b/include/hw/misc/armsse-mhu.h
58
index XXXXXXX..XXXXXXX 100644
59
--- a/include/hw/misc/armsse-mhu.h
60
+++ b/include/hw/misc/armsse-mhu.h
61
@@ -XXX,XX +XXX,XX @@
62
/*
63
* This is a model of the Message Handling Unit (MHU) which is part of the
64
* Arm SSE-200 and documented in
65
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
66
+ * https://developer.arm.com/documentation/101104/latest/
67
*
68
* QEMU interface:
69
* + sysbus MMIO region 0: the system information register bank
70
diff --git a/include/hw/misc/iotkit-secctl.h b/include/hw/misc/iotkit-secctl.h
71
index XXXXXXX..XXXXXXX 100644
72
--- a/include/hw/misc/iotkit-secctl.h
73
+++ b/include/hw/misc/iotkit-secctl.h
74
@@ -XXX,XX +XXX,XX @@
75
76
/* This is a model of the security controller which is part of the
77
* Arm IoT Kit and documented in
78
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
79
+ * https://developer.arm.com/documentation/ecm0601256/latest
80
*
81
* QEMU interface:
82
* + sysbus MMIO region 0 is the "secure privilege control block" registers
83
diff --git a/include/hw/misc/iotkit-sysctl.h b/include/hw/misc/iotkit-sysctl.h
84
index XXXXXXX..XXXXXXX 100644
85
--- a/include/hw/misc/iotkit-sysctl.h
86
+++ b/include/hw/misc/iotkit-sysctl.h
87
@@ -XXX,XX +XXX,XX @@
88
/*
89
* This is a model of the "system control element" which is part of the
90
* Arm IoTKit and documented in
91
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
92
+ * https://developer.arm.com/documentation/ecm0601256/latest
93
* Specifically, it implements the "system information block" and
94
* "system control register" blocks.
95
*
96
diff --git a/include/hw/misc/iotkit-sysinfo.h b/include/hw/misc/iotkit-sysinfo.h
97
index XXXXXXX..XXXXXXX 100644
98
--- a/include/hw/misc/iotkit-sysinfo.h
99
+++ b/include/hw/misc/iotkit-sysinfo.h
100
@@ -XXX,XX +XXX,XX @@
101
/*
102
* This is a model of the "system information block" which is part of the
103
* Arm IoTKit and documented in
104
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
105
+ * https://developer.arm.com/documentation/ecm0601256/latest
106
* QEMU interface:
107
* + QOM property "SYS_VERSION": value to use for SYS_VERSION register
108
* + QOM property "SYS_CONFIG": value to use for SYS_CONFIG register
109
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
110
index XXXXXXX..XXXXXXX 100644
111
--- a/include/hw/misc/mps2-fpgaio.h
112
+++ b/include/hw/misc/mps2-fpgaio.h
113
@@ -XXX,XX +XXX,XX @@
114
/* This is a model of the FPGAIO register block in the AN505
115
* FPGA image for the MPS2 dev board; it is documented in the
116
* application note:
117
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
118
+ * https://developer.arm.com/documentation/dai0505/latest/
119
*
120
* QEMU interface:
121
* + sysbus MMIO region 0: the register bank
122
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/hw/arm/mps2-tz.c
125
+++ b/hw/arm/mps2-tz.c
126
@@ -XXX,XX +XXX,XX @@
127
* https://developer.arm.com/products/system-design/development-boards/fpga-prototyping-boards/mps2
128
*
129
* Board TRM:
130
- * http://infocenter.arm.com/help/topic/com.arm.doc.100112_0200_06_en/versatile_express_cortex_m_prototyping_systems_v2m_mps2_and_v2m_mps2plus_technical_reference_100112_0200_06_en.pdf
131
+ * https://developer.arm.com/documentation/100112/latest/
132
* Application Note AN505:
133
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
134
+ * https://developer.arm.com/documentation/dai0505/latest/
135
* Application Note AN521:
136
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
137
+ * https://developer.arm.com/documentation/dai0521/latest/
138
* Application Note AN524:
139
* https://developer.arm.com/documentation/dai0524/latest/
140
*
141
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
142
* (ARM ECM0601256) for the details of some of the device layout:
143
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
144
+ * https://developer.arm.com/documentation/ecm0601256/latest
145
* Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
146
* most of the device layout:
147
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
148
- *
149
+ * https://developer.arm.com/documentation/101104/latest/
150
*/
151
152
#include "qemu/osdep.h"
153
diff --git a/hw/misc/armsse-cpuid.c b/hw/misc/armsse-cpuid.c
154
index XXXXXXX..XXXXXXX 100644
155
--- a/hw/misc/armsse-cpuid.c
156
+++ b/hw/misc/armsse-cpuid.c
157
@@ -XXX,XX +XXX,XX @@
158
/*
159
* This is a model of the "CPU_IDENTITY" register block which is part of the
160
* Arm SSE-200 and documented in
161
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
162
+ * https://developer.arm.com/documentation/101104/latest/
163
*
164
* It consists of one read-only CPUID register (set by QOM property), plus the
165
* usual ID registers.
166
diff --git a/hw/misc/armsse-mhu.c b/hw/misc/armsse-mhu.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/hw/misc/armsse-mhu.c
169
+++ b/hw/misc/armsse-mhu.c
170
@@ -XXX,XX +XXX,XX @@
171
/*
172
* This is a model of the Message Handling Unit (MHU) which is part of the
173
* Arm SSE-200 and documented in
174
- * http://infocenter.arm.com/help/topic/com.arm.doc.101104_0100_00_en/corelink_sse200_subsystem_for_embedded_technical_reference_manual_101104_0100_00_en.pdf
175
+ * https://developer.arm.com/documentation/101104/latest/
176
*/
177
178
#include "qemu/osdep.h"
179
diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c
180
index XXXXXXX..XXXXXXX 100644
181
--- a/hw/misc/iotkit-sysctl.c
182
+++ b/hw/misc/iotkit-sysctl.c
183
@@ -XXX,XX +XXX,XX @@
184
/*
185
* This is a model of the "system control element" which is part of the
186
* Arm IoTKit and documented in
187
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
188
+ * https://developer.arm.com/documentation/ecm0601256/latest
189
* Specifically, it implements the "system control register" blocks.
190
*/
191
192
diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/hw/misc/iotkit-sysinfo.c
195
+++ b/hw/misc/iotkit-sysinfo.c
196
@@ -XXX,XX +XXX,XX @@
197
/*
198
* This is a model of the "system information block" which is part of the
199
* Arm IoTKit and documented in
200
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
201
+ * https://developer.arm.com/documentation/ecm0601256/latest
202
* It consists of 2 read-only version/config registers, plus the
203
* usual ID registers.
204
*/
205
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c
206
index XXXXXXX..XXXXXXX 100644
207
--- a/hw/misc/mps2-fpgaio.c
208
+++ b/hw/misc/mps2-fpgaio.c
209
@@ -XXX,XX +XXX,XX @@
210
/* This is a model of the "FPGA system control and I/O" block found
211
* in the AN505 FPGA image for the MPS2 devboard.
212
* It is documented in AN505:
213
- * http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
214
+ * https://developer.arm.com/documentation/dai0505/latest/
215
*/
216
217
#include "qemu/osdep.h"
218
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
219
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/misc/mps2-scc.c
221
+++ b/hw/misc/mps2-scc.c
222
@@ -XXX,XX +XXX,XX @@
223
* found in the FPGA images of MPS2 development boards.
224
*
225
* Documentation of it can be found in the MPS2 TRM:
226
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.100112_0100_03_en/index.html
227
+ * https://developer.arm.com/documentation/100112/latest/
228
* and also in the Application Notes documenting individual FPGA images.
229
*/
230
43
231
--
44
--
232
2.20.1
45
2.20.1
233
46
234
47
diff view generated by jsdifflib
1
The AN505 and AN521 have the same layout of RAM; the AN524 does not.
1
The Arm ARM specifies that for Thumb encodings of the various plain
2
Replace the current hard-coding of where the RAM is and which parts
2
store insns, if the Rn field is 1111 then we must UNDEF. This is
3
of it are behind which MPCs with a data-driven approach.
3
different from the Arm encodings, where this case is either
4
UNPREDICTABLE or has well-defined behaviour. The exclusive stores,
5
store-release and STRD do not have this UNDEF case for any encoding.
4
6
7
Enforce the UNDEF for this case in the Thumb plain store insns.
8
9
Fixes: https://bugs.launchpad.net/qemu/+bug/1922887
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210215115138.20465-17-peter.maydell@linaro.org
12
Message-id: 20210408162402.5822-1-peter.maydell@linaro.org
8
---
13
---
9
hw/arm/mps2-tz.c | 175 +++++++++++++++++++++++++++++++++++++----------
14
target/arm/translate.c | 16 ++++++++++++++++
10
1 file changed, 138 insertions(+), 37 deletions(-)
15
1 file changed, 16 insertions(+)
11
16
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/mps2-tz.c
19
--- a/target/arm/translate.c
15
+++ b/hw/arm/mps2-tz.c
20
+++ b/target/arm/translate.c
16
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
17
#include "qom/object.h"
22
ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
18
23
TCGv_i32 addr, tmp;
19
#define MPS2TZ_NUMIRQ_MAX 92
24
20
+#define MPS2TZ_RAM_MAX 4
25
+ /*
21
26
+ * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
22
typedef enum MPS2TZFPGAType {
27
+ * is either UNPREDICTABLE or has defined behaviour
23
FPGA_AN505,
28
+ */
24
FPGA_AN521,
29
+ if (s->thumb && a->rn == 15) {
25
} MPS2TZFPGAType;
30
+ return false;
26
27
+/*
28
+ * Define the layout of RAM in a board, including which parts are
29
+ * behind which MPCs.
30
+ * mrindex specifies the index into mms->ram[] to use for the backing RAM;
31
+ * -1 means "use the system RAM".
32
+ */
33
+typedef struct RAMInfo {
34
+ const char *name;
35
+ uint32_t base;
36
+ uint32_t size;
37
+ int mpc; /* MPC number, -1 for "not behind an MPC" */
38
+ int mrindex;
39
+ int flags;
40
+} RAMInfo;
41
+
42
+/*
43
+ * Flag values:
44
+ * IS_ALIAS: this RAM area is an alias to the upstream end of the
45
+ * MPC specified by its .mpc value
46
+ */
47
+#define IS_ALIAS 1
48
+
49
struct MPS2TZMachineClass {
50
MachineClass parent;
51
MPS2TZFPGAType fpga_type;
52
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
53
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
54
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
55
int numirq; /* Number of external interrupts */
56
+ const RAMInfo *raminfo;
57
const char *armsse_type;
58
};
59
60
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
61
MachineState parent;
62
63
ARMSSE iotkit;
64
- MemoryRegion ssram[3];
65
- MemoryRegion ssram1_m;
66
+ MemoryRegion ram[MPS2TZ_RAM_MAX];
67
MPS2SCC scc;
68
MPS2FPGAIO fpgaio;
69
TZPPC ppc[5];
70
- TZMPC ssram_mpc[3];
71
+ TZMPC mpc[3];
72
PL022State spi[5];
73
ArmSbconI2CState i2c[4];
74
UnimplementedDeviceState i2s_audio;
75
@@ -XXX,XX +XXX,XX @@ static const uint32_t an505_oscclk[] = {
76
25000000,
77
};
78
79
+static const RAMInfo an505_raminfo[] = { {
80
+ .name = "ssram-0",
81
+ .base = 0x00000000,
82
+ .size = 0x00400000,
83
+ .mpc = 0,
84
+ .mrindex = 0,
85
+ }, {
86
+ .name = "ssram-1",
87
+ .base = 0x28000000,
88
+ .size = 0x00200000,
89
+ .mpc = 1,
90
+ .mrindex = 1,
91
+ }, {
92
+ .name = "ssram-2",
93
+ .base = 0x28200000,
94
+ .size = 0x00200000,
95
+ .mpc = 2,
96
+ .mrindex = 2,
97
+ }, {
98
+ .name = "ssram-0-alias",
99
+ .base = 0x00400000,
100
+ .size = 0x00400000,
101
+ .mpc = 0,
102
+ .mrindex = 3,
103
+ .flags = IS_ALIAS,
104
+ }, {
105
+ /* Use the largest bit of contiguous RAM as our "system memory" */
106
+ .name = "mps.ram",
107
+ .base = 0x80000000,
108
+ .size = 16 * MiB,
109
+ .mpc = -1,
110
+ .mrindex = -1,
111
+ }, {
112
+ .name = NULL,
113
+ },
114
+};
115
+
116
+static const RAMInfo *find_raminfo_for_mpc(MPS2TZMachineState *mms, int mpc)
117
+{
118
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
119
+ const RAMInfo *p;
120
+
121
+ for (p = mmc->raminfo; p->name; p++) {
122
+ if (p->mpc == mpc && !(p->flags & IS_ALIAS)) {
123
+ return p;
124
+ }
125
+ }
126
+ /* if raminfo array doesn't have an entry for each MPC this is a bug */
127
+ g_assert_not_reached();
128
+}
129
+
130
+static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
131
+ const RAMInfo *raminfo)
132
+{
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
+ }
31
+ }
141
+
32
+
142
+ assert(raminfo->mrindex < MPS2TZ_RAM_MAX);
33
addr = op_addr_rr_pre(s, a);
143
+ ram = &mms->ram[raminfo->mrindex];
34
35
tmp = load_reg(s, a->rt);
36
@@ -XXX,XX +XXX,XX @@ static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
37
ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
38
TCGv_i32 addr, tmp;
39
40
+ /*
41
+ * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
42
+ * is either UNPREDICTABLE or has defined behaviour
43
+ */
44
+ if (s->thumb && a->rn == 15) {
45
+ return false;
46
+ }
144
+
47
+
145
+ memory_region_init_ram(ram, NULL, raminfo->name,
48
addr = op_addr_ri_pre(s, a);
146
+ raminfo->size, &error_fatal);
49
147
+ return ram;
50
tmp = load_reg(s, a->rt);
148
+}
149
+
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)
200
+{
201
+ /*
202
+ * Handle the RAMs which are either not behind MPCs or which are
203
+ * aliases to another MPC.
204
+ */
205
+ const RAMInfo *p;
206
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
207
+
208
+ for (p = mmc->raminfo; p->name; p++) {
209
+ if (p->flags & IS_ALIAS) {
210
+ SysBusDevice *mpc_sbd = SYS_BUS_DEVICE(&mms->mpc[p->mpc]);
211
+ MemoryRegion *upstream = sysbus_mmio_get_region(mpc_sbd, 1);
212
+ make_ram_alias(&mms->ram[p->mrindex], p->name, upstream, p->base);
213
+ } else if (p->mpc == -1) {
214
+ /* RAM not behind an MPC */
215
+ MemoryRegion *mr = mr_for_raminfo(mms, p);
216
+ memory_region_add_subregion(get_system_memory(), p->base, mr);
217
+ }
218
+ }
219
+}
220
+
221
static void mps2tz_common_init(MachineState *machine)
222
{
223
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
224
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
225
qdev_connect_gpio_out_named(iotkitdev, "sec_resp_cfg", 0,
226
qdev_get_gpio_in(dev_splitter, 0));
227
228
- /* The IoTKit sets up much of the memory layout, including
229
+ /*
230
+ * The IoTKit sets up much of the memory layout, including
231
* the aliases between secure and non-secure regions in the
232
- * address space. The FPGA itself contains:
233
- *
234
- * 0x00000000..0x003fffff SSRAM1
235
- * 0x00400000..0x007fffff alias of SSRAM1
236
- * 0x28000000..0x283fffff 4MB SSRAM2 + SSRAM3
237
- * 0x40100000..0x4fffffff AHB Master Expansion 1 interface devices
238
- * 0x80000000..0x80ffffff 16MB PSRAM
239
- */
240
-
241
- /* The FPGA images have an odd combination of different RAMs,
242
+ * address space, and also most of the devices in the system.
243
+ * The FPGA itself contains various RAMs and some additional devices.
244
+ * The FPGA images have an odd combination of different RAMs,
245
* because in hardware they are different implementations and
246
* connected to different buses, giving varying performance/size
247
* tradeoffs. For QEMU they're all just RAM, though. We arbitrarily
248
- * call the 16MB our "system memory", as it's the largest lump.
249
+ * call the largest lump our "system memory".
250
*/
251
- memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
252
253
/*
254
* The overflow IRQs for all UARTs are ORed together.
255
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
256
const PPCInfo an505_ppcs[] = { {
257
.name = "apb_ppcexp0",
258
.ports = {
259
- { "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
260
- { "ssram-1", make_mpc, &mms->ssram_mpc[1], 0x58008000, 0x1000 },
261
- { "ssram-2", make_mpc, &mms->ssram_mpc[2], 0x58009000, 0x1000 },
262
+ { "ssram-0-mpc", make_mpc, &mms->mpc[0], 0x58007000, 0x1000 },
263
+ { "ssram-1-mpc", make_mpc, &mms->mpc[1], 0x58008000, 0x1000 },
264
+ { "ssram-2-mpc", make_mpc, &mms->mpc[2], 0x58009000, 0x1000 },
265
},
266
}, {
267
.name = "apb_ppcexp1",
268
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
269
270
create_unimplemented_device("FPGA NS PC", 0x48007000, 0x1000);
271
272
+ create_non_mpc_ram(mms);
273
+
274
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
275
}
276
277
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
278
mmc->fpgaio_num_leds = 2;
279
mmc->fpgaio_has_switches = false;
280
mmc->numirq = 92;
281
+ mmc->raminfo = an505_raminfo;
282
mmc->armsse_type = TYPE_IOTKIT;
283
}
284
285
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
286
mmc->fpgaio_num_leds = 2;
287
mmc->fpgaio_has_switches = false;
288
mmc->numirq = 92;
289
+ mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
290
mmc->armsse_type = TYPE_SSE200;
291
}
292
293
--
51
--
294
2.20.1
52
2.20.1
295
53
296
54
diff view generated by jsdifflib
1
Add brief documentation of the new mps3-an524 board.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We were incorrectly assuming that only the first byte of an MTE access
4
is checked against the tags. But per the ARM, unaligned accesses are
5
pre-decomposed into single-byte accesses. So by the time we reach the
6
actual MTE check in the ARM pseudocode, all accesses are aligned.
7
8
Therefore, the first failure is always either the first byte of the
9
access, or the first byte of the granule.
10
11
In addition, some of the arithmetic is off for last-first -> count.
12
This does not become directly visible until a later patch that passes
13
single bytes into this function, so ptr == ptr_last.
14
15
Buglink: https://bugs.launchpad.net/bugs/1921948
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20210416183106.1516563-2-richard.henderson@linaro.org
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
[PMM: tweaked a comment]
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215115138.20465-24-peter.maydell@linaro.org
7
---
21
---
8
docs/system/arm/mps2.rst | 24 ++++++++++++++++++------
22
target/arm/mte_helper.c | 40 ++++++++++++++++++----------------------
9
1 file changed, 18 insertions(+), 6 deletions(-)
23
1 file changed, 18 insertions(+), 22 deletions(-)
10
24
11
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
25
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
12
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
13
--- a/docs/system/arm/mps2.rst
27
--- a/target/arm/mte_helper.c
14
+++ b/docs/system/arm/mps2.rst
28
+++ b/target/arm/mte_helper.c
15
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
16
-Arm MPS2 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``)
30
uint64_t ptr, uintptr_t ra)
17
-================================================================================================================
31
{
18
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``)
32
int mmu_idx, ptr_tag, bit55;
19
+=========================================================================================================================================
33
- uint64_t ptr_last, ptr_end, prev_page, next_page;
20
34
- uint64_t tag_first, tag_end;
21
These board models all use Arm M-profile CPUs.
35
- uint64_t tag_byte_first, tag_byte_end;
22
36
- uint32_t esize, total, tag_count, tag_size, n, c;
23
-The Arm MPS2 and MPS2+ dev boards are FPGA based (the 2+ has a bigger
37
+ uint64_t ptr_last, prev_page, next_page;
24
-FPGA but is otherwise the same as the 2). Since the CPU itself
38
+ uint64_t tag_first, tag_last;
25
-and most of the devices are in the FPGA, the details of the board
39
+ uint64_t tag_byte_first, tag_byte_last;
26
-as seen by the guest depend significantly on the FPGA image.
40
+ uint32_t total, tag_count, tag_size, n, c;
27
+The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
41
uint8_t *mem1, *mem2;
28
+bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
42
MMUAccessType type;
29
+FPGA again, can handle 4GB of RAM and has a USB controller and QSPI flash).
43
30
+
44
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
31
+Since the CPU itself and most of the devices are in the FPGA, the
45
32
+details of the board as seen by the guest depend significantly on the
46
mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
33
+FPGA image.
47
type = FIELD_EX32(desc, MTEDESC, WRITE) ? MMU_DATA_STORE : MMU_DATA_LOAD;
34
48
- esize = FIELD_EX32(desc, MTEDESC, ESIZE);
35
QEMU models the following FPGA images:
49
total = FIELD_EX32(desc, MTEDESC, TSIZE);
36
50
37
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
51
- /* Find the addr of the end of the access, and of the last element. */
38
Cortex-M3 'DesignStart' as documented in Arm Application Note AN511
52
- ptr_end = ptr + total;
39
``mps2-an521``
53
- ptr_last = ptr_end - esize;
40
Dual Cortex-M33 as documented in Arm Application Note AN521
54
+ /* Find the addr of the end of the access */
41
+``mps3-an524``
55
+ ptr_last = ptr + total - 1;
42
+ Dual Cortex-M33 on an MPS3, as documented in Arm Application Note AN524
56
43
57
/* Round the bounds to the tag granule, and compute the number of tags. */
44
Differences between QEMU and real hardware:
58
tag_first = QEMU_ALIGN_DOWN(ptr, TAG_GRANULE);
45
59
- tag_end = QEMU_ALIGN_UP(ptr_last, TAG_GRANULE);
46
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
60
- tag_count = (tag_end - tag_first) / TAG_GRANULE;
47
block RAM is unimplemented (QEMU always maps this to ZBT SSRAM1, as
61
+ tag_last = QEMU_ALIGN_DOWN(ptr_last, TAG_GRANULE);
48
if zbt_boot_ctrl is always zero)
62
+ tag_count = ((tag_last - tag_first) / TAG_GRANULE) + 1;
49
+- AN524 remapping of low memory to either BRAM or to QSPI flash is
63
50
+ unimplemented (QEMU always maps this to BRAM, ignoring the
64
/* Round the bounds to twice the tag granule, and compute the bytes. */
51
+ SCC CFG_REG0 memory-remap bit)
65
tag_byte_first = QEMU_ALIGN_DOWN(ptr, 2 * TAG_GRANULE);
52
- QEMU provides a LAN9118 ethernet rather than LAN9220; the only guest
66
- tag_byte_end = QEMU_ALIGN_UP(ptr_last, 2 * TAG_GRANULE);
53
visible difference is that the LAN9118 doesn't support checksum
67
+ tag_byte_last = QEMU_ALIGN_DOWN(ptr_last, 2 * TAG_GRANULE);
54
offloading
68
55
+- QEMU does not model the QSPI flash in MPS3 boards as real QSPI
69
/* Locate the page boundaries. */
56
+ flash, but only as simple ROM, so attempting to rewrite the flash
70
prev_page = ptr & TARGET_PAGE_MASK;
57
+ from the guest will fail
71
next_page = prev_page + TARGET_PAGE_SIZE;
58
+- QEMU does not model the USB controller in MPS3 boards
72
73
- if (likely(tag_end - prev_page <= TARGET_PAGE_SIZE)) {
74
+ if (likely(tag_last - prev_page <= TARGET_PAGE_SIZE)) {
75
/* Memory access stays on one page. */
76
- tag_size = (tag_byte_end - tag_byte_first) / (2 * TAG_GRANULE);
77
+ tag_size = ((tag_byte_last - tag_byte_first) / (2 * TAG_GRANULE)) + 1;
78
mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, total,
79
MMU_DATA_LOAD, tag_size, ra);
80
if (!mem1) {
81
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
82
mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, next_page - ptr,
83
MMU_DATA_LOAD, tag_size, ra);
84
85
- tag_size = (tag_byte_end - next_page) / (2 * TAG_GRANULE);
86
+ tag_size = ((tag_byte_last - next_page) / (2 * TAG_GRANULE)) + 1;
87
mem2 = allocation_tag_mem(env, mmu_idx, next_page, type,
88
- ptr_end - next_page,
89
+ ptr_last - next_page + 1,
90
MMU_DATA_LOAD, tag_size, ra);
91
92
/*
93
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
94
}
95
96
/*
97
- * If we failed, we know which granule. Compute the element that
98
- * is first in that granule, and signal failure on that element.
99
+ * If we failed, we know which granule. For the first granule, the
100
+ * failure address is @ptr, the first byte accessed. Otherwise the
101
+ * failure address is the first byte of the nth granule.
102
*/
103
if (unlikely(n < tag_count)) {
104
- uint64_t fail_ofs;
105
-
106
- fail_ofs = tag_first + n * TAG_GRANULE - ptr;
107
- fail_ofs = ROUND_UP(fail_ofs, esize);
108
- mte_check_fail(env, desc, ptr + fail_ofs, ra);
109
+ uint64_t fault = (n == 0 ? ptr : tag_first + n * TAG_GRANULE);
110
+ mte_check_fail(env, desc, fault, ra);
111
}
112
113
done:
59
--
114
--
60
2.20.1
115
2.20.1
61
116
62
117
diff view generated by jsdifflib
1
From: Peter Collingbourne <pcc@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Section D6.7 of the ARM ARM states:
3
Split out a helper function from mte_checkN to perform
4
all of the checking and address manpulation. So far,
5
just use this in mte_checkN itself.
4
6
5
For the purpose of determining Tag Check Fault handling, unprivileged
7
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
load and store instructions are treated as if executed at EL0 when
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
executed at either:
9
Message-id: 20210416183106.1516563-3-richard.henderson@linaro.org
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
25
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
26
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
27
---
12
---
28
target/arm/helper.c | 2 +-
13
target/arm/mte_helper.c | 52 +++++++++++++++++++++++++++++++----------
29
target/arm/mte_helper.c | 13 +++++++++----
14
1 file changed, 40 insertions(+), 12 deletions(-)
30
2 files changed, 10 insertions(+), 5 deletions(-)
31
15
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
35
+++ b/target/arm/helper.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
37
if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
38
&& tbid
39
&& !(env->pstate & PSTATE_TCO)
40
- && (sctlr & SCTLR_TCF)
41
+ && (sctlr & SCTLR_TCF0)
42
&& allocation_tag_access_enabled(env, 0, sctlr)) {
43
flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
44
}
45
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
16
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
46
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/mte_helper.c
18
--- a/target/arm/mte_helper.c
48
+++ b/target/arm/mte_helper.c
19
+++ b/target/arm/mte_helper.c
49
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
20
@@ -XXX,XX +XXX,XX @@ static int checkN(uint8_t *mem, int odd, int cmp, int count)
50
reg_el = regime_el(env, arm_mmu_idx);
21
return n;
51
sctlr = env->cp15.sctlr_el[reg_el];
22
}
52
23
53
- el = arm_current_el(env);
24
-uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
54
- if (el == 0) {
25
- uint64_t ptr, uintptr_t ra)
55
+ switch (arm_mmu_idx) {
26
+/**
56
+ case ARMMMUIdx_E10_0:
27
+ * mte_probe_int() - helper for mte_probe and mte_check
57
+ case ARMMMUIdx_E20_0:
28
+ * @env: CPU environment
58
+ el = 0;
29
+ * @desc: MTEDESC descriptor
59
tcf = extract64(sctlr, 38, 2);
30
+ * @ptr: virtual address of the base of the access
60
- } else {
31
+ * @fault: return virtual address of the first check failure
61
+ break;
32
+ *
62
+ default:
33
+ * Internal routine for both mte_probe and mte_check.
63
+ el = reg_el;
34
+ * Return zero on failure, filling in *fault.
64
tcf = extract64(sctlr, 40, 2);
35
+ * Return negative on trivial success for tbi disabled.
36
+ * Return positive on success with tbi enabled.
37
+ */
38
+static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
39
+ uintptr_t ra, uint32_t total, uint64_t *fault)
40
{
41
int mmu_idx, ptr_tag, bit55;
42
uint64_t ptr_last, prev_page, next_page;
43
uint64_t tag_first, tag_last;
44
uint64_t tag_byte_first, tag_byte_last;
45
- uint32_t total, tag_count, tag_size, n, c;
46
+ uint32_t tag_count, tag_size, n, c;
47
uint8_t *mem1, *mem2;
48
MMUAccessType type;
49
50
bit55 = extract64(ptr, 55, 1);
51
+ *fault = ptr;
52
53
/* If TBI is disabled, the access is unchecked, and ptr is not dirty. */
54
if (unlikely(!tbi_check(desc, bit55))) {
55
- return ptr;
56
+ return -1;
65
}
57
}
66
58
67
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
59
ptr_tag = allocation_tag_from_addr(ptr);
68
env->exception.vaddress = dirty_ptr;
60
69
61
if (tcma_check(desc, bit55, ptr_tag)) {
70
is_write = FIELD_EX32(desc, MTEDESC, WRITE);
62
- goto done;
71
- syn = syn_data_abort_no_iss(el != 0, 0, 0, 0, 0, is_write, 0x11);
63
+ return 1;
72
+ syn = syn_data_abort_no_iss(arm_current_el(env) != 0, 0, 0, 0, 0,
64
}
73
+ is_write, 0x11);
65
74
raise_exception(env, EXCP_DATA_ABORT, syn, exception_target_el(env));
66
mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
75
/* noreturn, but fall through to the assert anyway */
67
type = FIELD_EX32(desc, MTEDESC, WRITE) ? MMU_DATA_STORE : MMU_DATA_LOAD;
68
- total = FIELD_EX32(desc, MTEDESC, TSIZE);
69
70
/* Find the addr of the end of the access */
71
ptr_last = ptr + total - 1;
72
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
73
mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, total,
74
MMU_DATA_LOAD, tag_size, ra);
75
if (!mem1) {
76
- goto done;
77
+ return 1;
78
}
79
/* Perform all of the comparisons. */
80
n = checkN(mem1, ptr & TAG_GRANULE, ptr_tag, tag_count);
81
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
82
}
83
if (n == c) {
84
if (!mem2) {
85
- goto done;
86
+ return 1;
87
}
88
n += checkN(mem2, 0, ptr_tag, tag_count - c);
89
}
90
}
91
92
+ if (likely(n == tag_count)) {
93
+ return 1;
94
+ }
95
+
96
/*
97
* If we failed, we know which granule. For the first granule, the
98
* failure address is @ptr, the first byte accessed. Otherwise the
99
* failure address is the first byte of the nth granule.
100
*/
101
- if (unlikely(n < tag_count)) {
102
- uint64_t fault = (n == 0 ? ptr : tag_first + n * TAG_GRANULE);
103
- mte_check_fail(env, desc, fault, ra);
104
+ if (n > 0) {
105
+ *fault = tag_first + n * TAG_GRANULE;
106
}
107
+ return 0;
108
+}
109
110
- done:
111
+uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
112
+ uint64_t ptr, uintptr_t ra)
113
+{
114
+ uint64_t fault;
115
+ uint32_t total = FIELD_EX32(desc, MTEDESC, TSIZE);
116
+ int ret = mte_probe_int(env, desc, ptr, ra, total, &fault);
117
+
118
+ if (unlikely(ret == 0)) {
119
+ mte_check_fail(env, desc, fault, ra);
120
+ } else if (ret < 0) {
121
+ return ptr;
122
+ }
123
return useronly_clean_ptr(ptr);
124
}
76
125
77
--
126
--
78
2.20.1
127
2.20.1
79
128
80
129
diff view generated by jsdifflib
1
We only include the template header once, so just inline it into the
1
From: Richard Henderson <richard.henderson@linaro.org>
2
source file for the device.
3
2
3
We were incorrectly assuming that only the first byte of an MTE access
4
is checked against the tags. But per the ARM, unaligned accesses are
5
pre-decomposed into single-byte accesses. So by the time we reach the
6
actual MTE check in the ARM pseudocode, all accesses are aligned.
7
8
We cannot tell a priori whether or not a given scalar access is aligned,
9
therefore we must at least check. Use mte_probe_int, which is already
10
set up for checking multiple granules.
11
12
Buglink: https://bugs.launchpad.net/bugs/1921948
13
Tested-by: Alex Bennée <alex.bennee@linaro.org>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20210416183106.1516563-4-richard.henderson@linaro.org
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>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215103215.4944-9-peter.maydell@linaro.org
8
---
18
---
9
hw/display/omap_lcd_template.h | 154 ---------------------------------
19
target/arm/mte_helper.c | 109 +++++++++++++---------------------------
10
hw/display/omap_lcdc.c | 127 ++++++++++++++++++++++++++-
20
1 file changed, 35 insertions(+), 74 deletions(-)
11
2 files changed, 125 insertions(+), 156 deletions(-)
12
delete mode 100644 hw/display/omap_lcd_template.h
13
21
14
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
22
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
15
deleted file mode 100644
23
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX
24
--- a/target/arm/mte_helper.c
17
--- a/hw/display/omap_lcd_template.h
25
+++ b/target/arm/mte_helper.c
18
+++ /dev/null
26
@@ -XXX,XX +XXX,XX @@ static void mte_check_fail(CPUARMState *env, uint32_t desc,
19
@@ -XXX,XX +XXX,XX @@
27
}
28
}
29
20
-/*
30
-/*
21
- * QEMU OMAP LCD Emulator templates
31
- * Perform an MTE checked access for a single logical or atomic access.
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
- */
32
- */
33
-static bool mte_probe1_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
34
- uintptr_t ra, int bit55)
35
-{
36
- int mem_tag, mmu_idx, ptr_tag, size;
37
- MMUAccessType type;
38
- uint8_t *mem;
48
-
39
-
49
-/*
40
- ptr_tag = allocation_tag_from_addr(ptr);
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
-
41
-
58
- do {
42
- if (tcma_check(desc, bit55, ptr_tag)) {
59
- v = ldub_p((void *) s);
43
- return true;
60
- r = (pal[v & 3] >> 4) & 0xf0;
44
- }
61
- g = pal[v & 3] & 0xf0;
45
-
62
- b = (pal[v & 3] << 4) & 0xf0;
46
- mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
63
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
47
- type = FIELD_EX32(desc, MTEDESC, WRITE) ? MMU_DATA_STORE : MMU_DATA_LOAD;
64
- d += 4;
48
- size = FIELD_EX32(desc, MTEDESC, ESIZE);
65
- v >>= 2;
49
-
66
- r = (pal[v & 3] >> 4) & 0xf0;
50
- mem = allocation_tag_mem(env, mmu_idx, ptr, type, size,
67
- g = pal[v & 3] & 0xf0;
51
- MMU_DATA_LOAD, 1, ra);
68
- b = (pal[v & 3] << 4) & 0xf0;
52
- if (!mem) {
69
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
53
- return true;
70
- d += 4;
54
- }
71
- v >>= 2;
55
-
72
- r = (pal[v & 3] >> 4) & 0xf0;
56
- mem_tag = load_tag1(ptr, mem);
73
- g = pal[v & 3] & 0xf0;
57
- return ptr_tag == mem_tag;
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
-}
58
-}
87
-
59
-
88
-/*
60
-/*
89
- * 4-bit colour
61
- * No-fault version of mte_check1, to be used by SVE for MemSingleNF.
62
- * Returns false if the access is Checked and the check failed. This
63
- * is only intended to probe the tag -- the validity of the page must
64
- * be checked beforehand.
90
- */
65
- */
91
-static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
66
-bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr)
92
- int width, int deststep)
93
-{
67
-{
94
- uint16_t *pal = opaque;
68
- int bit55 = extract64(ptr, 55, 1);
95
- uint8_t v, r, g, b;
96
-
69
-
97
- do {
70
- /* If TBI is disabled, the access is unchecked. */
98
- v = ldub_p((void *) s);
71
- if (unlikely(!tbi_check(desc, bit55))) {
99
- r = (pal[v & 0xf] >> 4) & 0xf0;
72
- return true;
100
- g = pal[v & 0xf] & 0xf0;
73
- }
101
- b = (pal[v & 0xf] << 4) & 0xf0;
74
-
102
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
75
- return mte_probe1_int(env, desc, ptr, 0, bit55);
103
- d += 4;
76
-}
104
- v >>= 4;
77
-
105
- r = (pal[v & 0xf] >> 4) & 0xf0;
78
-uint64_t mte_check1(CPUARMState *env, uint32_t desc,
106
- g = pal[v & 0xf] & 0xf0;
79
- uint64_t ptr, uintptr_t ra)
107
- b = (pal[v & 0xf] << 4) & 0xf0;
80
-{
108
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
81
- int bit55 = extract64(ptr, 55, 1);
109
- d += 4;
82
-
110
- s++;
83
- /* If TBI is disabled, the access is unchecked, and ptr is not dirty. */
111
- width -= 2;
84
- if (unlikely(!tbi_check(desc, bit55))) {
112
- } while (width > 0);
85
- return ptr;
86
- }
87
-
88
- if (unlikely(!mte_probe1_int(env, desc, ptr, ra, bit55))) {
89
- mte_check_fail(env, desc, ptr, ra);
90
- }
91
-
92
- return useronly_clean_ptr(ptr);
93
-}
94
-
95
-uint64_t HELPER(mte_check1)(CPUARMState *env, uint32_t desc, uint64_t ptr)
96
-{
97
- return mte_check1(env, desc, ptr, GETPC());
113
-}
98
-}
114
-
99
-
115
-/*
100
-/*
116
- * 8-bit colour
101
- * Perform an MTE checked access for multiple logical accesses.
117
- */
102
- */
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
-
103
-
124
- do {
104
/**
125
- v = ldub_p((void *) s);
105
* checkN:
126
- r = (pal[v] >> 4) & 0xf0;
106
* @tag: tag memory to test
127
- g = pal[v] & 0xf0;
107
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mte_checkN)(CPUARMState *env, uint32_t desc, uint64_t ptr)
128
- b = (pal[v] << 4) & 0xf0;
108
return mte_checkN(env, desc, ptr, GETPC());
129
- ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
109
}
130
- s++;
110
131
- d += 4;
111
+uint64_t mte_check1(CPUARMState *env, uint32_t desc,
132
- } while (-- width != 0);
112
+ uint64_t ptr, uintptr_t ra)
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
175
index XXXXXXX..XXXXXXX 100644
176
--- a/hw/display/omap_lcdc.c
177
+++ b/hw/display/omap_lcdc.c
178
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
179
180
#define draw_line_func drawfn
181
182
-#define DEPTH 32
183
-#include "omap_lcd_template.h"
184
+/*
185
+ * 2-bit colour
186
+ */
187
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
188
+ int width, int deststep)
189
+{
113
+{
190
+ uint16_t *pal = opaque;
114
+ uint64_t fault;
191
+ uint8_t v, r, g, b;
115
+ uint32_t total = FIELD_EX32(desc, MTEDESC, ESIZE);
116
+ int ret = mte_probe_int(env, desc, ptr, ra, total, &fault);
192
+
117
+
193
+ do {
118
+ if (unlikely(ret == 0)) {
194
+ v = ldub_p((void *) s);
119
+ mte_check_fail(env, desc, fault, ra);
195
+ r = (pal[v & 3] >> 4) & 0xf0;
120
+ } else if (ret < 0) {
196
+ g = pal[v & 3] & 0xf0;
121
+ return ptr;
197
+ b = (pal[v & 3] << 4) & 0xf0;
122
+ }
198
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
123
+ return useronly_clean_ptr(ptr);
199
+ d += 4;
124
+}
200
+ v >>= 2;
125
+
201
+ r = (pal[v & 3] >> 4) & 0xf0;
126
+uint64_t HELPER(mte_check1)(CPUARMState *env, uint32_t desc, uint64_t ptr)
202
+ g = pal[v & 3] & 0xf0;
127
+{
203
+ b = (pal[v & 3] << 4) & 0xf0;
128
+ return mte_check1(env, desc, ptr, GETPC());
204
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
205
+ d += 4;
206
+ v >>= 2;
207
+ r = (pal[v & 3] >> 4) & 0xf0;
208
+ g = pal[v & 3] & 0xf0;
209
+ b = (pal[v & 3] << 4) & 0xf0;
210
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
211
+ d += 4;
212
+ v >>= 2;
213
+ r = (pal[v & 3] >> 4) & 0xf0;
214
+ g = pal[v & 3] & 0xf0;
215
+ b = (pal[v & 3] << 4) & 0xf0;
216
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
217
+ d += 4;
218
+ s++;
219
+ width -= 4;
220
+ } while (width > 0);
221
+}
129
+}
222
+
130
+
223
+/*
131
+/*
224
+ * 4-bit colour
132
+ * No-fault version of mte_check1, to be used by SVE for MemSingleNF.
133
+ * Returns false if the access is Checked and the check failed. This
134
+ * is only intended to probe the tag -- the validity of the page must
135
+ * be checked beforehand.
225
+ */
136
+ */
226
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
137
+bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr)
227
+ int width, int deststep)
228
+{
138
+{
229
+ uint16_t *pal = opaque;
139
+ uint64_t fault;
230
+ uint8_t v, r, g, b;
140
+ uint32_t total = FIELD_EX32(desc, MTEDESC, ESIZE);
141
+ int ret = mte_probe_int(env, desc, ptr, 0, total, &fault);
231
+
142
+
232
+ do {
143
+ return ret != 0;
233
+ v = ldub_p((void *) s);
234
+ r = (pal[v & 0xf] >> 4) & 0xf0;
235
+ g = pal[v & 0xf] & 0xf0;
236
+ b = (pal[v & 0xf] << 4) & 0xf0;
237
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
238
+ d += 4;
239
+ v >>= 4;
240
+ r = (pal[v & 0xf] >> 4) & 0xf0;
241
+ g = pal[v & 0xf] & 0xf0;
242
+ b = (pal[v & 0xf] << 4) & 0xf0;
243
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
244
+ d += 4;
245
+ s++;
246
+ width -= 2;
247
+ } while (width > 0);
248
+}
144
+}
249
+
145
+
250
+/*
146
/*
251
+ * 8-bit colour
147
* Perform an MTE checked access for DC_ZVA.
252
+ */
148
*/
253
+static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
254
+ int width, int deststep)
255
+{
256
+ uint16_t *pal = opaque;
257
+ uint8_t v, r, g, b;
258
+
259
+ do {
260
+ v = ldub_p((void *) s);
261
+ r = (pal[v] >> 4) & 0xf0;
262
+ g = pal[v] & 0xf0;
263
+ b = (pal[v] << 4) & 0xf0;
264
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
265
+ s++;
266
+ d += 4;
267
+ } while (-- width != 0);
268
+}
269
+
270
+/*
271
+ * 12-bit colour
272
+ */
273
+static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
274
+ int width, int deststep)
275
+{
276
+ uint16_t v;
277
+ uint8_t r, g, b;
278
+
279
+ do {
280
+ v = lduw_le_p((void *) s);
281
+ r = (v >> 4) & 0xf0;
282
+ g = v & 0xf0;
283
+ b = (v << 4) & 0xf0;
284
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
285
+ s += 2;
286
+ d += 4;
287
+ } while (-- width != 0);
288
+}
289
+
290
+/*
291
+ * 16-bit colour
292
+ */
293
+static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
294
+ int width, int deststep)
295
+{
296
+ uint16_t v;
297
+ uint8_t r, g, b;
298
+
299
+ do {
300
+ v = lduw_le_p((void *) s);
301
+ r = (v >> 8) & 0xf8;
302
+ g = (v >> 3) & 0xfc;
303
+ b = (v << 3) & 0xf8;
304
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
305
+ s += 2;
306
+ d += 4;
307
+ } while (-- width != 0);
308
+}
309
310
static void omap_update_display(void *opaque)
311
{
312
--
149
--
313
2.20.1
150
2.20.1
314
151
315
152
diff view generated by jsdifflib
1
From: Doug Evans <dje@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reviewed-by: Hao Wu <wuhaotsh@google.com>
3
Buglink: https://bugs.launchpad.net/bugs/1921948
4
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Doug Evans <dje@google.com>
6
Message-id: 20210416183106.1516563-5-richard.henderson@linaro.org
7
Message-id: 20210218212453.831406-4-dje@google.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
8
---
10
tests/qtest/npcm7xx_emc-test.c | 862 +++++++++++++++++++++++++++++++++
9
tests/tcg/aarch64/mte-5.c | 44 +++++++++++++++++++++++++++++++
11
tests/qtest/meson.build | 3 +-
10
tests/tcg/aarch64/Makefile.target | 2 +-
12
2 files changed, 864 insertions(+), 1 deletion(-)
11
2 files changed, 45 insertions(+), 1 deletion(-)
13
create mode 100644 tests/qtest/npcm7xx_emc-test.c
12
create mode 100644 tests/tcg/aarch64/mte-5.c
14
13
15
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
14
diff --git a/tests/tcg/aarch64/mte-5.c b/tests/tcg/aarch64/mte-5.c
16
new file mode 100644
15
new file mode 100644
17
index XXXXXXX..XXXXXXX
16
index XXXXXXX..XXXXXXX
18
--- /dev/null
17
--- /dev/null
19
+++ b/tests/qtest/npcm7xx_emc-test.c
18
+++ b/tests/tcg/aarch64/mte-5.c
20
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
21
+/*
20
+/*
22
+ * QTests for Nuvoton NPCM7xx EMC Modules.
21
+ * Memory tagging, faulting unaligned access.
23
+ *
22
+ *
24
+ * Copyright 2020 Google LLC
23
+ * Copyright (c) 2021 Linaro Ltd
25
+ *
24
+ * SPDX-License-Identifier: GPL-2.0-or-later
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
+ */
25
+ */
36
+
26
+
37
+#include "qemu/osdep.h"
27
+#include "mte.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
+
28
+
45
+/* Name of the emc device. */
29
+void pass(int sig, siginfo_t *info, void *uc)
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
+{
30
+{
226
+ ptrdiff_t diff = mod - emc_module_list;
31
+ assert(info->si_code == SEGV_MTESERR);
227
+
32
+ exit(0);
228
+ g_assert_true(diff >= 0 && diff < ARRAY_SIZE(emc_module_list));
229
+
230
+ return diff;
231
+}
33
+}
232
+
34
+
233
+static void packet_test_clear(void *sockets)
35
+int main(int ac, char **av)
234
+{
36
+{
235
+ int *test_sockets = sockets;
37
+ struct sigaction sa;
38
+ void *p0, *p1, *p2;
39
+ long excl = 1;
236
+
40
+
237
+ close(test_sockets[0]);
41
+ enable_mte(PR_MTE_TCF_SYNC);
238
+ g_free(test_sockets);
42
+ p0 = alloc_mte_mem(sizeof(*p0));
43
+
44
+ /* Create two differently tagged pointers. */
45
+ asm("irg %0,%1,%2" : "=r"(p1) : "r"(p0), "r"(excl));
46
+ asm("gmi %0,%1,%0" : "+r"(excl) : "r" (p1));
47
+ assert(excl != 1);
48
+ asm("irg %0,%1,%2" : "=r"(p2) : "r"(p0), "r"(excl));
49
+ assert(p1 != p2);
50
+
51
+ memset(&sa, 0, sizeof(sa));
52
+ sa.sa_sigaction = pass;
53
+ sa.sa_flags = SA_SIGINFO;
54
+ sigaction(SIGSEGV, &sa, NULL);
55
+
56
+ /* Store store two different tags in sequential granules. */
57
+ asm("stg %0, [%0]" : : "r"(p1));
58
+ asm("stg %0, [%0]" : : "r"(p2 + 16));
59
+
60
+ /* Perform an unaligned load crossing the granules. */
61
+ asm volatile("ldr %0, [%1]" : "=r"(p0) : "r"(p1 + 12));
62
+ abort();
239
+}
63
+}
240
+
64
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
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
884
index XXXXXXX..XXXXXXX 100644
65
index XXXXXXX..XXXXXXX 100644
885
--- a/tests/qtest/meson.build
66
--- a/tests/tcg/aarch64/Makefile.target
886
+++ b/tests/qtest/meson.build
67
+++ b/tests/tcg/aarch64/Makefile.target
887
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
68
@@ -XXX,XX +XXX,XX @@ AARCH64_TESTS += bti-2
888
'npcm7xx_rng-test',
69
889
'npcm7xx_smbus-test',
70
# MTE Tests
890
'npcm7xx_timer-test',
71
ifneq ($(DOCKER_IMAGE)$(CROSS_CC_HAS_ARMV8_MTE),)
891
- 'npcm7xx_watchdog_timer-test']
72
-AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-6
892
+ 'npcm7xx_watchdog_timer-test'] + \
73
+AARCH64_TESTS += mte-1 mte-2 mte-3 mte-4 mte-5 mte-6
893
+ (slirp.found() ? ['npcm7xx_emc-test'] : [])
74
mte-%: CFLAGS += -march=armv8.5-a+memtag
894
qtests_arm = \
75
endif
895
(config_all_devices.has_key('CONFIG_CMSDK_APB_DUALTIMER') ? ['cmsdk-apb-dualtimer-test'] : []) + \
76
896
(config_all_devices.has_key('CONFIG_CMSDK_APB_TIMER') ? ['cmsdk-apb-timer-test'] : []) + \
897
--
77
--
898
2.20.1
78
2.20.1
899
79
900
80
diff view generated by jsdifflib
1
The AN524 has a PL031 RTC, which we have a model of; provide it
1
From: Richard Henderson <richard.henderson@linaro.org>
2
rather than an unimplemented-device stub.
3
2
3
After recent changes, mte_checkN does not use ESIZE,
4
and mte_check1 never used TSIZE. We can combine the
5
two into a single field: SIZEM1.
6
7
Choose to pass size - 1 because size == 0 is never used,
8
our immediate need in mte_probe_int is for the address
9
of the last byte (ptr + size - 1), and since almost all
10
operations are powers of 2, this makes the immediate
11
constant one bit smaller.
12
13
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210416183106.1516563-6-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
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
8
---
17
---
9
hw/arm/mps2-tz.c | 22 ++++++++++++++++++++--
18
target/arm/internals.h | 4 ++--
10
1 file changed, 20 insertions(+), 2 deletions(-)
19
target/arm/mte_helper.c | 18 ++++++++----------
20
target/arm/translate-a64.c | 5 ++---
21
target/arm/translate-sve.c | 5 ++---
22
4 files changed, 14 insertions(+), 18 deletions(-)
11
23
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
24
diff --git a/target/arm/internals.h b/target/arm/internals.h
13
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/mps2-tz.c
26
--- a/target/arm/internals.h
15
+++ b/hw/arm/mps2-tz.c
27
+++ b/target/arm/internals.h
16
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@
17
#include "hw/misc/tz-msc.h"
29
#define TARGET_ARM_INTERNALS_H
18
#include "hw/arm/armsse.h"
30
19
#include "hw/dma/pl080.h"
31
#include "hw/registerfields.h"
20
+#include "hw/rtc/pl031.h"
32
+#include "tcg/tcg-gvec-desc.h"
21
#include "hw/ssi/pl022.h"
33
#include "syndrome.h"
22
#include "hw/i2c/arm_sbcon_i2c.h"
34
23
#include "hw/net/lan9118.h"
35
/* register banks for CPU modes */
24
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
36
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, MIDX, 0, 4)
25
UnimplementedDeviceState gpio[4];
37
FIELD(MTEDESC, TBI, 4, 2)
26
UnimplementedDeviceState gfx;
38
FIELD(MTEDESC, TCMA, 6, 2)
27
UnimplementedDeviceState cldc;
39
FIELD(MTEDESC, WRITE, 8, 1)
28
- UnimplementedDeviceState rtc;
40
-FIELD(MTEDESC, ESIZE, 9, 5)
29
UnimplementedDeviceState usb;
41
-FIELD(MTEDESC, TSIZE, 14, 10) /* mte_checkN only */
30
+ PL031State rtc;
42
+FIELD(MTEDESC, SIZEM1, 9, SIMD_DATA_BITS - 9) /* size - 1 */
31
PL080State dma[4];
43
32
TZMSC msc[4];
44
bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr);
33
CMSDKAPBUART uart[6];
45
uint64_t mte_check1(CPUARMState *env, uint32_t desc,
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
46
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
35
return sysbus_mmio_get_region(s, 0);
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/mte_helper.c
49
+++ b/target/arm/mte_helper.c
50
@@ -XXX,XX +XXX,XX @@ static int checkN(uint8_t *mem, int odd, int cmp, int count)
51
* Return positive on success with tbi enabled.
52
*/
53
static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
54
- uintptr_t ra, uint32_t total, uint64_t *fault)
55
+ uintptr_t ra, uint64_t *fault)
56
{
57
int mmu_idx, ptr_tag, bit55;
58
uint64_t ptr_last, prev_page, next_page;
59
uint64_t tag_first, tag_last;
60
uint64_t tag_byte_first, tag_byte_last;
61
- uint32_t tag_count, tag_size, n, c;
62
+ uint32_t sizem1, tag_count, tag_size, n, c;
63
uint8_t *mem1, *mem2;
64
MMUAccessType type;
65
66
@@ -XXX,XX +XXX,XX @@ static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
67
68
mmu_idx = FIELD_EX32(desc, MTEDESC, MIDX);
69
type = FIELD_EX32(desc, MTEDESC, WRITE) ? MMU_DATA_STORE : MMU_DATA_LOAD;
70
+ sizem1 = FIELD_EX32(desc, MTEDESC, SIZEM1);
71
72
/* Find the addr of the end of the access */
73
- ptr_last = ptr + total - 1;
74
+ ptr_last = ptr + sizem1;
75
76
/* Round the bounds to the tag granule, and compute the number of tags. */
77
tag_first = QEMU_ALIGN_DOWN(ptr, TAG_GRANULE);
78
@@ -XXX,XX +XXX,XX @@ static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
79
if (likely(tag_last - prev_page <= TARGET_PAGE_SIZE)) {
80
/* Memory access stays on one page. */
81
tag_size = ((tag_byte_last - tag_byte_first) / (2 * TAG_GRANULE)) + 1;
82
- mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, total,
83
+ mem1 = allocation_tag_mem(env, mmu_idx, ptr, type, sizem1 + 1,
84
MMU_DATA_LOAD, tag_size, ra);
85
if (!mem1) {
86
return 1;
87
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
88
uint64_t ptr, uintptr_t ra)
89
{
90
uint64_t fault;
91
- uint32_t total = FIELD_EX32(desc, MTEDESC, TSIZE);
92
- int ret = mte_probe_int(env, desc, ptr, ra, total, &fault);
93
+ int ret = mte_probe_int(env, desc, ptr, ra, &fault);
94
95
if (unlikely(ret == 0)) {
96
mte_check_fail(env, desc, fault, ra);
97
@@ -XXX,XX +XXX,XX @@ uint64_t mte_check1(CPUARMState *env, uint32_t desc,
98
uint64_t ptr, uintptr_t ra)
99
{
100
uint64_t fault;
101
- uint32_t total = FIELD_EX32(desc, MTEDESC, ESIZE);
102
- int ret = mte_probe_int(env, desc, ptr, ra, total, &fault);
103
+ int ret = mte_probe_int(env, desc, ptr, ra, &fault);
104
105
if (unlikely(ret == 0)) {
106
mte_check_fail(env, desc, fault, ra);
107
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mte_check1)(CPUARMState *env, uint32_t desc, uint64_t ptr)
108
bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr)
109
{
110
uint64_t fault;
111
- uint32_t total = FIELD_EX32(desc, MTEDESC, ESIZE);
112
- int ret = mte_probe_int(env, desc, ptr, 0, total, &fault);
113
+ int ret = mte_probe_int(env, desc, ptr, 0, &fault);
114
115
return ret != 0;
36
}
116
}
37
117
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
38
+static MemoryRegion *make_rtc(MPS2TZMachineState *mms, void *opaque,
118
index XXXXXXX..XXXXXXX 100644
39
+ const char *name, hwaddr size,
119
--- a/target/arm/translate-a64.c
40
+ const int *irqs)
120
+++ b/target/arm/translate-a64.c
41
+{
121
@@ -XXX,XX +XXX,XX @@ static TCGv_i64 gen_mte_check1_mmuidx(DisasContext *s, TCGv_i64 addr,
42
+ PL031State *pl031 = opaque;
122
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
43
+ SysBusDevice *s;
123
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
44
+
124
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
45
+ object_initialize_child(OBJECT(mms), name, pl031, TYPE_PL031);
125
- desc = FIELD_DP32(desc, MTEDESC, ESIZE, 1 << log2_size);
46
+ s = SYS_BUS_DEVICE(pl031);
126
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << log2_size) - 1);
47
+ sysbus_realize(s, &error_fatal);
127
tcg_desc = tcg_const_i32(desc);
48
+ /*
128
49
+ * The board docs don't give an IRQ number for the PL031, so
129
ret = new_tmp_a64(s);
50
+ * presumably it is not connected.
130
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
51
+ */
131
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
52
+ return sysbus_mmio_get_region(s, 0);
132
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
53
+}
133
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
54
+
134
- desc = FIELD_DP32(desc, MTEDESC, ESIZE, 1 << log2_esize);
55
static void create_non_mpc_ram(MPS2TZMachineState *mms)
135
- desc = FIELD_DP32(desc, MTEDESC, TSIZE, total_size);
56
{
136
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, total_size - 1);
57
/*
137
tcg_desc = tcg_const_i32(desc);
58
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
138
59
139
ret = new_tmp_a64(s);
60
{ /* port 9 reserved */ },
140
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
61
{ "clcd", make_unimp_dev, &mms->cldc, 0x4130a000, 0x1000 },
141
index XXXXXXX..XXXXXXX 100644
62
- { "rtc", make_unimp_dev, &mms->rtc, 0x4130b000, 0x1000 },
142
--- a/target/arm/translate-sve.c
63
+ { "rtc", make_rtc, &mms->rtc, 0x4130b000, 0x1000 },
143
+++ b/target/arm/translate-sve.c
64
},
144
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
65
}, {
145
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
66
.name = "ahb_ppcexp0",
146
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
147
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
148
- desc = FIELD_DP32(desc, MTEDESC, ESIZE, 1 << msz);
149
- desc = FIELD_DP32(desc, MTEDESC, TSIZE, mte_n << msz);
150
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
151
desc <<= SVE_MTEDESC_SHIFT;
152
} else {
153
addr = clean_data_tbi(s, addr);
154
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm,
155
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
156
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
157
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
158
- desc = FIELD_DP32(desc, MTEDESC, ESIZE, 1 << msz);
159
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
160
desc <<= SVE_MTEDESC_SHIFT;
161
}
162
desc = simd_desc(vsz, vsz, desc | scale);
67
--
163
--
68
2.20.1
164
2.20.1
69
165
70
166
diff view generated by jsdifflib
1
The mps2-tz code uses PPCPortInfo data structures to define what
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
7
2
8
This commit adds the framework to allow PPCPortInfo structures to
3
The mte_check1 and mte_checkN functions are now identical.
9
specify interrupt numbers. We add an array of interrupt numbers to
4
Drop mte_check1 and rename mte_checkN to mte_check.
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.
13
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210416183106.1516563-7-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20210215115138.20465-13-peter.maydell@linaro.org
17
---
10
---
18
hw/arm/mps2-tz.c | 36 ++++++++++++++++++++++++------------
11
target/arm/helper-a64.h | 3 +--
19
1 file changed, 24 insertions(+), 12 deletions(-)
12
target/arm/internals.h | 5 +----
13
target/arm/mte_helper.c | 26 +++-----------------------
14
target/arm/sve_helper.c | 14 +++++++-------
15
target/arm/translate-a64.c | 4 ++--
16
5 files changed, 14 insertions(+), 38 deletions(-)
20
17
21
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/mps2-tz.c
20
--- a/target/arm/helper-a64.h
24
+++ b/hw/arm/mps2-tz.c
21
+++ b/target/arm/helper-a64.h
25
@@ -XXX,XX +XXX,XX @@ static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(autdb, TCG_CALL_NO_WG, i64, env, i64, i64)
26
* needs to be plugged into the downstream end of the PPC port.
23
DEF_HELPER_FLAGS_2(xpaci, TCG_CALL_NO_RWG_SE, i64, env, i64)
27
*/
24
DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64)
28
typedef MemoryRegion *MakeDevFn(MPS2TZMachineState *mms, void *opaque,
25
29
- const char *name, hwaddr size);
26
-DEF_HELPER_FLAGS_3(mte_check1, TCG_CALL_NO_WG, i64, env, i32, i64)
30
+ const char *name, hwaddr size,
27
-DEF_HELPER_FLAGS_3(mte_checkN, TCG_CALL_NO_WG, i64, env, i32, i64)
31
+ const int *irqs);
28
+DEF_HELPER_FLAGS_3(mte_check, TCG_CALL_NO_WG, i64, env, i32, i64)
32
29
DEF_HELPER_FLAGS_3(mte_check_zva, TCG_CALL_NO_WG, i64, env, i32, i64)
33
typedef struct PPCPortInfo {
30
DEF_HELPER_FLAGS_3(irg, TCG_CALL_NO_RWG, i64, env, i64, i64)
34
const char *name;
31
DEF_HELPER_FLAGS_4(addsubg, TCG_CALL_NO_RWG_SE, i64, env, i64, s32, i32)
35
@@ -XXX,XX +XXX,XX @@ typedef struct PPCPortInfo {
32
diff --git a/target/arm/internals.h b/target/arm/internals.h
36
void *opaque;
33
index XXXXXXX..XXXXXXX 100644
37
hwaddr addr;
34
--- a/target/arm/internals.h
38
hwaddr size;
35
+++ b/target/arm/internals.h
39
+ int irqs[3]; /* currently no device needs more IRQ lines than this */
36
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, WRITE, 8, 1)
40
} PPCPortInfo;
37
FIELD(MTEDESC, SIZEM1, 9, SIMD_DATA_BITS - 9) /* size - 1 */
41
38
42
typedef struct PPCInfo {
39
bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr);
43
@@ -XXX,XX +XXX,XX @@ typedef struct PPCInfo {
40
-uint64_t mte_check1(CPUARMState *env, uint32_t desc,
44
} PPCInfo;
41
- uint64_t ptr, uintptr_t ra);
45
42
-uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
46
static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
43
- uint64_t ptr, uintptr_t ra);
47
- void *opaque,
44
+uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
48
- const char *name, hwaddr size)
45
49
+ void *opaque,
46
static inline int allocation_tag_from_addr(uint64_t ptr)
50
+ const char *name, hwaddr size,
51
+ const int *irqs)
52
{
47
{
53
/* Initialize, configure and realize a TYPE_UNIMPLEMENTED_DEVICE,
48
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
54
* and return a pointer to its MemoryRegion.
49
index XXXXXXX..XXXXXXX 100644
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
50
--- a/target/arm/mte_helper.c
51
+++ b/target/arm/mte_helper.c
52
@@ -XXX,XX +XXX,XX @@ static int mte_probe_int(CPUARMState *env, uint32_t desc, uint64_t ptr,
53
return 0;
56
}
54
}
57
55
58
static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
56
-uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
59
- const char *name, hwaddr size)
57
- uint64_t ptr, uintptr_t ra)
60
+ const char *name, hwaddr size,
58
+uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra)
61
+ const int *irqs)
62
{
59
{
63
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
60
uint64_t fault;
64
CMSDKAPBUART *uart = opaque;
61
int ret = mte_probe_int(env, desc, ptr, ra, &fault);
65
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
62
@@ -XXX,XX +XXX,XX @@ uint64_t mte_checkN(CPUARMState *env, uint32_t desc,
63
return useronly_clean_ptr(ptr);
66
}
64
}
67
65
68
static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
66
-uint64_t HELPER(mte_checkN)(CPUARMState *env, uint32_t desc, uint64_t ptr)
69
- const char *name, hwaddr size)
67
+uint64_t HELPER(mte_check)(CPUARMState *env, uint32_t desc, uint64_t ptr)
70
+ const char *name, hwaddr size,
71
+ const int *irqs)
72
{
68
{
73
MPS2SCC *scc = opaque;
69
- return mte_checkN(env, desc, ptr, GETPC());
74
DeviceState *sccdev;
70
-}
75
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
71
-
72
-uint64_t mte_check1(CPUARMState *env, uint32_t desc,
73
- uint64_t ptr, uintptr_t ra)
74
-{
75
- uint64_t fault;
76
- int ret = mte_probe_int(env, desc, ptr, ra, &fault);
77
-
78
- if (unlikely(ret == 0)) {
79
- mte_check_fail(env, desc, fault, ra);
80
- } else if (ret < 0) {
81
- return ptr;
82
- }
83
- return useronly_clean_ptr(ptr);
84
-}
85
-
86
-uint64_t HELPER(mte_check1)(CPUARMState *env, uint32_t desc, uint64_t ptr)
87
-{
88
- return mte_check1(env, desc, ptr, GETPC());
89
+ return mte_check(env, desc, ptr, GETPC());
76
}
90
}
77
91
78
static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
92
/*
79
- const char *name, hwaddr size)
93
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
80
+ const char *name, hwaddr size,
94
index XXXXXXX..XXXXXXX 100644
81
+ const int *irqs)
95
--- a/target/arm/sve_helper.c
96
+++ b/target/arm/sve_helper.c
97
@@ -XXX,XX +XXX,XX @@ static void sve_cont_ldst_mte_check1(SVEContLdSt *info, CPUARMState *env,
98
uintptr_t ra)
82
{
99
{
83
MPS2FPGAIO *fpgaio = opaque;
100
sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
84
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
101
- mtedesc, ra, mte_check1);
85
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
102
+ mtedesc, ra, mte_check);
86
}
103
}
87
104
88
static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
105
static void sve_cont_ldst_mte_checkN(SVEContLdSt *info, CPUARMState *env,
89
- const char *name, hwaddr size)
106
@@ -XXX,XX +XXX,XX @@ static void sve_cont_ldst_mte_checkN(SVEContLdSt *info, CPUARMState *env,
90
+ const char *name, hwaddr size,
107
uintptr_t ra)
91
+ const int *irqs)
92
{
108
{
93
SysBusDevice *s;
109
sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
94
NICInfo *nd = &nd_table[0];
110
- mtedesc, ra, mte_checkN);
95
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
111
+ mtedesc, ra, mte_check);
96
}
112
}
97
113
98
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
114
99
- const char *name, hwaddr size)
115
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const target_ulong addr,
100
+ const char *name, hwaddr size,
116
if (fault == FAULT_FIRST) {
101
+ const int *irqs)
117
/* Trapping mte check for the first-fault element. */
102
{
118
if (mtedesc) {
103
TZMPC *mpc = opaque;
119
- mte_check1(env, mtedesc, addr + mem_off, retaddr);
104
int i = mpc - &mms->ssram_mpc[0];
120
+ mte_check(env, mtedesc, addr + mem_off, retaddr);
105
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
121
}
106
}
122
107
123
/*
108
static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
124
@@ -XXX,XX +XXX,XX @@ void sve_ld1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
109
- const char *name, hwaddr size)
125
info.attrs, BP_MEM_READ, retaddr);
110
+ const char *name, hwaddr size,
126
}
111
+ const int *irqs)
127
if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) {
112
{
128
- mte_check1(env, mtedesc, addr, retaddr);
113
PL080State *dma = opaque;
129
+ mte_check(env, mtedesc, addr, retaddr);
114
int i = dma - &mms->dma[0];
130
}
115
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
131
host_fn(&scratch, reg_off, info.host);
116
}
132
} else {
117
133
@@ -XXX,XX +XXX,XX @@ void sve_ld1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
118
static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
134
BP_MEM_READ, retaddr);
119
- const char *name, hwaddr size)
135
}
120
+ const char *name, hwaddr size,
136
if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) {
121
+ const int *irqs)
137
- mte_check1(env, mtedesc, addr, retaddr);
122
{
138
+ mte_check(env, mtedesc, addr, retaddr);
123
/*
139
}
124
* The AN505 has five PL022 SPI controllers.
140
tlb_fn(env, &scratch, reg_off, addr, retaddr);
125
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_spi(MPS2TZMachineState *mms, void *opaque,
141
}
126
}
142
@@ -XXX,XX +XXX,XX @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
127
143
*/
128
static MemoryRegion *make_i2c(MPS2TZMachineState *mms, void *opaque,
144
addr = base + (off_fn(vm, reg_off) << scale);
129
- const char *name, hwaddr size)
145
if (mtedesc) {
130
+ const char *name, hwaddr size,
146
- mte_check1(env, mtedesc, addr, retaddr);
131
+ const int *irqs)
147
+ mte_check(env, mtedesc, addr, retaddr);
132
{
148
}
133
ArmSbconI2CState *i2c = opaque;
149
tlb_fn(env, vd, reg_off, addr, retaddr);
134
SysBusDevice *s;
150
135
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
151
@@ -XXX,XX +XXX,XX @@ void sve_st1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
136
continue;
152
}
153
154
if (mtedesc && arm_tlb_mte_tagged(&info.attrs)) {
155
- mte_check1(env, mtedesc, addr, retaddr);
156
+ mte_check(env, mtedesc, addr, retaddr);
157
}
137
}
158
}
138
159
i += 1;
139
- mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size);
160
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
140
+ mr = pinfo->devfn(mms, pinfo->opaque, pinfo->name, pinfo->size,
161
index XXXXXXX..XXXXXXX 100644
141
+ pinfo->irqs);
162
--- a/target/arm/translate-a64.c
142
portname = g_strdup_printf("port[%d]", port);
163
+++ b/target/arm/translate-a64.c
143
object_property_set_link(OBJECT(ppc), portname, OBJECT(mr),
164
@@ -XXX,XX +XXX,XX @@ static TCGv_i64 gen_mte_check1_mmuidx(DisasContext *s, TCGv_i64 addr,
144
&error_fatal);
165
tcg_desc = tcg_const_i32(desc);
166
167
ret = new_tmp_a64(s);
168
- gen_helper_mte_check1(ret, cpu_env, tcg_desc, addr);
169
+ gen_helper_mte_check(ret, cpu_env, tcg_desc, addr);
170
tcg_temp_free_i32(tcg_desc);
171
172
return ret;
173
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
174
tcg_desc = tcg_const_i32(desc);
175
176
ret = new_tmp_a64(s);
177
- gen_helper_mte_checkN(ret, cpu_env, tcg_desc, addr);
178
+ gen_helper_mte_check(ret, cpu_env, tcg_desc, addr);
179
tcg_temp_free_i32(tcg_desc);
180
181
return ret;
145
--
182
--
146
2.20.1
183
2.20.1
147
184
148
185
diff view generated by jsdifflib
1
The function tc6393xb_draw_graphic32() is called in exactly one place,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
so just inline the function body at its callsite. This allows us to
3
drop the template header entirely.
4
2
5
The code move includes a single added space after 'for' to fix
3
For consistency with the mte_check1 + mte_checkN merge
6
the coding style.
4
to mte_check, rename the probe function as well.
7
5
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210416183106.1516563-8-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20210215103215.4944-5-peter.maydell@linaro.org
12
---
10
---
13
hw/display/tc6393xb_template.h | 45 ----------------------------------
11
target/arm/internals.h | 2 +-
14
hw/display/tc6393xb.c | 23 ++++++++++++++---
12
target/arm/mte_helper.c | 6 +++---
15
2 files changed, 19 insertions(+), 49 deletions(-)
13
target/arm/sve_helper.c | 6 +++---
16
delete mode 100644 hw/display/tc6393xb_template.h
14
3 files changed, 7 insertions(+), 7 deletions(-)
17
15
18
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
deleted file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- a/hw/display/tc6393xb_template.h
22
+++ /dev/null
23
@@ -XXX,XX +XXX,XX @@
24
-/*
25
- * Toshiba TC6393XB I/O Controller.
26
- * Found in Sharp Zaurus SL-6000 (tosa) or some
27
- * Toshiba e-Series PDAs.
28
- *
29
- * FB support code. Based on G364 fb emulator
30
- *
31
- * Copyright (c) 2007 Hervé Poussineau
32
- *
33
- * This program is free software; you can redistribute it and/or
34
- * modify it under the terms of the GNU General Public License as
35
- * published by the Free Software Foundation; either version 2 of
36
- * the License, or (at your option) any later version.
37
- *
38
- * This program is distributed in the hope that it will be useful,
39
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
40
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41
- * GNU General Public License for more details.
42
- *
43
- * You should have received a copy of the GNU General Public License along
44
- * with this program; if not, see <http://www.gnu.org/licenses/>.
45
- */
46
-
47
-static void tc6393xb_draw_graphic32(TC6393xbState *s)
48
-{
49
- DisplaySurface *surface = qemu_console_surface(s->con);
50
- int i;
51
- uint16_t *data_buffer;
52
- uint8_t *data_display;
53
-
54
- data_buffer = s->vram_ptr;
55
- data_display = surface_data(surface);
56
- for(i = 0; i < s->scr_height; i++) {
57
- int j;
58
- for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
59
- uint16_t color = *data_buffer;
60
- uint32_t dest_color = rgb_to_pixel32(
61
- ((color & 0xf800) * 0x108) >> 11,
62
- ((color & 0x7e0) * 0x41) >> 9,
63
- ((color & 0x1f) * 0x21) >> 2
64
- );
65
- *(uint32_t *)data_display = dest_color;
66
- }
67
- }
68
-}
69
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
70
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/display/tc6393xb.c
18
--- a/target/arm/internals.h
72
+++ b/hw/display/tc6393xb.c
19
+++ b/target/arm/internals.h
73
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
20
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TCMA, 6, 2)
74
(uint32_t) addr, value & 0xff);
21
FIELD(MTEDESC, WRITE, 8, 1)
22
FIELD(MTEDESC, SIZEM1, 9, SIMD_DATA_BITS - 9) /* size - 1 */
23
24
-bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr);
25
+bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
26
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
27
28
static inline int allocation_tag_from_addr(uint64_t ptr)
29
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/mte_helper.c
32
+++ b/target/arm/mte_helper.c
33
@@ -XXX,XX +XXX,XX @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx,
34
* exception for inaccessible pages, and resolves the virtual address
35
* into the softmmu tlb.
36
*
37
- * When RA == 0, this is for mte_probe1. The page is expected to be
38
+ * When RA == 0, this is for mte_probe. The page is expected to be
39
* valid. Indicate to probe_access_flags no-fault, then assert that
40
* we received a valid page.
41
*/
42
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(mte_check)(CPUARMState *env, uint32_t desc, uint64_t ptr)
75
}
43
}
76
44
77
-#define BITS 32
45
/*
78
-#include "tc6393xb_template.h"
46
- * No-fault version of mte_check1, to be used by SVE for MemSingleNF.
79
-
47
+ * No-fault version of mte_check, to be used by SVE for MemSingleNF.
80
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
48
* Returns false if the access is Checked and the check failed. This
49
* is only intended to probe the tag -- the validity of the page must
50
* be checked beforehand.
51
*/
52
-bool mte_probe1(CPUARMState *env, uint32_t desc, uint64_t ptr)
53
+bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr)
81
{
54
{
82
- tc6393xb_draw_graphic32(s);
55
uint64_t fault;
83
+ DisplaySurface *surface = qemu_console_surface(s->con);
56
int ret = mte_probe_int(env, desc, ptr, 0, &fault);
84
+ int i;
57
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
85
+ uint16_t *data_buffer;
58
index XXXXXXX..XXXXXXX 100644
86
+ uint8_t *data_display;
59
--- a/target/arm/sve_helper.c
87
+
60
+++ b/target/arm/sve_helper.c
88
+ data_buffer = s->vram_ptr;
61
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const target_ulong addr,
89
+ data_display = surface_data(surface);
62
/* Watchpoint hit, see below. */
90
+ for (i = 0; i < s->scr_height; i++) {
63
goto do_fault;
91
+ int j;
64
}
92
+ for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
65
- if (mtedesc && !mte_probe1(env, mtedesc, addr + mem_off)) {
93
+ uint16_t color = *data_buffer;
66
+ if (mtedesc && !mte_probe(env, mtedesc, addr + mem_off)) {
94
+ uint32_t dest_color = rgb_to_pixel32(
67
goto do_fault;
95
+ ((color & 0xf800) * 0x108) >> 11,
68
}
96
+ ((color & 0x7e0) * 0x41) >> 9,
69
/*
97
+ ((color & 0x1f) * 0x21) >> 2
70
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r(CPUARMState *env, void *vg, const target_ulong addr,
98
+ );
71
& BP_MEM_READ)) {
99
+ *(uint32_t *)data_display = dest_color;
72
goto do_fault;
100
+ }
73
}
101
+ }
74
- if (mtedesc && !mte_probe1(env, mtedesc, addr + mem_off)) {
102
dpy_gfx_update_full(s->con);
75
+ if (mtedesc && !mte_probe(env, mtedesc, addr + mem_off)) {
103
}
76
goto do_fault;
77
}
78
host_fn(vd, reg_off, host + mem_off);
79
@@ -XXX,XX +XXX,XX @@ void sve_ldff1_z(CPUARMState *env, void *vd, uint64_t *vg, void *vm,
80
}
81
if (mtedesc &&
82
arm_tlb_mte_tagged(&info.attrs) &&
83
- !mte_probe1(env, mtedesc, addr)) {
84
+ !mte_probe(env, mtedesc, addr)) {
85
goto fault;
86
}
104
87
105
--
88
--
106
2.20.1
89
2.20.1
107
90
108
91
diff view generated by jsdifflib
1
The macro draw_line_func is used only once; just expand it.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Now that mte_check1 and mte_checkN have been merged, we can
4
merge sve_cont_ldst_mte_check1 and sve_cont_ldst_mte_checkN.
5
6
Which means that we can eliminate the function pointer into
7
sve_ldN_r and sve_stN_r, calling sve_cont_ldst_mte_check directly.
8
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210416183106.1516563-9-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210215103215.4944-10-peter.maydell@linaro.org
7
---
13
---
8
hw/display/omap_lcdc.c | 4 +---
14
target/arm/sve_helper.c | 84 +++++++++++++----------------------------
9
1 file changed, 1 insertion(+), 3 deletions(-)
15
1 file changed, 26 insertions(+), 58 deletions(-)
10
16
11
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
17
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/display/omap_lcdc.c
19
--- a/target/arm/sve_helper.c
14
+++ b/hw/display/omap_lcdc.c
20
+++ b/target/arm/sve_helper.c
15
@@ -XXX,XX +XXX,XX @@ static void omap_lcd_interrupts(struct omap_lcd_panel_s *s)
21
@@ -XXX,XX +XXX,XX @@ static void sve_cont_ldst_watchpoints(SVEContLdSt *info, CPUARMState *env,
16
qemu_irq_lower(s->irq);
22
#endif
17
}
23
}
18
24
19
-#define draw_line_func drawfn
25
-typedef uint64_t mte_check_fn(CPUARMState *, uint32_t, uint64_t, uintptr_t);
26
-
27
-static inline QEMU_ALWAYS_INLINE
28
-void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
29
- uint64_t *vg, target_ulong addr, int esize,
30
- int msize, uint32_t mtedesc, uintptr_t ra,
31
- mte_check_fn *check)
32
+static void sve_cont_ldst_mte_check(SVEContLdSt *info, CPUARMState *env,
33
+ uint64_t *vg, target_ulong addr, int esize,
34
+ int msize, uint32_t mtedesc, uintptr_t ra)
35
{
36
intptr_t mem_off, reg_off, reg_last;
37
38
@@ -XXX,XX +XXX,XX @@ void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
39
uint64_t pg = vg[reg_off >> 6];
40
do {
41
if ((pg >> (reg_off & 63)) & 1) {
42
- check(env, mtedesc, addr, ra);
43
+ mte_check(env, mtedesc, addr, ra);
44
}
45
reg_off += esize;
46
mem_off += msize;
47
@@ -XXX,XX +XXX,XX @@ void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
48
uint64_t pg = vg[reg_off >> 6];
49
do {
50
if ((pg >> (reg_off & 63)) & 1) {
51
- check(env, mtedesc, addr, ra);
52
+ mte_check(env, mtedesc, addr, ra);
53
}
54
reg_off += esize;
55
mem_off += msize;
56
@@ -XXX,XX +XXX,XX @@ void sve_cont_ldst_mte_check_int(SVEContLdSt *info, CPUARMState *env,
57
}
58
}
59
60
-typedef void sve_cont_ldst_mte_check_fn(SVEContLdSt *info, CPUARMState *env,
61
- uint64_t *vg, target_ulong addr,
62
- int esize, int msize, uint32_t mtedesc,
63
- uintptr_t ra);
64
-
65
-static void sve_cont_ldst_mte_check1(SVEContLdSt *info, CPUARMState *env,
66
- uint64_t *vg, target_ulong addr,
67
- int esize, int msize, uint32_t mtedesc,
68
- uintptr_t ra)
69
-{
70
- sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
71
- mtedesc, ra, mte_check);
72
-}
73
-
74
-static void sve_cont_ldst_mte_checkN(SVEContLdSt *info, CPUARMState *env,
75
- uint64_t *vg, target_ulong addr,
76
- int esize, int msize, uint32_t mtedesc,
77
- uintptr_t ra)
78
-{
79
- sve_cont_ldst_mte_check_int(info, env, vg, addr, esize, msize,
80
- mtedesc, ra, mte_check);
81
-}
82
-
20
-
83
-
21
/*
84
/*
22
* 2-bit colour
85
* Common helper for all contiguous 1,2,3,4-register predicated stores.
23
*/
86
*/
24
@@ -XXX,XX +XXX,XX @@ static void omap_update_display(void *opaque)
87
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r(CPUARMState *env, uint64_t *vg, const target_ulong addr,
88
uint32_t desc, const uintptr_t retaddr,
89
const int esz, const int msz, const int N, uint32_t mtedesc,
90
sve_ldst1_host_fn *host_fn,
91
- sve_ldst1_tlb_fn *tlb_fn,
92
- sve_cont_ldst_mte_check_fn *mte_check_fn)
93
+ sve_ldst1_tlb_fn *tlb_fn)
25
{
94
{
26
struct omap_lcd_panel_s *omap_lcd = (struct omap_lcd_panel_s *) opaque;
95
const unsigned rd = simd_data(desc);
27
DisplaySurface *surface;
96
const intptr_t reg_max = simd_oprsz(desc);
28
- draw_line_func draw_line;
97
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r(CPUARMState *env, uint64_t *vg, const target_ulong addr,
29
+ drawfn draw_line;
98
* Handle mte checks for all active elements.
30
int size, height, first, last;
99
* Since TBI must be set for MTE, !mtedesc => !mte_active.
31
int width, linesize, step, bpp, frame_offset;
100
*/
32
hwaddr frame_base;
101
- if (mte_check_fn && mtedesc) {
102
- mte_check_fn(&info, env, vg, addr, 1 << esz, N << msz,
103
- mtedesc, retaddr);
104
+ if (mtedesc) {
105
+ sve_cont_ldst_mte_check(&info, env, vg, addr, 1 << esz, N << msz,
106
+ mtedesc, retaddr);
107
}
108
109
flags = info.page[0].flags | info.page[1].flags;
110
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
111
mtedesc = 0;
112
}
113
114
- sve_ldN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn,
115
- N == 1 ? sve_cont_ldst_mte_check1 : sve_cont_ldst_mte_checkN);
116
+ sve_ldN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn);
117
}
118
119
#define DO_LD1_1(NAME, ESZ) \
120
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_##NAME##_r)(CPUARMState *env, void *vg, \
121
target_ulong addr, uint32_t desc) \
122
{ \
123
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MO_8, 1, 0, \
124
- sve_##NAME##_host, sve_##NAME##_tlb, NULL); \
125
+ sve_##NAME##_host, sve_##NAME##_tlb); \
126
} \
127
void HELPER(sve_##NAME##_r_mte)(CPUARMState *env, void *vg, \
128
target_ulong addr, uint32_t desc) \
129
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_##NAME##_le_r)(CPUARMState *env, void *vg, \
130
target_ulong addr, uint32_t desc) \
131
{ \
132
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, 0, \
133
- sve_##NAME##_le_host, sve_##NAME##_le_tlb, NULL); \
134
+ sve_##NAME##_le_host, sve_##NAME##_le_tlb); \
135
} \
136
void HELPER(sve_##NAME##_be_r)(CPUARMState *env, void *vg, \
137
target_ulong addr, uint32_t desc) \
138
{ \
139
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, 0, \
140
- sve_##NAME##_be_host, sve_##NAME##_be_tlb, NULL); \
141
+ sve_##NAME##_be_host, sve_##NAME##_be_tlb); \
142
} \
143
void HELPER(sve_##NAME##_le_r_mte)(CPUARMState *env, void *vg, \
144
- target_ulong addr, uint32_t desc) \
145
+ target_ulong addr, uint32_t desc) \
146
{ \
147
sve_ldN_r_mte(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, \
148
sve_##NAME##_le_host, sve_##NAME##_le_tlb); \
149
} \
150
void HELPER(sve_##NAME##_be_r_mte)(CPUARMState *env, void *vg, \
151
- target_ulong addr, uint32_t desc) \
152
+ target_ulong addr, uint32_t desc) \
153
{ \
154
sve_ldN_r_mte(env, vg, addr, desc, GETPC(), ESZ, MSZ, 1, \
155
sve_##NAME##_be_host, sve_##NAME##_be_tlb); \
156
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_ld##N##bb_r)(CPUARMState *env, void *vg, \
157
target_ulong addr, uint32_t desc) \
158
{ \
159
sve_ldN_r(env, vg, addr, desc, GETPC(), MO_8, MO_8, N, 0, \
160
- sve_ld1bb_host, sve_ld1bb_tlb, NULL); \
161
+ sve_ld1bb_host, sve_ld1bb_tlb); \
162
} \
163
void HELPER(sve_ld##N##bb_r_mte)(CPUARMState *env, void *vg, \
164
target_ulong addr, uint32_t desc) \
165
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_ld##N##SUFF##_le_r)(CPUARMState *env, void *vg, \
166
target_ulong addr, uint32_t desc) \
167
{ \
168
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, ESZ, N, 0, \
169
- sve_ld1##SUFF##_le_host, sve_ld1##SUFF##_le_tlb, NULL); \
170
+ sve_ld1##SUFF##_le_host, sve_ld1##SUFF##_le_tlb); \
171
} \
172
void HELPER(sve_ld##N##SUFF##_be_r)(CPUARMState *env, void *vg, \
173
target_ulong addr, uint32_t desc) \
174
{ \
175
sve_ldN_r(env, vg, addr, desc, GETPC(), ESZ, ESZ, N, 0, \
176
- sve_ld1##SUFF##_be_host, sve_ld1##SUFF##_be_tlb, NULL); \
177
+ sve_ld1##SUFF##_be_host, sve_ld1##SUFF##_be_tlb); \
178
} \
179
void HELPER(sve_ld##N##SUFF##_le_r_mte)(CPUARMState *env, void *vg, \
180
target_ulong addr, uint32_t desc) \
181
@@ -XXX,XX +XXX,XX @@ void sve_stN_r(CPUARMState *env, uint64_t *vg, target_ulong addr,
182
uint32_t desc, const uintptr_t retaddr,
183
const int esz, const int msz, const int N, uint32_t mtedesc,
184
sve_ldst1_host_fn *host_fn,
185
- sve_ldst1_tlb_fn *tlb_fn,
186
- sve_cont_ldst_mte_check_fn *mte_check_fn)
187
+ sve_ldst1_tlb_fn *tlb_fn)
188
{
189
const unsigned rd = simd_data(desc);
190
const intptr_t reg_max = simd_oprsz(desc);
191
@@ -XXX,XX +XXX,XX @@ void sve_stN_r(CPUARMState *env, uint64_t *vg, target_ulong addr,
192
* Handle mte checks for all active elements.
193
* Since TBI must be set for MTE, !mtedesc => !mte_active.
194
*/
195
- if (mte_check_fn && mtedesc) {
196
- mte_check_fn(&info, env, vg, addr, 1 << esz, N << msz,
197
- mtedesc, retaddr);
198
+ if (mtedesc) {
199
+ sve_cont_ldst_mte_check(&info, env, vg, addr, 1 << esz, N << msz,
200
+ mtedesc, retaddr);
201
}
202
203
flags = info.page[0].flags | info.page[1].flags;
204
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
205
mtedesc = 0;
206
}
207
208
- sve_stN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn,
209
- N == 1 ? sve_cont_ldst_mte_check1 : sve_cont_ldst_mte_checkN);
210
+ sve_stN_r(env, vg, addr, desc, ra, esz, msz, N, mtedesc, host_fn, tlb_fn);
211
}
212
213
#define DO_STN_1(N, NAME, ESZ) \
214
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_st##N##NAME##_r)(CPUARMState *env, void *vg, \
215
target_ulong addr, uint32_t desc) \
216
{ \
217
sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MO_8, N, 0, \
218
- sve_st1##NAME##_host, sve_st1##NAME##_tlb, NULL); \
219
+ sve_st1##NAME##_host, sve_st1##NAME##_tlb); \
220
} \
221
void HELPER(sve_st##N##NAME##_r_mte)(CPUARMState *env, void *vg, \
222
target_ulong addr, uint32_t desc) \
223
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_st##N##NAME##_le_r)(CPUARMState *env, void *vg, \
224
target_ulong addr, uint32_t desc) \
225
{ \
226
sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, N, 0, \
227
- sve_st1##NAME##_le_host, sve_st1##NAME##_le_tlb, NULL); \
228
+ sve_st1##NAME##_le_host, sve_st1##NAME##_le_tlb); \
229
} \
230
void HELPER(sve_st##N##NAME##_be_r)(CPUARMState *env, void *vg, \
231
target_ulong addr, uint32_t desc) \
232
{ \
233
sve_stN_r(env, vg, addr, desc, GETPC(), ESZ, MSZ, N, 0, \
234
- sve_st1##NAME##_be_host, sve_st1##NAME##_be_tlb, NULL); \
235
+ sve_st1##NAME##_be_host, sve_st1##NAME##_be_tlb); \
236
} \
237
void HELPER(sve_st##N##NAME##_le_r_mte)(CPUARMState *env, void *vg, \
238
target_ulong addr, uint32_t desc) \
33
--
239
--
34
2.20.1
240
2.20.1
35
241
36
242
diff view generated by jsdifflib
1
In the mps2-tz board code, we handle devices whose interrupt lines
1
From: Richard Henderson <richard.henderson@linaro.org>
2
must be wired to all CPUs by creating IRQ splitter devices for the
3
AN521, because it has 2 CPUs, but wiring the device IRQ directly to
4
the SSE/IoTKit input for the AN505, which has only 1 CPU.
5
2
6
We can avoid making an explicit check on the board type constant by
3
The log2_esize parameter is not used except trivially.
7
instead creating and using the IRQ splitters for any board with more
4
Drop the parameter and the deferral to gen_mte_check1.
8
than 1 CPU. This avoids having to add extra cases to the
9
conditionals every time we add new boards.
10
5
6
This fixes a bug in that the parameters as documented
7
in the header file were the reverse from those in the
8
implementation. Which meant that translate-sve.c was
9
passing the parameters in the wrong order.
10
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210416183106.1516563-10-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20210215115138.20465-9-peter.maydell@linaro.org
15
---
15
---
16
hw/arm/mps2-tz.c | 19 +++++++++----------
16
target/arm/translate-a64.h | 2 +-
17
1 file changed, 9 insertions(+), 10 deletions(-)
17
target/arm/translate-a64.c | 15 +++++++--------
18
target/arm/translate-sve.c | 4 ++--
19
3 files changed, 10 insertions(+), 11 deletions(-)
18
20
19
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
21
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
20
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/mps2-tz.c
23
--- a/target/arm/translate-a64.h
22
+++ b/hw/arm/mps2-tz.c
24
+++ b/target/arm/translate-a64.h
23
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
25
@@ -XXX,XX +XXX,XX @@ TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr);
24
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
26
TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
27
bool tag_checked, int log2_size);
28
TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
29
- bool tag_checked, int count, int log2_esize);
30
+ bool tag_checked, int size);
31
32
/* We should have at some point before trying to access an FP register
33
* done the necessary access check, so assert that
34
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/arm/translate-a64.c
37
+++ b/target/arm/translate-a64.c
38
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
39
* For MTE, check multiple logical sequential accesses.
40
*/
41
TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
42
- bool tag_checked, int log2_esize, int total_size)
43
+ bool tag_checked, int size)
25
{
44
{
26
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
45
- if (tag_checked && s->mte_active[0] && total_size != (1 << log2_esize)) {
27
- MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
46
+ if (tag_checked && s->mte_active[0]) {
28
+ MachineClass *mc = MACHINE_GET_CLASS(mms);
47
TCGv_i32 tcg_desc;
29
48
TCGv_i64 ret;
30
assert(irqno < MPS2TZ_NUMIRQ);
49
int desc = 0;
31
50
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
32
- switch (mmc->fpga_type) {
51
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
33
- case FPGA_AN505:
52
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
34
- return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
53
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
35
- case FPGA_AN521:
54
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, total_size - 1);
36
+ if (mc->max_cpus > 1) {
55
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, size - 1);
37
return qdev_get_gpio_in(DEVICE(&mms->cpu_irq_splitter[irqno]), 0);
56
tcg_desc = tcg_const_i32(desc);
38
- default:
57
39
- g_assert_not_reached();
58
ret = new_tmp_a64(s);
40
+ } else {
59
@@ -XXX,XX +XXX,XX @@ TCGv_i64 gen_mte_checkN(DisasContext *s, TCGv_i64 addr, bool is_write,
41
+ return qdev_get_gpio_in_named(DEVICE(&mms->iotkit), "EXP_IRQ", irqno);
60
61
return ret;
42
}
62
}
63
- return gen_mte_check1(s, addr, is_write, tag_checked, log2_esize);
64
+ return clean_data_tbi(s, addr);
43
}
65
}
44
66
45
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
67
typedef struct DisasCompare64 {
46
sysbus_realize(SYS_BUS_DEVICE(&mms->iotkit), &error_fatal);
68
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
69
}
70
71
clean_addr = gen_mte_checkN(s, dirty_addr, !is_load,
72
- (wback || rn != 31) && !set_tag,
73
- size, 2 << size);
74
+ (wback || rn != 31) && !set_tag, 2 << size);
75
76
if (is_vector) {
77
if (is_load) {
78
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
79
* promote consecutive little-endian elements below.
80
*/
81
clean_addr = gen_mte_checkN(s, tcg_rn, is_store, is_postidx || rn != 31,
82
- size, total);
83
+ total);
47
84
48
/*
85
/*
49
- * The AN521 needs us to create splitters to feed the IRQ inputs
86
* Consecutive little-endian elements from a single register
50
- * for each CPU in the SSE-200 from each device in the board.
87
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
51
+ * If this board has more than one CPU, then we need to create splitters
88
tcg_rn = cpu_reg_sp(s, rn);
52
+ * to feed the IRQ inputs for each CPU in the SSE from each device in the
89
53
+ * board. If there is only one CPU, we can just wire the device IRQ
90
clean_addr = gen_mte_checkN(s, tcg_rn, !is_load, is_postidx || rn != 31,
54
+ * directly to the SSE's IRQ input.
91
- scale, total);
55
*/
92
+ total);
56
- if (mmc->fpga_type == FPGA_AN521) {
93
57
+ if (mc->max_cpus > 1) {
94
tcg_ebytes = tcg_const_i64(1 << scale);
58
for (i = 0; i < MPS2TZ_NUMIRQ; i++) {
95
for (xs = 0; xs < selem; xs++) {
59
char *name = g_strdup_printf("mps2-irq-splitter%d", i);
96
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
60
SplitIRQ *splitter = &mms->cpu_irq_splitter[i];
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/arm/translate-sve.c
99
+++ b/target/arm/translate-sve.c
100
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
101
102
dirty_addr = tcg_temp_new_i64();
103
tcg_gen_addi_i64(dirty_addr, cpu_reg_sp(s, rn), imm);
104
- clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len, MO_8);
105
+ clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len);
106
tcg_temp_free_i64(dirty_addr);
107
108
/*
109
@@ -XXX,XX +XXX,XX @@ static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
110
111
dirty_addr = tcg_temp_new_i64();
112
tcg_gen_addi_i64(dirty_addr, cpu_reg_sp(s, rn), imm);
113
- clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len, MO_8);
114
+ clean_addr = gen_mte_checkN(s, dirty_addr, false, rn != 31, len);
115
tcg_temp_free_i64(dirty_addr);
116
117
/* Note that unpredicated load/store of vector/predicate registers
61
--
118
--
62
2.20.1
119
2.20.1
63
120
64
121
diff view generated by jsdifflib
1
The AN524 version of the SCC interface has different behaviour for
1
From: Richard Henderson <richard.henderson@linaro.org>
2
some of the CFG registers; implement it.
3
2
4
Each board in this family can have minor differences in the meaning
3
The encoding of size = 2 and size = 3 had the incorrect decode
5
of the CFG registers, so rather than trying to specify all the
4
for align, overlapping the stride field. This error was hidden
6
possible semantics via individual device properties, we make the
5
by what should have been unnecessary masking in translate.
7
behaviour conditional on the part-number field of the SCC_ID register
8
which the board code already passes us.
9
6
10
For the AN524, the differences are:
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
* CFG3 is reserved rather than being board switches
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
* CFG5 is a new register ("ACLK Frequency in Hz")
9
Message-id: 20210419202257.161730-2-richard.henderson@linaro.org
13
* CFG6 is a new register ("Clock divider for BRAM")
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/neon-ls.decode | 4 ++--
13
target/arm/translate-neon.c.inc | 4 ++--
14
2 files changed, 4 insertions(+), 4 deletions(-)
14
15
15
We implement both of the new registers as reads-as-written.
16
diff --git a/target/arm/neon-ls.decode b/target/arm/neon-ls.decode
16
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20210215115138.20465-11-peter.maydell@linaro.org
20
---
21
include/hw/misc/mps2-scc.h | 3 ++
22
hw/misc/mps2-scc.c | 71 ++++++++++++++++++++++++++++++++++++--
23
2 files changed, 72 insertions(+), 2 deletions(-)
24
25
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/misc/mps2-scc.h
18
--- a/target/arm/neon-ls.decode
28
+++ b/include/hw/misc/mps2-scc.h
19
+++ b/target/arm/neon-ls.decode
29
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
20
@@ -XXX,XX +XXX,XX @@ VLD_all_lanes 1111 0100 1 . 1 0 rn:4 .... 11 n:2 size:2 t:1 a:1 rm:4 \
30
21
31
uint32_t cfg0;
22
VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 00 n:2 reg_idx:3 align:1 rm:4 \
32
uint32_t cfg1;
23
vd=%vd_dp size=0 stride=1
33
+ uint32_t cfg2;
24
-VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 align:2 rm:4 \
34
uint32_t cfg4;
25
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 01 n:2 reg_idx:2 . align:1 rm:4 \
35
+ uint32_t cfg5;
26
vd=%vd_dp size=1 stride=%imm1_5_p1
36
+ uint32_t cfg6;
27
-VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 align:3 rm:4 \
37
uint32_t cfgdata_rtn;
28
+VLDST_single 1111 0100 1 . l:1 0 rn:4 .... 10 n:2 reg_idx:1 . align:2 rm:4 \
38
uint32_t cfgdata_out;
29
vd=%vd_dp size=2 stride=%imm1_6_p1
39
uint32_t cfgctrl;
30
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
40
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
41
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/misc/mps2-scc.c
32
--- a/target/arm/translate-neon.c.inc
43
+++ b/hw/misc/mps2-scc.c
33
+++ b/target/arm/translate-neon.c.inc
44
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
45
35
switch (nregs) {
46
REG32(CFG0, 0)
36
case 1:
47
REG32(CFG1, 4)
37
if (((a->align & (1 << a->size)) != 0) ||
48
+REG32(CFG2, 8)
38
- (a->size == 2 && ((a->align & 3) == 1 || (a->align & 3) == 2))) {
49
REG32(CFG3, 0xc)
39
+ (a->size == 2 && (a->align == 1 || a->align == 2))) {
50
REG32(CFG4, 0x10)
40
return false;
51
+REG32(CFG5, 0x14)
52
+REG32(CFG6, 0x18)
53
REG32(CFGDATA_RTN, 0xa0)
54
REG32(CFGDATA_OUT, 0xa4)
55
REG32(CFGCTRL, 0xa8)
56
@@ -XXX,XX +XXX,XX @@ REG32(DLL, 0x100)
57
REG32(AID, 0xFF8)
58
REG32(ID, 0xFFC)
59
60
+static int scc_partno(MPS2SCC *s)
61
+{
62
+ /* Return the partno field of the SCC_ID (0x524, 0x511, etc) */
63
+ return extract32(s->id, 4, 8);
64
+}
65
+
66
/* Handle a write via the SYS_CFG channel to the specified function/device.
67
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
68
*/
69
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
70
case A_CFG1:
71
r = s->cfg1;
72
break;
73
+ case A_CFG2:
74
+ if (scc_partno(s) != 0x524) {
75
+ /* CFG2 reserved on other boards */
76
+ goto bad_offset;
77
+ }
78
+ r = s->cfg2;
79
+ break;
80
case A_CFG3:
81
+ if (scc_partno(s) == 0x524) {
82
+ /* CFG3 reserved on AN524 */
83
+ goto bad_offset;
84
+ }
85
/* These are user-settable DIP switches on the board. We don't
86
* model that, so just return zeroes.
87
*/
88
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
89
case A_CFG4:
90
r = s->cfg4;
91
break;
92
+ case A_CFG5:
93
+ if (scc_partno(s) != 0x524) {
94
+ /* CFG5 reserved on other boards */
95
+ goto bad_offset;
96
+ }
97
+ r = s->cfg5;
98
+ break;
99
+ case A_CFG6:
100
+ if (scc_partno(s) != 0x524) {
101
+ /* CFG6 reserved on other boards */
102
+ goto bad_offset;
103
+ }
104
+ r = s->cfg6;
105
+ break;
106
case A_CFGDATA_RTN:
107
r = s->cfgdata_rtn;
108
break;
109
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
110
r = s->id;
111
break;
112
default:
113
+ bad_offset:
114
qemu_log_mask(LOG_GUEST_ERROR,
115
"MPS2 SCC read: bad offset %x\n", (int) offset);
116
r = 0;
117
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
118
led_set_state(s->led[i], extract32(value, i, 1));
119
}
41
}
120
break;
42
break;
121
+ case A_CFG2:
43
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
122
+ if (scc_partno(s) != 0x524) {
44
}
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;
45
break;
148
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
46
case 4:
149
s->dll = deposit32(s->dll, 24, 8, extract32(value, 24, 8));
47
- if ((a->size == 2) && ((a->align & 3) == 3)) {
48
+ if (a->size == 2 && a->align == 3) {
49
return false;
50
}
150
break;
51
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),
184
--
52
--
185
2.20.1
53
2.20.1
186
54
187
55
diff view generated by jsdifflib
1
The AN524 has a USB controller (an ISP1763); we don't have a model of
1
From: Richard Henderson <richard.henderson@linaro.org>
2
it but we should provide a stub "unimplemented-device" for it. This
3
is slightly complicated because the USB controller shares a PPC port
4
with the ethernet controller.
5
2
6
Implement a make_* function which provides creates a container
3
We're about to rearrange the macro expansion surrounding tbflags,
7
MemoryRegion with both the ethernet controller and an
4
and this field name will be expanded using the bit definition of
8
unimplemented-device stub for the USB controller.
5
the same name, resulting in a token pasting error.
9
6
7
So SCTLR_B -> SCTLR__B in the 3 uses, and document it.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210419202257.161730-3-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210215115138.20465-22-peter.maydell@linaro.org
14
---
13
---
15
hw/arm/mps2-tz.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
14
target/arm/cpu.h | 2 +-
16
1 file changed, 47 insertions(+), 1 deletion(-)
15
target/arm/helper.c | 2 +-
16
target/arm/translate.c | 2 +-
17
3 files changed, 3 insertions(+), 3 deletions(-)
17
18
18
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/mps2-tz.c
21
--- a/target/arm/cpu.h
21
+++ b/hw/arm/mps2-tz.c
22
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
23
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, VECSTRIDE, 12, 2) /* Not cached. */
23
24
*/
24
ARMSSE iotkit;
25
FIELD(TBFLAG_A32, XSCALE_CPAR, 12, 2)
25
MemoryRegion ram[MPS2TZ_RAM_MAX];
26
FIELD(TBFLAG_A32, VFPEN, 14, 1) /* Partially cached, minus FPEXC. */
26
+ MemoryRegion eth_usb_container;
27
-FIELD(TBFLAG_A32, SCTLR_B, 15, 1)
27
+
28
+FIELD(TBFLAG_A32, SCTLR__B, 15, 1) /* Cannot overlap with SCTLR_B */
28
MPS2SCC scc;
29
FIELD(TBFLAG_A32, HSTR_ACTIVE, 16, 1)
29
MPS2FPGAIO fpgaio;
30
/*
30
TZPPC ppc[5];
31
* Indicates whether cp register reads and writes by guest code should access
31
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
UnimplementedDeviceState gfx;
33
index XXXXXXX..XXXXXXX 100644
33
UnimplementedDeviceState cldc;
34
--- a/target/arm/helper.c
34
UnimplementedDeviceState rtc;
35
+++ b/target/arm/helper.c
35
+ UnimplementedDeviceState usb;
36
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
36
PL080State dma[4];
37
bool sctlr_b = arm_sctlr_b(env);
37
TZMSC msc[4];
38
38
CMSDKAPBUART uart[6];
39
if (sctlr_b) {
39
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
40
- flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, 1);
40
return sysbus_mmio_get_region(s, 0);
41
+ flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR__B, 1);
41
}
42
}
42
43
if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
43
+static MemoryRegion *make_eth_usb(MPS2TZMachineState *mms, void *opaque,
44
flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
44
+ const char *name, hwaddr size,
45
diff --git a/target/arm/translate.c b/target/arm/translate.c
45
+ const int *irqs)
46
index XXXXXXX..XXXXXXX 100644
46
+{
47
--- a/target/arm/translate.c
47
+ /*
48
+++ b/target/arm/translate.c
48
+ * The AN524 makes the ethernet and USB share a PPC port.
49
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
49
+ * irqs[] is the ethernet IRQ.
50
FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
50
+ */
51
dc->debug_target_el =
51
+ SysBusDevice *s;
52
FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
52
+ NICInfo *nd = &nd_table[0];
53
- dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
53
+
54
+ dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR__B);
54
+ memory_region_init(&mms->eth_usb_container, OBJECT(mms),
55
dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
55
+ "mps2-tz-eth-usb-container", 0x200000);
56
dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
56
+
57
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
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
+ */
61
+ qemu_check_nic_model(nd, "lan9118");
62
+ mms->lan9118 = qdev_new(TYPE_LAN9118);
63
+ qdev_set_nic_properties(mms->lan9118, nd);
64
+
65
+ s = SYS_BUS_DEVICE(mms->lan9118);
66
+ sysbus_realize_and_unref(s, &error_fatal);
67
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
68
+
69
+ memory_region_add_subregion(&mms->eth_usb_container,
70
+ 0, sysbus_mmio_get_region(s, 0));
71
+
72
+ /* The USB OTG controller is an ISP1763; we don't have a model of it. */
73
+ object_initialize_child(OBJECT(mms), "usb-otg",
74
+ &mms->usb, TYPE_UNIMPLEMENTED_DEVICE);
75
+ qdev_prop_set_string(DEVICE(&mms->usb), "name", "usb-otg");
76
+ qdev_prop_set_uint64(DEVICE(&mms->usb), "size", 0x100000);
77
+ s = SYS_BUS_DEVICE(&mms->usb);
78
+ sysbus_realize(s, &error_fatal);
79
+
80
+ memory_region_add_subregion(&mms->eth_usb_container,
81
+ 0x100000, sysbus_mmio_get_region(s, 0));
82
+
83
+ return &mms->eth_usb_container;
84
+}
85
+
86
static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
87
const char *name, hwaddr size,
88
const int *irqs)
89
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
90
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x41101000, 0x1000 },
91
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x41102000, 0x1000 },
92
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x41103000, 0x1000 },
93
- { "eth", make_eth_dev, NULL, 0x41400000, 0x100000, { 48 } },
94
+ { "eth-usb", make_eth_usb, NULL, 0x41400000, 0x200000, { 48 } },
95
},
96
},
97
};
98
--
58
--
99
2.20.1
59
2.20.1
100
60
101
61
diff view generated by jsdifflib
1
The AN505 and AN521 don't have any read-only memory, but the AN524
1
From: Richard Henderson <richard.henderson@linaro.org>
2
does; add a flag to ROMInfo to mark a region as ROM.
3
2
3
We're about to rearrange the macro expansion surrounding tbflags,
4
and this field name will be expanded using the bit definition of
5
the same name, resulting in a token pasting error.
6
7
So PSTATE_SS -> PSTATE__SS in the uses, and document it.
8
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210419202257.161730-4-richard.henderson@linaro.org
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215115138.20465-19-peter.maydell@linaro.org
7
---
13
---
8
hw/arm/mps2-tz.c | 6 ++++++
14
target/arm/cpu.h | 2 +-
9
1 file changed, 6 insertions(+)
15
target/arm/helper.c | 4 ++--
16
target/arm/translate-a64.c | 2 +-
17
target/arm/translate.c | 2 +-
18
4 files changed, 5 insertions(+), 5 deletions(-)
10
19
11
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/mps2-tz.c
22
--- a/target/arm/cpu.h
14
+++ b/hw/arm/mps2-tz.c
23
+++ b/target/arm/cpu.h
15
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
24
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
16
* Flag values:
17
* IS_ALIAS: this RAM area is an alias to the upstream end of the
18
* MPC specified by its .mpc value
19
+ * IS_ROM: this RAM area is read-only
20
*/
25
*/
21
#define IS_ALIAS 1
26
FIELD(TBFLAG_ANY, AARCH64_STATE, 31, 1)
22
+#define IS_ROM 2
27
FIELD(TBFLAG_ANY, SS_ACTIVE, 30, 1)
23
28
-FIELD(TBFLAG_ANY, PSTATE_SS, 29, 1) /* Not cached. */
24
struct MPS2TZMachineClass {
29
+FIELD(TBFLAG_ANY, PSTATE__SS, 29, 1) /* Not cached. */
25
MachineClass parent;
30
FIELD(TBFLAG_ANY, BE_DATA, 28, 1)
26
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
31
FIELD(TBFLAG_ANY, MMUIDX, 24, 4)
27
if (raminfo->mrindex < 0) {
32
/* Target EL if we take a floating-point-disabled exception */
28
/* Means this RAMInfo is for QEMU's "system memory" */
33
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
MachineState *machine = MACHINE(mms);
34
index XXXXXXX..XXXXXXX 100644
30
+ assert(!(raminfo->flags & IS_ROM));
35
--- a/target/arm/helper.c
31
return machine->ram;
36
+++ b/target/arm/helper.c
37
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
38
* 0 x Inactive (the TB flag for SS is always 0)
39
* 1 0 Active-pending
40
* 1 1 Active-not-pending
41
- * SS_ACTIVE is set in hflags; PSTATE_SS is computed every TB.
42
+ * SS_ACTIVE is set in hflags; PSTATE__SS is computed every TB.
43
*/
44
if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE) &&
45
(env->pstate & PSTATE_SS)) {
46
- flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
47
+ flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE__SS, 1);
32
}
48
}
33
49
34
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS2TZMachineState *mms,
50
*pflags = flags;
35
51
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
36
memory_region_init_ram(ram, NULL, raminfo->name,
52
index XXXXXXX..XXXXXXX 100644
37
raminfo->size, &error_fatal);
53
--- a/target/arm/translate-a64.c
38
+ if (raminfo->flags & IS_ROM) {
54
+++ b/target/arm/translate-a64.c
39
+ memory_region_set_readonly(ram, true);
55
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
40
+ }
56
* end the TB
41
return ram;
57
*/
42
}
58
dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
43
59
- dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
60
+ dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE__SS);
61
dc->is_ldex = false;
62
dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
63
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate.c
67
+++ b/target/arm/translate.c
68
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
69
* end the TB
70
*/
71
dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
72
- dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
73
+ dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE__SS);
74
dc->is_ldex = false;
75
76
dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
44
--
77
--
45
2.20.1
78
2.20.1
46
79
47
80
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Always perform one call instead of two for 16-byte operands.
3
We're about to split tbflags into two parts. These macros
4
Use byte loads/stores directly into the vector register file
4
will ensure that the correct part is used with the correct
5
instead of extractions and deposits to a 64-bit local variable.
5
set of bits.
6
6
7
In order to easily receive pointers into the vector register file,
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
convert the helper to the gvec out-of-line signature. Move the
9
helper into vec_helper.c, where it can make use of H1 and clear_tail.
10
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20210419202257.161730-5-richard.henderson@linaro.org
13
Tested-by: Alex Bennée <alex.bennee@linaro.org>
14
Message-id: 20210224230532.276878-1-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
11
---
17
target/arm/helper-a64.h | 2 +-
12
target/arm/cpu.h | 22 +++++++++-
18
target/arm/helper-a64.c | 32 ---------------------
13
target/arm/helper-a64.c | 2 +-
19
target/arm/translate-a64.c | 58 +++++---------------------------------
14
target/arm/helper.c | 85 +++++++++++++++++---------------------
20
target/arm/vec_helper.c | 48 +++++++++++++++++++++++++++++++
15
target/arm/translate-a64.c | 36 ++++++++--------
21
4 files changed, 56 insertions(+), 84 deletions(-)
16
target/arm/translate.c | 48 ++++++++++-----------
17
5 files changed, 101 insertions(+), 92 deletions(-)
22
18
23
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper-a64.h
21
--- a/target/arm/cpu.h
26
+++ b/target/arm/helper-a64.h
22
+++ b/target/arm/cpu.h
27
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
23
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, TCMA, 16, 2)
28
DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr)
24
FIELD(TBFLAG_A64, MTE_ACTIVE, 18, 1)
29
DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr)
25
FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
30
DEF_HELPER_3(vfp_cmped_a64, i64, f64, f64, ptr)
26
31
-DEF_HELPER_FLAGS_5(simd_tbl, TCG_CALL_NO_RWG_SE, i64, env, i64, i64, i32, i32)
27
+/*
32
+DEF_HELPER_FLAGS_4(simd_tblx, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
28
+ * Helpers for using the above.
33
DEF_HELPER_FLAGS_3(vfp_mulxs, TCG_CALL_NO_RWG, f32, f32, f32, ptr)
29
+ */
34
DEF_HELPER_FLAGS_3(vfp_mulxd, TCG_CALL_NO_RWG, f64, f64, f64, ptr)
30
+#define DP_TBFLAG_ANY(DST, WHICH, VAL) \
35
DEF_HELPER_FLAGS_3(neon_ceq_f64, TCG_CALL_NO_RWG, i64, i64, i64, ptr)
31
+ (DST = FIELD_DP32(DST, TBFLAG_ANY, WHICH, VAL))
32
+#define DP_TBFLAG_A64(DST, WHICH, VAL) \
33
+ (DST = FIELD_DP32(DST, TBFLAG_A64, WHICH, VAL))
34
+#define DP_TBFLAG_A32(DST, WHICH, VAL) \
35
+ (DST = FIELD_DP32(DST, TBFLAG_A32, WHICH, VAL))
36
+#define DP_TBFLAG_M32(DST, WHICH, VAL) \
37
+ (DST = FIELD_DP32(DST, TBFLAG_M32, WHICH, VAL))
38
+#define DP_TBFLAG_AM32(DST, WHICH, VAL) \
39
+ (DST = FIELD_DP32(DST, TBFLAG_AM32, WHICH, VAL))
40
+
41
+#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN, TBFLAG_ANY, WHICH)
42
+#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN, TBFLAG_A64, WHICH)
43
+#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN, TBFLAG_A32, WHICH)
44
+#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN, TBFLAG_M32, WHICH)
45
+#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN, TBFLAG_AM32, WHICH)
46
+
47
/**
48
* cpu_mmu_index:
49
* @env: The cpu environment
50
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
51
*/
52
static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
53
{
54
- return FIELD_EX32(env->hflags, TBFLAG_ANY, MMUIDX);
55
+ return EX_TBFLAG_ANY(env->hflags, MMUIDX);
56
}
57
58
static inline bool bswap_code(bool sctlr_b)
36
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
59
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
37
index XXXXXXX..XXXXXXX 100644
60
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/helper-a64.c
61
--- a/target/arm/helper-a64.c
39
+++ b/target/arm/helper-a64.c
62
+++ b/target/arm/helper-a64.c
40
@@ -XXX,XX +XXX,XX @@ float64 HELPER(vfp_mulxd)(float64 a, float64 b, void *fpstp)
63
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
41
return float64_mul(a, b, fpst);
64
* the hflags rebuild, since we can pull the composite TBII field
65
* from there.
66
*/
67
- tbii = FIELD_EX32(env->hflags, TBFLAG_A64, TBII);
68
+ tbii = EX_TBFLAG_A64(env->hflags, TBII);
69
if ((tbii >> extract64(new_pc, 55, 1)) & 1) {
70
/* TBI is enabled. */
71
int core_mmu_idx = cpu_mmu_index(env, false);
72
diff --git a/target/arm/helper.c b/target/arm/helper.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/arm/helper.c
75
+++ b/target/arm/helper.c
76
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
77
static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
78
ARMMMUIdx mmu_idx, uint32_t flags)
79
{
80
- flags = FIELD_DP32(flags, TBFLAG_ANY, FPEXC_EL, fp_el);
81
- flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX,
82
- arm_to_core_mmu_idx(mmu_idx));
83
+ DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el);
84
+ DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
85
86
if (arm_singlestep_active(env)) {
87
- flags = FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1);
88
+ DP_TBFLAG_ANY(flags, SS_ACTIVE, 1);
89
}
90
return flags;
42
}
91
}
43
92
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
44
-uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices,
93
bool sctlr_b = arm_sctlr_b(env);
45
- uint32_t rn, uint32_t numregs)
94
46
-{
95
if (sctlr_b) {
47
- /* Helper function for SIMD TBL and TBX. We have to do the table
96
- flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR__B, 1);
48
- * lookup part for the 64 bits worth of indices we're passed in.
97
+ DP_TBFLAG_A32(flags, SCTLR__B, 1);
49
- * result is the initial results vector (either zeroes for TBL
98
}
50
- * or some guest values for TBX), rn the register number where
99
if (arm_cpu_data_is_big_endian_a32(env, sctlr_b)) {
51
- * the table starts, and numregs the number of registers in the table.
100
- flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
52
- * We return the results of the lookups.
101
+ DP_TBFLAG_ANY(flags, BE_DATA, 1);
53
- */
102
}
54
- int shift;
103
- flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
55
-
104
+ DP_TBFLAG_A32(flags, NS, !access_secure_reg(env));
56
- for (shift = 0; shift < 64; shift += 8) {
105
57
- int index = extract64(indices, shift, 8);
106
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
58
- if (index < 16 * numregs) {
107
}
59
- /* Convert index (a byte offset into the virtual table
108
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
60
- * which is a series of 128-bit vectors concatenated)
109
uint32_t flags = 0;
61
- * into the correct register element plus a bit offset
110
62
- * into that element, bearing in mind that the table
111
if (arm_v7m_is_handler_mode(env)) {
63
- * can wrap around from V31 to V0.
112
- flags = FIELD_DP32(flags, TBFLAG_M32, HANDLER, 1);
64
- */
113
+ DP_TBFLAG_M32(flags, HANDLER, 1);
65
- int elt = (rn * 2 + (index >> 3)) % 64;
114
}
66
- int bitidx = (index & 7) * 8;
115
67
- uint64_t *q = aa64_vfp_qreg(env, elt >> 1);
116
/*
68
- uint64_t val = extract64(q[elt & 1], bitidx, 8);
117
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
69
-
118
if (arm_feature(env, ARM_FEATURE_V8) &&
70
- result = deposit64(result, shift, 8, val);
119
!((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
71
- }
120
(env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
72
- }
121
- flags = FIELD_DP32(flags, TBFLAG_M32, STACKCHECK, 1);
73
- return result;
122
+ DP_TBFLAG_M32(flags, STACKCHECK, 1);
74
-}
123
}
75
-
124
76
/* 64bit/double versions of the neon float compare functions */
125
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
77
uint64_t HELPER(neon_ceq_f64)(float64 a, float64 b, void *fpstp)
126
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_aprofile(CPUARMState *env)
78
{
127
{
128
int flags = 0;
129
130
- flags = FIELD_DP32(flags, TBFLAG_ANY, DEBUG_TARGET_EL,
131
- arm_debug_target_el(env));
132
+ DP_TBFLAG_ANY(flags, DEBUG_TARGET_EL, arm_debug_target_el(env));
133
return flags;
134
}
135
136
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
137
uint32_t flags = rebuild_hflags_aprofile(env);
138
139
if (arm_el_is_aa64(env, 1)) {
140
- flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
141
+ DP_TBFLAG_A32(flags, VFPEN, 1);
142
}
143
144
if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
145
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
146
- flags = FIELD_DP32(flags, TBFLAG_A32, HSTR_ACTIVE, 1);
147
+ DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
148
}
149
150
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
151
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
152
uint64_t sctlr;
153
int tbii, tbid;
154
155
- flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
156
+ DP_TBFLAG_ANY(flags, AARCH64_STATE, 1);
157
158
/* Get control bits for tagged addresses. */
159
tbid = aa64_va_parameter_tbi(tcr, mmu_idx);
160
tbii = tbid & ~aa64_va_parameter_tbid(tcr, mmu_idx);
161
162
- flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
163
- flags = FIELD_DP32(flags, TBFLAG_A64, TBID, tbid);
164
+ DP_TBFLAG_A64(flags, TBII, tbii);
165
+ DP_TBFLAG_A64(flags, TBID, tbid);
166
167
if (cpu_isar_feature(aa64_sve, env_archcpu(env))) {
168
int sve_el = sve_exception_el(env, el);
169
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
170
} else {
171
zcr_len = sve_zcr_len_for_el(env, el);
172
}
173
- flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
174
- flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
175
+ DP_TBFLAG_A64(flags, SVEEXC_EL, sve_el);
176
+ DP_TBFLAG_A64(flags, ZCR_LEN, zcr_len);
177
}
178
179
sctlr = regime_sctlr(env, stage1);
180
181
if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
182
- flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
183
+ DP_TBFLAG_ANY(flags, BE_DATA, 1);
184
}
185
186
if (cpu_isar_feature(aa64_pauth, env_archcpu(env))) {
187
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
188
* The decision of which action to take is left to a helper.
189
*/
190
if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
191
- flags = FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1);
192
+ DP_TBFLAG_A64(flags, PAUTH_ACTIVE, 1);
193
}
194
}
195
196
if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
197
/* Note that SCTLR_EL[23].BT == SCTLR_BT1. */
198
if (sctlr & (el == 0 ? SCTLR_BT0 : SCTLR_BT1)) {
199
- flags = FIELD_DP32(flags, TBFLAG_A64, BT, 1);
200
+ DP_TBFLAG_A64(flags, BT, 1);
201
}
202
}
203
204
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
205
case ARMMMUIdx_SE10_1:
206
case ARMMMUIdx_SE10_1_PAN:
207
/* TODO: ARMv8.3-NV */
208
- flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
209
+ DP_TBFLAG_A64(flags, UNPRIV, 1);
210
break;
211
case ARMMMUIdx_E20_2:
212
case ARMMMUIdx_E20_2_PAN:
213
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
214
* gated by HCR_EL2.<E2H,TGE> == '11', and so is LDTR.
215
*/
216
if (env->cp15.hcr_el2 & HCR_TGE) {
217
- flags = FIELD_DP32(flags, TBFLAG_A64, UNPRIV, 1);
218
+ DP_TBFLAG_A64(flags, UNPRIV, 1);
219
}
220
break;
221
default:
222
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
223
* 4) If no Allocation Tag Access, then all accesses are Unchecked.
224
*/
225
if (allocation_tag_access_enabled(env, el, sctlr)) {
226
- flags = FIELD_DP32(flags, TBFLAG_A64, ATA, 1);
227
+ DP_TBFLAG_A64(flags, ATA, 1);
228
if (tbid
229
&& !(env->pstate & PSTATE_TCO)
230
&& (sctlr & (el == 0 ? SCTLR_TCF0 : SCTLR_TCF))) {
231
- flags = FIELD_DP32(flags, TBFLAG_A64, MTE_ACTIVE, 1);
232
+ DP_TBFLAG_A64(flags, MTE_ACTIVE, 1);
233
}
234
}
235
/* And again for unprivileged accesses, if required. */
236
- if (FIELD_EX32(flags, TBFLAG_A64, UNPRIV)
237
+ if (EX_TBFLAG_A64(flags, UNPRIV)
238
&& tbid
239
&& !(env->pstate & PSTATE_TCO)
240
&& (sctlr & SCTLR_TCF0)
241
&& allocation_tag_access_enabled(env, 0, sctlr)) {
242
- flags = FIELD_DP32(flags, TBFLAG_A64, MTE0_ACTIVE, 1);
243
+ DP_TBFLAG_A64(flags, MTE0_ACTIVE, 1);
244
}
245
/* Cache TCMA as well as TBI. */
246
- flags = FIELD_DP32(flags, TBFLAG_A64, TCMA,
247
- aa64_va_parameter_tcma(tcr, mmu_idx));
248
+ DP_TBFLAG_A64(flags, TCMA, aa64_va_parameter_tcma(tcr, mmu_idx));
249
}
250
251
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
252
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
253
*cs_base = 0;
254
assert_hflags_rebuild_correctly(env);
255
256
- if (FIELD_EX32(flags, TBFLAG_ANY, AARCH64_STATE)) {
257
+ if (EX_TBFLAG_ANY(flags, AARCH64_STATE)) {
258
*pc = env->pc;
259
if (cpu_isar_feature(aa64_bti, env_archcpu(env))) {
260
- flags = FIELD_DP32(flags, TBFLAG_A64, BTYPE, env->btype);
261
+ DP_TBFLAG_A64(flags, BTYPE, env->btype);
262
}
263
} else {
264
*pc = env->regs[15];
265
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
266
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
267
FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S)
268
!= env->v7m.secure) {
269
- flags = FIELD_DP32(flags, TBFLAG_M32, FPCCR_S_WRONG, 1);
270
+ DP_TBFLAG_M32(flags, FPCCR_S_WRONG, 1);
271
}
272
273
if ((env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
274
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
275
* active FP context; we must create a new FP context before
276
* executing any FP insn.
277
*/
278
- flags = FIELD_DP32(flags, TBFLAG_M32, NEW_FP_CTXT_NEEDED, 1);
279
+ DP_TBFLAG_M32(flags, NEW_FP_CTXT_NEEDED, 1);
280
}
281
282
bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
283
if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
284
- flags = FIELD_DP32(flags, TBFLAG_M32, LSPACT, 1);
285
+ DP_TBFLAG_M32(flags, LSPACT, 1);
286
}
287
} else {
288
/*
289
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
290
* Note that VECLEN+VECSTRIDE are RES0 for M-profile.
291
*/
292
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
293
- flags = FIELD_DP32(flags, TBFLAG_A32,
294
- XSCALE_CPAR, env->cp15.c15_cpar);
295
+ DP_TBFLAG_A32(flags, XSCALE_CPAR, env->cp15.c15_cpar);
296
} else {
297
- flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN,
298
- env->vfp.vec_len);
299
- flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE,
300
- env->vfp.vec_stride);
301
+ DP_TBFLAG_A32(flags, VECLEN, env->vfp.vec_len);
302
+ DP_TBFLAG_A32(flags, VECSTRIDE, env->vfp.vec_stride);
303
}
304
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) {
305
- flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
306
+ DP_TBFLAG_A32(flags, VFPEN, 1);
307
}
308
}
309
310
- flags = FIELD_DP32(flags, TBFLAG_AM32, THUMB, env->thumb);
311
- flags = FIELD_DP32(flags, TBFLAG_AM32, CONDEXEC, env->condexec_bits);
312
+ DP_TBFLAG_AM32(flags, THUMB, env->thumb);
313
+ DP_TBFLAG_AM32(flags, CONDEXEC, env->condexec_bits);
314
}
315
316
/*
317
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
318
* 1 1 Active-not-pending
319
* SS_ACTIVE is set in hflags; PSTATE__SS is computed every TB.
320
*/
321
- if (FIELD_EX32(flags, TBFLAG_ANY, SS_ACTIVE) &&
322
- (env->pstate & PSTATE_SS)) {
323
- flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE__SS, 1);
324
+ if (EX_TBFLAG_ANY(flags, SS_ACTIVE) && (env->pstate & PSTATE_SS)) {
325
+ DP_TBFLAG_ANY(flags, PSTATE__SS, 1);
326
}
327
328
*pflags = flags;
79
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
329
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
80
index XXXXXXX..XXXXXXX 100644
330
index XXXXXXX..XXXXXXX 100644
81
--- a/target/arm/translate-a64.c
331
--- a/target/arm/translate-a64.c
82
+++ b/target/arm/translate-a64.c
332
+++ b/target/arm/translate-a64.c
83
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
333
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
84
int rm = extract32(insn, 16, 5);
334
!arm_el_is_aa64(env, 3);
85
int rn = extract32(insn, 5, 5);
335
dc->thumb = 0;
86
int rd = extract32(insn, 0, 5);
336
dc->sctlr_b = 0;
87
- int is_tblx = extract32(insn, 12, 1);
337
- dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
88
- int len = extract32(insn, 13, 2);
338
+ dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
89
- TCGv_i64 tcg_resl, tcg_resh, tcg_idx;
339
dc->condexec_mask = 0;
90
- TCGv_i32 tcg_regno, tcg_numregs;
340
dc->condexec_cond = 0;
91
+ int is_tbx = extract32(insn, 12, 1);
341
- core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
92
+ int len = (extract32(insn, 13, 2) + 1) * 16;
342
+ core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
93
343
dc->mmu_idx = core_to_aa64_mmu_idx(core_mmu_idx);
94
if (op2 != 0) {
344
- dc->tbii = FIELD_EX32(tb_flags, TBFLAG_A64, TBII);
95
unallocated_encoding(s);
345
- dc->tbid = FIELD_EX32(tb_flags, TBFLAG_A64, TBID);
96
@@ -XXX,XX +XXX,XX @@ static void disas_simd_tb(DisasContext *s, uint32_t insn)
346
- dc->tcma = FIELD_EX32(tb_flags, TBFLAG_A64, TCMA);
97
return;
347
+ dc->tbii = EX_TBFLAG_A64(tb_flags, TBII);
98
}
348
+ dc->tbid = EX_TBFLAG_A64(tb_flags, TBID);
99
349
+ dc->tcma = EX_TBFLAG_A64(tb_flags, TCMA);
100
- /* This does a table lookup: for every byte element in the input
350
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
101
- * we index into a table formed from up to four vector registers,
351
#if !defined(CONFIG_USER_ONLY)
102
- * and then the output is the result of the lookups. Our helper
352
dc->user = (dc->current_el == 0);
103
- * function does the lookup operation for a single 64 bit part of
353
#endif
104
- * the input.
354
- dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
105
- */
355
- dc->sve_excp_el = FIELD_EX32(tb_flags, TBFLAG_A64, SVEEXC_EL);
106
- tcg_resl = tcg_temp_new_i64();
356
- dc->sve_len = (FIELD_EX32(tb_flags, TBFLAG_A64, ZCR_LEN) + 1) * 16;
107
- tcg_resh = NULL;
357
- dc->pauth_active = FIELD_EX32(tb_flags, TBFLAG_A64, PAUTH_ACTIVE);
108
-
358
- dc->bt = FIELD_EX32(tb_flags, TBFLAG_A64, BT);
109
- if (is_tblx) {
359
- dc->btype = FIELD_EX32(tb_flags, TBFLAG_A64, BTYPE);
110
- read_vec_element(s, tcg_resl, rd, 0, MO_64);
360
- dc->unpriv = FIELD_EX32(tb_flags, TBFLAG_A64, UNPRIV);
111
- } else {
361
- dc->ata = FIELD_EX32(tb_flags, TBFLAG_A64, ATA);
112
- tcg_gen_movi_i64(tcg_resl, 0);
362
- dc->mte_active[0] = FIELD_EX32(tb_flags, TBFLAG_A64, MTE_ACTIVE);
113
- }
363
- dc->mte_active[1] = FIELD_EX32(tb_flags, TBFLAG_A64, MTE0_ACTIVE);
114
-
364
+ dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
115
- if (is_q) {
365
+ dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
116
- tcg_resh = tcg_temp_new_i64();
366
+ dc->sve_len = (EX_TBFLAG_A64(tb_flags, ZCR_LEN) + 1) * 16;
117
- if (is_tblx) {
367
+ dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
118
- read_vec_element(s, tcg_resh, rd, 1, MO_64);
368
+ dc->bt = EX_TBFLAG_A64(tb_flags, BT);
119
- } else {
369
+ dc->btype = EX_TBFLAG_A64(tb_flags, BTYPE);
120
- tcg_gen_movi_i64(tcg_resh, 0);
370
+ dc->unpriv = EX_TBFLAG_A64(tb_flags, UNPRIV);
121
- }
371
+ dc->ata = EX_TBFLAG_A64(tb_flags, ATA);
122
- }
372
+ dc->mte_active[0] = EX_TBFLAG_A64(tb_flags, MTE_ACTIVE);
123
-
373
+ dc->mte_active[1] = EX_TBFLAG_A64(tb_flags, MTE0_ACTIVE);
124
- tcg_idx = tcg_temp_new_i64();
374
dc->vec_len = 0;
125
- tcg_regno = tcg_const_i32(rn);
375
dc->vec_stride = 0;
126
- tcg_numregs = tcg_const_i32(len + 1);
376
dc->cp_regs = arm_cpu->cp_regs;
127
- read_vec_element(s, tcg_idx, rm, 0, MO_64);
377
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
128
- gen_helper_simd_tbl(tcg_resl, cpu_env, tcg_resl, tcg_idx,
378
* emit code to generate a software step exception
129
- tcg_regno, tcg_numregs);
379
* end the TB
130
- if (is_q) {
380
*/
131
- read_vec_element(s, tcg_idx, rm, 1, MO_64);
381
- dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
132
- gen_helper_simd_tbl(tcg_resh, cpu_env, tcg_resh, tcg_idx,
382
- dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE__SS);
133
- tcg_regno, tcg_numregs);
383
+ dc->ss_active = EX_TBFLAG_ANY(tb_flags, SS_ACTIVE);
134
- }
384
+ dc->pstate_ss = EX_TBFLAG_ANY(tb_flags, PSTATE__SS);
135
- tcg_temp_free_i64(tcg_idx);
385
dc->is_ldex = false;
136
- tcg_temp_free_i32(tcg_regno);
386
- dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
137
- tcg_temp_free_i32(tcg_numregs);
387
+ dc->debug_target_el = EX_TBFLAG_ANY(tb_flags, DEBUG_TARGET_EL);
138
-
388
139
- write_vec_element(s, tcg_resl, rd, 0, MO_64);
389
/* Bound the number of insns to execute to those left on the page. */
140
- tcg_temp_free_i64(tcg_resl);
390
bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
141
-
391
diff --git a/target/arm/translate.c b/target/arm/translate.c
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
392
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/vec_helper.c
393
--- a/target/arm/translate.c
158
+++ b/target/arm/vec_helper.c
394
+++ b/target/arm/translate.c
159
@@ -XXX,XX +XXX,XX @@ DO_VRINT_RMODE(gvec_vrint_rm_h, helper_rinth, uint16_t)
395
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
160
DO_VRINT_RMODE(gvec_vrint_rm_s, helper_rints, uint32_t)
396
*/
161
397
dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
162
#undef DO_VRINT_RMODE
398
!arm_el_is_aa64(env, 3);
163
+
399
- dc->thumb = FIELD_EX32(tb_flags, TBFLAG_AM32, THUMB);
164
+#ifdef TARGET_AARCH64
400
- dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
165
+void HELPER(simd_tblx)(void *vd, void *vm, void *venv, uint32_t desc)
401
- condexec = FIELD_EX32(tb_flags, TBFLAG_AM32, CONDEXEC);
166
+{
402
+ dc->thumb = EX_TBFLAG_AM32(tb_flags, THUMB);
167
+ const uint8_t *indices = vm;
403
+ dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
168
+ CPUARMState *env = venv;
404
+ condexec = EX_TBFLAG_AM32(tb_flags, CONDEXEC);
169
+ size_t oprsz = simd_oprsz(desc);
405
dc->condexec_mask = (condexec & 0xf) << 1;
170
+ uint32_t rn = extract32(desc, SIMD_DATA_SHIFT, 5);
406
dc->condexec_cond = condexec >> 4;
171
+ bool is_tbx = extract32(desc, SIMD_DATA_SHIFT + 5, 1);
407
172
+ uint32_t table_len = desc >> (SIMD_DATA_SHIFT + 6);
408
- core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
173
+ union {
409
+ core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
174
+ uint8_t b[16];
410
dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
175
+ uint64_t d[2];
411
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
176
+ } result;
412
#if !defined(CONFIG_USER_ONLY)
177
+
413
dc->user = (dc->current_el == 0);
178
+ /*
414
#endif
179
+ * We must construct the final result in a temp, lest the output
415
- dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
180
+ * overlaps the input table. For TBL, begin with zero; for TBX,
416
+ dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
181
+ * begin with the original register contents. Note that we always
417
182
+ * copy 16 bytes here to avoid an extra branch; clearing the high
418
if (arm_feature(env, ARM_FEATURE_M)) {
183
+ * bits of the register for oprsz == 8 is handled below.
419
dc->vfp_enabled = 1;
184
+ */
420
dc->be_data = MO_TE;
185
+ if (is_tbx) {
421
- dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_M32, HANDLER);
186
+ memcpy(&result, vd, 16);
422
+ dc->v7m_handler_mode = EX_TBFLAG_M32(tb_flags, HANDLER);
187
+ } else {
423
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
188
+ memset(&result, 0, 16);
424
regime_is_secure(env, dc->mmu_idx);
189
+ }
425
- dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_M32, STACKCHECK);
190
+
426
- dc->v8m_fpccr_s_wrong =
191
+ for (size_t i = 0; i < oprsz; ++i) {
427
- FIELD_EX32(tb_flags, TBFLAG_M32, FPCCR_S_WRONG);
192
+ uint32_t index = indices[H1(i)];
428
+ dc->v8m_stackcheck = EX_TBFLAG_M32(tb_flags, STACKCHECK);
193
+
429
+ dc->v8m_fpccr_s_wrong = EX_TBFLAG_M32(tb_flags, FPCCR_S_WRONG);
194
+ if (index < table_len) {
430
dc->v7m_new_fp_ctxt_needed =
195
+ /*
431
- FIELD_EX32(tb_flags, TBFLAG_M32, NEW_FP_CTXT_NEEDED);
196
+ * Convert index (a byte offset into the virtual table
432
- dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_M32, LSPACT);
197
+ * which is a series of 128-bit vectors concatenated)
433
+ EX_TBFLAG_M32(tb_flags, NEW_FP_CTXT_NEEDED);
198
+ * into the correct register element, bearing in mind
434
+ dc->v7m_lspact = EX_TBFLAG_M32(tb_flags, LSPACT);
199
+ * that the table can wrap around from V31 to V0.
435
} else {
200
+ */
436
- dc->be_data =
201
+ const uint8_t *table = (const uint8_t *)
437
- FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
202
+ aa64_vfp_qreg(env, (rn + (index >> 4)) % 32);
438
- dc->debug_target_el =
203
+ result.b[H1(i)] = table[H1(index % 16)];
439
- FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
204
+ }
440
- dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR__B);
205
+ }
441
- dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
206
+
442
- dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
207
+ memcpy(vd, &result, 16);
443
- dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
208
+ clear_tail(vd, oprsz, simd_maxsz(desc));
444
+ dc->debug_target_el = EX_TBFLAG_ANY(tb_flags, DEBUG_TARGET_EL);
209
+}
445
+ dc->sctlr_b = EX_TBFLAG_A32(tb_flags, SCTLR__B);
210
+#endif
446
+ dc->hstr_active = EX_TBFLAG_A32(tb_flags, HSTR_ACTIVE);
447
+ dc->ns = EX_TBFLAG_A32(tb_flags, NS);
448
+ dc->vfp_enabled = EX_TBFLAG_A32(tb_flags, VFPEN);
449
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
450
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
451
+ dc->c15_cpar = EX_TBFLAG_A32(tb_flags, XSCALE_CPAR);
452
} else {
453
- dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
454
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
455
+ dc->vec_len = EX_TBFLAG_A32(tb_flags, VECLEN);
456
+ dc->vec_stride = EX_TBFLAG_A32(tb_flags, VECSTRIDE);
457
}
458
}
459
dc->cp_regs = cpu->cp_regs;
460
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
461
* emit code to generate a software step exception
462
* end the TB
463
*/
464
- dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
465
- dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE__SS);
466
+ dc->ss_active = EX_TBFLAG_ANY(tb_flags, SS_ACTIVE);
467
+ dc->pstate_ss = EX_TBFLAG_ANY(tb_flags, PSTATE__SS);
468
dc->is_ldex = false;
469
470
dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
471
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
472
DisasContext dc = { };
473
const TranslatorOps *ops = &arm_translator_ops;
474
475
- if (FIELD_EX32(tb->flags, TBFLAG_AM32, THUMB)) {
476
+ if (EX_TBFLAG_AM32(tb->flags, THUMB)) {
477
ops = &thumb_translator_ops;
478
}
479
#ifdef TARGET_AARCH64
480
- if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
481
+ if (EX_TBFLAG_ANY(tb->flags, AARCH64_STATE)) {
482
ops = &aarch64_translator_ops;
483
}
484
#endif
211
--
485
--
212
2.20.1
486
2.20.1
213
487
214
488
diff view generated by jsdifflib
1
From: Rebecca Cran <rebecca@nuviainc.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for FEAT_SSBS. SSBS (Speculative Store Bypass Safe) is an
3
In preparation for splitting tb->flags across multiple
4
optional feature in ARMv8.0, and mandatory in ARMv8.5.
4
fields, introduce a structure to hold the value(s).
5
5
So far this only migrates the one uint32_t and fixes
6
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
6
all of the places that require adjustment to match.
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
8
Message-id: 20210216224543.16142-2-rebecca@nuviainc.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210419202257.161730-6-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/cpu.h | 15 ++++++++++++++-
13
target/arm/cpu.h | 26 ++++++++++++---------
12
target/arm/internals.h | 6 ++++++
14
target/arm/translate.h | 11 +++++++++
13
target/arm/helper.c | 37 +++++++++++++++++++++++++++++++++++++
15
target/arm/helper.c | 48 +++++++++++++++++++++-----------------
14
target/arm/translate-a64.c | 12 ++++++++++++
16
target/arm/translate-a64.c | 2 +-
15
4 files changed, 69 insertions(+), 1 deletion(-)
17
target/arm/translate.c | 7 +++---
18
5 files changed, 57 insertions(+), 37 deletions(-)
16
19
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
22
--- a/target/arm/cpu.h
20
+++ b/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
21
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
24
@@ -XXX,XX +XXX,XX @@ typedef struct ARMPACKey {
22
#define SCTLR_TE (1U << 30) /* AArch32 only */
25
} ARMPACKey;
23
#define SCTLR_EnIB (1U << 30) /* v8.3, AArch64 only */
26
#endif
24
#define SCTLR_EnIA (1U << 31) /* v8.3, AArch64 only */
27
25
+#define SCTLR_DSSBS_32 (1U << 31) /* v8.5, AArch32 only */
28
+/* See the commentary above the TBFLAG field definitions. */
26
#define SCTLR_BT0 (1ULL << 35) /* v8.5-BTI */
29
+typedef struct CPUARMTBFlags {
27
#define SCTLR_BT1 (1ULL << 36) /* v8.5-BTI */
30
+ uint32_t flags;
28
#define SCTLR_ITFSB (1ULL << 37) /* v8.5-MemTag */
31
+} CPUARMTBFlags;
29
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
32
30
#define SCTLR_TCF (3ULL << 40) /* v8.5-MemTag */
33
typedef struct CPUARMState {
31
#define SCTLR_ATA0 (1ULL << 42) /* v8.5-MemTag */
34
/* Regs for current mode. */
32
#define SCTLR_ATA (1ULL << 43) /* v8.5-MemTag */
35
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
33
-#define SCTLR_DSSBS (1ULL << 44) /* v8.5 */
36
uint32_t aarch64; /* 1 if CPU is in aarch64 state; inverse of PSTATE.nRW */
34
+#define SCTLR_DSSBS_64 (1ULL << 44) /* v8.5, AArch64 only */
37
35
38
/* Cached TBFLAGS state. See below for which bits are included. */
36
#define CPTR_TCPAC (1U << 31)
39
- uint32_t hflags;
37
#define CPTR_TTA (1U << 20)
40
+ CPUARMTBFlags hflags;
38
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
41
39
#define CPSR_IL (1U << 20)
42
/* Frequently accessed CPSR bits are stored separately for efficiency.
40
#define CPSR_DIT (1U << 21)
43
This contains all the other bits. Use cpsr_{read,write} to access
41
#define CPSR_PAN (1U << 22)
44
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
42
+#define CPSR_SSBS (1U << 23)
45
* Helpers for using the above.
43
#define CPSR_J (1U << 24)
46
*/
44
#define CPSR_IT_0_1 (3U << 25)
47
#define DP_TBFLAG_ANY(DST, WHICH, VAL) \
45
#define CPSR_Q (1U << 27)
48
- (DST = FIELD_DP32(DST, TBFLAG_ANY, WHICH, VAL))
46
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
49
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_ANY, WHICH, VAL))
47
#define PSTATE_A (1U << 8)
50
#define DP_TBFLAG_A64(DST, WHICH, VAL) \
48
#define PSTATE_D (1U << 9)
51
- (DST = FIELD_DP32(DST, TBFLAG_A64, WHICH, VAL))
49
#define PSTATE_BTYPE (3U << 10)
52
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_A64, WHICH, VAL))
50
+#define PSTATE_SSBS (1U << 12)
53
#define DP_TBFLAG_A32(DST, WHICH, VAL) \
51
#define PSTATE_IL (1U << 20)
54
- (DST = FIELD_DP32(DST, TBFLAG_A32, WHICH, VAL))
52
#define PSTATE_SS (1U << 21)
55
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_A32, WHICH, VAL))
53
#define PSTATE_PAN (1U << 22)
56
#define DP_TBFLAG_M32(DST, WHICH, VAL) \
54
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_dit(const ARMISARegisters *id)
57
- (DST = FIELD_DP32(DST, TBFLAG_M32, WHICH, VAL))
55
return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0;
58
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_M32, WHICH, VAL))
56
}
59
#define DP_TBFLAG_AM32(DST, WHICH, VAL) \
57
60
- (DST = FIELD_DP32(DST, TBFLAG_AM32, WHICH, VAL))
58
+static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
61
+ (DST.flags = FIELD_DP32(DST.flags, TBFLAG_AM32, WHICH, VAL))
62
63
-#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN, TBFLAG_ANY, WHICH)
64
-#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN, TBFLAG_A64, WHICH)
65
-#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN, TBFLAG_A32, WHICH)
66
-#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN, TBFLAG_M32, WHICH)
67
-#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN, TBFLAG_AM32, WHICH)
68
+#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_ANY, WHICH)
69
+#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A64, WHICH)
70
+#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A32, WHICH)
71
+#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_M32, WHICH)
72
+#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_AM32, WHICH)
73
74
/**
75
* cpu_mmu_index:
76
diff --git a/target/arm/translate.h b/target/arm/translate.h
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/translate.h
79
+++ b/target/arm/translate.h
80
@@ -XXX,XX +XXX,XX @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
81
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
82
typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
83
84
+/**
85
+ * arm_tbflags_from_tb:
86
+ * @tb: the TranslationBlock
87
+ *
88
+ * Extract the flag values from @tb.
89
+ */
90
+static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb)
59
+{
91
+{
60
+ return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
92
+ return (CPUARMTBFlags){ tb->flags };
61
+}
93
+}
62
+
94
+
63
/*
95
/*
64
* 64-bit feature tests via id registers.
96
* Enum for argument to fpstatus_ptr().
65
*/
97
*/
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
79
index XXXXXXX..XXXXXXX 100644
80
--- a/target/arm/internals.h
81
+++ b/target/arm/internals.h
82
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch32_cpsr_valid_mask(uint64_t features,
83
if (isar_feature_aa32_dit(id)) {
84
valid |= CPSR_DIT;
85
}
86
+ if (isar_feature_aa32_ssbs(id)) {
87
+ valid |= CPSR_SSBS;
88
+ }
89
90
return valid;
91
}
92
@@ -XXX,XX +XXX,XX @@ static inline uint32_t aarch64_pstate_valid_mask(const ARMISARegisters *id)
93
if (isar_feature_aa64_dit(id)) {
94
valid |= PSTATE_DIT;
95
}
96
+ if (isar_feature_aa64_ssbs(id)) {
97
+ valid |= PSTATE_SSBS;
98
+ }
99
if (isar_feature_aa64_mte(id)) {
100
valid |= PSTATE_TCO;
101
}
102
diff --git a/target/arm/helper.c b/target/arm/helper.c
98
diff --git a/target/arm/helper.c b/target/arm/helper.c
103
index XXXXXXX..XXXXXXX 100644
99
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/helper.c
100
--- a/target/arm/helper.c
105
+++ b/target/arm/helper.c
101
+++ b/target/arm/helper.c
106
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo dit_reginfo = {
102
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
107
.readfn = aa64_dit_read, .writefn = aa64_dit_write
103
}
108
};
104
#endif
109
105
110
+static uint64_t aa64_ssbs_read(CPUARMState *env, const ARMCPRegInfo *ri)
106
-static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
111
+{
107
- ARMMMUIdx mmu_idx, uint32_t flags)
112
+ return env->pstate & PSTATE_SSBS;
108
+static CPUARMTBFlags rebuild_hflags_common(CPUARMState *env, int fp_el,
113
+}
109
+ ARMMMUIdx mmu_idx,
110
+ CPUARMTBFlags flags)
111
{
112
DP_TBFLAG_ANY(flags, FPEXC_EL, fp_el);
113
DP_TBFLAG_ANY(flags, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
114
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common(CPUARMState *env, int fp_el,
115
return flags;
116
}
117
118
-static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
119
- ARMMMUIdx mmu_idx, uint32_t flags)
120
+static CPUARMTBFlags rebuild_hflags_common_32(CPUARMState *env, int fp_el,
121
+ ARMMMUIdx mmu_idx,
122
+ CPUARMTBFlags flags)
123
{
124
bool sctlr_b = arm_sctlr_b(env);
125
126
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_common_32(CPUARMState *env, int fp_el,
127
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
128
}
129
130
-static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
131
- ARMMMUIdx mmu_idx)
132
+static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
133
+ ARMMMUIdx mmu_idx)
134
{
135
- uint32_t flags = 0;
136
+ CPUARMTBFlags flags = {};
137
138
if (arm_v7m_is_handler_mode(env)) {
139
DP_TBFLAG_M32(flags, HANDLER, 1);
140
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_m32(CPUARMState *env, int fp_el,
141
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
142
}
143
144
-static uint32_t rebuild_hflags_aprofile(CPUARMState *env)
145
+static CPUARMTBFlags rebuild_hflags_aprofile(CPUARMState *env)
146
{
147
- int flags = 0;
148
+ CPUARMTBFlags flags = {};
149
150
DP_TBFLAG_ANY(flags, DEBUG_TARGET_EL, arm_debug_target_el(env));
151
return flags;
152
}
153
154
-static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
155
- ARMMMUIdx mmu_idx)
156
+static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
157
+ ARMMMUIdx mmu_idx)
158
{
159
- uint32_t flags = rebuild_hflags_aprofile(env);
160
+ CPUARMTBFlags flags = rebuild_hflags_aprofile(env);
161
162
if (arm_el_is_aa64(env, 1)) {
163
DP_TBFLAG_A32(flags, VFPEN, 1);
164
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a32(CPUARMState *env, int fp_el,
165
return rebuild_hflags_common_32(env, fp_el, mmu_idx, flags);
166
}
167
168
-static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
169
- ARMMMUIdx mmu_idx)
170
+static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
171
+ ARMMMUIdx mmu_idx)
172
{
173
- uint32_t flags = rebuild_hflags_aprofile(env);
174
+ CPUARMTBFlags flags = rebuild_hflags_aprofile(env);
175
ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
176
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
177
uint64_t sctlr;
178
@@ -XXX,XX +XXX,XX @@ static uint32_t rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
179
return rebuild_hflags_common(env, fp_el, mmu_idx, flags);
180
}
181
182
-static uint32_t rebuild_hflags_internal(CPUARMState *env)
183
+static CPUARMTBFlags rebuild_hflags_internal(CPUARMState *env)
184
{
185
int el = arm_current_el(env);
186
int fp_el = fp_exception_el(env, el);
187
@@ -XXX,XX +XXX,XX @@ void HELPER(rebuild_hflags_m32_newel)(CPUARMState *env)
188
int el = arm_current_el(env);
189
int fp_el = fp_exception_el(env, el);
190
ARMMMUIdx mmu_idx = arm_mmu_idx_el(env, el);
114
+
191
+
115
+static void aa64_ssbs_write(CPUARMState *env, const ARMCPRegInfo *ri,
192
env->hflags = rebuild_hflags_m32(env, fp_el, mmu_idx);
116
+ uint64_t value)
193
}
117
+{
194
118
+ env->pstate = (env->pstate & ~PSTATE_SSBS) | (value & PSTATE_SSBS);
195
@@ -XXX,XX +XXX,XX @@ void HELPER(rebuild_hflags_a64)(CPUARMState *env, int el)
119
+}
196
static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
120
+
197
{
121
+static const ARMCPRegInfo ssbs_reginfo = {
198
#ifdef CONFIG_DEBUG_TCG
122
+ .name = "SSBS", .state = ARM_CP_STATE_AA64,
199
- uint32_t env_flags_current = env->hflags;
123
+ .opc0 = 3, .opc1 = 3, .crn = 4, .crm = 2, .opc2 = 6,
200
- uint32_t env_flags_rebuilt = rebuild_hflags_internal(env);
124
+ .type = ARM_CP_NO_RAW, .access = PL0_RW,
201
+ CPUARMTBFlags c = env->hflags;
125
+ .readfn = aa64_ssbs_read, .writefn = aa64_ssbs_write
202
+ CPUARMTBFlags r = rebuild_hflags_internal(env);
126
+};
203
127
+
204
- if (unlikely(env_flags_current != env_flags_rebuilt)) {
128
static CPAccessResult aa64_cacheop_poc_access(CPUARMState *env,
205
+ if (unlikely(c.flags != r.flags)) {
129
const ARMCPRegInfo *ri,
206
fprintf(stderr, "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n",
130
bool isread)
207
- env_flags_current, env_flags_rebuilt);
131
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
208
+ c.flags, r.flags);
132
if (cpu_isar_feature(aa64_dit, cpu)) {
209
abort();
133
define_one_arm_cp_reg(cpu, &dit_reginfo);
210
}
134
}
211
#endif
135
+ if (cpu_isar_feature(aa64_ssbs, cpu)) {
212
@@ -XXX,XX +XXX,XX @@ static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
136
+ define_one_arm_cp_reg(cpu, &ssbs_reginfo);
213
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
137
+ }
214
target_ulong *cs_base, uint32_t *pflags)
138
215
{
139
if (arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu)) {
216
- uint32_t flags = env->hflags;
140
define_arm_cp_regs(cpu, vhe_reginfo);
217
+ CPUARMTBFlags flags;
141
@@ -XXX,XX +XXX,XX @@ static void take_aarch32_exception(CPUARMState *env, int new_mode,
218
142
env->uncached_cpsr &= ~(CPSR_IL | CPSR_J);
219
*cs_base = 0;
143
env->daif |= mask;
220
assert_hflags_rebuild_correctly(env);
144
221
+ flags = env->hflags;
145
+ if (cpu_isar_feature(aa32_ssbs, env_archcpu(env))) {
222
146
+ if (env->cp15.sctlr_el[new_el] & SCTLR_DSSBS_32) {
223
if (EX_TBFLAG_ANY(flags, AARCH64_STATE)) {
147
+ env->uncached_cpsr |= CPSR_SSBS;
224
*pc = env->pc;
148
+ } else {
225
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
149
+ env->uncached_cpsr &= ~CPSR_SSBS;
226
DP_TBFLAG_ANY(flags, PSTATE__SS, 1);
150
+ }
227
}
151
+ }
228
152
+
229
- *pflags = flags;
153
if (new_mode == ARM_CPU_MODE_HYP) {
230
+ *pflags = flags.flags;
154
env->thumb = (env->cp15.sctlr_el[2] & SCTLR_TE) != 0;
231
}
155
env->elr_el[2] = env->regs[15];
232
156
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
233
#ifdef TARGET_AARCH64
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
234
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
172
index XXXXXXX..XXXXXXX 100644
235
index XXXXXXX..XXXXXXX 100644
173
--- a/target/arm/translate-a64.c
236
--- a/target/arm/translate-a64.c
174
+++ b/target/arm/translate-a64.c
237
+++ b/target/arm/translate-a64.c
175
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
238
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
176
tcg_temp_free_i32(t1);
239
DisasContext *dc = container_of(dcbase, DisasContext, base);
177
break;
240
CPUARMState *env = cpu->env_ptr;
178
241
ARMCPU *arm_cpu = env_archcpu(env);
179
+ case 0x19: /* SSBS */
242
- uint32_t tb_flags = dc->base.tb->flags;
180
+ if (!dc_isar_feature(aa64_ssbs, s)) {
243
+ CPUARMTBFlags tb_flags = arm_tbflags_from_tb(dc->base.tb);
181
+ goto do_unallocated;
244
int bound, core_mmu_idx;
182
+ }
245
183
+ if (crm & 1) {
246
dc->isar = &arm_cpu->isar;
184
+ set_pstate_bits(PSTATE_SSBS);
247
diff --git a/target/arm/translate.c b/target/arm/translate.c
185
+ } else {
248
index XXXXXXX..XXXXXXX 100644
186
+ clear_pstate_bits(PSTATE_SSBS);
249
--- a/target/arm/translate.c
187
+ }
250
+++ b/target/arm/translate.c
188
+ /* Don't need to rebuild hflags since SSBS is a nop */
251
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
189
+ break;
252
DisasContext *dc = container_of(dcbase, DisasContext, base);
190
+
253
CPUARMState *env = cs->env_ptr;
191
case 0x1a: /* DIT */
254
ARMCPU *cpu = env_archcpu(env);
192
if (!dc_isar_feature(aa64_dit, s)) {
255
- uint32_t tb_flags = dc->base.tb->flags;
193
goto do_unallocated;
256
+ CPUARMTBFlags tb_flags = arm_tbflags_from_tb(dc->base.tb);
257
uint32_t condexec, core_mmu_idx;
258
259
dc->isar = &cpu->isar;
260
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
261
{
262
DisasContext dc = { };
263
const TranslatorOps *ops = &arm_translator_ops;
264
+ CPUARMTBFlags tb_flags = arm_tbflags_from_tb(tb);
265
266
- if (EX_TBFLAG_AM32(tb->flags, THUMB)) {
267
+ if (EX_TBFLAG_AM32(tb_flags, THUMB)) {
268
ops = &thumb_translator_ops;
269
}
270
#ifdef TARGET_AARCH64
271
- if (EX_TBFLAG_ANY(tb->flags, AARCH64_STATE)) {
272
+ if (EX_TBFLAG_ANY(tb_flags, AARCH64_STATE)) {
273
ops = &aarch64_translator_ops;
274
}
275
#endif
194
--
276
--
195
2.20.1
277
2.20.1
196
278
197
279
diff view generated by jsdifflib
1
Move the specification of the IRQ information for the uart, ethernet,
1
From: Richard Henderson <richard.henderson@linaro.org>
2
dma and spi devices to the data structures. (The other devices
3
handled by the PPCPortInfo structures don't have any interrupt lines
4
we need to wire up.)
5
2
3
Now that we have all of the proper macros defined, expanding
4
the CPUARMTBFlags structure and populating the two TB fields
5
is relatively simple.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210419202257.161730-7-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-14-peter.maydell@linaro.org
9
---
11
---
10
hw/arm/mps2-tz.c | 52 +++++++++++++++++++++++-------------------------
12
target/arm/cpu.h | 49 ++++++++++++++++++++++++------------------
11
1 file changed, 25 insertions(+), 27 deletions(-)
13
target/arm/translate.h | 2 +-
14
target/arm/helper.c | 10 +++++----
15
3 files changed, 35 insertions(+), 26 deletions(-)
12
16
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
19
--- a/target/arm/cpu.h
16
+++ b/hw/arm/mps2-tz.c
20
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
21
@@ -XXX,XX +XXX,XX @@ typedef struct ARMPACKey {
18
const char *name, hwaddr size,
22
/* See the commentary above the TBFLAG field definitions. */
19
const int *irqs)
23
typedef struct CPUARMTBFlags {
24
uint32_t flags;
25
+ target_ulong flags2;
26
} CPUARMTBFlags;
27
28
typedef struct CPUARMState {
29
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
30
#include "exec/cpu-all.h"
31
32
/*
33
- * Bit usage in the TB flags field: bit 31 indicates whether we are
34
- * in 32 or 64 bit mode. The meaning of the other bits depends on that.
35
- * We put flags which are shared between 32 and 64 bit mode at the top
36
- * of the word, and flags which apply to only one mode at the bottom.
37
+ * We have more than 32-bits worth of state per TB, so we split the data
38
+ * between tb->flags and tb->cs_base, which is otherwise unused for ARM.
39
+ * We collect these two parts in CPUARMTBFlags where they are named
40
+ * flags and flags2 respectively.
41
*
42
- * 31 20 18 14 9 0
43
- * +--------------+-----+-----+----------+--------------+
44
- * | | | TBFLAG_A32 | |
45
- * | | +-----+----------+ TBFLAG_AM32 |
46
- * | TBFLAG_ANY | |TBFLAG_M32| |
47
- * | +-----------+----------+--------------|
48
- * | | TBFLAG_A64 |
49
- * +--------------+-------------------------------------+
50
- * 31 20 0
51
+ * The flags that are shared between all execution modes, TBFLAG_ANY,
52
+ * are stored in flags. The flags that are specific to a given mode
53
+ * are stores in flags2. Since cs_base is sized on the configured
54
+ * address size, flags2 always has 64-bits for A64, and a minimum of
55
+ * 32-bits for A32 and M32.
56
+ *
57
+ * The bits for 32-bit A-profile and M-profile partially overlap:
58
+ *
59
+ * 18 9 0
60
+ * +----------------+--------------+
61
+ * | TBFLAG_A32 | |
62
+ * +-----+----------+ TBFLAG_AM32 |
63
+ * | |TBFLAG_M32| |
64
+ * +-----+----------+--------------+
65
+ * 14 9 0
66
*
67
* Unless otherwise noted, these bits are cached in env->hflags.
68
*/
69
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, MTE0_ACTIVE, 19, 1)
70
#define DP_TBFLAG_ANY(DST, WHICH, VAL) \
71
(DST.flags = FIELD_DP32(DST.flags, TBFLAG_ANY, WHICH, VAL))
72
#define DP_TBFLAG_A64(DST, WHICH, VAL) \
73
- (DST.flags = FIELD_DP32(DST.flags, TBFLAG_A64, WHICH, VAL))
74
+ (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_A64, WHICH, VAL))
75
#define DP_TBFLAG_A32(DST, WHICH, VAL) \
76
- (DST.flags = FIELD_DP32(DST.flags, TBFLAG_A32, WHICH, VAL))
77
+ (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_A32, WHICH, VAL))
78
#define DP_TBFLAG_M32(DST, WHICH, VAL) \
79
- (DST.flags = FIELD_DP32(DST.flags, TBFLAG_M32, WHICH, VAL))
80
+ (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_M32, WHICH, VAL))
81
#define DP_TBFLAG_AM32(DST, WHICH, VAL) \
82
- (DST.flags = FIELD_DP32(DST.flags, TBFLAG_AM32, WHICH, VAL))
83
+ (DST.flags2 = FIELD_DP32(DST.flags2, TBFLAG_AM32, WHICH, VAL))
84
85
#define EX_TBFLAG_ANY(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_ANY, WHICH)
86
-#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A64, WHICH)
87
-#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_A32, WHICH)
88
-#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_M32, WHICH)
89
-#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags, TBFLAG_AM32, WHICH)
90
+#define EX_TBFLAG_A64(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_A64, WHICH)
91
+#define EX_TBFLAG_A32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_A32, WHICH)
92
+#define EX_TBFLAG_M32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_M32, WHICH)
93
+#define EX_TBFLAG_AM32(IN, WHICH) FIELD_EX32(IN.flags2, TBFLAG_AM32, WHICH)
94
95
/**
96
* cpu_mmu_index:
97
diff --git a/target/arm/translate.h b/target/arm/translate.h
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/arm/translate.h
100
+++ b/target/arm/translate.h
101
@@ -XXX,XX +XXX,XX @@ typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
102
*/
103
static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb)
20
{
104
{
21
+ /* The irq[] array is tx, rx, combined, in that order */
105
- return (CPUARMTBFlags){ tb->flags };
22
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
106
+ return (CPUARMTBFlags){ tb->flags, tb->cs_base };
23
CMSDKAPBUART *uart = opaque;
24
int i = uart - &mms->uart[0];
25
- int rxirqno = i * 2 + 32;
26
- int txirqno = i * 2 + 33;
27
- int combirqno = i + 42;
28
SysBusDevice *s;
29
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
30
31
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
32
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
33
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
34
s = SYS_BUS_DEVICE(uart);
35
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
36
- sysbus_connect_irq(s, 1, get_sse_irq_in(mms, rxirqno));
37
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
38
+ sysbus_connect_irq(s, 1, get_sse_irq_in(mms, irqs[1]));
39
sysbus_connect_irq(s, 2, qdev_get_gpio_in(orgate_dev, i * 2));
40
sysbus_connect_irq(s, 3, qdev_get_gpio_in(orgate_dev, i * 2 + 1));
41
- sysbus_connect_irq(s, 4, get_sse_irq_in(mms, combirqno));
42
+ sysbus_connect_irq(s, 4, get_sse_irq_in(mms, irqs[2]));
43
return sysbus_mmio_get_region(SYS_BUS_DEVICE(uart), 0);
44
}
107
}
45
108
46
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
109
/*
47
110
diff --git a/target/arm/helper.c b/target/arm/helper.c
48
s = SYS_BUS_DEVICE(mms->lan9118);
111
index XXXXXXX..XXXXXXX 100644
49
sysbus_realize_and_unref(s, &error_fatal);
112
--- a/target/arm/helper.c
50
- sysbus_connect_irq(s, 0, get_sse_irq_in(mms, 48));
113
+++ b/target/arm/helper.c
51
+ sysbus_connect_irq(s, 0, get_sse_irq_in(mms, irqs[0]));
114
@@ -XXX,XX +XXX,XX @@ static inline void assert_hflags_rebuild_correctly(CPUARMState *env)
52
return sysbus_mmio_get_region(s, 0);
115
CPUARMTBFlags c = env->hflags;
116
CPUARMTBFlags r = rebuild_hflags_internal(env);
117
118
- if (unlikely(c.flags != r.flags)) {
119
- fprintf(stderr, "TCG hflags mismatch (current:0x%08x rebuilt:0x%08x)\n",
120
- c.flags, r.flags);
121
+ if (unlikely(c.flags != r.flags || c.flags2 != r.flags2)) {
122
+ fprintf(stderr, "TCG hflags mismatch "
123
+ "(current:(0x%08x,0x" TARGET_FMT_lx ")"
124
+ " rebuilt:(0x%08x,0x" TARGET_FMT_lx ")\n",
125
+ c.flags, c.flags2, r.flags, r.flags2);
126
abort();
127
}
128
#endif
129
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
130
{
131
CPUARMTBFlags flags;
132
133
- *cs_base = 0;
134
assert_hflags_rebuild_correctly(env);
135
flags = env->hflags;
136
137
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
138
}
139
140
*pflags = flags.flags;
141
+ *cs_base = flags.flags2;
53
}
142
}
54
143
55
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
144
#ifdef TARGET_AARCH64
56
const char *name, hwaddr size,
57
const int *irqs)
58
{
59
+ /* The irq[] array is DMACINTR, DMACINTERR, DMACINTTC, in that order */
60
PL080State *dma = opaque;
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);
89
}
90
91
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
92
}, {
93
.name = "apb_ppcexp1",
94
.ports = {
95
- { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000 },
96
- { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000 },
97
- { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000 },
98
- { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000 },
99
- { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000 },
100
- { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000 },
101
- { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000 },
102
- { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000 },
103
- { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000 },
104
- { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000 },
105
+ { "spi0", make_spi, &mms->spi[0], 0x40205000, 0x1000, { 51 } },
106
+ { "spi1", make_spi, &mms->spi[1], 0x40206000, 0x1000, { 52 } },
107
+ { "spi2", make_spi, &mms->spi[2], 0x40209000, 0x1000, { 53 } },
108
+ { "spi3", make_spi, &mms->spi[3], 0x4020a000, 0x1000, { 54 } },
109
+ { "spi4", make_spi, &mms->spi[4], 0x4020b000, 0x1000, { 55 } },
110
+ { "uart0", make_uart, &mms->uart[0], 0x40200000, 0x1000, { 32, 33, 42 } },
111
+ { "uart1", make_uart, &mms->uart[1], 0x40201000, 0x1000, { 34, 35, 43 } },
112
+ { "uart2", make_uart, &mms->uart[2], 0x40202000, 0x1000, { 36, 37, 44 } },
113
+ { "uart3", make_uart, &mms->uart[3], 0x40203000, 0x1000, { 38, 39, 45 } },
114
+ { "uart4", make_uart, &mms->uart[4], 0x40204000, 0x1000, { 40, 41, 46 } },
115
{ "i2c0", make_i2c, &mms->i2c[0], 0x40207000, 0x1000 },
116
{ "i2c1", make_i2c, &mms->i2c[1], 0x40208000, 0x1000 },
117
{ "i2c2", make_i2c, &mms->i2c[2], 0x4020c000, 0x1000 },
118
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
119
{ "gpio1", make_unimp_dev, &mms->gpio[1], 0x40101000, 0x1000 },
120
{ "gpio2", make_unimp_dev, &mms->gpio[2], 0x40102000, 0x1000 },
121
{ "gpio3", make_unimp_dev, &mms->gpio[3], 0x40103000, 0x1000 },
122
- { "eth", make_eth_dev, NULL, 0x42000000, 0x100000 },
123
+ { "eth", make_eth_dev, NULL, 0x42000000, 0x100000, { 48 } },
124
},
125
}, {
126
.name = "ahb_ppcexp1",
127
.ports = {
128
- { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000 },
129
- { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000 },
130
- { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000 },
131
- { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000 },
132
+ { "dma0", make_dma, &mms->dma[0], 0x40110000, 0x1000, { 58, 56, 57 } },
133
+ { "dma1", make_dma, &mms->dma[1], 0x40111000, 0x1000, { 61, 59, 60 } },
134
+ { "dma2", make_dma, &mms->dma[2], 0x40112000, 0x1000, { 64, 62, 63 } },
135
+ { "dma3", make_dma, &mms->dma[3], 0x40113000, 0x1000, { 67, 65, 66 } },
136
},
137
},
138
};
139
--
145
--
140
2.20.1
146
2.20.1
141
147
142
148
diff view generated by jsdifflib
1
The omap_lcdc template header is already only included once, for
1
From: Richard Henderson <richard.henderson@linaro.org>
2
DEPTH==32, but it still has all the macro-driven parameterization
3
for other depths. Expand out all the macros in the header.
4
2
3
Now that these bits have been moved out of tb->flags,
4
where TBFLAG_ANY was filling from the top, move AM32
5
to fill from the top, and A32 and M32 to fill from the
6
bottom. This means fewer changes when adding new bits.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210419202257.161730-9-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20210215103215.4944-6-peter.maydell@linaro.org
9
---
12
---
10
hw/display/omap_lcd_template.h | 67 ++++++++++++++--------------------
13
target/arm/cpu.h | 42 +++++++++++++++++++++---------------------
11
1 file changed, 28 insertions(+), 39 deletions(-)
14
1 file changed, 21 insertions(+), 21 deletions(-)
12
15
13
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/display/omap_lcd_template.h
18
--- a/target/arm/cpu.h
16
+++ b/hw/display/omap_lcd_template.h
19
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
18
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21
*
22
* The bits for 32-bit A-profile and M-profile partially overlap:
23
*
24
- * 18 9 0
25
- * +----------------+--------------+
26
- * | TBFLAG_A32 | |
27
- * +-----+----------+ TBFLAG_AM32 |
28
- * | |TBFLAG_M32| |
29
- * +-----+----------+--------------+
30
- * 14 9 0
31
+ * 31 23 11 10 0
32
+ * +-------------+----------+----------------+
33
+ * | | | TBFLAG_A32 |
34
+ * | TBFLAG_AM32 | +-----+----------+
35
+ * | | |TBFLAG_M32|
36
+ * +-------------+----------------+----------+
37
+ * 31 23 5 4 0
38
*
39
* Unless otherwise noted, these bits are cached in env->hflags.
19
*/
40
*/
20
41
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 20, 2)
21
-#if DEPTH == 32
22
-# define BPP 4
23
-# define PIXEL_TYPE uint32_t
24
-#else
25
-# error unsupport depth
26
-#endif
27
-
28
/*
42
/*
29
* 2-bit colour
43
* Bit usage when in AArch32 state, both A- and M-profile.
30
*/
44
*/
31
-static void glue(draw_line2_, DEPTH)(void *opaque,
45
-FIELD(TBFLAG_AM32, CONDEXEC, 0, 8) /* Not cached. */
32
- uint8_t *d, const uint8_t *s, int width, int deststep)
46
-FIELD(TBFLAG_AM32, THUMB, 8, 1) /* Not cached. */
33
+static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
47
+FIELD(TBFLAG_AM32, CONDEXEC, 24, 8) /* Not cached. */
34
+ int width, int deststep)
48
+FIELD(TBFLAG_AM32, THUMB, 23, 1) /* Not cached. */
35
{
49
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
/*
50
/*
75
* 4-bit colour
51
* Bit usage when in AArch32 state, for A-profile only.
76
*/
52
*/
77
-static void glue(draw_line4_, DEPTH)(void *opaque,
53
-FIELD(TBFLAG_A32, VECLEN, 9, 3) /* Not cached. */
78
- uint8_t *d, const uint8_t *s, int width, int deststep)
54
-FIELD(TBFLAG_A32, VECSTRIDE, 12, 2) /* Not cached. */
79
+static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
55
+FIELD(TBFLAG_A32, VECLEN, 0, 3) /* Not cached. */
80
+ int width, int deststep)
56
+FIELD(TBFLAG_A32, VECSTRIDE, 3, 2) /* Not cached. */
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
/*
57
/*
105
* 8-bit colour
58
* We store the bottom two bits of the CPAR as TB flags and handle
59
* checks on the other bits at runtime. This shares the same bits as
60
* VECSTRIDE, which is OK as no XScale CPU has VFP.
61
* Not cached, because VECLEN+VECSTRIDE are not cached.
106
*/
62
*/
107
-static void glue(draw_line8_, DEPTH)(void *opaque,
63
-FIELD(TBFLAG_A32, XSCALE_CPAR, 12, 2)
108
- uint8_t *d, const uint8_t *s, int width, int deststep)
64
-FIELD(TBFLAG_A32, VFPEN, 14, 1) /* Partially cached, minus FPEXC. */
109
+static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
65
-FIELD(TBFLAG_A32, SCTLR__B, 15, 1) /* Cannot overlap with SCTLR_B */
110
+ int width, int deststep)
66
-FIELD(TBFLAG_A32, HSTR_ACTIVE, 16, 1)
111
{
67
+FIELD(TBFLAG_A32, XSCALE_CPAR, 5, 2)
112
uint16_t *pal = opaque;
68
+FIELD(TBFLAG_A32, VFPEN, 7, 1) /* Partially cached, minus FPEXC. */
113
uint8_t v, r, g, b;
69
+FIELD(TBFLAG_A32, SCTLR__B, 8, 1) /* Cannot overlap with SCTLR_B */
114
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line8_, DEPTH)(void *opaque,
70
+FIELD(TBFLAG_A32, HSTR_ACTIVE, 9, 1)
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);
124
}
125
126
/*
71
/*
127
* 12-bit colour
72
* Indicates whether cp register reads and writes by guest code should access
73
* the secure or nonsecure bank of banked registers; note that this is not
74
* the same thing as the current security state of the processor!
128
*/
75
*/
129
-static void glue(draw_line12_, DEPTH)(void *opaque,
76
-FIELD(TBFLAG_A32, NS, 17, 1)
130
- uint8_t *d, const uint8_t *s, int width, int deststep)
77
+FIELD(TBFLAG_A32, NS, 10, 1)
131
+static void draw_line12_32(void *opaque, uint8_t *d, const uint8_t *s,
132
+ int width, int deststep)
133
{
134
uint16_t v;
135
uint8_t r, g, b;
136
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line12_, DEPTH)(void *opaque,
137
r = (v >> 4) & 0xf0;
138
g = v & 0xf0;
139
b = (v << 4) & 0xf0;
140
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
141
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
142
s += 2;
143
- d += BPP;
144
+ d += 4;
145
} while (-- width != 0);
146
}
147
78
148
/*
79
/*
149
* 16-bit colour
80
* Bit usage when in AArch32 state, for M-profile only.
150
*/
81
*/
151
-static void glue(draw_line16_, DEPTH)(void *opaque,
82
/* Handler (ie not Thread) mode */
152
- uint8_t *d, const uint8_t *s, int width, int deststep)
83
-FIELD(TBFLAG_M32, HANDLER, 9, 1)
153
+static void draw_line16_32(void *opaque, uint8_t *d, const uint8_t *s,
84
+FIELD(TBFLAG_M32, HANDLER, 0, 1)
154
+ int width, int deststep)
85
/* Whether we should generate stack-limit checks */
155
{
86
-FIELD(TBFLAG_M32, STACKCHECK, 10, 1)
156
#if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN)
87
+FIELD(TBFLAG_M32, STACKCHECK, 1, 1)
157
memcpy(d, s, width * 2);
88
/* Set if FPCCR.LSPACT is set */
158
@@ -XXX,XX +XXX,XX @@ static void glue(draw_line16_, DEPTH)(void *opaque,
89
-FIELD(TBFLAG_M32, LSPACT, 11, 1) /* Not cached. */
159
r = (v >> 8) & 0xf8;
90
+FIELD(TBFLAG_M32, LSPACT, 2, 1) /* Not cached. */
160
g = (v >> 3) & 0xfc;
91
/* Set if we must create a new FP context */
161
b = (v << 3) & 0xf8;
92
-FIELD(TBFLAG_M32, NEW_FP_CTXT_NEEDED, 12, 1) /* Not cached. */
162
- ((PIXEL_TYPE *) d)[0] = glue(rgb_to_pixel, DEPTH)(r, g, b);
93
+FIELD(TBFLAG_M32, NEW_FP_CTXT_NEEDED, 3, 1) /* Not cached. */
163
+ ((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
94
/* Set if FPCCR.S does not match current security state */
164
s += 2;
95
-FIELD(TBFLAG_M32, FPCCR_S_WRONG, 13, 1) /* Not cached. */
165
- d += BPP;
96
+FIELD(TBFLAG_M32, FPCCR_S_WRONG, 4, 1) /* Not cached. */
166
+ d += 4;
97
167
} while (-- width != 0);
98
/*
168
#endif
99
* Bit usage when in AArch64 state
169
}
170
-
171
-#undef DEPTH
172
-#undef BPP
173
-#undef PIXEL_TYPE
174
--
100
--
175
2.20.1
101
2.20.1
176
102
177
103
diff view generated by jsdifflib
1
For a long time now the UI layer has guaranteed that the console
1
From: Richard Henderson <richard.henderson@linaro.org>
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().
8
2
9
Drop the never-used BGR-handling code, and assert that we have
3
Now that other bits have been moved out of tb->flags,
10
a 32-bit surface rather than just doing nothing if it isn't.
4
there's no point in filling from the top.
11
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210419202257.161730-10-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
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
---
10
---
17
hw/display/tcx.c | 31 ++++++++-----------------------
11
target/arm/cpu.h | 14 +++++++-------
18
1 file changed, 8 insertions(+), 23 deletions(-)
12
1 file changed, 7 insertions(+), 7 deletions(-)
19
13
20
diff --git a/hw/display/tcx.c b/hw/display/tcx.c
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/display/tcx.c
16
--- a/target/arm/cpu.h
23
+++ b/hw/display/tcx.c
17
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ static int tcx_check_dirty(TCXState *s, DirtyBitmapSnapshot *snap,
18
@@ -XXX,XX +XXX,XX @@ typedef ARMCPU ArchCPU;
25
19
*
26
static void update_palette_entries(TCXState *s, int start, int end)
20
* Unless otherwise noted, these bits are cached in env->hflags.
27
{
21
*/
28
- DisplaySurface *surface = qemu_console_surface(s->con);
22
-FIELD(TBFLAG_ANY, AARCH64_STATE, 31, 1)
29
int i;
23
-FIELD(TBFLAG_ANY, SS_ACTIVE, 30, 1)
30
24
-FIELD(TBFLAG_ANY, PSTATE__SS, 29, 1) /* Not cached. */
31
for (i = start; i < end; i++) {
25
-FIELD(TBFLAG_ANY, BE_DATA, 28, 1)
32
- if (is_surface_bgr(surface)) {
26
-FIELD(TBFLAG_ANY, MMUIDX, 24, 4)
33
- s->palette[i] = rgb_to_pixel32bgr(s->r[i], s->g[i], s->b[i]);
27
+FIELD(TBFLAG_ANY, AARCH64_STATE, 0, 1)
34
- } else {
28
+FIELD(TBFLAG_ANY, SS_ACTIVE, 1, 1)
35
- s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
29
+FIELD(TBFLAG_ANY, PSTATE__SS, 2, 1) /* Not cached. */
36
- }
30
+FIELD(TBFLAG_ANY, BE_DATA, 3, 1)
37
+ s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
31
+FIELD(TBFLAG_ANY, MMUIDX, 4, 4)
38
}
32
/* Target EL if we take a floating-point-disabled exception */
39
tcx_set_dirty(s, 0, memory_region_size(&s->vram_mem));
33
-FIELD(TBFLAG_ANY, FPEXC_EL, 22, 2)
40
}
34
+FIELD(TBFLAG_ANY, FPEXC_EL, 8, 2)
41
@@ -XXX,XX +XXX,XX @@ static void tcx_draw_cursor32(TCXState *s1, uint8_t *d,
35
/* For A-profile only, target EL for debug exceptions. */
42
}
36
-FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 20, 2)
37
+FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 10, 2)
43
38
44
/*
39
/*
45
- XXX Could be much more optimal:
40
* Bit usage when in AArch32 state, both A- and M-profile.
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
--
41
--
102
2.20.1
42
2.20.1
103
43
104
44
diff view generated by jsdifflib
1
The AN505 and AN521 have the same device layout, but the AN524 is
1
From: Richard Henderson <richard.henderson@linaro.org>
2
somewhat different. Allow for more than one PPCInfo array, which can
3
be selected based on the board type.
4
2
3
Use this to signal when memory access alignment is required.
4
This value comes from the CCR register for M-profile, and
5
from the SCTLR register for A-profile.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210419202257.161730-11-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210215115138.20465-16-peter.maydell@linaro.org
8
---
11
---
9
hw/arm/mps2-tz.c | 16 ++++++++++++++--
12
target/arm/cpu.h | 2 ++
10
1 file changed, 14 insertions(+), 2 deletions(-)
13
target/arm/translate.h | 2 ++
14
target/arm/helper.c | 19 +++++++++++++++++--
15
target/arm/translate-a64.c | 1 +
16
target/arm/translate.c | 7 +++----
17
5 files changed, 25 insertions(+), 6 deletions(-)
11
18
12
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/mps2-tz.c
21
--- a/target/arm/cpu.h
15
+++ b/hw/arm/mps2-tz.c
22
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
23
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, MMUIDX, 4, 4)
17
MemoryRegion *system_memory = get_system_memory();
24
FIELD(TBFLAG_ANY, FPEXC_EL, 8, 2)
18
DeviceState *iotkitdev;
25
/* For A-profile only, target EL for debug exceptions. */
19
DeviceState *dev_splitter;
26
FIELD(TBFLAG_ANY, DEBUG_TARGET_EL, 10, 2)
20
+ const PPCInfo *ppcs;
27
+/* Memory operations require alignment: SCTLR_ELx.A or CCR.UNALIGN_TRP */
21
+ int num_ppcs;
28
+FIELD(TBFLAG_ANY, ALIGN_MEM, 12, 1)
22
int i;
29
23
30
/*
24
if (strcmp(machine->cpu_type, mc->default_cpu_type) != 0) {
31
* Bit usage when in AArch32 state, both A- and M-profile.
25
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
32
diff --git a/target/arm/translate.h b/target/arm/translate.h
26
* + wire up the PPC's control lines to the IoTKit object
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate.h
35
+++ b/target/arm/translate.h
36
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
37
bool bt;
38
/* True if any CP15 access is trapped by HSTR_EL2 */
39
bool hstr_active;
40
+ /* True if memory operations require alignment */
41
+ bool align_mem;
42
/*
43
* >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
44
* < 0, set by the current instruction.
45
diff --git a/target/arm/helper.c b/target/arm/helper.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/helper.c
48
+++ b/target/arm/helper.c
49
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
50
ARMMMUIdx mmu_idx)
51
{
52
CPUARMTBFlags flags = {};
53
+ uint32_t ccr = env->v7m.ccr[env->v7m.secure];
54
+
55
+ /* Without HaveMainExt, CCR.UNALIGN_TRP is RES1. */
56
+ if (ccr & R_V7M_CCR_UNALIGN_TRP_MASK) {
57
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
58
+ }
59
60
if (arm_v7m_is_handler_mode(env)) {
61
DP_TBFLAG_M32(flags, HANDLER, 1);
62
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_m32(CPUARMState *env, int fp_el,
27
*/
63
*/
28
64
if (arm_feature(env, ARM_FEATURE_V8) &&
29
- const PPCInfo ppcs[] = { {
65
!((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
30
+ const PPCInfo an505_ppcs[] = { {
66
- (env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
31
.name = "apb_ppcexp0",
67
+ (ccr & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
32
.ports = {
68
DP_TBFLAG_M32(flags, STACKCHECK, 1);
33
{ "ssram-0", make_mpc, &mms->ssram_mpc[0], 0x58007000, 0x1000 },
69
}
34
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
70
35
},
71
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a32(CPUARMState *env, int fp_el,
36
};
72
ARMMMUIdx mmu_idx)
37
73
{
38
- for (i = 0; i < ARRAY_SIZE(ppcs); i++) {
74
CPUARMTBFlags flags = rebuild_hflags_aprofile(env);
39
+ switch (mmc->fpga_type) {
75
+ int el = arm_current_el(env);
40
+ case FPGA_AN505:
76
+
41
+ case FPGA_AN521:
77
+ if (arm_sctlr(env, el) & SCTLR_A) {
42
+ ppcs = an505_ppcs;
78
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
43
+ num_ppcs = ARRAY_SIZE(an505_ppcs);
79
+ }
44
+ break;
80
45
+ default:
81
if (arm_el_is_aa64(env, 1)) {
46
+ g_assert_not_reached();
82
DP_TBFLAG_A32(flags, VFPEN, 1);
83
}
84
85
- if (arm_current_el(env) < 2 && env->cp15.hstr_el2 &&
86
+ if (el < 2 && env->cp15.hstr_el2 &&
87
(arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
88
DP_TBFLAG_A32(flags, HSTR_ACTIVE, 1);
89
}
90
@@ -XXX,XX +XXX,XX @@ static CPUARMTBFlags rebuild_hflags_a64(CPUARMState *env, int el, int fp_el,
91
92
sctlr = regime_sctlr(env, stage1);
93
94
+ if (sctlr & SCTLR_A) {
95
+ DP_TBFLAG_ANY(flags, ALIGN_MEM, 1);
47
+ }
96
+ }
48
+
97
+
49
+ for (i = 0; i < num_ppcs; i++) {
98
if (arm_cpu_data_is_big_endian_a64(el, sctlr)) {
50
const PPCInfo *ppcinfo = &ppcs[i];
99
DP_TBFLAG_ANY(flags, BE_DATA, 1);
51
TZPPC *ppc = &mms->ppc[i];
100
}
52
DeviceState *ppcdev;
101
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
102
index XXXXXXX..XXXXXXX 100644
103
--- a/target/arm/translate-a64.c
104
+++ b/target/arm/translate-a64.c
105
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
106
dc->user = (dc->current_el == 0);
107
#endif
108
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
109
+ dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
110
dc->sve_excp_el = EX_TBFLAG_A64(tb_flags, SVEEXC_EL);
111
dc->sve_len = (EX_TBFLAG_A64(tb_flags, ZCR_LEN) + 1) * 16;
112
dc->pauth_active = EX_TBFLAG_A64(tb_flags, PAUTH_ACTIVE);
113
diff --git a/target/arm/translate.c b/target/arm/translate.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/arm/translate.c
116
+++ b/target/arm/translate.c
117
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
118
{
119
TCGv addr;
120
121
- if (arm_dc_feature(s, ARM_FEATURE_M) &&
122
- !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
123
+ if (s->align_mem) {
124
opc |= MO_ALIGN;
125
}
126
127
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
128
{
129
TCGv addr;
130
131
- if (arm_dc_feature(s, ARM_FEATURE_M) &&
132
- !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
133
+ if (s->align_mem) {
134
opc |= MO_ALIGN;
135
}
136
137
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
138
dc->user = (dc->current_el == 0);
139
#endif
140
dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
141
+ dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
142
143
if (arm_feature(env, ARM_FEATURE_M)) {
144
dc->vfp_enabled = 1;
53
--
145
--
54
2.20.1
146
2.20.1
55
147
56
148
diff view generated by jsdifflib
1
The armv7m_load_kernel() function takes a mem_size argument which it
1
From: Richard Henderson <richard.henderson@linaro.org>
2
expects to be the size of the memory region at guest address 0. (It
2
3
uses this argument only as a limit on how large a raw image file it
3
Create a finalize_memop function that computes alignment and
4
can load at address zero).
4
endianness and returns the final MemOp for the operation.
5
5
6
Instead of hardcoding this value, find the RAMInfo corresponding to
6
Split out gen_aa32_{ld,st}_internal_i32 which bypasses any special
7
the 0 address and extract its size.
7
handling of endianness or alignment. Adjust gen_aa32_{ld,st}_i32
8
8
so that s->be_data is not added by the callers.
9
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210419202257.161730-12-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-20-peter.maydell@linaro.org
13
---
14
---
14
hw/arm/mps2-tz.c | 17 ++++++++++++++++-
15
target/arm/translate.h | 24 ++++++++
15
1 file changed, 16 insertions(+), 1 deletion(-)
16
target/arm/translate.c | 100 +++++++++++++++++---------------
16
17
target/arm/translate-neon.c.inc | 9 +--
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
3 files changed, 79 insertions(+), 54 deletions(-)
19
20
diff --git a/target/arm/translate.h b/target/arm/translate.h
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2-tz.c
22
--- a/target/arm/translate.h
20
+++ b/hw/arm/mps2-tz.c
23
+++ b/target/arm/translate.h
21
@@ -XXX,XX +XXX,XX @@ static void create_non_mpc_ram(MPS2TZMachineState *mms)
24
@@ -XXX,XX +XXX,XX @@ static inline TCGv_ptr fpstatus_ptr(ARMFPStatusFlavour flavour)
22
}
25
return statusptr;
23
}
26
}
24
27
25
+static uint32_t boot_ram_size(MPS2TZMachineState *mms)
28
+/**
29
+ * finalize_memop:
30
+ * @s: DisasContext
31
+ * @opc: size+sign+align of the memory operation
32
+ *
33
+ * Build the complete MemOp for a memory operation, including alignment
34
+ * and endianness.
35
+ *
36
+ * If (op & MO_AMASK) then the operation already contains the required
37
+ * alignment, e.g. for AccType_ATOMIC. Otherwise, this an optionally
38
+ * unaligned operation, e.g. for AccType_NORMAL.
39
+ *
40
+ * In the latter case, there are configuration bits that require alignment,
41
+ * and this is applied here. Note that there is no way to indicate that
42
+ * no alignment should ever be enforced; this must be handled manually.
43
+ */
44
+static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
26
+{
45
+{
27
+ /* Return the size of the RAM block at guest address zero */
46
+ if (s->align_mem && !(opc & MO_AMASK)) {
28
+ const RAMInfo *p;
47
+ opc |= MO_ALIGN;
29
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
30
+
31
+ for (p = mmc->raminfo; p->name; p++) {
32
+ if (p->base == 0) {
33
+ return p->size;
34
+ }
35
+ }
48
+ }
36
+ g_assert_not_reached();
49
+ return opc | s->be_data;
37
+}
50
+}
38
+
51
+
39
static void mps2tz_common_init(MachineState *machine)
52
#endif /* TARGET_ARM_TRANSLATE_H */
53
diff --git a/target/arm/translate.c b/target/arm/translate.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.c
56
+++ b/target/arm/translate.c
57
@@ -XXX,XX +XXX,XX @@ static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
58
#define IS_USER_ONLY 0
59
#endif
60
61
-/* Abstractions of "generate code to do a guest load/store for
62
+/*
63
+ * Abstractions of "generate code to do a guest load/store for
64
* AArch32", where a vaddr is always 32 bits (and is zero
65
* extended if we're a 64 bit core) and data is also
66
* 32 bits unless specifically doing a 64 bit access.
67
@@ -XXX,XX +XXX,XX @@ static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
68
* that the address argument is TCGv_i32 rather than TCGv.
69
*/
70
71
-static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
72
+static TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
40
{
73
{
41
MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
74
TCGv addr = tcg_temp_new();
42
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
75
tcg_gen_extu_i32_tl(addr, a32);
43
76
@@ -XXX,XX +XXX,XX @@ static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
44
create_non_mpc_ram(mms);
77
return addr;
45
46
- armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename, 0x400000);
47
+ armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
48
+ boot_ram_size(mms));
49
}
78
}
50
79
51
static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
80
+/*
81
+ * Internal routines are used for NEON cases where the endianness
82
+ * and/or alignment has already been taken into account and manipulated.
83
+ */
84
+static void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
85
+ TCGv_i32 a32, int index, MemOp opc)
86
+{
87
+ TCGv addr = gen_aa32_addr(s, a32, opc);
88
+ tcg_gen_qemu_ld_i32(val, addr, index, opc);
89
+ tcg_temp_free(addr);
90
+}
91
+
92
+static void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
93
+ TCGv_i32 a32, int index, MemOp opc)
94
+{
95
+ TCGv addr = gen_aa32_addr(s, a32, opc);
96
+ tcg_gen_qemu_st_i32(val, addr, index, opc);
97
+ tcg_temp_free(addr);
98
+}
99
+
100
static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
101
int index, MemOp opc)
102
{
103
- TCGv addr;
104
-
105
- if (s->align_mem) {
106
- opc |= MO_ALIGN;
107
- }
108
-
109
- addr = gen_aa32_addr(s, a32, opc);
110
- tcg_gen_qemu_ld_i32(val, addr, index, opc);
111
- tcg_temp_free(addr);
112
+ gen_aa32_ld_internal_i32(s, val, a32, index, finalize_memop(s, opc));
113
}
114
115
static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
116
int index, MemOp opc)
117
{
118
- TCGv addr;
119
+ gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
120
+}
121
122
- if (s->align_mem) {
123
- opc |= MO_ALIGN;
124
+#define DO_GEN_LD(SUFF, OPC) \
125
+ static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
126
+ TCGv_i32 a32, int index) \
127
+ { \
128
+ gen_aa32_ld_i32(s, val, a32, index, OPC); \
129
}
130
131
- addr = gen_aa32_addr(s, a32, opc);
132
- tcg_gen_qemu_st_i32(val, addr, index, opc);
133
- tcg_temp_free(addr);
134
-}
135
-
136
-#define DO_GEN_LD(SUFF, OPC) \
137
-static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
138
- TCGv_i32 a32, int index) \
139
-{ \
140
- gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
141
-}
142
-
143
-#define DO_GEN_ST(SUFF, OPC) \
144
-static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
145
- TCGv_i32 a32, int index) \
146
-{ \
147
- gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
148
-}
149
+#define DO_GEN_ST(SUFF, OPC) \
150
+ static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
151
+ TCGv_i32 a32, int index) \
152
+ { \
153
+ gen_aa32_st_i32(s, val, a32, index, OPC); \
154
+ }
155
156
static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
157
{
158
@@ -XXX,XX +XXX,XX @@ static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
159
addr = op_addr_rr_pre(s, a);
160
161
tmp = tcg_temp_new_i32();
162
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
163
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
164
disas_set_da_iss(s, mop, issinfo);
165
166
/*
167
@@ -XXX,XX +XXX,XX @@ static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
168
addr = op_addr_rr_pre(s, a);
169
170
tmp = load_reg(s, a->rt);
171
- gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
172
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
173
disas_set_da_iss(s, mop, issinfo);
174
tcg_temp_free_i32(tmp);
175
176
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
177
addr = op_addr_rr_pre(s, a);
178
179
tmp = tcg_temp_new_i32();
180
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
181
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
182
store_reg(s, a->rt, tmp);
183
184
tcg_gen_addi_i32(addr, addr, 4);
185
186
tmp = tcg_temp_new_i32();
187
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
188
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
189
store_reg(s, a->rt + 1, tmp);
190
191
/* LDRD w/ base writeback is undefined if the registers overlap. */
192
@@ -XXX,XX +XXX,XX @@ static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
193
addr = op_addr_rr_pre(s, a);
194
195
tmp = load_reg(s, a->rt);
196
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
197
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
198
tcg_temp_free_i32(tmp);
199
200
tcg_gen_addi_i32(addr, addr, 4);
201
202
tmp = load_reg(s, a->rt + 1);
203
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
204
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
205
tcg_temp_free_i32(tmp);
206
207
op_addr_rr_post(s, a, addr, -4);
208
@@ -XXX,XX +XXX,XX @@ static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
209
addr = op_addr_ri_pre(s, a);
210
211
tmp = tcg_temp_new_i32();
212
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
213
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
214
disas_set_da_iss(s, mop, issinfo);
215
216
/*
217
@@ -XXX,XX +XXX,XX @@ static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
218
addr = op_addr_ri_pre(s, a);
219
220
tmp = load_reg(s, a->rt);
221
- gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
222
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
223
disas_set_da_iss(s, mop, issinfo);
224
tcg_temp_free_i32(tmp);
225
226
@@ -XXX,XX +XXX,XX @@ static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
227
addr = op_addr_ri_pre(s, a);
228
229
tmp = tcg_temp_new_i32();
230
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
231
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
232
store_reg(s, a->rt, tmp);
233
234
tcg_gen_addi_i32(addr, addr, 4);
235
236
tmp = tcg_temp_new_i32();
237
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
238
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
239
store_reg(s, rt2, tmp);
240
241
/* LDRD w/ base writeback is undefined if the registers overlap. */
242
@@ -XXX,XX +XXX,XX @@ static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
243
addr = op_addr_ri_pre(s, a);
244
245
tmp = load_reg(s, a->rt);
246
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
247
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
248
tcg_temp_free_i32(tmp);
249
250
tcg_gen_addi_i32(addr, addr, 4);
251
252
tmp = load_reg(s, rt2);
253
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
254
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
255
tcg_temp_free_i32(tmp);
256
257
op_addr_ri_post(s, a, addr, -4);
258
@@ -XXX,XX +XXX,XX @@ static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
259
addr = load_reg(s, a->rn);
260
tmp = load_reg(s, a->rt);
261
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
262
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
263
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop);
264
disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
265
266
tcg_temp_free_i32(tmp);
267
@@ -XXX,XX +XXX,XX @@ static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
268
269
addr = load_reg(s, a->rn);
270
tmp = tcg_temp_new_i32();
271
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
272
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop);
273
disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
274
tcg_temp_free_i32(addr);
275
276
@@ -XXX,XX +XXX,XX @@ static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
277
addr = load_reg(s, a->rn);
278
tcg_gen_add_i32(addr, addr, tmp);
279
280
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
281
- half ? MO_UW | s->be_data : MO_UB);
282
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), half ? MO_UW : MO_UB);
283
tcg_temp_free_i32(addr);
284
285
tcg_gen_add_i32(tmp, tmp, tmp);
286
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
287
index XXXXXXX..XXXXXXX 100644
288
--- a/target/arm/translate-neon.c.inc
289
+++ b/target/arm/translate-neon.c.inc
290
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
291
addr = tcg_temp_new_i32();
292
load_reg_var(s, addr, a->rn);
293
for (reg = 0; reg < nregs; reg++) {
294
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
295
- s->be_data | size);
296
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), size);
297
if ((vd & 1) && vec_size == 16) {
298
/*
299
* We cannot write 16 bytes at once because the
300
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
301
*/
302
for (reg = 0; reg < nregs; reg++) {
303
if (a->l) {
304
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
305
- s->be_data | a->size);
306
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), a->size);
307
neon_store_element(vd, a->reg_idx, a->size, tmp);
308
} else { /* Store */
309
neon_load_element(tmp, vd, a->reg_idx, a->size);
310
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
311
- s->be_data | a->size);
312
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), a->size);
313
}
314
vd += a->stride;
315
tcg_gen_addi_i32(addr, addr, 1 << a->size);
52
--
316
--
53
2.20.1
317
2.20.1
54
318
55
319
diff view generated by jsdifflib
1
For a long time now the UI layer has guaranteed that the console
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
5
2
3
This is the only caller. Adjust some commentary to talk
4
about SCTLR_B instead of the vanishing function.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210419202257.161730-13-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215103215.4944-3-peter.maydell@linaro.org
9
---
10
---
10
include/ui/console.h | 10 ----------
11
target/arm/translate.c | 37 ++++++++++++++++---------------------
11
hw/display/tc6393xb.c | 33 +--------------------------------
12
1 file changed, 16 insertions(+), 21 deletions(-)
12
2 files changed, 1 insertion(+), 42 deletions(-)
13
13
14
diff --git a/include/ui/console.h b/include/ui/console.h
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/ui/console.h
16
--- a/target/arm/translate.c
17
+++ b/include/ui/console.h
17
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ PixelFormat qemu_default_pixelformat(int bpp);
18
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
19
DisplaySurface *qemu_create_displaysurface(int width, int height);
19
gen_aa32_st_i32(s, val, a32, index, OPC); \
20
void qemu_free_displaysurface(DisplaySurface *surface);
20
}
21
21
22
-static inline int is_surface_bgr(DisplaySurface *surface)
22
-static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
23
-{
23
-{
24
- if (PIXMAN_FORMAT_BPP(surface->format) == 32 &&
24
- /* Not needed for user-mode BE32, where we use MO_BE instead. */
25
- PIXMAN_FORMAT_TYPE(surface->format) == PIXMAN_TYPE_ABGR) {
25
- if (!IS_USER_ONLY && s->sctlr_b) {
26
- return 1;
26
- tcg_gen_rotri_i64(val, val, 32);
27
- } else {
28
- return 0;
29
- }
27
- }
30
-}
28
-}
31
-
29
-
32
static inline int is_buffer_shared(DisplaySurface *surface)
30
static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
31
int index, MemOp opc)
33
{
32
{
34
return !(surface->flags & QEMU_ALLOCATED_FLAG);
33
TCGv addr = gen_aa32_addr(s, a32, opc);
35
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
34
tcg_gen_qemu_ld_i64(val, addr, index, opc);
36
index XXXXXXX..XXXXXXX 100644
35
- gen_aa32_frob64(s, val);
37
--- a/hw/display/tc6393xb.c
36
+
38
+++ b/hw/display/tc6393xb.c
37
+ /* Not needed for user-mode BE32, where we use MO_BE instead. */
39
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_nand_writeb(TC6393xbState *s, hwaddr addr, uint32_t value)
38
+ if (!IS_USER_ONLY && s->sctlr_b) {
40
(uint32_t) addr, value & 0xff);
39
+ tcg_gen_rotri_i64(val, val, 32);
40
+ }
41
+
42
tcg_temp_free(addr);
41
}
43
}
42
44
43
-#define BITS 8
45
@@ -XXX,XX +XXX,XX @@ static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
44
-#include "tc6393xb_template.h"
46
TCGv_i32 tmp2 = tcg_temp_new_i32();
45
-#define BITS 15
47
TCGv_i64 t64 = tcg_temp_new_i64();
46
-#include "tc6393xb_template.h"
48
47
-#define BITS 16
49
- /* For AArch32, architecturally the 32-bit word at the lowest
48
-#include "tc6393xb_template.h"
50
+ /*
49
-#define BITS 24
51
+ * For AArch32, architecturally the 32-bit word at the lowest
50
-#include "tc6393xb_template.h"
52
* address is always Rt and the one at addr+4 is Rt2, even if
51
#define BITS 32
53
* the CPU is big-endian. That means we don't want to do a
52
#include "tc6393xb_template.h"
54
- * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
53
55
- * for an architecturally 64-bit access, but instead do a
54
static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update)
56
- * 64-bit access using MO_BE if appropriate and then split
55
{
57
- * the two halves.
56
- DisplaySurface *surface = qemu_console_surface(s->con);
58
- * This only makes a difference for BE32 user-mode, where
57
-
59
- * frob64() must not flip the two halves of the 64-bit data
58
- switch (surface_bits_per_pixel(surface)) {
60
- * but this code must treat BE32 user-mode like BE32 system.
59
- case 8:
61
+ * gen_aa32_ld_i64(), which checks SCTLR_B as if for an
60
- tc6393xb_draw_graphic8(s);
62
+ * architecturally 64-bit access, but instead do a 64-bit access
61
- break;
63
+ * using MO_BE if appropriate and then split the two halves.
62
- case 15:
64
*/
63
- tc6393xb_draw_graphic15(s);
65
TCGv taddr = gen_aa32_addr(s, addr, opc);
64
- break;
66
65
- case 16:
67
@@ -XXX,XX +XXX,XX @@ static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
66
- tc6393xb_draw_graphic16(s);
68
TCGv_i64 n64 = tcg_temp_new_i64();
67
- break;
69
68
- case 24:
70
t2 = load_reg(s, rt2);
69
- tc6393xb_draw_graphic24(s);
71
- /* For AArch32, architecturally the 32-bit word at the lowest
70
- break;
72
+
71
- case 32:
73
+ /*
72
- tc6393xb_draw_graphic32(s);
74
+ * For AArch32, architecturally the 32-bit word at the lowest
73
- break;
75
* address is always Rt and the one at addr+4 is Rt2, even if
74
- default:
76
* the CPU is big-endian. Since we're going to treat this as a
75
- printf("tc6393xb: unknown depth %d\n",
77
* single 64-bit BE store, we need to put the two halves in the
76
- surface_bits_per_pixel(surface));
78
* opposite order for BE to LE, so that they end up in the right
77
- return;
79
- * places.
78
- }
80
- * We don't want gen_aa32_frob64() because that does the wrong
79
-
81
- * thing for BE32 usermode.
80
+ tc6393xb_draw_graphic32(s);
82
+ * places. We don't want gen_aa32_st_i64, because that checks
81
dpy_gfx_update_full(s->con);
83
+ * SCTLR_B as if for an architectural 64-bit access.
82
}
84
*/
83
85
if (s->be_data == MO_BE) {
86
tcg_gen_concat_i32_i64(n64, t2, t1);
84
--
87
--
85
2.20.1
88
2.20.1
86
89
87
90
diff view generated by jsdifflib
1
From: schspa <schspa@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
At the moment the following QEMU command line triggers an assertion
3
Just because operating on a TCGv_i64 temporary does not
4
failure On xlnx-versal SOC:
4
mean that we're performing a 64-bit operation. Restrict
5
qemu-system-aarch64 \
5
the frobbing to actual 64-bit operations.
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
6
12
qemu-system-aarch64: ../migration/savevm.c:860:
7
This bug is not currently visible because all current
13
vmstate_register_with_alias_id:
8
users of these two functions always pass MO_64.
14
Assertion `!se->compat || se->instance_id == 0' failed.
15
9
16
This problem was fixed on arm virt platform in commit f58b39d2d5b
17
("virtio-mmio: format transport base address in BusClass.get_dev_path")
18
19
It works perfectly on arm virt platform. but there is still there on
20
xlnx-versal SOC.
21
22
The main difference between arm virt and xlnx-versal is they use
23
different way to create virtio-mmio qdev. on arm virt, it calls
24
sysbus_create_simple("virtio-mmio", base, pic[irq]); which will call
25
sysbus_mmio_map internally and assign base address to subsys device
26
mmio correctly. but xlnx-versal's implements won't do this.
27
28
However, xlnx-versal can't switch to sysbus_create_simple() to create
29
virtio-mmio device. It's because xlnx-versal's cpu use
30
VersalVirt.soc.fpd.apu.mr as it's memory. which is subregion of
31
system_memory. sysbus_create_simple will add virtio to system_memory,
32
which can't be accessed by cpu.
33
34
Besides, xlnx-versal can't add sysbus_mmio_map api call too, because
35
this will add memory region to system_memory, and it can't be added
36
to VersalVirt.soc.fpd.apu.mr again.
37
38
We can solve this by assign correct base address offset on dev_path.
39
40
This path was test on aarch64 virt & xlnx-versal platform.
41
42
Signed-off-by: schspa <schspa@gmail.com>
43
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210419202257.161730-14-richard.henderson@linaro.org
44
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
45
---
14
---
46
hw/virtio/virtio-mmio.c | 13 +++++++------
15
target/arm/translate.c | 4 ++--
47
1 file changed, 7 insertions(+), 6 deletions(-)
16
1 file changed, 2 insertions(+), 2 deletions(-)
48
17
49
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
50
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/virtio/virtio-mmio.c
20
--- a/target/arm/translate.c
52
+++ b/hw/virtio/virtio-mmio.c
21
+++ b/target/arm/translate.c
53
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
22
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
54
BusState *virtio_mmio_bus;
23
tcg_gen_qemu_ld_i64(val, addr, index, opc);
55
VirtIOMMIOProxy *virtio_mmio_proxy;
24
56
char *proxy_path;
25
/* Not needed for user-mode BE32, where we use MO_BE instead. */
57
- SysBusDevice *proxy_sbd;
26
- if (!IS_USER_ONLY && s->sctlr_b) {
58
char *path;
27
+ if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
59
+ MemoryRegionSection section;
28
tcg_gen_rotri_i64(val, val, 32);
60
61
virtio_mmio_bus = qdev_get_parent_bus(dev);
62
virtio_mmio_proxy = VIRTIO_MMIO(virtio_mmio_bus->parent);
63
@@ -XXX,XX +XXX,XX @@ static char *virtio_mmio_bus_get_dev_path(DeviceState *dev)
64
}
29
}
65
30
66
/* Otherwise, we append the base address of the transport. */
31
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
67
- proxy_sbd = SYS_BUS_DEVICE(virtio_mmio_proxy);
32
TCGv addr = gen_aa32_addr(s, a32, opc);
68
- assert(proxy_sbd->num_mmio == 1);
33
69
- assert(proxy_sbd->mmio[0].memory == &virtio_mmio_proxy->iomem);
34
/* Not needed for user-mode BE32, where we use MO_BE instead. */
70
+ section = memory_region_find(&virtio_mmio_proxy->iomem, 0, 0x200);
35
- if (!IS_USER_ONLY && s->sctlr_b) {
71
+ assert(section.mr);
36
+ if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
72
37
TCGv_i64 tmp = tcg_temp_new_i64();
73
if (proxy_path) {
38
tcg_gen_rotri_i64(tmp, val, 32);
74
path = g_strdup_printf("%s/virtio-mmio@" TARGET_FMT_plx, proxy_path,
39
tcg_gen_qemu_st_i64(tmp, addr, index, opc);
75
- proxy_sbd->mmio[0].addr);
76
+ section.offset_within_address_space);
77
} else {
78
path = g_strdup_printf("virtio-mmio@" TARGET_FMT_plx,
79
- proxy_sbd->mmio[0].addr);
80
+ section.offset_within_address_space);
81
}
82
+ memory_region_unref(section.mr);
83
+
84
g_free(proxy_path);
85
return path;
86
}
87
--
40
--
88
2.20.1
41
2.20.1
89
42
90
43
diff view generated by jsdifflib
1
Instead of hardcoding the MachineClass default_ram_size and
1
From: Richard Henderson <richard.henderson@linaro.org>
2
default_ram_id fields, set them on class creation by finding the
3
entry in the RAMInfo array which is marked as being the QEMU system
4
RAM.
5
2
3
Adjust the interface to match what has been done to the
4
TCGv_i32 load/store functions.
5
6
This is less obvious, because at present the only user of
7
these functions, trans_VLDST_multiple, also wants to manipulate
8
the endianness to speed up loading multiple bytes. Thus we
9
retain an "internal" interface which is identical to the
10
current gen_aa32_{ld,st}_i64 interface.
11
12
The "new" interface will gain users as we remove the legacy
13
interfaces, gen_aa32_ld64 and gen_aa32_st64.
14
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20210419202257.161730-15-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215115138.20465-18-peter.maydell@linaro.org
9
---
19
---
10
hw/arm/mps2-tz.c | 24 ++++++++++++++++++++++--
20
target/arm/translate.c | 78 +++++++++++++++++++--------------
11
1 file changed, 22 insertions(+), 2 deletions(-)
21
target/arm/translate-neon.c.inc | 6 ++-
22
2 files changed, 49 insertions(+), 35 deletions(-)
12
23
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
24
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
26
--- a/target/arm/translate.c
16
+++ b/hw/arm/mps2-tz.c
27
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ static void mps2tz_class_init(ObjectClass *oc, void *data)
28
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
18
29
tcg_temp_free(addr);
19
mc->init = mps2tz_common_init;
30
}
20
iic->check = mps2_tz_idau_check;
31
21
- mc->default_ram_size = 16 * MiB;
32
+static void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
22
- mc->default_ram_id = "mps.ram";
33
+ TCGv_i32 a32, int index, MemOp opc)
34
+{
35
+ TCGv addr = gen_aa32_addr(s, a32, opc);
36
+
37
+ tcg_gen_qemu_ld_i64(val, addr, index, opc);
38
+
39
+ /* Not needed for user-mode BE32, where we use MO_BE instead. */
40
+ if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
41
+ tcg_gen_rotri_i64(val, val, 32);
42
+ }
43
+ tcg_temp_free(addr);
23
+}
44
+}
24
+
45
+
25
+static void mps2tz_set_default_ram_info(MPS2TZMachineClass *mmc)
46
+static void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
47
+ TCGv_i32 a32, int index, MemOp opc)
26
+{
48
+{
27
+ /*
49
+ TCGv addr = gen_aa32_addr(s, a32, opc);
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;
33
+
50
+
34
+ for (p = mmc->raminfo; p->name; p++) {
51
+ /* Not needed for user-mode BE32, where we use MO_BE instead. */
35
+ if (p->mrindex < 0) {
52
+ if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
36
+ /* Found the entry for "system memory" */
53
+ TCGv_i64 tmp = tcg_temp_new_i64();
37
+ mc->default_ram_size = p->size;
54
+ tcg_gen_rotri_i64(tmp, val, 32);
38
+ mc->default_ram_id = p->name;
55
+ tcg_gen_qemu_st_i64(tmp, addr, index, opc);
39
+ return;
56
+ tcg_temp_free_i64(tmp);
40
+ }
57
+ } else {
58
+ tcg_gen_qemu_st_i64(val, addr, index, opc);
41
+ }
59
+ }
42
+ g_assert_not_reached();
60
+ tcg_temp_free(addr);
61
+}
62
+
63
static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
64
int index, MemOp opc)
65
{
66
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
67
gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
43
}
68
}
44
69
45
static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
70
+static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
46
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
71
+ int index, MemOp opc)
47
mmc->numirq = 92;
72
+{
48
mmc->raminfo = an505_raminfo;
73
+ gen_aa32_ld_internal_i64(s, val, a32, index, finalize_memop(s, opc));
49
mmc->armsse_type = TYPE_IOTKIT;
74
+}
50
+ mps2tz_set_default_ram_info(mmc);
75
+
76
+static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
77
+ int index, MemOp opc)
78
+{
79
+ gen_aa32_st_internal_i64(s, val, a32, index, finalize_memop(s, opc));
80
+}
81
+
82
#define DO_GEN_LD(SUFF, OPC) \
83
static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
84
TCGv_i32 a32, int index) \
85
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
86
gen_aa32_st_i32(s, val, a32, index, OPC); \
87
}
88
89
-static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
90
- int index, MemOp opc)
91
-{
92
- TCGv addr = gen_aa32_addr(s, a32, opc);
93
- tcg_gen_qemu_ld_i64(val, addr, index, opc);
94
-
95
- /* Not needed for user-mode BE32, where we use MO_BE instead. */
96
- if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
97
- tcg_gen_rotri_i64(val, val, 32);
98
- }
99
-
100
- tcg_temp_free(addr);
101
-}
102
-
103
static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
104
TCGv_i32 a32, int index)
105
{
106
- gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
107
-}
108
-
109
-static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
110
- int index, MemOp opc)
111
-{
112
- TCGv addr = gen_aa32_addr(s, a32, opc);
113
-
114
- /* Not needed for user-mode BE32, where we use MO_BE instead. */
115
- if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
116
- TCGv_i64 tmp = tcg_temp_new_i64();
117
- tcg_gen_rotri_i64(tmp, val, 32);
118
- tcg_gen_qemu_st_i64(tmp, addr, index, opc);
119
- tcg_temp_free_i64(tmp);
120
- } else {
121
- tcg_gen_qemu_st_i64(val, addr, index, opc);
122
- }
123
- tcg_temp_free(addr);
124
+ gen_aa32_ld_i64(s, val, a32, index, MO_Q);
51
}
125
}
52
126
53
static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
127
static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
54
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
128
TCGv_i32 a32, int index)
55
mmc->numirq = 92;
129
{
56
mmc->raminfo = an505_raminfo; /* AN521 is the same as AN505 here */
130
- gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
57
mmc->armsse_type = TYPE_SSE200;
131
+ gen_aa32_st_i64(s, val, a32, index, MO_Q);
58
+ mps2tz_set_default_ram_info(mmc);
59
}
132
}
60
133
61
static const TypeInfo mps2tz_info = {
134
DO_GEN_LD(8u, MO_UB)
135
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
136
index XXXXXXX..XXXXXXX 100644
137
--- a/target/arm/translate-neon.c.inc
138
+++ b/target/arm/translate-neon.c.inc
139
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
140
int tt = a->vd + reg + spacing * xs;
141
142
if (a->l) {
143
- gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
144
+ gen_aa32_ld_internal_i64(s, tmp64, addr, mmu_idx,
145
+ endian | size);
146
neon_store_element64(tt, n, size, tmp64);
147
} else {
148
neon_load_element64(tmp64, tt, n, size);
149
- gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
150
+ gen_aa32_st_internal_i64(s, tmp64, addr, mmu_idx,
151
+ endian | size);
152
}
153
tcg_gen_add_i32(addr, addr, tmp);
154
}
62
--
155
--
63
2.20.1
156
2.20.1
64
157
65
158
diff view generated by jsdifflib
1
We create an OR gate to wire together the overflow IRQs for all the
1
From: Richard Henderson <richard.henderson@linaro.org>
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.)
8
2
3
Buglink: https://bugs.launchpad.net/qemu/+bug/1905356
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210419202257.161730-16-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210215115138.20465-15-peter.maydell@linaro.org
12
---
8
---
13
hw/arm/mps2-tz.c | 11 ++++++++---
9
target/arm/translate.c | 16 ++++++++--------
14
1 file changed, 8 insertions(+), 3 deletions(-)
10
1 file changed, 8 insertions(+), 8 deletions(-)
15
11
16
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
12
diff --git a/target/arm/translate.c b/target/arm/translate.c
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/mps2-tz.c
14
--- a/target/arm/translate.c
19
+++ b/hw/arm/mps2-tz.c
15
+++ b/target/arm/translate.c
20
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
16
@@ -XXX,XX +XXX,XX @@ static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
21
*/
17
addr = op_addr_rr_pre(s, a);
22
memory_region_add_subregion(system_memory, 0x80000000, machine->ram);
18
23
19
tmp = tcg_temp_new_i32();
24
- /* The overflow IRQs for all UARTs are ORed together.
20
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
25
+ /*
21
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
26
+ * The overflow IRQs for all UARTs are ORed together.
22
store_reg(s, a->rt, tmp);
27
* Tx, Rx and "combined" IRQs are sent to the NVIC separately.
23
28
- * Create the OR gate for this.
24
tcg_gen_addi_i32(addr, addr, 4);
29
+ * Create the OR gate for this: it has one input for the TX overflow
25
30
+ * and one for the RX overflow for each UART we might have.
26
tmp = tcg_temp_new_i32();
31
+ * (If the board has fewer than the maximum possible number of UARTs
27
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
32
+ * those inputs are never wired up and are treated as always-zero.)
28
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
33
*/
29
store_reg(s, a->rt + 1, tmp);
34
object_initialize_child(OBJECT(mms), "uart-irq-orgate",
30
35
&mms->uart_irq_orgate, TYPE_OR_IRQ);
31
/* LDRD w/ base writeback is undefined if the registers overlap. */
36
- object_property_set_int(OBJECT(&mms->uart_irq_orgate), "num-lines", 10,
32
@@ -XXX,XX +XXX,XX @@ static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
37
+ object_property_set_int(OBJECT(&mms->uart_irq_orgate), "num-lines",
33
addr = op_addr_rr_pre(s, a);
38
+ 2 * ARRAY_SIZE(mms->uart),
34
39
&error_fatal);
35
tmp = load_reg(s, a->rt);
40
qdev_realize(DEVICE(&mms->uart_irq_orgate), NULL, &error_fatal);
36
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
41
qdev_connect_gpio_out(DEVICE(&mms->uart_irq_orgate), 0,
37
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
38
tcg_temp_free_i32(tmp);
39
40
tcg_gen_addi_i32(addr, addr, 4);
41
42
tmp = load_reg(s, a->rt + 1);
43
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
44
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
45
tcg_temp_free_i32(tmp);
46
47
op_addr_rr_post(s, a, addr, -4);
48
@@ -XXX,XX +XXX,XX @@ static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
49
addr = op_addr_ri_pre(s, a);
50
51
tmp = tcg_temp_new_i32();
52
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
53
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
54
store_reg(s, a->rt, tmp);
55
56
tcg_gen_addi_i32(addr, addr, 4);
57
58
tmp = tcg_temp_new_i32();
59
- gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL);
60
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
61
store_reg(s, rt2, tmp);
62
63
/* LDRD w/ base writeback is undefined if the registers overlap. */
64
@@ -XXX,XX +XXX,XX @@ static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
65
addr = op_addr_ri_pre(s, a);
66
67
tmp = load_reg(s, a->rt);
68
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
69
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
70
tcg_temp_free_i32(tmp);
71
72
tcg_gen_addi_i32(addr, addr, 4);
73
74
tmp = load_reg(s, rt2);
75
- gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL);
76
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
77
tcg_temp_free_i32(tmp);
78
79
op_addr_ri_post(s, a, addr, -4);
42
--
80
--
43
2.20.1
81
2.20.1
44
82
45
83
diff view generated by jsdifflib
1
The AN524 has more interrupt lines than the AN505 and AN521; make
1
From: Richard Henderson <richard.henderson@linaro.org>
2
numirq board-specific rather than a compile-time constant.
3
2
4
Since the difference is small (92 on the current boards and 95 on the
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
new one) we don't dynamically allocate the cpu_irq_splitter[] array
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
but leave it as a fixed length array whose size is the maximum needed
5
Message-id: 20210419202257.161730-17-richard.henderson@linaro.org
7
for any of the boards.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate.c | 4 ++--
9
1 file changed, 2 insertions(+), 2 deletions(-)
8
10
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-10-peter.maydell@linaro.org
13
---
14
hw/arm/mps2-tz.c | 15 ++++++++++-----
15
1 file changed, 10 insertions(+), 5 deletions(-)
16
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2-tz.c
13
--- a/target/arm/translate.c
20
+++ b/hw/arm/mps2-tz.c
14
+++ b/target/arm/translate.c
21
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
22
#include "hw/qdev-clock.h"
16
addr = load_reg(s, a->rn);
23
#include "qom/object.h"
17
tmp = load_reg(s, a->rt);
24
18
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
25
-#define MPS2TZ_NUMIRQ 92
19
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop);
26
+#define MPS2TZ_NUMIRQ_MAX 92
20
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | MO_ALIGN);
27
21
disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
28
typedef enum MPS2TZFPGAType {
22
29
FPGA_AN505,
23
tcg_temp_free_i32(tmp);
30
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
24
@@ -XXX,XX +XXX,XX @@ static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
31
const uint32_t *oscclk;
25
32
uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
26
addr = load_reg(s, a->rn);
33
bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
27
tmp = tcg_temp_new_i32();
34
+ int numirq; /* Number of external interrupts */
28
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop);
35
const char *armsse_type;
29
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | MO_ALIGN);
36
};
30
disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
37
31
tcg_temp_free_i32(addr);
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)
48
{
49
/* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
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;
84
}
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
}
93
32
94
--
33
--
95
2.20.1
34
2.20.1
96
35
97
36
diff view generated by jsdifflib
1
Set the FPGAIO num-leds and have-switches properties explicitly
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
5
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-18-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: 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
10
---
7
---
11
hw/arm/mps2-tz.c | 9 +++++++++
8
target/arm/translate.c | 4 ++--
12
1 file changed, 9 insertions(+)
9
1 file changed, 2 insertions(+), 2 deletions(-)
13
10
14
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/mps2-tz.c
13
--- a/target/arm/translate.c
17
+++ b/hw/arm/mps2-tz.c
14
+++ b/target/arm/translate.c
18
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
15
@@ -XXX,XX +XXX,XX @@ static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
19
uint32_t sysclk_frq; /* Main SYSCLK frequency in Hz */
16
} else {
20
uint32_t len_oscclk;
17
tmp = load_reg(s, i);
21
const uint32_t *oscclk;
18
}
22
+ uint32_t fpgaio_num_leds; /* Number of LEDs in FPGAIO LED0 register */
19
- gen_aa32_st32(s, tmp, addr, mem_idx);
23
+ bool fpgaio_has_switches; /* Does FPGAIO have SWITCH register? */
20
+ gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
24
const char *armsse_type;
21
tcg_temp_free_i32(tmp);
25
};
22
26
23
/* No need to add after the last transfer. */
27
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_fpgaio(MPS2TZMachineState *mms, void *opaque,
24
@@ -XXX,XX +XXX,XX @@ static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
28
const char *name, hwaddr size)
25
}
29
{
26
30
MPS2FPGAIO *fpgaio = opaque;
27
tmp = tcg_temp_new_i32();
31
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
28
- gen_aa32_ld32u(s, tmp, addr, mem_idx);
32
29
+ gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
33
object_initialize_child(OBJECT(mms), "fpgaio", fpgaio, TYPE_MPS2_FPGAIO);
30
if (user) {
34
+ qdev_prop_set_uint32(DEVICE(fpgaio), "num-leds", mmc->fpgaio_num_leds);
31
tmp2 = tcg_const_i32(i);
35
+ qdev_prop_set_bit(DEVICE(fpgaio), "has-switches", mmc->fpgaio_has_switches);
32
gen_helper_set_user_reg(cpu_env, tmp2, tmp);
36
sysbus_realize(SYS_BUS_DEVICE(fpgaio), &error_fatal);
37
return sysbus_mmio_get_region(SYS_BUS_DEVICE(fpgaio), 0);
38
}
39
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
40
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
41
mmc->oscclk = an505_oscclk;
42
mmc->len_oscclk = ARRAY_SIZE(an505_oscclk);
43
+ mmc->fpgaio_num_leds = 2;
44
+ mmc->fpgaio_has_switches = false;
45
mmc->armsse_type = TYPE_IOTKIT;
46
}
47
48
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
49
mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
50
mmc->oscclk = an505_oscclk; /* AN521 is the same as AN505 here */
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
57
--
33
--
58
2.20.1
34
2.20.1
59
35
60
36
diff view generated by jsdifflib
1
On the MPS2 boards, the first 32 interrupt lines are entirely
1
From: Richard Henderson <richard.henderson@linaro.org>
2
internal to the SSE; interrupt lines for devices outside the SSE
3
start at 32. In the application notes that document each FPGA image,
4
the interrupt wiring is documented from the point of view of the CPU,
5
so '0' is the first of the SSE's interrupts and the devices in the
6
FPGA image itself are '32' and up: so the UART 0 Receive interrupt is
7
32, the SPI #0 interrupt is 51, and so on.
8
2
9
Within our implementation, because the external interrupts must be
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
connected to the EXP_IRQ[0...n] lines of the SSE object, we made the
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
get_sse_irq_in() function take an irqno whose values start at 0 for
5
Message-id: 20210419202257.161730-19-richard.henderson@linaro.org
12
the first FPGA device interrupt. In this numbering scheme the UART 0
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Receive interrupt is 0, the SPI #0 interrupt is 19, and so on.
7
---
8
target/arm/translate.c | 4 ++--
9
1 file changed, 2 insertions(+), 2 deletions(-)
14
10
15
The result of these two different numbering schemes has been that
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
half of the devices were wired up to the wrong IRQs: the UART IRQs
17
are wired up correctly, but the DMA and SPI devices were passing
18
start-at-32 values to get_sse_irq_in() and so being mis-connected.
19
20
Fix the bug by making get_sse_irq_in() take values specified with the
21
same scheme that the hardware manuals use, to avoid confusion.
22
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20210215115138.20465-12-peter.maydell@linaro.org
26
---
27
hw/arm/mps2-tz.c | 24 +++++++++++++++++-------
28
1 file changed, 17 insertions(+), 7 deletions(-)
29
30
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
31
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/mps2-tz.c
13
--- a/target/arm/translate.c
33
+++ b/hw/arm/mps2-tz.c
14
+++ b/target/arm/translate.c
34
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
15
@@ -XXX,XX +XXX,XX @@ static bool trans_RFE(DisasContext *s, arg_RFE *a)
35
16
36
static qemu_irq get_sse_irq_in(MPS2TZMachineState *mms, int irqno)
17
/* Load PC into tmp and CPSR into tmp2. */
37
{
18
t1 = tcg_temp_new_i32();
38
- /* Return a qemu_irq which will signal IRQ n to all CPUs in the SSE. */
19
- gen_aa32_ld32u(s, t1, addr, get_mem_index(s));
39
+ /*
20
+ gen_aa32_ld_i32(s, t1, addr, get_mem_index(s), MO_UL | MO_ALIGN);
40
+ * Return a qemu_irq which will signal IRQ n to all CPUs in the
21
tcg_gen_addi_i32(addr, addr, 4);
41
+ * SSE. The irqno should be as the CPU sees it, so the first
22
t2 = tcg_temp_new_i32();
42
+ * external-to-the-SSE interrupt is 32.
23
- gen_aa32_ld32u(s, t2, addr, get_mem_index(s));
43
+ */
24
+ gen_aa32_ld_i32(s, t2, addr, get_mem_index(s), MO_UL | MO_ALIGN);
44
MachineClass *mc = MACHINE_GET_CLASS(mms);
25
45
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
26
if (a->w) {
46
27
/* Base writeback. */
47
- assert(irqno < mmc->numirq);
48
+ assert(irqno >= 32 && irqno < (mmc->numirq + 32));
49
+
50
+ /*
51
+ * Convert from "CPU irq number" (as listed in the FPGA image
52
+ * documentation) to the SSE external-interrupt number.
53
+ */
54
+ irqno -= 32;
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 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:
89
--
28
--
90
2.20.1
29
2.20.1
91
30
92
31
diff view generated by jsdifflib
1
We were previously using the default OSCCLK settings, which are
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
6
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-20-richard.henderson@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
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
---
7
---
12
hw/arm/mps2-tz.c | 4 ++--
8
target/arm/translate.c | 4 ++--
13
1 file changed, 2 insertions(+), 2 deletions(-)
9
1 file changed, 2 insertions(+), 2 deletions(-)
14
10
15
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/mps2-tz.c
13
--- a/target/arm/translate.c
18
+++ b/hw/arm/mps2-tz.c
14
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
15
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
20
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
16
}
21
/* This will need to be per-FPGA image eventually */
17
tcg_gen_addi_i32(addr, addr, offset);
22
qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
18
tmp = load_reg(s, 14);
23
- qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
19
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
24
- qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
20
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
25
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 40000000);
21
tcg_temp_free_i32(tmp);
26
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24580000);
22
tmp = load_cpu_field(spsr);
27
qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
23
tcg_gen_addi_i32(addr, addr, 4);
28
sysbus_realize(SYS_BUS_DEVICE(scc), &error_fatal);
24
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
29
return sysbus_mmio_get_region(SYS_BUS_DEVICE(sccdev), 0);
25
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
26
tcg_temp_free_i32(tmp);
27
if (writeback) {
28
switch (amode) {
30
--
29
--
31
2.20.1
30
2.20.1
32
31
33
32
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
IDAU is specific to M-profile. KVM only supports A-profile.
4
Restrict this interface to TCG, as it is pointless (and
5
confusing) on a KVM-only build.
6
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210221222617.2579610-2-f4bug@amsat.org
5
Message-id: 20210419202257.161730-21-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
7
---
13
target/arm/cpu.c | 7 -------
8
target/arm/translate-vfp.c.inc | 8 ++++----
14
target/arm/cpu_tcg.c | 8 ++++++++
9
1 file changed, 4 insertions(+), 4 deletions(-)
15
2 files changed, 8 insertions(+), 7 deletions(-)
16
10
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
11
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.c
13
--- a/target/arm/translate-vfp.c.inc
20
+++ b/target/arm/cpu.c
14
+++ b/target/arm/translate-vfp.c.inc
21
@@ -XXX,XX +XXX,XX @@ static const TypeInfo arm_cpu_type_info = {
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_sp(DisasContext *s, arg_VLDM_VSTM_sp *a)
22
.class_init = arm_cpu_class_init,
16
for (i = 0; i < n; i++) {
23
};
17
if (a->l) {
24
18
/* load */
25
-static const TypeInfo idau_interface_type_info = {
19
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
26
- .name = TYPE_IDAU_INTERFACE,
20
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
27
- .parent = TYPE_INTERFACE,
21
vfp_store_reg32(tmp, a->vd + i);
28
- .class_size = sizeof(IDAUInterfaceClass),
22
} else {
29
-};
23
/* store */
30
-
24
vfp_load_reg32(tmp, a->vd + i);
31
static void arm_cpu_register_types(void)
25
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
32
{
26
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
33
const size_t cpu_count = ARRAY_SIZE(arm_cpus);
34
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_register_types(void)
35
if (cpu_count) {
36
size_t i;
37
38
- type_register_static(&idau_interface_type_info);
39
for (i = 0; i < cpu_count; ++i) {
40
arm_cpu_register(&arm_cpus[i]);
41
}
27
}
42
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
28
tcg_gen_addi_i32(addr, addr, offset);
43
index XXXXXXX..XXXXXXX 100644
29
}
44
--- a/target/arm/cpu_tcg.c
30
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDM_VSTM_dp(DisasContext *s, arg_VLDM_VSTM_dp *a)
45
+++ b/target/arm/cpu_tcg.c
31
for (i = 0; i < n; i++) {
46
@@ -XXX,XX +XXX,XX @@
32
if (a->l) {
47
#include "hw/core/tcg-cpu-ops.h"
33
/* load */
48
#endif /* CONFIG_TCG */
34
- gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
49
#include "internals.h"
35
+ gen_aa32_ld_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4);
50
+#include "target/arm/idau.h"
36
vfp_store_reg64(tmp, a->vd + i);
51
37
} else {
52
/* CPU models. These are not needed for the AArch64 linux-user build. */
38
/* store */
53
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
39
vfp_load_reg64(tmp, a->vd + i);
54
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
40
- gen_aa32_st64(s, tmp, addr, get_mem_index(s));
55
{ .name = "pxa270-c5", .initfn = pxa270c5_initfn },
41
+ gen_aa32_st_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4);
56
};
42
}
57
43
tcg_gen_addi_i32(addr, addr, offset);
58
+static const TypeInfo idau_interface_type_info = {
59
+ .name = TYPE_IDAU_INTERFACE,
60
+ .parent = TYPE_INTERFACE,
61
+ .class_size = sizeof(IDAUInterfaceClass),
62
+};
63
+
64
static void arm_tcg_cpu_register_types(void)
65
{
66
size_t i;
67
68
+ type_register_static(&idau_interface_type_info);
69
for (i = 0; i < ARRAY_SIZE(arm_tcg_cpus); ++i) {
70
arm_cpu_register(&arm_tcg_cpus[i]);
71
}
44
}
72
--
45
--
73
2.20.1
46
2.20.1
74
47
75
48
diff view generated by jsdifflib
1
From: Rebecca Cran <rebecca@nuviainc.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Set ID_AA64PFR1_EL1.SSBS to 2 and ID_PFR2.SSBS to 1.
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
5
Message-id: 20210419202257.161730-22-richard.henderson@linaro.org
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>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
7
---
10
target/arm/cpu64.c | 5 +++++
8
target/arm/translate-vfp.c.inc | 12 ++++++------
11
1 file changed, 5 insertions(+)
9
1 file changed, 6 insertions(+), 6 deletions(-)
12
10
13
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
11
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu64.c
13
--- a/target/arm/translate-vfp.c.inc
16
+++ b/target/arm/cpu64.c
14
+++ b/target/arm/translate-vfp.c.inc
17
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_hp(DisasContext *s, arg_VLDR_VSTR_sp *a)
18
16
addr = add_reg_for_lit(s, a->rn, offset);
19
t = cpu->isar.id_aa64pfr1;
17
tmp = tcg_temp_new_i32();
20
t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
18
if (a->l) {
21
+ t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2);
19
- gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
22
/*
20
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), MO_UW | MO_ALIGN);
23
* Begin with full support for MTE. This will be downgraded to MTE=0
21
vfp_store_reg32(tmp, a->vd);
24
* during realize if the board provides no tag memory, much like
22
} else {
25
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
23
vfp_load_reg32(tmp, a->vd);
26
u = FIELD_DP32(u, ID_PFR0, DIT, 1);
24
- gen_aa32_st16(s, tmp, addr, get_mem_index(s));
27
cpu->isar.id_pfr0 = u;
25
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UW | MO_ALIGN);
28
26
}
29
+ u = cpu->isar.id_pfr2;
27
tcg_temp_free_i32(tmp);
30
+ u = FIELD_DP32(u, ID_PFR2, SSBS, 1);
28
tcg_temp_free_i32(addr);
31
+ cpu->isar.id_pfr2 = u;
29
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_sp(DisasContext *s, arg_VLDR_VSTR_sp *a)
32
+
30
addr = add_reg_for_lit(s, a->rn, offset);
33
u = cpu->isar.id_mmfr3;
31
tmp = tcg_temp_new_i32();
34
u = FIELD_DP32(u, ID_MMFR3, PAN, 2); /* ATS1E1 */
32
if (a->l) {
35
cpu->isar.id_mmfr3 = u;
33
- gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
34
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
35
vfp_store_reg32(tmp, a->vd);
36
} else {
37
vfp_load_reg32(tmp, a->vd);
38
- gen_aa32_st32(s, tmp, addr, get_mem_index(s));
39
+ gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
40
}
41
tcg_temp_free_i32(tmp);
42
tcg_temp_free_i32(addr);
43
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDR_VSTR_dp(DisasContext *s, arg_VLDR_VSTR_dp *a)
44
addr = add_reg_for_lit(s, a->rn, offset);
45
tmp = tcg_temp_new_i64();
46
if (a->l) {
47
- gen_aa32_ld64(s, tmp, addr, get_mem_index(s));
48
+ gen_aa32_ld_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4);
49
vfp_store_reg64(tmp, a->vd);
50
} else {
51
vfp_load_reg64(tmp, a->vd);
52
- gen_aa32_st64(s, tmp, addr, get_mem_index(s));
53
+ gen_aa32_st_i64(s, tmp, addr, get_mem_index(s), MO_Q | MO_ALIGN_4);
54
}
55
tcg_temp_free_i64(tmp);
56
tcg_temp_free_i32(addr);
36
--
57
--
37
2.20.1
58
2.20.1
38
59
39
60
diff view generated by jsdifflib
1
For a long time now the UI layer has guaranteed that the console
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
5
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-23-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210215103215.4944-2-peter.maydell@linaro.org
9
---
7
---
10
hw/arm/musicpal.c | 64 ++++++++++++++++++-----------------------------
8
target/arm/translate.h | 1 +
11
1 file changed, 24 insertions(+), 40 deletions(-)
9
target/arm/translate.c | 15 +++++++++++++
10
target/arm/translate-neon.c.inc | 37 +++++++++++++++++++++++++--------
11
3 files changed, 44 insertions(+), 9 deletions(-)
12
12
13
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
13
diff --git a/target/arm/translate.h b/target/arm/translate.h
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/musicpal.c
15
--- a/target/arm/translate.h
16
+++ b/hw/arm/musicpal.c
16
+++ b/target/arm/translate.h
17
@@ -XXX,XX +XXX,XX @@ static uint8_t scale_lcd_color(musicpal_lcd_state *s, uint8_t col)
17
@@ -XXX,XX +XXX,XX @@ void arm_test_cc(DisasCompare *cmp, int cc);
18
void arm_free_cc(DisasCompare *cmp);
19
void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
20
void arm_gen_test_cc(int cc, TCGLabel *label);
21
+MemOp pow2_align(unsigned i);
22
23
/* Return state of Alternate Half-precision flag, caller frees result */
24
static inline TCGv_i32 get_ahp_flag(void)
25
diff --git a/target/arm/translate.c b/target/arm/translate.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/translate.c
28
+++ b/target/arm/translate.c
29
@@ -XXX,XX +XXX,XX @@ static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
30
#define IS_USER_ONLY 0
31
#endif
32
33
+MemOp pow2_align(unsigned i)
34
+{
35
+ static const MemOp mop_align[] = {
36
+ 0, MO_ALIGN_2, MO_ALIGN_4, MO_ALIGN_8, MO_ALIGN_16,
37
+ /*
38
+ * FIXME: TARGET_PAGE_BITS_MIN affects TLB_FLAGS_MASK such
39
+ * that 256-bit alignment (MO_ALIGN_32) cannot be supported:
40
+ * see get_alignment_bits(). Enforce only 128-bit alignment for now.
41
+ */
42
+ MO_ALIGN_16
43
+ };
44
+ g_assert(i < ARRAY_SIZE(mop_align));
45
+ return mop_align[i];
46
+}
47
+
48
/*
49
* Abstractions of "generate code to do a guest load/store for
50
* AArch32", where a vaddr is always 32 bits (and is zero
51
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/translate-neon.c.inc
54
+++ b/target/arm/translate-neon.c.inc
55
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
56
int size = a->size;
57
int nregs = a->n + 1;
58
TCGv_i32 addr, tmp;
59
+ MemOp mop, align;
60
61
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
62
return false;
63
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
64
return false;
18
}
65
}
19
}
66
20
67
+ align = 0;
21
-#define SET_LCD_PIXEL(depth, type) \
68
if (size == 3) {
22
-static inline void glue(set_lcd_pixel, depth) \
69
if (nregs != 4 || a->a == 0) {
23
- (musicpal_lcd_state *s, int x, int y, type col) \
70
return false;
24
-{ \
71
}
25
- int dx, dy; \
72
/* For VLD4 size == 3 a == 1 means 32 bits at 16 byte alignment */
26
- DisplaySurface *surface = qemu_console_surface(s->con); \
73
- size = 2;
27
- type *pixel = &((type *) surface_data(surface))[(y * 128 * 3 + x) * 3]; \
74
- }
28
-\
75
- if (nregs == 1 && a->a == 1 && size == 0) {
29
- for (dy = 0; dy < 3; dy++, pixel += 127 * 3) \
76
- return false;
30
- for (dx = 0; dx < 3; dx++, pixel++) \
77
- }
31
- *pixel = col; \
78
- if (nregs == 3 && a->a == 1) {
32
+static inline void set_lcd_pixel32(musicpal_lcd_state *s,
79
- return false;
33
+ int x, int y, uint32_t col)
80
+ size = MO_32;
34
+{
81
+ align = MO_ALIGN_16;
35
+ int dx, dy;
82
+ } else if (a->a) {
36
+ DisplaySurface *surface = qemu_console_surface(s->con);
83
+ switch (nregs) {
37
+ uint32_t *pixel =
84
+ case 1:
38
+ &((uint32_t *) surface_data(surface))[(y * 128 * 3 + x) * 3];
85
+ if (size == 0) {
39
+
86
+ return false;
40
+ for (dy = 0; dy < 3; dy++, pixel += 127 * 3) {
41
+ for (dx = 0; dx < 3; dx++, pixel++) {
42
+ *pixel = col;
43
+ }
44
+ }
45
}
46
-SET_LCD_PIXEL(8, uint8_t)
47
-SET_LCD_PIXEL(16, uint16_t)
48
-SET_LCD_PIXEL(32, uint32_t)
49
50
static void lcd_refresh(void *opaque)
51
{
52
musicpal_lcd_state *s = opaque;
53
- DisplaySurface *surface = qemu_console_surface(s->con);
54
int x, y, col;
55
56
- switch (surface_bits_per_pixel(surface)) {
57
- case 0:
58
- return;
59
-#define LCD_REFRESH(depth, func) \
60
- case depth: \
61
- col = func(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff), \
62
- scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff), \
63
- scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff)); \
64
- for (x = 0; x < 128; x++) { \
65
- for (y = 0; y < 64; y++) { \
66
- if (s->video_ram[x + (y/8)*128] & (1 << (y % 8))) { \
67
- glue(set_lcd_pixel, depth)(s, x, y, col); \
68
- } else { \
69
- glue(set_lcd_pixel, depth)(s, x, y, 0); \
70
- } \
71
- } \
72
- } \
73
- break;
74
- LCD_REFRESH(8, rgb_to_pixel8)
75
- LCD_REFRESH(16, rgb_to_pixel16)
76
- LCD_REFRESH(32, (is_surface_bgr(surface) ?
77
- rgb_to_pixel32bgr : rgb_to_pixel32))
78
- default:
79
- hw_error("unsupported colour depth %i\n",
80
- surface_bits_per_pixel(surface));
81
+ col = rgb_to_pixel32(scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 16) & 0xff),
82
+ scale_lcd_color(s, (MP_LCD_TEXTCOLOR >> 8) & 0xff),
83
+ scale_lcd_color(s, MP_LCD_TEXTCOLOR & 0xff));
84
+ for (x = 0; x < 128; x++) {
85
+ for (y = 0; y < 64; y++) {
86
+ if (s->video_ram[x + (y / 8) * 128] & (1 << (y % 8))) {
87
+ set_lcd_pixel32(s, x, y, col);
88
+ } else {
89
+ set_lcd_pixel32(s, x, y, 0);
90
+ }
87
+ }
88
+ align = MO_ALIGN;
89
+ break;
90
+ case 2:
91
+ align = pow2_align(size + 1);
92
+ break;
93
+ case 3:
94
+ return false;
95
+ case 4:
96
+ align = pow2_align(size + 2);
97
+ break;
98
+ default:
99
+ g_assert_not_reached();
91
+ }
100
+ }
92
}
101
}
93
102
94
dpy_gfx_update(s->con, 0, 0, 128*3, 64*3);
103
if (!vfp_access_check(s)) {
104
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
105
*/
106
stride = a->t ? 2 : 1;
107
vec_size = nregs == 1 ? stride * 8 : 8;
108
-
109
+ mop = size | align;
110
tmp = tcg_temp_new_i32();
111
addr = tcg_temp_new_i32();
112
load_reg_var(s, addr, a->rn);
113
for (reg = 0; reg < nregs; reg++) {
114
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), size);
115
+ gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop);
116
if ((vd & 1) && vec_size == 16) {
117
/*
118
* We cannot write 16 bytes at once because the
119
@@ -XXX,XX +XXX,XX @@ static bool trans_VLD_all_lanes(DisasContext *s, arg_VLD_all_lanes *a)
120
}
121
tcg_gen_addi_i32(addr, addr, 1 << size);
122
vd += stride;
123
+
124
+ /* Subsequent memory operations inherit alignment */
125
+ mop &= ~MO_AMASK;
126
}
127
tcg_temp_free_i32(tmp);
128
tcg_temp_free_i32(addr);
95
--
129
--
96
2.20.1
130
2.20.1
97
131
98
132
diff view generated by jsdifflib
1
From: Doug Evans <dje@google.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
This is a 10/100 ethernet device that has several features.
4
Only the ones needed by the Linux driver have been implemented.
5
See npcm7xx_emc.c for a list of unimplemented features.
6
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Doug Evans <dje@google.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20210218212453.831406-3-dje@google.com
5
Message-id: 20210419202257.161730-24-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
7
---
14
docs/system/arm/nuvoton.rst | 3 ++-
8
target/arm/translate-neon.c.inc | 27 ++++++++++++++++++++++-----
15
include/hw/arm/npcm7xx.h | 2 ++
9
1 file changed, 22 insertions(+), 5 deletions(-)
16
hw/arm/npcm7xx.c | 50 +++++++++++++++++++++++++++++++++++--
17
3 files changed, 52 insertions(+), 3 deletions(-)
18
10
19
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
11
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
20
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
21
--- a/docs/system/arm/nuvoton.rst
13
--- a/target/arm/translate-neon.c.inc
22
+++ b/docs/system/arm/nuvoton.rst
14
+++ b/target/arm/translate-neon.c.inc
23
@@ -XXX,XX +XXX,XX @@ Supported devices
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
24
* Analog to Digital Converter (ADC)
16
{
25
* Pulse Width Modulation (PWM)
17
/* Neon load/store multiple structures */
26
* SMBus controller (SMBF)
18
int nregs, interleave, spacing, reg, n;
27
+ * Ethernet controller (EMC)
19
- MemOp endian = s->be_data;
28
20
+ MemOp mop, align, endian;
29
Missing devices
21
int mmu_idx = get_mem_index(s);
30
---------------
22
int size = a->size;
31
@@ -XXX,XX +XXX,XX @@ Missing devices
23
TCGv_i64 tmp64;
32
* Shared memory (SHM)
24
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
33
* eSPI slave interface
25
}
34
26
35
- * Ethernet controllers (GMAC and EMC)
27
/* For our purposes, bytes are always little-endian. */
36
+ * Ethernet controller (GMAC)
28
+ endian = s->be_data;
37
* USB device (USBD)
29
if (size == 0) {
38
* Peripheral SPI controller (PSPI)
30
endian = MO_LE;
39
* SD/MMC host
40
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/include/hw/arm/npcm7xx.h
43
+++ b/include/hw/arm/npcm7xx.h
44
@@ -XXX,XX +XXX,XX @@
45
#include "hw/misc/npcm7xx_gcr.h"
46
#include "hw/misc/npcm7xx_pwm.h"
47
#include "hw/misc/npcm7xx_rng.h"
48
+#include "hw/net/npcm7xx_emc.h"
49
#include "hw/nvram/npcm7xx_otp.h"
50
#include "hw/timer/npcm7xx_timer.h"
51
#include "hw/ssi/npcm7xx_fiu.h"
52
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
53
EHCISysBusState ehci;
54
OHCISysBusState ohci;
55
NPCM7xxFIUState fiu[2];
56
+ NPCM7xxEMCState emc[2];
57
} NPCM7xxState;
58
59
#define TYPE_NPCM7XX "npcm7xx"
60
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/hw/arm/npcm7xx.c
63
+++ b/hw/arm/npcm7xx.c
64
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
65
NPCM7XX_UART1_IRQ,
66
NPCM7XX_UART2_IRQ,
67
NPCM7XX_UART3_IRQ,
68
+ NPCM7XX_EMC1RX_IRQ = 15,
69
+ NPCM7XX_EMC1TX_IRQ,
70
NPCM7XX_TIMER0_IRQ = 32, /* Timer Module 0 */
71
NPCM7XX_TIMER1_IRQ,
72
NPCM7XX_TIMER2_IRQ,
73
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
74
NPCM7XX_SMBUS15_IRQ,
75
NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
76
NPCM7XX_PWM1_IRQ, /* PWM module 1 */
77
+ NPCM7XX_EMC2RX_IRQ = 114,
78
+ NPCM7XX_EMC2TX_IRQ,
79
NPCM7XX_GPIO0_IRQ = 116,
80
NPCM7XX_GPIO1_IRQ,
81
NPCM7XX_GPIO2_IRQ,
82
@@ -XXX,XX +XXX,XX @@ static const hwaddr npcm7xx_smbus_addr[] = {
83
0xf008f000,
84
};
85
86
+/* Register base address for each EMC Module */
87
+static const hwaddr npcm7xx_emc_addr[] = {
88
+ 0xf0825000,
89
+ 0xf0826000,
90
+};
91
+
92
static const struct {
93
hwaddr regs_addr;
94
uint32_t unconnected_pins;
95
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
96
for (i = 0; i < ARRAY_SIZE(s->pwm); i++) {
97
object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
98
}
31
}
99
+
32
+
100
+ for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
33
+ /* Enforce alignment requested by the instruction */
101
+ object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
34
+ if (a->align) {
102
+ }
35
+ align = pow2_align(a->align + 2); /* 4 ** a->align */
103
}
36
+ } else {
104
37
+ align = s->align_mem ? MO_ALIGN : 0;
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
+ }
38
+ }
143
+
39
+
144
/*
40
/*
145
* Flash Interface Unit (FIU). Can fail if incorrect number of chip selects
41
* Consecutive little-endian elements from a single register
146
* specified, but this is a programming error.
42
* can be promoted to a larger little-endian operation.
147
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
43
*/
148
create_unimplemented_device("npcm7xx.vcd", 0xf0810000, 64 * KiB);
44
if (interleave == 1 && endian == MO_LE) {
149
create_unimplemented_device("npcm7xx.ece", 0xf0820000, 8 * KiB);
45
+ /* Retain any natural alignment. */
150
create_unimplemented_device("npcm7xx.vdma", 0xf0822000, 8 * KiB);
46
+ if (align == MO_ALIGN) {
151
- create_unimplemented_device("npcm7xx.emc1", 0xf0825000, 4 * KiB);
47
+ align = pow2_align(size);
152
- create_unimplemented_device("npcm7xx.emc2", 0xf0826000, 4 * KiB);
48
+ }
153
create_unimplemented_device("npcm7xx.usbd[0]", 0xf0830000, 4 * KiB);
49
size = 3;
154
create_unimplemented_device("npcm7xx.usbd[1]", 0xf0831000, 4 * KiB);
50
}
155
create_unimplemented_device("npcm7xx.usbd[2]", 0xf0832000, 4 * KiB);
51
+
52
tmp64 = tcg_temp_new_i64();
53
addr = tcg_temp_new_i32();
54
tmp = tcg_const_i32(1 << size);
55
load_reg_var(s, addr, a->rn);
56
+
57
+ mop = endian | size | align;
58
for (reg = 0; reg < nregs; reg++) {
59
for (n = 0; n < 8 >> size; n++) {
60
int xs;
61
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_multiple(DisasContext *s, arg_VLDST_multiple *a)
62
int tt = a->vd + reg + spacing * xs;
63
64
if (a->l) {
65
- gen_aa32_ld_internal_i64(s, tmp64, addr, mmu_idx,
66
- endian | size);
67
+ gen_aa32_ld_internal_i64(s, tmp64, addr, mmu_idx, mop);
68
neon_store_element64(tt, n, size, tmp64);
69
} else {
70
neon_load_element64(tmp64, tt, n, size);
71
- gen_aa32_st_internal_i64(s, tmp64, addr, mmu_idx,
72
- endian | size);
73
+ gen_aa32_st_internal_i64(s, tmp64, addr, mmu_idx, mop);
74
}
75
tcg_gen_add_i32(addr, addr, tmp);
76
+
77
+ /* Subsequent memory operations inherit alignment */
78
+ mop &= ~MO_AMASK;
79
}
80
}
81
}
156
--
82
--
157
2.20.1
83
2.20.1
158
84
159
85
diff view generated by jsdifflib
1
The MPS2 board has 2 LEDs, but the MPS3 board has 10 LEDs. The
1
From: Richard Henderson <richard.henderson@linaro.org>
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.
5
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20210419202257.161730-25-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: 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
---
7
---
11
include/hw/misc/mps2-fpgaio.h | 5 ++++-
8
target/arm/translate-neon.c.inc | 48 ++++++++++++++++++++++++++++-----
12
hw/misc/mps2-fpgaio.c | 31 +++++++++++++++++++++++--------
9
1 file changed, 42 insertions(+), 6 deletions(-)
13
2 files changed, 27 insertions(+), 9 deletions(-)
14
10
15
diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h
11
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/misc/mps2-fpgaio.h
13
--- a/target/arm/translate-neon.c.inc
18
+++ b/include/hw/misc/mps2-fpgaio.h
14
+++ b/target/arm/translate-neon.c.inc
19
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
20
#define TYPE_MPS2_FPGAIO "mps2-fpgaio"
16
int nregs = a->n + 1;
21
OBJECT_DECLARE_SIMPLE_TYPE(MPS2FPGAIO, MPS2_FPGAIO)
17
int vd = a->vd;
22
18
TCGv_i32 addr, tmp;
23
+#define MPS2FPGAIO_MAX_LEDS 32
19
+ MemOp mop;
20
21
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
22
return false;
23
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
24
return true;
25
}
26
27
+ /* Pick up SCTLR settings */
28
+ mop = finalize_memop(s, a->size);
24
+
29
+
25
struct MPS2FPGAIO {
30
+ if (a->align) {
26
/*< private >*/
31
+ MemOp align_op;
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
+
32
+
51
+ s->led0 = value & MAKE_64BIT_MASK(0, s->num_leds);
33
+ switch (nregs) {
52
+ for (i = 0; i < s->num_leds; i++) {
34
+ case 1:
53
+ led_set_state(s->led[i], value & (1 << i));
35
+ /* For VLD1, use natural alignment. */
36
+ align_op = MO_ALIGN;
37
+ break;
38
+ case 2:
39
+ /* For VLD2, use double alignment. */
40
+ align_op = pow2_align(a->size + 1);
41
+ break;
42
+ case 4:
43
+ if (a->size == MO_32) {
44
+ /*
45
+ * For VLD4.32, align = 1 is double alignment, align = 2 is
46
+ * quad alignment; align = 3 is rejected above.
47
+ */
48
+ align_op = pow2_align(a->size + a->align);
49
+ } else {
50
+ /* For VLD4.8 and VLD.16, we want quad alignment. */
51
+ align_op = pow2_align(a->size + 2);
54
+ }
52
+ }
53
+ break;
54
+ default:
55
+ /* For VLD3, the alignment field is zero and rejected above. */
56
+ g_assert_not_reached();
55
+ }
57
+ }
56
break;
58
+
57
case A_PRESCALE:
59
+ mop = (mop & ~MO_AMASK) | align_op;
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]));
66
}
67
}
68
@@ -XXX,XX +XXX,XX @@ static void mps2_fpgaio_init(Object *obj)
69
static void mps2_fpgaio_realize(DeviceState *dev, Error **errp)
70
{
71
MPS2FPGAIO *s = MPS2_FPGAIO(dev);
72
+ uint32_t i;
73
74
- s->led[0] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
75
- LED_COLOR_GREEN, "USERLED0");
76
- s->led[1] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
77
- LED_COLOR_GREEN, "USERLED1");
78
+ if (s->num_leds > MPS2FPGAIO_MAX_LEDS) {
79
+ error_setg(errp, "num-leds cannot be greater than %d",
80
+ MPS2FPGAIO_MAX_LEDS);
81
+ return;
82
+ }
60
+ }
83
+
61
+
84
+ for (i = 0; i < s->num_leds; i++) {
62
tmp = tcg_temp_new_i32();
85
+ g_autofree char *ledname = g_strdup_printf("USERLED%d", i);
63
addr = tcg_temp_new_i32();
86
+ s->led[i] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH,
64
load_reg_var(s, addr, a->rn);
87
+ LED_COLOR_GREEN, ledname);
65
- /*
88
+ }
66
- * TODO: if we implemented alignment exceptions, we should check
89
}
67
- * addr against the alignment encoded in a->align here.
90
68
- */
91
static bool mps2_fpgaio_counters_needed(void *opaque)
69
+
92
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_fpgaio_vmstate = {
70
for (reg = 0; reg < nregs; reg++) {
93
static Property mps2_fpgaio_properties[] = {
71
if (a->l) {
94
/* Frequency of the prescale counter */
72
- gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), a->size);
95
DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000),
73
+ gen_aa32_ld_internal_i32(s, tmp, addr, get_mem_index(s), mop);
96
+ /* Number of LEDs controlled by LED0 register */
74
neon_store_element(vd, a->reg_idx, a->size, tmp);
97
+ DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2),
75
} else { /* Store */
98
DEFINE_PROP_END_OF_LIST(),
76
neon_load_element(tmp, vd, a->reg_idx, a->size);
99
};
77
- gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), a->size);
100
78
+ gen_aa32_st_internal_i32(s, tmp, addr, get_mem_index(s), mop);
79
}
80
vd += a->stride;
81
tcg_gen_addi_i32(addr, addr, 1 << a->size);
82
+
83
+ /* Subsequent memory operations inherit alignment */
84
+ mop &= ~MO_AMASK;
85
}
86
tcg_temp_free_i32(addr);
87
tcg_temp_free_i32(tmp);
101
--
88
--
102
2.20.1
89
2.20.1
103
90
104
91
diff view generated by jsdifflib
1
From: Rebecca Cran <rebecca@nuviainc.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Enable FEAT_SSBS for the "max" 32-bit CPU.
3
In the case of gpr load, merge the size and is_signed arguments;
4
4
otherwise, simply convert size to memop.
5
Signed-off-by: Rebecca Cran <rebecca@nuviainc.com>
5
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20210216224543.16142-4-rebecca@nuviainc.com
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
[PMM: fix typo causing compilation failure]
8
Message-id: 20210419202257.161730-26-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/cpu.c | 4 ++++
11
target/arm/translate-a64.c | 78 ++++++++++++++++----------------------
12
1 file changed, 4 insertions(+)
12
1 file changed, 33 insertions(+), 45 deletions(-)
13
13
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.c
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/cpu.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
18
@@ -XXX,XX +XXX,XX @@ static void gen_adc_CC(int sf, TCGv_i64 dest, TCGv_i64 t0, TCGv_i64 t1)
19
t = cpu->isar.id_pfr0;
19
* Store from GPR register to memory.
20
t = FIELD_DP32(t, ID_PFR0, DIT, 1);
20
*/
21
cpu->isar.id_pfr0 = t;
21
static void do_gpr_st_memidx(DisasContext *s, TCGv_i64 source,
22
+
22
- TCGv_i64 tcg_addr, int size, int memidx,
23
+ t = cpu->isar.id_pfr2;
23
+ TCGv_i64 tcg_addr, MemOp memop, int memidx,
24
+ t = FIELD_DP32(t, ID_PFR2, SSBS, 1);
24
bool iss_valid,
25
+ cpu->isar.id_pfr2 = t;
25
unsigned int iss_srt,
26
}
26
bool iss_sf, bool iss_ar)
27
#endif
27
{
28
- g_assert(size <= 3);
29
- tcg_gen_qemu_st_i64(source, tcg_addr, memidx, s->be_data + size);
30
+ memop = finalize_memop(s, memop);
31
+ tcg_gen_qemu_st_i64(source, tcg_addr, memidx, memop);
32
33
if (iss_valid) {
34
uint32_t syn;
35
36
syn = syn_data_abort_with_iss(0,
37
- size,
38
+ (memop & MO_SIZE),
39
false,
40
iss_srt,
41
iss_sf,
42
@@ -XXX,XX +XXX,XX @@ static void do_gpr_st_memidx(DisasContext *s, TCGv_i64 source,
43
}
44
45
static void do_gpr_st(DisasContext *s, TCGv_i64 source,
46
- TCGv_i64 tcg_addr, int size,
47
+ TCGv_i64 tcg_addr, MemOp memop,
48
bool iss_valid,
49
unsigned int iss_srt,
50
bool iss_sf, bool iss_ar)
51
{
52
- do_gpr_st_memidx(s, source, tcg_addr, size, get_mem_index(s),
53
+ do_gpr_st_memidx(s, source, tcg_addr, memop, get_mem_index(s),
54
iss_valid, iss_srt, iss_sf, iss_ar);
55
}
56
57
/*
58
* Load from memory to GPR register
59
*/
60
-static void do_gpr_ld_memidx(DisasContext *s,
61
- TCGv_i64 dest, TCGv_i64 tcg_addr,
62
- int size, bool is_signed,
63
- bool extend, int memidx,
64
+static void do_gpr_ld_memidx(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
65
+ MemOp memop, bool extend, int memidx,
66
bool iss_valid, unsigned int iss_srt,
67
bool iss_sf, bool iss_ar)
68
{
69
- MemOp memop = s->be_data + size;
70
-
71
- g_assert(size <= 3);
72
-
73
- if (is_signed) {
74
- memop += MO_SIGN;
75
- }
76
-
77
+ memop = finalize_memop(s, memop);
78
tcg_gen_qemu_ld_i64(dest, tcg_addr, memidx, memop);
79
80
- if (extend && is_signed) {
81
- g_assert(size < 3);
82
+ if (extend && (memop & MO_SIGN)) {
83
+ g_assert((memop & MO_SIZE) <= MO_32);
84
tcg_gen_ext32u_i64(dest, dest);
85
}
86
87
@@ -XXX,XX +XXX,XX @@ static void do_gpr_ld_memidx(DisasContext *s,
88
uint32_t syn;
89
90
syn = syn_data_abort_with_iss(0,
91
- size,
92
- is_signed,
93
+ (memop & MO_SIZE),
94
+ (memop & MO_SIGN) != 0,
95
iss_srt,
96
iss_sf,
97
iss_ar,
98
@@ -XXX,XX +XXX,XX @@ static void do_gpr_ld_memidx(DisasContext *s,
99
}
100
}
101
102
-static void do_gpr_ld(DisasContext *s,
103
- TCGv_i64 dest, TCGv_i64 tcg_addr,
104
- int size, bool is_signed, bool extend,
105
+static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
106
+ MemOp memop, bool extend,
107
bool iss_valid, unsigned int iss_srt,
108
bool iss_sf, bool iss_ar)
109
{
110
- do_gpr_ld_memidx(s, dest, tcg_addr, size, is_signed, extend,
111
- get_mem_index(s),
112
+ do_gpr_ld_memidx(s, dest, tcg_addr, memop, extend, get_mem_index(s),
113
iss_valid, iss_srt, iss_sf, iss_ar);
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
117
}
118
clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn),
119
false, rn != 31, size);
120
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, false, true, rt,
121
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, true, rt,
122
disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
123
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
124
return;
125
@@ -XXX,XX +XXX,XX @@ static void disas_ld_lit(DisasContext *s, uint32_t insn)
126
/* Only unsigned 32bit loads target 32bit registers. */
127
bool iss_sf = opc != 0;
128
129
- do_gpr_ld(s, tcg_rt, clean_addr, size, is_signed, false,
130
- true, rt, iss_sf, false);
131
+ do_gpr_ld(s, tcg_rt, clean_addr, size + is_signed * MO_SIGN,
132
+ false, true, rt, iss_sf, false);
133
}
134
tcg_temp_free_i64(clean_addr);
135
}
136
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pair(DisasContext *s, uint32_t insn)
137
/* Do not modify tcg_rt before recognizing any exception
138
* from the second load.
139
*/
140
- do_gpr_ld(s, tmp, clean_addr, size, is_signed, false,
141
- false, 0, false, false);
142
+ do_gpr_ld(s, tmp, clean_addr, size + is_signed * MO_SIGN,
143
+ false, false, 0, false, false);
144
tcg_gen_addi_i64(clean_addr, clean_addr, 1 << size);
145
- do_gpr_ld(s, tcg_rt2, clean_addr, size, is_signed, false,
146
- false, 0, false, false);
147
+ do_gpr_ld(s, tcg_rt2, clean_addr, size + is_signed * MO_SIGN,
148
+ false, false, 0, false, false);
149
150
tcg_gen_mov_i64(tcg_rt, tmp);
151
tcg_temp_free_i64(tmp);
152
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_imm9(DisasContext *s, uint32_t insn,
153
do_gpr_st_memidx(s, tcg_rt, clean_addr, size, memidx,
154
iss_valid, rt, iss_sf, false);
155
} else {
156
- do_gpr_ld_memidx(s, tcg_rt, clean_addr, size,
157
- is_signed, is_extended, memidx,
158
+ do_gpr_ld_memidx(s, tcg_rt, clean_addr, size + is_signed * MO_SIGN,
159
+ is_extended, memidx,
160
iss_valid, rt, iss_sf, false);
161
}
162
}
163
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_roffset(DisasContext *s, uint32_t insn,
164
do_gpr_st(s, tcg_rt, clean_addr, size,
165
true, rt, iss_sf, false);
166
} else {
167
- do_gpr_ld(s, tcg_rt, clean_addr, size,
168
- is_signed, is_extended,
169
- true, rt, iss_sf, false);
170
+ do_gpr_ld(s, tcg_rt, clean_addr, size + is_signed * MO_SIGN,
171
+ is_extended, true, rt, iss_sf, false);
172
}
173
}
174
}
175
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg_unsigned_imm(DisasContext *s, uint32_t insn,
176
do_gpr_st(s, tcg_rt, clean_addr, size,
177
true, rt, iss_sf, false);
178
} else {
179
- do_gpr_ld(s, tcg_rt, clean_addr, size, is_signed, is_extended,
180
- true, rt, iss_sf, false);
181
+ do_gpr_ld(s, tcg_rt, clean_addr, size + is_signed * MO_SIGN,
182
+ is_extended, true, rt, iss_sf, false);
183
}
184
}
185
}
186
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
187
* full load-acquire (we only need "load-acquire processor consistent"),
188
* but we choose to implement them as full LDAQ.
189
*/
190
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, false,
191
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false,
192
true, rt, disas_ldst_compute_iss_sf(size, false, 0), true);
193
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
194
return;
195
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_pac(DisasContext *s, uint32_t insn,
196
is_wback || rn != 31, size);
197
198
tcg_rt = cpu_reg(s, rt);
199
- do_gpr_ld(s, tcg_rt, clean_addr, size, /* is_signed */ false,
200
+ do_gpr_ld(s, tcg_rt, clean_addr, size,
201
/* extend */ false, /* iss_valid */ !is_wback,
202
/* iss_srt */ rt, /* iss_sf */ true, /* iss_ar */ false);
203
204
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
205
* Load-AcquirePC semantics; we implement as the slightly more
206
* restrictive Load-Acquire.
207
*/
208
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, is_signed, extend,
209
- true, rt, iss_sf, true);
210
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size + is_signed * MO_SIGN,
211
+ extend, true, rt, iss_sf, true);
212
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
213
}
28
}
214
}
29
--
215
--
30
2.20.1
216
2.20.1
31
217
32
218
diff view generated by jsdifflib
1
The AN524 has a different SYSCLK frequency from the AN505 and AN521;
1
From: Richard Henderson <richard.henderson@linaro.org>
2
make the SYSCLK frequency a field in the MPS2TZMachineClass rather
3
than a compile-time constant so we can support the AN524.
4
2
3
For 128-bit load/store, use 16-byte alignment. This
4
requires that we perform the two operations in the
5
correct order so that we generate the alignment fault
6
before modifying memory.
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20210419202257.161730-27-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
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
---
12
---
10
hw/arm/mps2-tz.c | 10 ++++++----
13
target/arm/translate-a64.c | 42 +++++++++++++++++++++++---------------
11
1 file changed, 6 insertions(+), 4 deletions(-)
14
1 file changed, 26 insertions(+), 16 deletions(-)
12
15
13
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/mps2-tz.c
18
--- a/target/arm/translate-a64.c
16
+++ b/hw/arm/mps2-tz.c
19
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineClass {
20
@@ -XXX,XX +XXX,XX @@ static void do_gpr_ld(DisasContext *s, TCGv_i64 dest, TCGv_i64 tcg_addr,
18
MachineClass parent;
21
static void do_fp_st(DisasContext *s, int srcidx, TCGv_i64 tcg_addr, int size)
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
{
22
{
38
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
23
/* This writes the bottom N bits of a 128 bit wide vector to memory */
39
CMSDKAPBUART *uart = opaque;
24
- TCGv_i64 tmp = tcg_temp_new_i64();
40
int i = uart - &mms->uart[0];
25
- tcg_gen_ld_i64(tmp, cpu_env, fp_reg_offset(s, srcidx, MO_64));
41
int rxirqno = i * 2;
26
+ TCGv_i64 tmplo = tcg_temp_new_i64();
42
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
27
+ MemOp mop;
43
28
+
44
object_initialize_child(OBJECT(mms), name, uart, TYPE_CMSDK_APB_UART);
29
+ tcg_gen_ld_i64(tmplo, cpu_env, fp_reg_offset(s, srcidx, MO_64));
45
qdev_prop_set_chr(DEVICE(uart), "chardev", serial_hd(i));
30
+
46
- qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", SYSCLK_FRQ);
31
if (size < 4) {
47
+ qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", mmc->sysclk_frq);
32
- tcg_gen_qemu_st_i64(tmp, tcg_addr, get_mem_index(s),
48
sysbus_realize(SYS_BUS_DEVICE(uart), &error_fatal);
33
- s->be_data + size);
49
s = SYS_BUS_DEVICE(uart);
34
+ mop = finalize_memop(s, size);
50
sysbus_connect_irq(s, 0, get_sse_irq_in(mms, txirqno));
35
+ tcg_gen_qemu_st_i64(tmplo, tcg_addr, get_mem_index(s), mop);
51
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
36
} else {
52
37
bool be = s->be_data == MO_BE;
53
/* These clocks don't need migration because they are fixed-frequency */
38
TCGv_i64 tcg_hiaddr = tcg_temp_new_i64();
54
mms->sysclk = clock_new(OBJECT(machine), "SYSCLK");
39
+ TCGv_i64 tmphi = tcg_temp_new_i64();
55
- clock_set_hz(mms->sysclk, SYSCLK_FRQ);
40
56
+ clock_set_hz(mms->sysclk, mmc->sysclk_frq);
41
+ tcg_gen_ld_i64(tmphi, cpu_env, fp_reg_hi_offset(s, srcidx));
57
mms->s32kclk = clock_new(OBJECT(machine), "S32KCLK");
42
+
58
clock_set_hz(mms->s32kclk, S32KCLK_FRQ);
43
+ mop = s->be_data | MO_Q;
59
44
+ tcg_gen_qemu_st_i64(be ? tmphi : tmplo, tcg_addr, get_mem_index(s),
60
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data)
45
+ mop | (s->align_mem ? MO_ALIGN_16 : 0));
61
mmc->fpga_type = FPGA_AN505;
46
tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
62
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
47
- tcg_gen_qemu_st_i64(tmp, be ? tcg_hiaddr : tcg_addr, get_mem_index(s),
63
mmc->scc_id = 0x41045050;
48
- s->be_data | MO_Q);
64
+ mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
49
- tcg_gen_ld_i64(tmp, cpu_env, fp_reg_hi_offset(s, srcidx));
65
mmc->armsse_type = TYPE_IOTKIT;
50
- tcg_gen_qemu_st_i64(tmp, be ? tcg_addr : tcg_hiaddr, get_mem_index(s),
51
- s->be_data | MO_Q);
52
+ tcg_gen_qemu_st_i64(be ? tmplo : tmphi, tcg_hiaddr,
53
+ get_mem_index(s), mop);
54
+
55
tcg_temp_free_i64(tcg_hiaddr);
56
+ tcg_temp_free_i64(tmphi);
57
}
58
59
- tcg_temp_free_i64(tmp);
60
+ tcg_temp_free_i64(tmplo);
66
}
61
}
67
62
68
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
63
/*
69
mmc->fpga_type = FPGA_AN521;
64
@@ -XXX,XX +XXX,XX @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
70
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
65
/* This always zero-extends and writes to a full 128 bit wide vector */
71
mmc->scc_id = 0x41045210;
66
TCGv_i64 tmplo = tcg_temp_new_i64();
72
+ mmc->sysclk_frq = 20 * 1000 * 1000; /* 20MHz */
67
TCGv_i64 tmphi = NULL;
73
mmc->armsse_type = TYPE_SSE200;
68
+ MemOp mop;
74
}
69
70
if (size < 4) {
71
- MemOp memop = s->be_data + size;
72
- tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), memop);
73
+ mop = finalize_memop(s, size);
74
+ tcg_gen_qemu_ld_i64(tmplo, tcg_addr, get_mem_index(s), mop);
75
} else {
76
bool be = s->be_data == MO_BE;
77
TCGv_i64 tcg_hiaddr;
78
@@ -XXX,XX +XXX,XX @@ static void do_fp_ld(DisasContext *s, int destidx, TCGv_i64 tcg_addr, int size)
79
tmphi = tcg_temp_new_i64();
80
tcg_hiaddr = tcg_temp_new_i64();
81
82
+ mop = s->be_data | MO_Q;
83
+ tcg_gen_qemu_ld_i64(be ? tmphi : tmplo, tcg_addr, get_mem_index(s),
84
+ mop | (s->align_mem ? MO_ALIGN_16 : 0));
85
tcg_gen_addi_i64(tcg_hiaddr, tcg_addr, 8);
86
- tcg_gen_qemu_ld_i64(tmplo, be ? tcg_hiaddr : tcg_addr, get_mem_index(s),
87
- s->be_data | MO_Q);
88
- tcg_gen_qemu_ld_i64(tmphi, be ? tcg_addr : tcg_hiaddr, get_mem_index(s),
89
- s->be_data | MO_Q);
90
+ tcg_gen_qemu_ld_i64(be ? tmplo : tmphi, tcg_hiaddr,
91
+ get_mem_index(s), mop);
92
tcg_temp_free_i64(tcg_hiaddr);
93
}
75
94
76
--
95
--
77
2.20.1
96
2.20.1
78
97
79
98
diff view generated by jsdifflib
1
Add support for the mps3-an524 board; this is an SSE-200 based FPGA
1
From: Richard Henderson <richard.henderson@linaro.org>
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
2
5
In real hardware this image runs on a newer generation of the FPGA
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
board, the MPS3 rather than the older MPS2. Architecturally the two
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
boards are similar, so we implement the MPS3 boards in the mps2-tz.c
5
Message-id: 20210419202257.161730-28-richard.henderson@linaro.org
8
file as variations of the existing MPS2 boards.
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-a64.c | 23 ++++++++++++++---------
9
1 file changed, 14 insertions(+), 9 deletions(-)
9
10
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210215115138.20465-21-peter.maydell@linaro.org
13
---
14
hw/arm/mps2-tz.c | 139 +++++++++++++++++++++++++++++++++++++++++++++--
15
1 file changed, 135 insertions(+), 4 deletions(-)
16
17
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
18
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/mps2-tz.c
13
--- a/target/arm/translate-a64.c
20
+++ b/hw/arm/mps2-tz.c
14
+++ b/target/arm/translate-a64.c
21
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
22
* This source file covers the following FPGA images, for TrustZone cores:
16
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
23
* "mps2-an505" -- Cortex-M33 as documented in ARM Application Note AN505
17
clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn),
24
* "mps2-an521" -- Dual Cortex-M33 as documented in Application Note AN521
18
true, rn != 31, size);
25
+ * "mps2-an524" -- Dual Cortex-M33 as documented in Application Note AN524
19
- do_gpr_st(s, cpu_reg(s, rt), clean_addr, size, true, rt,
26
*
20
+ /* TODO: ARMv8.4-LSE SCTLR.nAA */
27
* Links to the TRM for the board itself and to the various Application
21
+ do_gpr_st(s, cpu_reg(s, rt), clean_addr, size | MO_ALIGN, true, rt,
28
* Notes which document the FPGA images can be found here:
22
disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
29
@@ -XXX,XX +XXX,XX @@
23
return;
30
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0505b/index.html
24
31
* Application Note AN521:
25
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_excl(DisasContext *s, uint32_t insn)
32
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0521c/index.html
26
}
33
+ * Application Note AN524:
27
clean_addr = gen_mte_check1(s, cpu_reg_sp(s, rn),
34
+ * https://developer.arm.com/documentation/dai0524/latest/
28
false, rn != 31, size);
35
*
29
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size, false, true, rt,
36
* The AN505 defers to the Cortex-M33 processor ARMv8M IoT Kit FVP User Guide
30
- disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
37
* (ARM ECM0601256) for the details of some of the device layout:
31
+ /* TODO: ARMv8.4-LSE SCTLR.nAA */
38
* http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ecm0601256/index.html
32
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size | MO_ALIGN, false, true,
39
- * Similarly, the AN521 uses the SSE-200, and the SSE-200 TRM defines
33
+ rt, disas_ldst_compute_iss_sf(size, false, 0), is_lasr);
40
+ * Similarly, the AN521 and AN524 use the SSE-200, and the SSE-200 TRM defines
34
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
41
* most of the device layout:
35
return;
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
36
43
*
37
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
44
@@ -XXX,XX +XXX,XX @@
38
int size = extract32(insn, 30, 2);
45
#include "hw/qdev-clock.h"
39
TCGv_i64 clean_addr, dirty_addr;
46
#include "qom/object.h"
40
bool is_store = false;
47
41
- bool is_signed = false;
48
-#define MPS2TZ_NUMIRQ_MAX 92
42
bool extend = false;
49
+#define MPS2TZ_NUMIRQ_MAX 95
43
bool iss_sf;
50
#define MPS2TZ_RAM_MAX 4
44
+ MemOp mop;
51
45
52
typedef enum MPS2TZFPGAType {
46
if (!dc_isar_feature(aa64_rcpc_8_4, s)) {
53
FPGA_AN505,
47
unallocated_encoding(s);
54
FPGA_AN521,
48
return;
55
+ FPGA_AN524,
49
}
56
} MPS2TZFPGAType;
50
57
51
+ /* TODO: ARMv8.4-LSE SCTLR.nAA */
58
/*
52
+ mop = size | MO_ALIGN;
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
+
53
+
98
static const RAMInfo an505_raminfo[] = { {
54
switch (opc) {
99
.name = "ssram-0",
55
case 0: /* STLURB */
100
.base = 0x00000000,
56
is_store = true;
101
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an505_raminfo[] = { {
57
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
102
},
58
unallocated_encoding(s);
103
};
59
return;
104
60
}
105
+static const RAMInfo an524_raminfo[] = { {
61
- is_signed = true;
106
+ .name = "bram",
62
+ mop |= MO_SIGN;
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;
63
break;
199
+ case FPGA_AN524:
64
case 3: /* LDAPURS* 32-bit variant */
200
+ ppcs = an524_ppcs;
65
if (size > 1) {
201
+ num_ppcs = ARRAY_SIZE(an524_ppcs);
66
unallocated_encoding(s);
202
+ break;
67
return;
68
}
69
- is_signed = true;
70
+ mop |= MO_SIGN;
71
extend = true; /* zero-extend 32->64 after signed load */
72
break;
203
default:
73
default:
204
g_assert_not_reached();
74
g_assert_not_reached();
205
}
75
}
206
@@ -XXX,XX +XXX,XX @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data)
76
207
mps2tz_set_default_ram_info(mmc);
77
- iss_sf = disas_ldst_compute_iss_sf(size, is_signed, opc);
208
}
78
+ iss_sf = disas_ldst_compute_iss_sf(size, (mop & MO_SIGN) != 0, opc);
209
79
210
+static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
80
if (rn == 31) {
211
+{
81
gen_check_sp_alignment(s);
212
+ MachineClass *mc = MACHINE_CLASS(oc);
82
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_ldapr_stlr(DisasContext *s, uint32_t insn)
213
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc);
83
if (is_store) {
214
+
84
/* Store-Release semantics */
215
+ mc->desc = "ARM MPS3 with AN524 FPGA image for dual Cortex-M33";
85
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
216
+ mc->default_cpus = 2;
86
- do_gpr_st(s, cpu_reg(s, rt), clean_addr, size, true, rt, iss_sf, true);
217
+ mc->min_cpus = mc->default_cpus;
87
+ do_gpr_st(s, cpu_reg(s, rt), clean_addr, mop, true, rt, iss_sf, true);
218
+ mc->max_cpus = mc->default_cpus;
88
} else {
219
+ mmc->fpga_type = FPGA_AN524;
89
/*
220
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-m33");
90
* Load-AcquirePC semantics; we implement as the slightly more
221
+ mmc->scc_id = 0x41045240;
91
* restrictive Load-Acquire.
222
+ mmc->sysclk_frq = 32 * 1000 * 1000; /* 32MHz */
92
*/
223
+ mmc->oscclk = an524_oscclk;
93
- do_gpr_ld(s, cpu_reg(s, rt), clean_addr, size + is_signed * MO_SIGN,
224
+ mmc->len_oscclk = ARRAY_SIZE(an524_oscclk);
94
+ do_gpr_ld(s, cpu_reg(s, rt), clean_addr, mop,
225
+ mmc->fpgaio_num_leds = 10;
95
extend, true, rt, iss_sf, true);
226
+ mmc->fpgaio_has_switches = true;
96
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
227
+ mmc->numirq = 95;
97
}
228
+ mmc->raminfo = an524_raminfo;
229
+ mmc->armsse_type = TYPE_SSE200;
230
+ mps2tz_set_default_ram_info(mmc);
231
+}
232
+
233
static const TypeInfo mps2tz_info = {
234
.name = TYPE_MPS2TZ_MACHINE,
235
.parent = TYPE_MACHINE,
236
@@ -XXX,XX +XXX,XX @@ static const TypeInfo mps2tz_an521_info = {
237
.class_init = mps2tz_an521_class_init,
238
};
239
240
+static const TypeInfo mps3tz_an524_info = {
241
+ .name = TYPE_MPS3TZ_AN524_MACHINE,
242
+ .parent = TYPE_MPS2TZ_MACHINE,
243
+ .class_init = mps3tz_an524_class_init,
244
+};
245
+
246
static void mps2tz_machine_init(void)
247
{
248
type_register_static(&mps2tz_info);
249
type_register_static(&mps2tz_an505_info);
250
type_register_static(&mps2tz_an521_info);
251
+ type_register_static(&mps3tz_an524_info);
252
}
253
254
type_init(mps2tz_machine_init);
255
--
98
--
256
2.20.1
99
2.20.1
257
100
258
101
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The STATUS register will be reset to IDLE in
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
cnpcm7xx_smbus_enter_reset(), no need to preset
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
it in instance_init().
5
Message-id: 20210419202257.161730-29-richard.henderson@linaro.org
6
7
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Hao Wu <wuhaotsh@google.com>
9
Message-id: 20210228224813.312532-1-f4bug@amsat.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
hw/i2c/npcm7xx_smbus.c | 1 -
8
target/arm/translate-a64.c | 20 ++++++++++----------
13
1 file changed, 1 deletion(-)
9
1 file changed, 10 insertions(+), 10 deletions(-)
14
10
15
diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/i2c/npcm7xx_smbus.c
13
--- a/target/arm/translate-a64.c
18
+++ b/hw/i2c/npcm7xx_smbus.c
14
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_smbus_init(Object *obj)
15
@@ -XXX,XX +XXX,XX @@ static void write_vec_element_i32(DisasContext *s, TCGv_i32 tcg_src,
20
sysbus_init_mmio(sbd, &s->iomem);
16
21
17
/* Store from vector register to memory */
22
s->bus = i2c_init_bus(DEVICE(s), "i2c-bus");
18
static void do_vec_st(DisasContext *s, int srcidx, int element,
23
- s->status = NPCM7XX_SMBUS_STATUS_IDLE;
19
- TCGv_i64 tcg_addr, int size, MemOp endian)
20
+ TCGv_i64 tcg_addr, MemOp mop)
21
{
22
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
23
24
- read_vec_element(s, tcg_tmp, srcidx, element, size);
25
- tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), endian | size);
26
+ read_vec_element(s, tcg_tmp, srcidx, element, mop & MO_SIZE);
27
+ tcg_gen_qemu_st_i64(tcg_tmp, tcg_addr, get_mem_index(s), mop);
28
29
tcg_temp_free_i64(tcg_tmp);
24
}
30
}
25
31
26
static const VMStateDescription vmstate_npcm7xx_smbus = {
32
/* Load from memory to vector register */
33
static void do_vec_ld(DisasContext *s, int destidx, int element,
34
- TCGv_i64 tcg_addr, int size, MemOp endian)
35
+ TCGv_i64 tcg_addr, MemOp mop)
36
{
37
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
38
39
- tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), endian | size);
40
- write_vec_element(s, tcg_tmp, destidx, element, size);
41
+ tcg_gen_qemu_ld_i64(tcg_tmp, tcg_addr, get_mem_index(s), mop);
42
+ write_vec_element(s, tcg_tmp, destidx, element, mop & MO_SIZE);
43
44
tcg_temp_free_i64(tcg_tmp);
45
}
46
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
47
for (xs = 0; xs < selem; xs++) {
48
int tt = (rt + r + xs) % 32;
49
if (is_store) {
50
- do_vec_st(s, tt, e, clean_addr, size, endian);
51
+ do_vec_st(s, tt, e, clean_addr, size | endian);
52
} else {
53
- do_vec_ld(s, tt, e, clean_addr, size, endian);
54
+ do_vec_ld(s, tt, e, clean_addr, size | endian);
55
}
56
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
57
}
58
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
59
} else {
60
/* Load/store one element per register */
61
if (is_load) {
62
- do_vec_ld(s, rt, index, clean_addr, scale, s->be_data);
63
+ do_vec_ld(s, rt, index, clean_addr, scale | s->be_data);
64
} else {
65
- do_vec_st(s, rt, index, clean_addr, scale, s->be_data);
66
+ do_vec_st(s, rt, index, clean_addr, scale | s->be_data);
67
}
68
}
69
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
27
--
70
--
28
2.20.1
71
2.20.1
29
72
30
73
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
We hint the 'has_rpu' property is no longer required since commit
4
6908ec448b4 ("xlnx-zynqmp: Properly support the smp command line
5
option") which was released in QEMU v2.11.0.
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.
13
2
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20210219144350.1979905-1-f4bug@amsat.org
5
Message-id: 20210419202257.161730-30-richard.henderson@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
7
---
19
include/hw/arm/xlnx-zynqmp.h | 2 --
8
target/arm/translate-a64.c | 15 +++++++++++----
20
hw/arm/xlnx-zynqmp.c | 6 ------
9
1 file changed, 11 insertions(+), 4 deletions(-)
21
2 files changed, 8 deletions(-)
22
10
23
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
24
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/xlnx-zynqmp.h
13
--- a/target/arm/translate-a64.c
26
+++ b/include/hw/arm/xlnx-zynqmp.h
14
+++ b/target/arm/translate-a64.c
27
@@ -XXX,XX +XXX,XX @@ struct XlnxZynqMPState {
15
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
28
bool secure;
16
bool is_postidx = extract32(insn, 23, 1);
29
/* Has the ARM Virtualization extensions? */
17
bool is_q = extract32(insn, 30, 1);
30
bool virt;
18
TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
31
- /* Has the RPU subsystem? */
19
- MemOp endian = s->be_data;
32
- bool has_rpu;
20
+ MemOp endian, align, mop;
33
21
34
/* CAN bus. */
22
int total; /* total bytes */
35
CanBusState *canbus[XLNX_ZYNQMP_NUM_CAN];
23
int elements; /* elements per vector */
36
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
24
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/xlnx-zynqmp.c
39
+++ b/hw/arm/xlnx-zynqmp.c
40
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
41
}
42
}
25
}
43
26
44
- if (s->has_rpu) {
27
/* For our purposes, bytes are always little-endian. */
45
- info_report("The 'has_rpu' property is no longer required, to use the "
28
+ endian = s->be_data;
46
- "RPUs just use -smp 6.");
29
if (size == 0) {
47
- }
30
endian = MO_LE;
48
-
31
}
49
xlnx_zynqmp_create_rpu(ms, s, boot_cpu, &err);
32
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
50
if (err) {
33
* Consecutive little-endian elements from a single register
51
error_propagate(errp, err);
34
* can be promoted to a larger little-endian operation.
52
@@ -XXX,XX +XXX,XX @@ static Property xlnx_zynqmp_props[] = {
35
*/
53
DEFINE_PROP_STRING("boot-cpu", XlnxZynqMPState, boot_cpu),
36
+ align = MO_ALIGN;
54
DEFINE_PROP_BOOL("secure", XlnxZynqMPState, secure, false),
37
if (selem == 1 && endian == MO_LE) {
55
DEFINE_PROP_BOOL("virtualization", XlnxZynqMPState, virt, false),
38
+ align = pow2_align(size);
56
- DEFINE_PROP_BOOL("has_rpu", XlnxZynqMPState, has_rpu, false),
39
size = 3;
57
DEFINE_PROP_LINK("ddr-ram", XlnxZynqMPState, ddr_ram, TYPE_MEMORY_REGION,
40
}
58
MemoryRegion *),
41
- elements = (is_q ? 16 : 8) >> size;
59
DEFINE_PROP_LINK("canbus0", XlnxZynqMPState, canbus[0], TYPE_CAN_BUS,
42
+ if (!s->align_mem) {
43
+ align = 0;
44
+ }
45
+ mop = endian | size | align;
46
47
+ elements = (is_q ? 16 : 8) >> size;
48
tcg_ebytes = tcg_const_i64(1 << size);
49
for (r = 0; r < rpt; r++) {
50
int e;
51
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_multiple_struct(DisasContext *s, uint32_t insn)
52
for (xs = 0; xs < selem; xs++) {
53
int tt = (rt + r + xs) % 32;
54
if (is_store) {
55
- do_vec_st(s, tt, e, clean_addr, size | endian);
56
+ do_vec_st(s, tt, e, clean_addr, mop);
57
} else {
58
- do_vec_ld(s, tt, e, clean_addr, size | endian);
59
+ do_vec_ld(s, tt, e, clean_addr, mop);
60
}
61
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
62
}
60
--
63
--
61
2.20.1
64
2.20.1
62
65
63
66
diff view generated by jsdifflib
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Let add 'max' cpu while work goes on adding newer CPU types than
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Cortex-A72. This allows us to check SVE etc support.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
5
Message-id: 20210419202257.161730-31-richard.henderson@linaro.org
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
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
hw/arm/sbsa-ref.c | 1 +
8
target/arm/translate-a64.c | 9 +++++----
13
1 file changed, 1 insertion(+)
9
1 file changed, 5 insertions(+), 4 deletions(-)
14
10
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
13
--- a/target/arm/translate-a64.c
18
+++ b/hw/arm/sbsa-ref.c
14
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
15
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
20
static const char * const valid_cpus[] = {
16
int index = is_q << 3 | S << 2 | size;
21
ARM_CPU_TYPE_NAME("cortex-a57"),
17
int xs, total;
22
ARM_CPU_TYPE_NAME("cortex-a72"),
18
TCGv_i64 clean_addr, tcg_rn, tcg_ebytes;
23
+ ARM_CPU_TYPE_NAME("max"),
19
+ MemOp mop;
24
};
20
25
21
if (extract32(insn, 31, 1)) {
26
static bool cpu_type_valid(const char *cpu)
22
unallocated_encoding(s);
23
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
24
25
clean_addr = gen_mte_checkN(s, tcg_rn, !is_load, is_postidx || rn != 31,
26
total);
27
+ mop = finalize_memop(s, scale);
28
29
tcg_ebytes = tcg_const_i64(1 << scale);
30
for (xs = 0; xs < selem; xs++) {
31
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
32
/* Load and replicate to all elements */
33
TCGv_i64 tcg_tmp = tcg_temp_new_i64();
34
35
- tcg_gen_qemu_ld_i64(tcg_tmp, clean_addr,
36
- get_mem_index(s), s->be_data + scale);
37
+ tcg_gen_qemu_ld_i64(tcg_tmp, clean_addr, get_mem_index(s), mop);
38
tcg_gen_gvec_dup_i64(scale, vec_full_reg_offset(s, rt),
39
(is_q + 1) * 8, vec_full_reg_size(s),
40
tcg_tmp);
41
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_single_struct(DisasContext *s, uint32_t insn)
42
} else {
43
/* Load/store one element per register */
44
if (is_load) {
45
- do_vec_ld(s, rt, index, clean_addr, scale | s->be_data);
46
+ do_vec_ld(s, rt, index, clean_addr, mop);
47
} else {
48
- do_vec_st(s, rt, index, clean_addr, scale | s->be_data);
49
+ do_vec_st(s, rt, index, clean_addr, mop);
50
}
51
}
52
tcg_gen_add_i64(clean_addr, clean_addr, tcg_ebytes);
27
--
53
--
28
2.20.1
54
2.20.1
29
55
30
56
diff view generated by jsdifflib
1
From: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Cortex-A53 supports 40bits of address space. sbsa-ref's memory starts
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
above this limit.
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
5
Message-id: 20210419202257.161730-32-richard.henderson@linaro.org
6
Signed-off-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Acked-by: Leif Lindholm <leif@nuviainc.com>
9
Message-id: 20210216150122.3830863-2-marcin.juszkiewicz@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
hw/arm/sbsa-ref.c | 1 -
8
target/arm/translate-sve.c | 2 +-
13
1 file changed, 1 deletion(-)
9
1 file changed, 1 insertion(+), 1 deletion(-)
14
10
15
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
11
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/sbsa-ref.c
13
--- a/target/arm/translate-sve.c
18
+++ b/hw/arm/sbsa-ref.c
14
+++ b/target/arm/translate-sve.c
19
@@ -XXX,XX +XXX,XX @@ static const int sbsa_ref_irqmap[] = {
15
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a)
20
};
16
clean_addr = gen_mte_check1(s, temp, false, true, msz);
21
17
22
static const char * const valid_cpus[] = {
18
tcg_gen_qemu_ld_i64(temp, clean_addr, get_mem_index(s),
23
- ARM_CPU_TYPE_NAME("cortex-a53"),
19
- s->be_data | dtype_mop[a->dtype]);
24
ARM_CPU_TYPE_NAME("cortex-a57"),
20
+ finalize_memop(s, dtype_mop[a->dtype]));
25
ARM_CPU_TYPE_NAME("cortex-a72"),
21
26
};
22
/* Broadcast to *all* elements. */
23
tcg_gen_gvec_dup_i64(esz, vec_full_reg_offset(s, a->rd),
27
--
24
--
28
2.20.1
25
2.20.1
29
26
30
27
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Cornelia Huck <cohuck@redhat.com>
2
2
3
We will move this code in the next commit. Clean it up
3
Add 6.1 machine types for arm/i440fx/q35/s390x/spapr.
4
first to avoid checkpatch.pl errors.
4
5
5
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
6
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Acked-by: Greg Kurz <groug@kaod.org>
7
Message-id: 20210221222617.2579610-3-f4bug@amsat.org
7
Message-id: 20210331111900.118274-1-cohuck@redhat.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/cpu.c | 12 ++++++++----
11
include/hw/boards.h | 3 +++
12
1 file changed, 8 insertions(+), 4 deletions(-)
12
include/hw/i386/pc.h | 3 +++
13
13
hw/arm/virt.c | 7 ++++++-
14
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
14
hw/core/machine.c | 3 +++
15
index XXXXXXX..XXXXXXX 100644
15
hw/i386/pc.c | 3 +++
16
--- a/target/arm/cpu.c
16
hw/i386/pc_piix.c | 14 +++++++++++++-
17
+++ b/target/arm/cpu.c
17
hw/i386/pc_q35.c | 13 ++++++++++++-
18
@@ -XXX,XX +XXX,XX @@ static void cortex_a8_initfn(Object *obj)
18
hw/ppc/spapr.c | 17 ++++++++++++++---
19
}
19
hw/s390x/s390-virtio-ccw.c | 14 +++++++++++++-
20
20
9 files changed, 70 insertions(+), 7 deletions(-)
21
static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
21
22
- /* power_control should be set to maximum latency. Again,
22
diff --git a/include/hw/boards.h b/include/hw/boards.h
23
+ /*
23
index XXXXXXX..XXXXXXX 100644
24
+ * power_control should be set to maximum latency. Again,
24
--- a/include/hw/boards.h
25
* default to 0 and set by private hook
25
+++ b/include/hw/boards.h
26
*/
26
@@ -XXX,XX +XXX,XX @@ struct MachineState {
27
{ .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
27
} \
28
@@ -XXX,XX +XXX,XX @@ static void cortex_a9_initfn(Object *obj)
28
type_init(machine_initfn##_register_types)
29
set_feature(&cpu->env, ARM_FEATURE_NEON);
29
30
set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
30
+extern GlobalProperty hw_compat_6_0[];
31
set_feature(&cpu->env, ARM_FEATURE_EL3);
31
+extern const size_t hw_compat_6_0_len;
32
- /* Note that A9 supports the MP extensions even for
32
+
33
+ /*
33
extern GlobalProperty hw_compat_5_2[];
34
+ * Note that A9 supports the MP extensions even for
34
extern const size_t hw_compat_5_2_len;
35
* A9UP and single-core A9MP (which are both different
35
36
* and valid configurations; we don't model A9UP).
36
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
37
*/
37
index XXXXXXX..XXXXXXX 100644
38
@@ -XXX,XX +XXX,XX @@ static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
38
--- a/include/hw/i386/pc.h
39
{
39
+++ b/include/hw/i386/pc.h
40
MachineState *ms = MACHINE(qdev_get_machine());
40
@@ -XXX,XX +XXX,XX @@ bool pc_system_ovmf_table_find(const char *entry, uint8_t **data,
41
41
void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
42
- /* Linux wants the number of processors from here.
42
const CPUArchIdList *apic_ids, GArray *entry);
43
+ /*
43
44
+ * Linux wants the number of processors from here.
44
+extern GlobalProperty pc_compat_6_0[];
45
* Might as well set the interrupt-controller bit too.
45
+extern const size_t pc_compat_6_0_len;
46
*/
46
+
47
return ((ms->smp.cpus - 1) << 24) | (1 << 23);
47
extern GlobalProperty pc_compat_5_2[];
48
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
48
extern const size_t pc_compat_5_2_len;
49
cpu->isar.id_mmfr1 = 0x40000000;
49
50
cpu->isar.id_mmfr2 = 0x01240000;
50
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
51
cpu->isar.id_mmfr3 = 0x02102211;
51
index XXXXXXX..XXXXXXX 100644
52
- /* a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
52
--- a/hw/arm/virt.c
53
+ /*
53
+++ b/hw/arm/virt.c
54
+ * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
54
@@ -XXX,XX +XXX,XX @@ static void machvirt_machine_init(void)
55
* table 4-41 gives 0x02101110, which includes the arm div insns.
55
}
56
*/
56
type_init(machvirt_machine_init);
57
cpu->isar.id_isar0 = 0x02101110;
57
58
+static void virt_machine_6_1_options(MachineClass *mc)
59
+{
60
+}
61
+DEFINE_VIRT_MACHINE_AS_LATEST(6, 1)
62
+
63
static void virt_machine_6_0_options(MachineClass *mc)
64
{
65
}
66
-DEFINE_VIRT_MACHINE_AS_LATEST(6, 0)
67
+DEFINE_VIRT_MACHINE(6, 0)
68
69
static void virt_machine_5_2_options(MachineClass *mc)
70
{
71
diff --git a/hw/core/machine.c b/hw/core/machine.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/hw/core/machine.c
74
+++ b/hw/core/machine.c
75
@@ -XXX,XX +XXX,XX @@
76
#include "hw/virtio/virtio.h"
77
#include "hw/virtio/virtio-pci.h"
78
79
+GlobalProperty hw_compat_6_0[] = {};
80
+const size_t hw_compat_6_0_len = G_N_ELEMENTS(hw_compat_6_0);
81
+
82
GlobalProperty hw_compat_5_2[] = {
83
{ "ICH9-LPC", "smm-compat", "on"},
84
{ "PIIX4_PM", "smm-compat", "on"},
85
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/i386/pc.c
88
+++ b/hw/i386/pc.c
89
@@ -XXX,XX +XXX,XX @@
90
#include "trace.h"
91
#include CONFIG_DEVICES
92
93
+GlobalProperty pc_compat_6_0[] = {};
94
+const size_t pc_compat_6_0_len = G_N_ELEMENTS(pc_compat_6_0);
95
+
96
GlobalProperty pc_compat_5_2[] = {
97
{ "ICH9-LPC", "x-smi-cpu-hotunplug", "off" },
98
};
99
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/i386/pc_piix.c
102
+++ b/hw/i386/pc_piix.c
103
@@ -XXX,XX +XXX,XX @@ static void pc_i440fx_machine_options(MachineClass *m)
104
machine_class_allow_dynamic_sysbus_dev(m, TYPE_VMBUS_BRIDGE);
105
}
106
107
-static void pc_i440fx_6_0_machine_options(MachineClass *m)
108
+static void pc_i440fx_6_1_machine_options(MachineClass *m)
109
{
110
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
111
pc_i440fx_machine_options(m);
112
@@ -XXX,XX +XXX,XX @@ static void pc_i440fx_6_0_machine_options(MachineClass *m)
113
pcmc->default_cpu_version = 1;
114
}
115
116
+DEFINE_I440FX_MACHINE(v6_1, "pc-i440fx-6.1", NULL,
117
+ pc_i440fx_6_1_machine_options);
118
+
119
+static void pc_i440fx_6_0_machine_options(MachineClass *m)
120
+{
121
+ pc_i440fx_6_1_machine_options(m);
122
+ m->alias = NULL;
123
+ m->is_default = false;
124
+ compat_props_add(m->compat_props, hw_compat_6_0, hw_compat_6_0_len);
125
+ compat_props_add(m->compat_props, pc_compat_6_0, pc_compat_6_0_len);
126
+}
127
+
128
DEFINE_I440FX_MACHINE(v6_0, "pc-i440fx-6.0", NULL,
129
pc_i440fx_6_0_machine_options);
130
131
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/hw/i386/pc_q35.c
134
+++ b/hw/i386/pc_q35.c
135
@@ -XXX,XX +XXX,XX @@ static void pc_q35_machine_options(MachineClass *m)
136
m->max_cpus = 288;
137
}
138
139
-static void pc_q35_6_0_machine_options(MachineClass *m)
140
+static void pc_q35_6_1_machine_options(MachineClass *m)
141
{
142
PCMachineClass *pcmc = PC_MACHINE_CLASS(m);
143
pc_q35_machine_options(m);
144
@@ -XXX,XX +XXX,XX @@ static void pc_q35_6_0_machine_options(MachineClass *m)
145
pcmc->default_cpu_version = 1;
146
}
147
148
+DEFINE_Q35_MACHINE(v6_1, "pc-q35-6.1", NULL,
149
+ pc_q35_6_1_machine_options);
150
+
151
+static void pc_q35_6_0_machine_options(MachineClass *m)
152
+{
153
+ pc_q35_6_1_machine_options(m);
154
+ m->alias = NULL;
155
+ compat_props_add(m->compat_props, hw_compat_6_0, hw_compat_6_0_len);
156
+ compat_props_add(m->compat_props, pc_compat_6_0, pc_compat_6_0_len);
157
+}
158
+
159
DEFINE_Q35_MACHINE(v6_0, "pc-q35-6.0", NULL,
160
pc_q35_6_0_machine_options);
161
162
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/hw/ppc/spapr.c
165
+++ b/hw/ppc/spapr.c
166
@@ -XXX,XX +XXX,XX @@ static void spapr_machine_latest_class_options(MachineClass *mc)
167
type_init(spapr_machine_register_##suffix)
168
169
/*
170
- * pseries-6.0
171
+ * pseries-6.1
172
*/
173
-static void spapr_machine_6_0_class_options(MachineClass *mc)
174
+static void spapr_machine_6_1_class_options(MachineClass *mc)
175
{
176
/* Defaults for the latest behaviour inherited from the base class */
177
}
178
179
-DEFINE_SPAPR_MACHINE(6_0, "6.0", true);
180
+DEFINE_SPAPR_MACHINE(6_1, "6.1", true);
181
+
182
+/*
183
+ * pseries-6.0
184
+ */
185
+static void spapr_machine_6_0_class_options(MachineClass *mc)
186
+{
187
+ spapr_machine_6_1_class_options(mc);
188
+ compat_props_add(mc->compat_props, hw_compat_6_0, hw_compat_6_0_len);
189
+}
190
+
191
+DEFINE_SPAPR_MACHINE(6_0, "6.0", false);
192
193
/*
194
* pseries-5.2
195
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
196
index XXXXXXX..XXXXXXX 100644
197
--- a/hw/s390x/s390-virtio-ccw.c
198
+++ b/hw/s390x/s390-virtio-ccw.c
199
@@ -XXX,XX +XXX,XX @@ bool css_migration_enabled(void)
200
} \
201
type_init(ccw_machine_register_##suffix)
202
203
+static void ccw_machine_6_1_instance_options(MachineState *machine)
204
+{
205
+}
206
+
207
+static void ccw_machine_6_1_class_options(MachineClass *mc)
208
+{
209
+}
210
+DEFINE_CCW_MACHINE(6_1, "6.1", true);
211
+
212
static void ccw_machine_6_0_instance_options(MachineState *machine)
213
{
214
+ ccw_machine_6_1_instance_options(machine);
215
}
216
217
static void ccw_machine_6_0_class_options(MachineClass *mc)
218
{
219
+ ccw_machine_6_1_class_options(mc);
220
+ compat_props_add(mc->compat_props, hw_compat_6_0, hw_compat_6_0_len);
221
}
222
-DEFINE_CCW_MACHINE(6_0, "6.0", true);
223
+DEFINE_CCW_MACHINE(6_0, "6.0", false);
224
225
static void ccw_machine_5_2_instance_options(MachineState *machine)
226
{
58
--
227
--
59
2.20.1
228
2.20.1
60
229
61
230
diff view generated by jsdifflib
1
From: Doug Evans <dje@google.com>
1
Currently the gpex PCI controller implements no special behaviour for
2
guest accesses to areas of the PIO and MMIO where it has not mapped
3
any PCI devices, which means that for Arm you end up with a CPU
4
exception due to a data abort.
2
5
3
This is a 10/100 ethernet device that has several features.
6
Most host OSes expect "like an x86 PC" behaviour, where bad accesses
4
Only the ones needed by the Linux driver have been implemented.
7
like this return -1 for reads and ignore writes. In the interests of
5
See npcm7xx_emc.c for a list of unimplemented features.
8
not being surprising, make host CPU accesses to these windows behave
9
as -1/discard where there's no mapped PCI device.
6
10
7
Reviewed-by: Hao Wu <wuhaotsh@google.com>
11
The old behaviour generally didn't cause any problems, because
8
Reviewed-by: Avi Fishman <avi.fishman@nuvoton.com>
12
almost always the guest OS will map the PCI devices and then only
9
Signed-off-by: Doug Evans <dje@google.com>
13
access where it has mapped them. One corner case where you will see
10
Message-id: 20210218212453.831406-2-dje@google.com
14
this kind of access is if Linux attempts to probe legacy ISA
15
devices via a PIO window access. So far the only case where we've
16
seen this has been via the syzkaller fuzzer.
17
18
Reported-by: Dmitry Vyukov <dvyukov@google.com>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Acked-by: Michael S. Tsirkin <mst@redhat.com>
22
Message-id: 20210325163315.27724-1-peter.maydell@linaro.org
23
Fixes: https://bugs.launchpad.net/qemu/+bug/1918917
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
25
---
13
include/hw/net/npcm7xx_emc.h | 286 ++++++++++++
26
include/hw/pci-host/gpex.h | 4 +++
14
hw/net/npcm7xx_emc.c | 857 +++++++++++++++++++++++++++++++++++
27
hw/core/machine.c | 4 ++-
15
hw/net/meson.build | 1 +
28
hw/pci-host/gpex.c | 56 ++++++++++++++++++++++++++++++++++++--
16
hw/net/trace-events | 17 +
29
3 files changed, 60 insertions(+), 4 deletions(-)
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
20
30
21
diff --git a/include/hw/net/npcm7xx_emc.h b/include/hw/net/npcm7xx_emc.h
31
diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h
22
new file mode 100644
32
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX
33
--- a/include/hw/pci-host/gpex.h
24
--- /dev/null
34
+++ b/include/hw/pci-host/gpex.h
25
+++ b/include/hw/net/npcm7xx_emc.h
35
@@ -XXX,XX +XXX,XX @@ struct GPEXHost {
36
37
MemoryRegion io_ioport;
38
MemoryRegion io_mmio;
39
+ MemoryRegion io_ioport_window;
40
+ MemoryRegion io_mmio_window;
41
qemu_irq irq[GPEX_NUM_IRQS];
42
int irq_num[GPEX_NUM_IRQS];
43
+
44
+ bool allow_unmapped_accesses;
45
};
46
47
struct GPEXConfig {
48
diff --git a/hw/core/machine.c b/hw/core/machine.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/core/machine.c
51
+++ b/hw/core/machine.c
26
@@ -XXX,XX +XXX,XX @@
52
@@ -XXX,XX +XXX,XX @@
27
+/*
53
#include "hw/virtio/virtio.h"
28
+ * Nuvoton NPCM7xx EMC Module
54
#include "hw/virtio/virtio-pci.h"
29
+ *
55
30
+ * Copyright 2020 Google LLC
56
-GlobalProperty hw_compat_6_0[] = {};
31
+ *
57
+GlobalProperty hw_compat_6_0[] = {
32
+ * This program is free software; you can redistribute it and/or modify it
58
+ { "gpex-pcihost", "allow-unmapped-accesses", "false" },
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.
41
+ */
42
+
43
+#ifndef NPCM7XX_EMC_H
44
+#define NPCM7XX_EMC_H
45
+
46
+#include "hw/irq.h"
47
+#include "hw/sysbus.h"
48
+#include "net/net.h"
49
+
50
+/* 32-bit register indices. */
51
+enum NPCM7xxPWMRegister {
52
+ /* Control registers. */
53
+ REG_CAMCMR,
54
+ REG_CAMEN,
55
+
56
+ /* There are 16 CAMn[ML] registers. */
57
+ REG_CAMM_BASE,
58
+ REG_CAML_BASE,
59
+ REG_CAMML_LAST = 0x21,
60
+
61
+ REG_TXDLSA = 0x22,
62
+ REG_RXDLSA,
63
+ REG_MCMDR,
64
+ REG_MIID,
65
+ REG_MIIDA,
66
+ REG_FFTCR,
67
+ REG_TSDR,
68
+ REG_RSDR,
69
+ REG_DMARFC,
70
+ REG_MIEN,
71
+
72
+ /* Status registers. */
73
+ REG_MISTA,
74
+ REG_MGSTA,
75
+ REG_MPCNT,
76
+ REG_MRPC,
77
+ REG_MRPCC,
78
+ REG_MREPC,
79
+ REG_DMARFS,
80
+ REG_CTXDSA,
81
+ REG_CTXBSA,
82
+ REG_CRXDSA,
83
+ REG_CRXBSA,
84
+
85
+ NPCM7XX_NUM_EMC_REGS,
86
+};
59
+};
87
+
60
const size_t hw_compat_6_0_len = G_N_ELEMENTS(hw_compat_6_0);
88
+/* REG_CAMCMR fields */
61
89
+/* Enable CAM Compare */
62
GlobalProperty hw_compat_5_2[] = {
90
+#define REG_CAMCMR_ECMP (1 << 4)
63
diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
91
+/* Complement CAM Compare */
64
index XXXXXXX..XXXXXXX 100644
92
+#define REG_CAMCMR_CCAM (1 << 3)
65
--- a/hw/pci-host/gpex.c
93
+/* Accept Broadcast Packet */
66
+++ b/hw/pci-host/gpex.c
94
+#define REG_CAMCMR_ABP (1 << 2)
67
@@ -XXX,XX +XXX,XX @@ static void gpex_host_realize(DeviceState *dev, Error **errp)
95
+/* Accept Multicast Packet */
68
int i;
96
+#define REG_CAMCMR_AMP (1 << 1)
69
97
+/* Accept Unicast Packet */
70
pcie_host_mmcfg_init(pex, PCIE_MMCFG_SIZE_MAX);
98
+#define REG_CAMCMR_AUP (1 << 0)
71
+ sysbus_init_mmio(sbd, &pex->mmio);
99
+
100
+/* REG_MCMDR fields */
101
+/* Software Reset */
102
+#define REG_MCMDR_SWR (1 << 24)
103
+/* Internal Loopback Select */
104
+#define REG_MCMDR_LBK (1 << 21)
105
+/* Operation Mode Select */
106
+#define REG_MCMDR_OPMOD (1 << 20)
107
+/* Enable MDC Clock Generation */
108
+#define REG_MCMDR_ENMDC (1 << 19)
109
+/* Full-Duplex Mode Select */
110
+#define REG_MCMDR_FDUP (1 << 18)
111
+/* Enable SQE Checking */
112
+#define REG_MCMDR_ENSEQ (1 << 17)
113
+/* Send PAUSE Frame */
114
+#define REG_MCMDR_SDPZ (1 << 16)
115
+/* No Defer */
116
+#define REG_MCMDR_NDEF (1 << 9)
117
+/* Frame Transmission On */
118
+#define REG_MCMDR_TXON (1 << 8)
119
+/* Strip CRC Checksum */
120
+#define REG_MCMDR_SPCRC (1 << 5)
121
+/* Accept CRC Error Packet */
122
+#define REG_MCMDR_AEP (1 << 4)
123
+/* Accept Control Packet */
124
+#define REG_MCMDR_ACP (1 << 3)
125
+/* Accept Runt Packet */
126
+#define REG_MCMDR_ARP (1 << 2)
127
+/* Accept Long Packet */
128
+#define REG_MCMDR_ALP (1 << 1)
129
+/* Frame Reception On */
130
+#define REG_MCMDR_RXON (1 << 0)
131
+
132
+/* REG_MIEN fields */
133
+/* Enable Transmit Descriptor Unavailable Interrupt */
134
+#define REG_MIEN_ENTDU (1 << 23)
135
+/* Enable Transmit Completion Interrupt */
136
+#define REG_MIEN_ENTXCP (1 << 18)
137
+/* Enable Transmit Interrupt */
138
+#define REG_MIEN_ENTXINTR (1 << 16)
139
+/* Enable Receive Descriptor Unavailable Interrupt */
140
+#define REG_MIEN_ENRDU (1 << 10)
141
+/* Enable Receive Good Interrupt */
142
+#define REG_MIEN_ENRXGD (1 << 4)
143
+/* Enable Receive Interrupt */
144
+#define REG_MIEN_ENRXINTR (1 << 0)
145
+
146
+/* REG_MISTA fields */
147
+/* TODO: Add error fields and support simulated errors? */
148
+/* Transmit Bus Error Interrupt */
149
+#define REG_MISTA_TXBERR (1 << 24)
150
+/* Transmit Descriptor Unavailable Interrupt */
151
+#define REG_MISTA_TDU (1 << 23)
152
+/* Transmit Completion Interrupt */
153
+#define REG_MISTA_TXCP (1 << 18)
154
+/* Transmit Interrupt */
155
+#define REG_MISTA_TXINTR (1 << 16)
156
+/* Receive Bus Error Interrupt */
157
+#define REG_MISTA_RXBERR (1 << 11)
158
+/* Receive Descriptor Unavailable Interrupt */
159
+#define REG_MISTA_RDU (1 << 10)
160
+/* DMA Early Notification Interrupt */
161
+#define REG_MISTA_DENI (1 << 9)
162
+/* Maximum Frame Length Interrupt */
163
+#define REG_MISTA_DFOI (1 << 8)
164
+/* Receive Good Interrupt */
165
+#define REG_MISTA_RXGD (1 << 4)
166
+/* Packet Too Long Interrupt */
167
+#define REG_MISTA_PTLE (1 << 3)
168
+/* Receive Interrupt */
169
+#define REG_MISTA_RXINTR (1 << 0)
170
+
171
+/* REG_MGSTA fields */
172
+/* Transmission Halted */
173
+#define REG_MGSTA_TXHA (1 << 11)
174
+/* Receive Halted */
175
+#define REG_MGSTA_RXHA (1 << 11)
176
+
177
+/* REG_DMARFC fields */
178
+/* Maximum Receive Frame Length */
179
+#define REG_DMARFC_RXMS(word) extract32((word), 0, 16)
180
+
181
+/* REG MIIDA fields */
182
+/* Busy Bit */
183
+#define REG_MIIDA_BUSY (1 << 17)
184
+
185
+/* Transmit and receive descriptors */
186
+typedef struct NPCM7xxEMCTxDesc NPCM7xxEMCTxDesc;
187
+typedef struct NPCM7xxEMCRxDesc NPCM7xxEMCRxDesc;
188
+
189
+struct NPCM7xxEMCTxDesc {
190
+ uint32_t flags;
191
+ uint32_t txbsa;
192
+ uint32_t status_and_length;
193
+ uint32_t ntxdsa;
194
+};
195
+
196
+struct NPCM7xxEMCRxDesc {
197
+ uint32_t status_and_length;
198
+ uint32_t rxbsa;
199
+ uint32_t reserved;
200
+ uint32_t nrxdsa;
201
+};
202
+
203
+/* NPCM7xxEMCTxDesc.flags values */
204
+/* Owner: 0 = cpu, 1 = emc */
205
+#define TX_DESC_FLAG_OWNER_MASK (1 << 31)
206
+/* Transmit interrupt enable */
207
+#define TX_DESC_FLAG_INTEN (1 << 2)
208
+/* CRC append */
209
+#define TX_DESC_FLAG_CRCAPP (1 << 1)
210
+/* Padding enable */
211
+#define TX_DESC_FLAG_PADEN (1 << 0)
212
+
213
+/* NPCM7xxEMCTxDesc.status_and_length values */
214
+/* Collision count */
215
+#define TX_DESC_STATUS_CCNT_SHIFT 28
216
+#define TX_DESC_STATUS_CCNT_BITSIZE 4
217
+/* SQE error */
218
+#define TX_DESC_STATUS_SQE (1 << 26)
219
+/* Transmission paused */
220
+#define TX_DESC_STATUS_PAU (1 << 25)
221
+/* P transmission halted */
222
+#define TX_DESC_STATUS_TXHA (1 << 24)
223
+/* Late collision */
224
+#define TX_DESC_STATUS_LC (1 << 23)
225
+/* Transmission abort */
226
+#define TX_DESC_STATUS_TXABT (1 << 22)
227
+/* No carrier sense */
228
+#define TX_DESC_STATUS_NCS (1 << 21)
229
+/* Defer exceed */
230
+#define TX_DESC_STATUS_EXDEF (1 << 20)
231
+/* Transmission complete */
232
+#define TX_DESC_STATUS_TXCP (1 << 19)
233
+/* Transmission deferred */
234
+#define TX_DESC_STATUS_DEF (1 << 17)
235
+/* Transmit interrupt */
236
+#define TX_DESC_STATUS_TXINTR (1 << 16)
237
+
238
+#define TX_DESC_PKT_LEN(word) extract32((word), 0, 16)
239
+
240
+/* Transmit buffer start address */
241
+#define TX_DESC_TXBSA(word) ((uint32_t) (word) & ~3u)
242
+
243
+/* Next transmit descriptor start address */
244
+#define TX_DESC_NTXDSA(word) ((uint32_t) (word) & ~3u)
245
+
246
+/* NPCM7xxEMCRxDesc.status_and_length values */
247
+/* Owner: 0b00 = cpu, 0b01 = undefined, 0b10 = emc, 0b11 = undefined */
248
+#define RX_DESC_STATUS_OWNER_SHIFT 30
249
+#define RX_DESC_STATUS_OWNER_BITSIZE 2
250
+#define RX_DESC_STATUS_OWNER_MASK (3 << RX_DESC_STATUS_OWNER_SHIFT)
251
+/* Runt packet */
252
+#define RX_DESC_STATUS_RP (1 << 22)
253
+/* Alignment error */
254
+#define RX_DESC_STATUS_ALIE (1 << 21)
255
+/* Frame reception complete */
256
+#define RX_DESC_STATUS_RXGD (1 << 20)
257
+/* Packet too long */
258
+#define RX_DESC_STATUS_PTLE (1 << 19)
259
+/* CRC error */
260
+#define RX_DESC_STATUS_CRCE (1 << 17)
261
+/* Receive interrupt */
262
+#define RX_DESC_STATUS_RXINTR (1 << 16)
263
+
264
+#define RX_DESC_PKT_LEN(word) extract32((word), 0, 16)
265
+
266
+/* Receive buffer start address */
267
+#define RX_DESC_RXBSA(word) ((uint32_t) (word) & ~3u)
268
+
269
+/* Next receive descriptor start address */
270
+#define RX_DESC_NRXDSA(word) ((uint32_t) (word) & ~3u)
271
+
272
+/* Minimum packet length, when TX_DESC_FLAG_PADEN is set. */
273
+#define MIN_PACKET_LENGTH 64
274
+
275
+struct NPCM7xxEMCState {
276
+ /*< private >*/
277
+ SysBusDevice parent;
278
+ /*< public >*/
279
+
280
+ MemoryRegion iomem;
281
+
282
+ qemu_irq tx_irq;
283
+ qemu_irq rx_irq;
284
+
285
+ NICState *nic;
286
+ NICConf conf;
287
+
288
+ /* 0 or 1, for log messages */
289
+ uint8_t emc_num;
290
+
291
+ uint32_t regs[NPCM7XX_NUM_EMC_REGS];
292
+
72
+
293
+ /*
73
+ /*
294
+ * tx is active. Set to true by TSDR and then switches off when out of
74
+ * Note that the MemoryRegions io_mmio and io_ioport that we pass
295
+ * descriptors. If the TXON bit in REG_MCMDR is off then this is off.
75
+ * to pci_register_root_bus() are not the same as the
76
+ * MemoryRegions io_mmio_window and io_ioport_window that we
77
+ * expose as SysBus MRs. The difference is in the behaviour of
78
+ * accesses to addresses where no PCI device has been mapped.
79
+ *
80
+ * io_mmio and io_ioport are the underlying PCI view of the PCI
81
+ * address space, and when a PCI device does a bus master access
82
+ * to a bad address this is reported back to it as a transaction
83
+ * failure.
84
+ *
85
+ * io_mmio_window and io_ioport_window implement "unmapped
86
+ * addresses read as -1 and ignore writes"; this is traditional
87
+ * x86 PC behaviour, which is not mandated by the PCI spec proper
88
+ * but expected by much PCI-using guest software, including Linux.
89
+ *
90
+ * In the interests of not being unnecessarily surprising, we
91
+ * implement it in the gpex PCI host controller, by providing the
92
+ * _window MRs, which are containers with io ops that implement
93
+ * the 'background' behaviour and which hold the real PCI MRs as
94
+ * subregions.
296
+ */
95
+ */
297
+ bool tx_active;
96
memory_region_init(&s->io_mmio, OBJECT(s), "gpex_mmio", UINT64_MAX);
97
memory_region_init(&s->io_ioport, OBJECT(s), "gpex_ioport", 64 * 1024);
98
99
- sysbus_init_mmio(sbd, &pex->mmio);
100
- sysbus_init_mmio(sbd, &s->io_mmio);
101
- sysbus_init_mmio(sbd, &s->io_ioport);
102
+ if (s->allow_unmapped_accesses) {
103
+ memory_region_init_io(&s->io_mmio_window, OBJECT(s),
104
+ &unassigned_io_ops, OBJECT(s),
105
+ "gpex_mmio_window", UINT64_MAX);
106
+ memory_region_init_io(&s->io_ioport_window, OBJECT(s),
107
+ &unassigned_io_ops, OBJECT(s),
108
+ "gpex_ioport_window", 64 * 1024);
298
+
109
+
299
+ /*
110
+ memory_region_add_subregion(&s->io_mmio_window, 0, &s->io_mmio);
300
+ * rx is active. Set to true by RSDR and then switches off when out of
111
+ memory_region_add_subregion(&s->io_ioport_window, 0, &s->io_ioport);
301
+ * descriptors. If the RXON bit in REG_MCMDR is off then this is off.
112
+ sysbus_init_mmio(sbd, &s->io_mmio_window);
302
+ */
113
+ sysbus_init_mmio(sbd, &s->io_ioport_window);
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 {
114
+ } else {
471
+ emc->regs[REG_MISTA] &= ~REG_MISTA_TXINTR;
115
+ sysbus_init_mmio(sbd, &s->io_mmio);
472
+ }
116
+ sysbus_init_mmio(sbd, &s->io_ioport);
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
+ }
117
+ }
652
+
118
+
653
+ /* Nothing we can do if we don't own the descriptor. */
119
for (i = 0; i < GPEX_NUM_IRQS; i++) {
654
+ if (!(tx_desc.flags & TX_DESC_FLAG_OWNER_MASK)) {
120
sysbus_init_irq(sbd, &s->irq[i]);
655
+ trace_npcm7xx_emc_cpu_owned_desc(desc_addr);
121
s->irq_num[i] = -1;
656
+ emc_halt_tx(emc, REG_MISTA_TDU);
122
@@ -XXX,XX +XXX,XX @@ static const char *gpex_host_root_bus_path(PCIHostState *host_bridge,
657
+ emc_update_tx_irq(emc);
123
return "0000:00";
658
+ return;
124
}
659
+ }
125
660
+
126
+static Property gpex_host_properties[] = {
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
+ /*
127
+ /*
666
+ * Despite the h/w documentation saying the tx buffer is word aligned,
128
+ * Permit CPU accesses to unmapped areas of the PIO and MMIO windows
667
+ * the linux driver does not word align the buffer. There is value in not
129
+ * (discarding writes and returning -1 for reads) rather than aborting.
668
+ * aligning the buffer: See the description of NET_IP_ALIGN in linux
669
+ * kernel sources.
670
+ */
130
+ */
671
+ next_buf_addr = tx_desc.txbsa;
131
+ DEFINE_PROP_BOOL("allow-unmapped-accesses", GPEXHost,
672
+ emc->regs[REG_CTXBSA] = next_buf_addr;
132
+ allow_unmapped_accesses, true),
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(),
133
+ DEFINE_PROP_END_OF_LIST(),
1148
+};
134
+};
1149
+
135
+
1150
+static void npcm7xx_emc_class_init(ObjectClass *klass, void *data)
136
static void gpex_host_class_init(ObjectClass *klass, void *data)
1151
+{
137
{
1152
+ DeviceClass *dc = DEVICE_CLASS(klass);
138
DeviceClass *dc = DEVICE_CLASS(klass);
1153
+
139
@@ -XXX,XX +XXX,XX @@ static void gpex_host_class_init(ObjectClass *klass, void *data)
1154
+ set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
140
dc->realize = gpex_host_realize;
1155
+ dc->desc = "NPCM7xx EMC Controller";
141
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
1156
+ dc->realize = npcm7xx_emc_realize;
142
dc->fw_name = "pci";
1157
+ dc->unrealize = npcm7xx_emc_unrealize;
143
+ device_class_set_props(dc, gpex_host_properties);
1158
+ dc->reset = npcm7xx_emc_reset;
144
}
1159
+ dc->vmsd = &vmstate_npcm7xx_emc;
145
1160
+ device_class_set_props(dc, npcm7xx_emc_properties);
146
static void gpex_host_initfn(Object *obj)
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
1177
index XXXXXXX..XXXXXXX 100644
1178
--- a/hw/net/meson.build
1179
+++ b/hw/net/meson.build
1180
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_I82596_COMMON', if_true: files('i82596.c'))
1181
softmmu_ss.add(when: 'CONFIG_SUNHME', if_true: files('sunhme.c'))
1182
softmmu_ss.add(when: 'CONFIG_FTGMAC100', if_true: files('ftgmac100.c'))
1183
softmmu_ss.add(when: 'CONFIG_SUNGEM', if_true: files('sungem.c'))
1184
+softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_emc.c'))
1185
1186
softmmu_ss.add(when: 'CONFIG_ETRAXFS', if_true: files('etraxfs_eth.c'))
1187
softmmu_ss.add(when: 'CONFIG_COLDFIRE', if_true: files('mcf_fec.c'))
1188
diff --git a/hw/net/trace-events b/hw/net/trace-events
1189
index XXXXXXX..XXXXXXX 100644
1190
--- a/hw/net/trace-events
1191
+++ b/hw/net/trace-events
1192
@@ -XXX,XX +XXX,XX @@ imx_fec_receive_last(int last) "rx frame flags 0x%04x"
1193
imx_enet_receive(size_t size) "len %zu"
1194
imx_enet_receive_len(uint64_t addr, int len) "rx_bd 0x%"PRIx64" length %d"
1195
imx_enet_receive_last(int last) "rx frame flags 0x%04x"
1196
+
1197
+# npcm7xx_emc.c
1198
+npcm7xx_emc_reset(int emc_num) "Resetting emc%d"
1199
+npcm7xx_emc_update_tx_irq(int level) "Setting tx irq to %d"
1200
+npcm7xx_emc_update_rx_irq(int level) "Setting rx irq to %d"
1201
+npcm7xx_emc_set_mista(uint32_t flags) "ORing 0x%x into MISTA"
1202
+npcm7xx_emc_cpu_owned_desc(uint32_t addr) "Can't process cpu-owned descriptor @0x%x"
1203
+npcm7xx_emc_sent_packet(uint32_t len) "Sent %u byte packet"
1204
+npcm7xx_emc_tx_done(uint32_t ctxdsa) "TX done, CTXDSA=0x%x"
1205
+npcm7xx_emc_can_receive(int can_receive) "Can receive: %d"
1206
+npcm7xx_emc_packet_filtered_out(const char* fail_reason) "Packet filtered out: %s"
1207
+npcm7xx_emc_packet_dropped(uint32_t len) "%u byte packet dropped"
1208
+npcm7xx_emc_receiving_packet(uint32_t len) "Receiving %u byte packet"
1209
+npcm7xx_emc_received_packet(uint32_t len) "Received %u byte packet"
1210
+npcm7xx_emc_rx_done(uint32_t crxdsa) "RX done, CRXDSA=0x%x"
1211
+npcm7xx_emc_reg_read(int emc_num, uint32_t result, const char *name, int regno) "emc%d: 0x%x = reg[%s/%d]"
1212
+npcm7xx_emc_reg_write(int emc_num, const char *name, int regno, uint32_t value) "emc%d: reg[%s/%d] = 0x%x"
1213
--
147
--
1214
2.20.1
148
2.20.1
1215
149
1216
150
diff view generated by jsdifflib
Deleted patch
1
Now the template header is included only for BITS==32, expand
2
out all the macros that depended on the BITS setting.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210215103215.4944-4-peter.maydell@linaro.org
7
---
8
hw/display/tc6393xb_template.h | 35 ++++------------------------------
9
1 file changed, 4 insertions(+), 31 deletions(-)
10
11
diff --git a/hw/display/tc6393xb_template.h b/hw/display/tc6393xb_template.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/display/tc6393xb_template.h
14
+++ b/hw/display/tc6393xb_template.h
15
@@ -XXX,XX +XXX,XX @@
16
* with this program; if not, see <http://www.gnu.org/licenses/>.
17
*/
18
19
-#if BITS == 8
20
-# define SET_PIXEL(addr, color) (*(uint8_t *)addr = color)
21
-#elif BITS == 15 || BITS == 16
22
-# define SET_PIXEL(addr, color) (*(uint16_t *)addr = color)
23
-#elif BITS == 24
24
-# define SET_PIXEL(addr, color) \
25
- do { \
26
- addr[0] = color; \
27
- addr[1] = (color) >> 8; \
28
- addr[2] = (color) >> 16; \
29
- } while (0)
30
-#elif BITS == 32
31
-# define SET_PIXEL(addr, color) (*(uint32_t *)addr = color)
32
-#else
33
-# error unknown bit depth
34
-#endif
35
-
36
-
37
-static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
38
+static void tc6393xb_draw_graphic32(TC6393xbState *s)
39
{
40
DisplaySurface *surface = qemu_console_surface(s->con);
41
int i;
42
@@ -XXX,XX +XXX,XX @@ static void glue(tc6393xb_draw_graphic, BITS)(TC6393xbState *s)
43
data_buffer = s->vram_ptr;
44
data_display = surface_data(surface);
45
for(i = 0; i < s->scr_height; i++) {
46
-#if (BITS == 16)
47
- memcpy(data_display, data_buffer, s->scr_width * 2);
48
- data_buffer += s->scr_width;
49
- data_display += surface_stride(surface);
50
-#else
51
int j;
52
- for (j = 0; j < s->scr_width; j++, data_display += BITS / 8, data_buffer++) {
53
+ for (j = 0; j < s->scr_width; j++, data_display += 4, data_buffer++) {
54
uint16_t color = *data_buffer;
55
- uint32_t dest_color = glue(rgb_to_pixel, BITS)(
56
+ uint32_t dest_color = rgb_to_pixel32(
57
((color & 0xf800) * 0x108) >> 11,
58
((color & 0x7e0) * 0x41) >> 9,
59
((color & 0x1f) * 0x21) >> 2
60
);
61
- SET_PIXEL(data_display, dest_color);
62
+ *(uint32_t *)data_display = dest_color;
63
}
64
-#endif
65
}
66
}
67
-
68
-#undef BITS
69
-#undef SET_PIXEL
70
--
71
2.20.1
72
73
diff view generated by jsdifflib
Deleted 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.
8
1
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
Deleted patch
1
Fix some minor coding style issues in the template header,
2
so checkpatch doesn't complain when we move the code.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Message-id: 20210215103215.4944-8-peter.maydell@linaro.org
8
---
9
hw/display/omap_lcd_template.h | 6 +++---
10
1 file changed, 3 insertions(+), 3 deletions(-)
11
12
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/display/omap_lcd_template.h
15
+++ b/hw/display/omap_lcd_template.h
16
@@ -XXX,XX +XXX,XX @@ static void draw_line2_32(void *opaque, uint8_t *d, const uint8_t *s,
17
b = (pal[v & 3] << 4) & 0xf0;
18
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
19
d += 4;
20
- s ++;
21
+ s++;
22
width -= 4;
23
} while (width > 0);
24
}
25
@@ -XXX,XX +XXX,XX @@ static void draw_line4_32(void *opaque, uint8_t *d, const uint8_t *s,
26
b = (pal[v & 0xf] << 4) & 0xf0;
27
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
28
d += 4;
29
- s ++;
30
+ s++;
31
width -= 2;
32
} while (width > 0);
33
}
34
@@ -XXX,XX +XXX,XX @@ static void draw_line8_32(void *opaque, uint8_t *d, const uint8_t *s,
35
g = pal[v] & 0xf0;
36
b = (pal[v] << 4) & 0xf0;
37
((uint32_t *) d)[0] = rgb_to_pixel32(r, g, b);
38
- s ++;
39
+ s++;
40
d += 4;
41
} while (-- width != 0);
42
}
43
--
44
2.20.1
45
46
diff view generated by jsdifflib
Deleted patch
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.
6
1
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.
11
12
This is a migration compatibility break for all the mps boards.
13
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
18
---
19
include/hw/misc/mps2-scc.h | 7 +++----
20
hw/arm/mps2-tz.c | 5 +++++
21
hw/arm/mps2.c | 5 +++++
22
hw/misc/mps2-scc.c | 24 +++++++++++++-----------
23
4 files changed, 26 insertions(+), 15 deletions(-)
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
}
66
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/mps2.c
69
+++ b/hw/arm/mps2.c
70
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
71
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
72
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
73
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
74
+ /* All these FPGA images have the same OSCCLK configuration */
75
+ qdev_prop_set_uint32(sccdev, "len-oscclk", 3);
76
+ qdev_prop_set_uint32(sccdev, "oscclk[0]", 50000000);
77
+ qdev_prop_set_uint32(sccdev, "oscclk[1]", 24576000);
78
+ qdev_prop_set_uint32(sccdev, "oscclk[2]", 25000000);
79
sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
80
sysbus_mmio_map(SYS_BUS_DEVICE(sccdev), 0, 0x4002f000);
81
object_initialize_child(OBJECT(mms), "fpgaio",
82
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/misc/mps2-scc.c
85
+++ b/hw/misc/mps2-scc.c
86
@@ -XXX,XX +XXX,XX @@ static bool scc_cfg_write(MPS2SCC *s, unsigned function,
87
{
88
trace_mps2_scc_cfg_write(function, device, value);
89
90
- if (function != 1 || device >= NUM_OSCCLK) {
91
+ if (function != 1 || device >= s->num_oscclk) {
92
qemu_log_mask(LOG_GUEST_ERROR,
93
"MPS2 SCC config write: bad function %d device %d\n",
94
function, device);
95
@@ -XXX,XX +XXX,XX @@ static bool scc_cfg_write(MPS2SCC *s, unsigned function,
96
static bool scc_cfg_read(MPS2SCC *s, unsigned function,
97
unsigned device, uint32_t *value)
98
{
99
- if (function != 1 || device >= NUM_OSCCLK) {
100
+ if (function != 1 || device >= s->num_oscclk) {
101
qemu_log_mask(LOG_GUEST_ERROR,
102
"MPS2 SCC config read: bad function %d device %d\n",
103
function, device);
104
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_reset(DeviceState *dev)
105
s->cfgctrl = 0x100000;
106
s->cfgstat = 0;
107
s->dll = 0xffff0001;
108
- for (i = 0; i < NUM_OSCCLK; i++) {
109
+ for (i = 0; i < s->num_oscclk; i++) {
110
s->oscclk[i] = s->oscclk_reset[i];
111
}
112
for (i = 0; i < ARRAY_SIZE(s->led); i++) {
113
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_realize(DeviceState *dev, Error **errp)
114
LED_COLOR_GREEN, name);
115
g_free(name);
116
}
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
159
--
160
2.20.1
161
162
diff view generated by jsdifflib
Deleted 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.
4
1
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
Deleted 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.
4
1
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