1
The following changes since commit 4cc10cae64c51e17844dc4358481c393d7bf1ed4:
1
target-arm queue: mostly aspeed changes from Cédric.
2
2
3
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging (2021-05-06 18:56:17 +0100)
3
thanks
4
-- PMM
5
6
The following changes since commit 85182c96de61f0b600bbe834d5a23e713162e892:
7
8
Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20190912a' into staging (2019-09-13 14:37:48 +0100)
4
9
5
are available in the Git repository at:
10
are available in the Git repository at:
6
11
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210510
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190913
8
13
9
for you to fetch changes up to 8f96812baa53005f32aece3e30b140826c20aa19:
14
for you to fetch changes up to 27a296fce9821e3608d537756cffa6e43a46df3b:
10
15
11
hw/arm/xlnx: Fix PHY address for xilinx-zynq-a9 (2021-05-10 13:24:09 +0100)
16
qemu-ga: Convert invocation documentation to rST (2019-09-13 16:05:01 +0100)
12
17
13
----------------------------------------------------------------
18
----------------------------------------------------------------
14
target-arm queue:
19
target-arm queue:
15
* docs: fix link in sbsa description
20
* aspeed: add a GPIO controller to the SoC
16
* linux-user/aarch64: Enable hwcap for RND, BTI, and MTE
21
* aspeed: Various refactorings
17
* target/arm: Fix tlbbits calculation in tlbi_aa64_vae2is_write()
22
* aspeed: Improve DMA controller modelling
18
* target/arm: Split neon and vfp translation to their own
23
* atomic_template: fix indentation in GEN_ATOMIC_HELPER
19
compilation units
24
* qemu-ga: Convert invocation documentation to rST
20
* target/arm: Make WFI a NOP for userspace emulators
21
* hw/sd/omap_mmc: Use device_cold_reset() instead of
22
device_legacy_reset()
23
* include: More fixes for 'extern "C"' block use
24
* hw/arm/imx25_pdk: Fix error message for invalid RAM size
25
* hw/arm/mps2-tz: Implement AN524 memory remapping via machine property
26
* hw/arm/xlnx: Fix PHY address for xilinx-zynq-a9
27
25
28
----------------------------------------------------------------
26
----------------------------------------------------------------
29
Alex Bennée (1):
27
Christian Svensson (1):
30
docs: fix link in sbsa description
28
aspeed/smc: Calculate checksum on normal DMA
31
29
32
Guenter Roeck (1):
30
Cédric Le Goater (7):
33
hw/arm/xlnx: Fix PHY address for xilinx-zynq-a9
31
aspeed: Remove unused SoC definitions
32
aspeed: Use consistent typenames
33
aspeed/smc: Add support for DMAs
34
aspeed/smc: Add DMA calibration settings
35
aspeed/smc: Inject errors in DMA checksum
36
aspeed/scu: Introduce per-SoC SCU types
37
aspeed/scu: Introduce a aspeed_scu_get_apb_freq() routine
34
38
35
Peter Maydell (22):
39
Emilio G. Cota (1):
36
target/arm: Fix tlbbits calculation in tlbi_aa64_vae2is_write()
40
atomic_template: fix indentation in GEN_ATOMIC_HELPER
37
target/arm: Move constant expanders to translate.h
38
target/arm: Share unallocated_encoding() and gen_exception_insn()
39
target/arm: Make functions used by m-nocp global
40
target/arm: Split m-nocp trans functions into their own file
41
target/arm: Move gen_aa32 functions to translate-a32.h
42
target/arm: Move vfp_{load, store}_reg{32, 64} to translate-vfp.c.inc
43
target/arm: Make functions used by translate-vfp global
44
target/arm: Make translate-vfp.c.inc its own compilation unit
45
target/arm: Move vfp_reg_ptr() to translate-neon.c.inc
46
target/arm: Delete unused typedef
47
target/arm: Move NeonGenThreeOpEnvFn typedef to translate.h
48
target/arm: Make functions used by translate-neon global
49
target/arm: Make translate-neon.c.inc its own compilation unit
50
target/arm: Make WFI a NOP for userspace emulators
51
hw/sd/omap_mmc: Use device_cold_reset() instead of device_legacy_reset()
52
osdep: Make os-win32.h and os-posix.h handle 'extern "C"' themselves
53
include/qemu/bswap.h: Handle being included outside extern "C" block
54
include/disas/dis-asm.h: Handle being included outside 'extern "C"'
55
hw/misc/mps2-scc: Add "QEMU interface" comment
56
hw/misc/mps2-scc: Support using CFG0 bit 0 for remapping
57
hw/arm/mps2-tz: Implement AN524 memory remapping via machine property
58
41
59
Philippe Mathieu-Daudé (1):
42
Peter Maydell (1):
60
hw/arm/imx25_pdk: Fix error message for invalid RAM size
43
qemu-ga: Convert invocation documentation to rST
61
44
62
Richard Henderson (1):
45
Rashmica Gupta (2):
63
linux-user/aarch64: Enable hwcap for RND, BTI, and MTE
46
hw/gpio: Add basic Aspeed GPIO model for AST2400 and AST2500
47
aspeed: add a GPIO controller to the SoC
64
48
65
docs/system/arm/mps2.rst | 10 +
49
Makefile | 24 +-
66
docs/system/arm/sbsa.rst | 2 +-
50
hw/gpio/Makefile.objs | 1 +
67
include/disas/dis-asm.h | 12 +-
51
accel/tcg/atomic_template.h | 2 +-
68
include/hw/misc/mps2-scc.h | 21 ++
52
include/hw/arm/aspeed_soc.h | 4 +-
69
include/qemu/bswap.h | 26 ++-
53
include/hw/gpio/aspeed_gpio.h | 100 +++++
70
include/qemu/osdep.h | 8 +-
54
include/hw/misc/aspeed_scu.h | 21 +-
71
include/sysemu/os-posix.h | 8 +
55
include/hw/ssi/aspeed_smc.h | 7 +
72
include/sysemu/os-win32.h | 8 +
56
hw/arm/aspeed.c | 2 +
73
target/arm/translate-a32.h | 144 +++++++++++++
57
hw/arm/aspeed_soc.c | 63 ++-
74
target/arm/translate-a64.h | 2 -
58
hw/gpio/aspeed_gpio.c | 884 ++++++++++++++++++++++++++++++++++++++++++
75
target/arm/translate.h | 29 +++
59
hw/misc/aspeed_scu.c | 102 ++---
76
hw/arm/imx25_pdk.c | 5 +-
60
hw/ssi/aspeed_smc.c | 335 +++++++++++++++-
77
hw/arm/mps2-tz.c | 108 +++++++++-
61
hw/timer/aspeed_timer.c | 3 +-
78
hw/arm/xilinx_zynq.c | 2 +-
62
MAINTAINERS | 2 +-
79
hw/misc/mps2-scc.c | 13 +-
63
docs/conf.py | 18 +-
80
hw/sd/omap_mmc.c | 2 +-
64
docs/interop/conf.py | 7 +
81
linux-user/elfload.c | 13 ++
65
docs/interop/index.rst | 1 +
82
target/arm/helper.c | 2 +-
66
docs/interop/qemu-ga.rst | 133 +++++++
83
target/arm/op_helper.c | 12 ++
67
qemu-doc.texi | 5 -
84
target/arm/translate-a64.c | 15 --
68
qemu-ga.texi | 137 -------
85
target/arm/translate-m-nocp.c | 221 ++++++++++++++++++++
69
20 files changed, 1585 insertions(+), 266 deletions(-)
86
.../arm/{translate-neon.c.inc => translate-neon.c} | 19 +-
70
create mode 100644 include/hw/gpio/aspeed_gpio.h
87
.../arm/{translate-vfp.c.inc => translate-vfp.c} | 230 +++------------------
71
create mode 100644 hw/gpio/aspeed_gpio.c
88
target/arm/translate.c | 200 ++++--------------
72
create mode 100644 docs/interop/qemu-ga.rst
89
disas/arm-a64.cc | 2 -
73
delete mode 100644 qemu-ga.texi
90
disas/nanomips.cpp | 2 -
91
target/arm/meson.build | 15 +-
92
27 files changed, 718 insertions(+), 413 deletions(-)
93
create mode 100644 target/arm/translate-a32.h
94
create mode 100644 target/arm/translate-m-nocp.c
95
rename target/arm/{translate-neon.c.inc => translate-neon.c} (99%)
96
rename target/arm/{translate-vfp.c.inc => translate-vfp.c} (94%)
97
74
diff view generated by jsdifflib
1
Currently the trans functions for m-nocp.decode all live in
1
From: Rashmica Gupta <rashmica.g@gmail.com>
2
translate-vfp.inc.c; move them out into their own translation unit,
3
translate-m-nocp.c.
4
2
5
The trans_* functions here are pure code motion with no changes.
3
GPIO pins are arranged in groups of 8 pins labeled A,B,..,Y,Z,AA,AB,AC.
4
(Note that the ast2400 controller only goes up to group AB).
5
A set has four groups (except set AC which only has one) and is
6
referred to by the groups it is composed of (eg ABCD,EFGH,...,YZAAAB).
7
Each set is accessed and controlled by a bank of 14 registers.
6
8
9
These registers operate on a per pin level where each bit in the register
10
corresponds to a pin, except for the command source registers. The command
11
source registers operate on a per group level where bits 24, 16, 8 and 0
12
correspond to each group in the set.
13
14
eg. registers for set ABCD:
15
|D7...D0|C7...C0|B7...B0|A7...A0| <- GPIOs
16
|31...24|23...16|15....8|7.....0| <- bit position
17
18
Note that there are a couple of groups that only have 4 pins.
19
20
There are two ways that this model deviates from the behaviour of the
21
actual controller:
22
(1) The only control source driving the GPIO pins in the model is the ARM
23
model (as there currently aren't models for the LPC or Coprocessor).
24
25
(2) None of the registers in the model are reset tolerant (needs
26
integration with the watchdog).
27
28
Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
29
Tested-by: Andrew Jeffery <andrew@aj.id.au>
30
Reviewed-by: Cédric Le Goater <clg@kaod.org>
31
Signed-off-by: Cédric Le Goater <clg@kaod.org>
32
Message-id: 20190904070506.1052-2-clg@kaod.org
33
[clg: fixed missing header files
34
made use of HWADDR_PRIx to fix compilation on windows ]
35
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210430132740.10391-5-peter.maydell@linaro.org
10
---
37
---
11
target/arm/translate-a32.h | 3 +
38
hw/gpio/Makefile.objs | 1 +
12
target/arm/translate-m-nocp.c | 221 +++++++++++++++++++++++++++++++++
39
include/hw/gpio/aspeed_gpio.h | 100 ++++
13
target/arm/translate.c | 1 -
40
hw/gpio/aspeed_gpio.c | 884 ++++++++++++++++++++++++++++++++++
14
target/arm/translate-vfp.c.inc | 196 -----------------------------
41
3 files changed, 985 insertions(+)
15
target/arm/meson.build | 3 +-
42
create mode 100644 include/hw/gpio/aspeed_gpio.h
16
5 files changed, 226 insertions(+), 198 deletions(-)
43
create mode 100644 hw/gpio/aspeed_gpio.c
17
create mode 100644 target/arm/translate-m-nocp.c
18
44
19
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
45
diff --git a/hw/gpio/Makefile.objs b/hw/gpio/Makefile.objs
20
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-a32.h
47
--- a/hw/gpio/Makefile.objs
22
+++ b/target/arm/translate-a32.h
48
+++ b/hw/gpio/Makefile.objs
23
@@ -XXX,XX +XXX,XX @@
49
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_OMAP) += omap_gpio.o
24
#ifndef TARGET_ARM_TRANSLATE_A64_H
50
obj-$(CONFIG_IMX) += imx_gpio.o
25
#define TARGET_ARM_TRANSLATE_A64_H
51
obj-$(CONFIG_RASPI) += bcm2835_gpio.o
26
52
obj-$(CONFIG_NRF51_SOC) += nrf51_gpio.o
27
+/* Prototypes for autogenerated disassembler functions */
53
+obj-$(CONFIG_ASPEED_SOC) += aspeed_gpio.o
28
+bool disas_m_nocp(DisasContext *dc, uint32_t insn);
54
diff --git a/include/hw/gpio/aspeed_gpio.h b/include/hw/gpio/aspeed_gpio.h
29
+
30
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
31
void arm_gen_condlabel(DisasContext *s);
32
bool vfp_access_check(DisasContext *s);
33
diff --git a/target/arm/translate-m-nocp.c b/target/arm/translate-m-nocp.c
34
new file mode 100644
55
new file mode 100644
35
index XXXXXXX..XXXXXXX
56
index XXXXXXX..XXXXXXX
36
--- /dev/null
57
--- /dev/null
37
+++ b/target/arm/translate-m-nocp.c
58
+++ b/include/hw/gpio/aspeed_gpio.h
38
@@ -XXX,XX +XXX,XX @@
59
@@ -XXX,XX +XXX,XX @@
39
+/*
60
+/*
40
+ * ARM translation: M-profile NOCP special-case instructions
61
+ * ASPEED GPIO Controller
41
+ *
62
+ *
42
+ * Copyright (c) 2020 Linaro, Ltd.
63
+ * Copyright (C) 2017-2018 IBM Corp.
43
+ *
64
+ *
44
+ * This library is free software; you can redistribute it and/or
65
+ * This code is licensed under the GPL version 2 or later. See
45
+ * modify it under the terms of the GNU Lesser General Public
66
+ * the COPYING file in the top-level directory.
46
+ * License as published by the Free Software Foundation; either
67
+ */
47
+ * version 2.1 of the License, or (at your option) any later version.
68
+
69
+#ifndef ASPEED_GPIO_H
70
+#define ASPEED_GPIO_H
71
+
72
+#include "hw/sysbus.h"
73
+
74
+#define TYPE_ASPEED_GPIO "aspeed.gpio"
75
+#define ASPEED_GPIO(obj) OBJECT_CHECK(AspeedGPIOState, (obj), TYPE_ASPEED_GPIO)
76
+#define ASPEED_GPIO_CLASS(klass) \
77
+ OBJECT_CLASS_CHECK(AspeedGPIOClass, (klass), TYPE_ASPEED_GPIO)
78
+#define ASPEED_GPIO_GET_CLASS(obj) \
79
+ OBJECT_GET_CLASS(AspeedGPIOClass, (obj), TYPE_ASPEED_GPIO)
80
+
81
+#define ASPEED_GPIO_MAX_NR_SETS 8
82
+#define ASPEED_REGS_PER_BANK 14
83
+#define ASPEED_GPIO_MAX_NR_REGS (ASPEED_REGS_PER_BANK * ASPEED_GPIO_MAX_NR_SETS)
84
+#define ASPEED_GPIO_NR_PINS 228
85
+#define ASPEED_GROUPS_PER_SET 4
86
+#define ASPEED_GPIO_NR_DEBOUNCE_REGS 3
87
+#define ASPEED_CHARS_PER_GROUP_LABEL 4
88
+
89
+typedef struct GPIOSets GPIOSets;
90
+
91
+typedef struct GPIOSetProperties {
92
+ uint32_t input;
93
+ uint32_t output;
94
+ char group_label[ASPEED_GROUPS_PER_SET][ASPEED_CHARS_PER_GROUP_LABEL];
95
+} GPIOSetProperties;
96
+
97
+enum GPIORegType {
98
+ gpio_not_a_reg,
99
+ gpio_reg_data_value,
100
+ gpio_reg_direction,
101
+ gpio_reg_int_enable,
102
+ gpio_reg_int_sens_0,
103
+ gpio_reg_int_sens_1,
104
+ gpio_reg_int_sens_2,
105
+ gpio_reg_int_status,
106
+ gpio_reg_reset_tolerant,
107
+ gpio_reg_debounce_1,
108
+ gpio_reg_debounce_2,
109
+ gpio_reg_cmd_source_0,
110
+ gpio_reg_cmd_source_1,
111
+ gpio_reg_data_read,
112
+ gpio_reg_input_mask,
113
+};
114
+
115
+typedef struct AspeedGPIOReg {
116
+ uint16_t set_idx;
117
+ enum GPIORegType type;
118
+ } AspeedGPIOReg;
119
+
120
+typedef struct AspeedGPIOClass {
121
+ SysBusDevice parent_obj;
122
+ const GPIOSetProperties *props;
123
+ uint32_t nr_gpio_pins;
124
+ uint32_t nr_gpio_sets;
125
+ uint32_t gap;
126
+ const AspeedGPIOReg *reg_table;
127
+} AspeedGPIOClass;
128
+
129
+typedef struct AspeedGPIOState {
130
+ /* <private> */
131
+ SysBusDevice parent;
132
+
133
+ /*< public >*/
134
+ MemoryRegion iomem;
135
+ int pending;
136
+ qemu_irq irq;
137
+ qemu_irq gpios[ASPEED_GPIO_NR_PINS];
138
+
139
+/* Parallel GPIO Registers */
140
+ uint32_t debounce_regs[ASPEED_GPIO_NR_DEBOUNCE_REGS];
141
+ struct GPIOSets {
142
+ uint32_t data_value; /* Reflects pin values */
143
+ uint32_t data_read; /* Contains last value written to data value */
144
+ uint32_t direction;
145
+ uint32_t int_enable;
146
+ uint32_t int_sens_0;
147
+ uint32_t int_sens_1;
148
+ uint32_t int_sens_2;
149
+ uint32_t int_status;
150
+ uint32_t reset_tol;
151
+ uint32_t cmd_source_0;
152
+ uint32_t cmd_source_1;
153
+ uint32_t debounce_1;
154
+ uint32_t debounce_2;
155
+ uint32_t input_mask;
156
+ } sets[ASPEED_GPIO_MAX_NR_SETS];
157
+} AspeedGPIOState;
158
+
159
+#endif /* _ASPEED_GPIO_H_ */
160
diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c
161
new file mode 100644
162
index XXXXXXX..XXXXXXX
163
--- /dev/null
164
+++ b/hw/gpio/aspeed_gpio.c
165
@@ -XXX,XX +XXX,XX @@
166
+/*
167
+ * ASPEED GPIO Controller
48
+ *
168
+ *
49
+ * This library is distributed in the hope that it will be useful,
169
+ * Copyright (C) 2017-2019 IBM Corp.
50
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
51
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
52
+ * Lesser General Public License for more details.
53
+ *
170
+ *
54
+ * You should have received a copy of the GNU Lesser General Public
171
+ * SPDX-License-Identifier: GPL-2.0-or-later
55
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
56
+ */
172
+ */
57
+
173
+
174
+#include <assert.h>
175
+
58
+#include "qemu/osdep.h"
176
+#include "qemu/osdep.h"
59
+#include "tcg/tcg-op.h"
177
+#include "qemu/host-utils.h"
60
+#include "translate.h"
178
+#include "qemu/log.h"
61
+#include "translate-a32.h"
179
+#include "hw/gpio/aspeed_gpio.h"
62
+
180
+#include "include/hw/misc/aspeed_scu.h"
63
+#include "decode-m-nocp.c.inc"
181
+#include "qapi/error.h"
64
+
182
+#include "qapi/visitor.h"
183
+#include "hw/irq.h"
184
+#include "migration/vmstate.h"
185
+
186
+#define GPIOS_PER_REG 32
187
+#define GPIOS_PER_SET GPIOS_PER_REG
188
+#define GPIO_PIN_GAP_SIZE 4
189
+#define GPIOS_PER_GROUP 8
190
+#define GPIO_GROUP_SHIFT 3
191
+
192
+/* GPIO Source Types */
193
+#define ASPEED_CMD_SRC_MASK 0x01010101
194
+#define ASPEED_SOURCE_ARM 0
195
+#define ASPEED_SOURCE_LPC 1
196
+#define ASPEED_SOURCE_COPROCESSOR 2
197
+#define ASPEED_SOURCE_RESERVED 3
198
+
199
+/* GPIO Interrupt Triggers */
65
+/*
200
+/*
66
+ * Decode VLLDM and VLSTM are nonstandard because:
201
+ * For each set of gpios there are three sensitivity registers that control
67
+ * * if there is no FPU then these insns must NOP in
202
+ * the interrupt trigger mode.
68
+ * Secure state and UNDEF in Nonsecure state
203
+ *
69
+ * * if there is an FPU then these insns do not have
204
+ * | 2 | 1 | 0 | trigger mode
70
+ * the usual behaviour that vfp_access_check() provides of
205
+ * -----------------------------
71
+ * being controlled by CPACR/NSACR enable bits or the
206
+ * | 0 | 0 | 0 | falling-edge
72
+ * lazy-stacking logic.
207
+ * | 0 | 0 | 1 | rising-edge
208
+ * | 0 | 1 | 0 | level-low
209
+ * | 0 | 1 | 1 | level-high
210
+ * | 1 | X | X | dual-edge
73
+ */
211
+ */
74
+static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
212
+#define ASPEED_FALLING_EDGE 0
75
+{
213
+#define ASPEED_RISING_EDGE 1
76
+ TCGv_i32 fptr;
214
+#define ASPEED_LEVEL_LOW 2
77
+
215
+#define ASPEED_LEVEL_HIGH 3
78
+ if (!arm_dc_feature(s, ARM_FEATURE_M) ||
216
+#define ASPEED_DUAL_EDGE 4
79
+ !arm_dc_feature(s, ARM_FEATURE_V8)) {
217
+
80
+ return false;
218
+/* GPIO Register Address Offsets */
81
+ }
219
+#define GPIO_ABCD_DATA_VALUE (0x000 >> 2)
82
+
220
+#define GPIO_ABCD_DIRECTION (0x004 >> 2)
83
+ if (a->op) {
221
+#define GPIO_ABCD_INT_ENABLE (0x008 >> 2)
222
+#define GPIO_ABCD_INT_SENS_0 (0x00C >> 2)
223
+#define GPIO_ABCD_INT_SENS_1 (0x010 >> 2)
224
+#define GPIO_ABCD_INT_SENS_2 (0x014 >> 2)
225
+#define GPIO_ABCD_INT_STATUS (0x018 >> 2)
226
+#define GPIO_ABCD_RESET_TOLERANT (0x01C >> 2)
227
+#define GPIO_EFGH_DATA_VALUE (0x020 >> 2)
228
+#define GPIO_EFGH_DIRECTION (0x024 >> 2)
229
+#define GPIO_EFGH_INT_ENABLE (0x028 >> 2)
230
+#define GPIO_EFGH_INT_SENS_0 (0x02C >> 2)
231
+#define GPIO_EFGH_INT_SENS_1 (0x030 >> 2)
232
+#define GPIO_EFGH_INT_SENS_2 (0x034 >> 2)
233
+#define GPIO_EFGH_INT_STATUS (0x038 >> 2)
234
+#define GPIO_EFGH_RESET_TOLERANT (0x03C >> 2)
235
+#define GPIO_ABCD_DEBOUNCE_1 (0x040 >> 2)
236
+#define GPIO_ABCD_DEBOUNCE_2 (0x044 >> 2)
237
+#define GPIO_EFGH_DEBOUNCE_1 (0x048 >> 2)
238
+#define GPIO_EFGH_DEBOUNCE_2 (0x04C >> 2)
239
+#define GPIO_DEBOUNCE_TIME_1 (0x050 >> 2)
240
+#define GPIO_DEBOUNCE_TIME_2 (0x054 >> 2)
241
+#define GPIO_DEBOUNCE_TIME_3 (0x058 >> 2)
242
+#define GPIO_ABCD_COMMAND_SRC_0 (0x060 >> 2)
243
+#define GPIO_ABCD_COMMAND_SRC_1 (0x064 >> 2)
244
+#define GPIO_EFGH_COMMAND_SRC_0 (0x068 >> 2)
245
+#define GPIO_EFGH_COMMAND_SRC_1 (0x06C >> 2)
246
+#define GPIO_IJKL_DATA_VALUE (0x070 >> 2)
247
+#define GPIO_IJKL_DIRECTION (0x074 >> 2)
248
+#define GPIO_MNOP_DATA_VALUE (0x078 >> 2)
249
+#define GPIO_MNOP_DIRECTION (0x07C >> 2)
250
+#define GPIO_QRST_DATA_VALUE (0x080 >> 2)
251
+#define GPIO_QRST_DIRECTION (0x084 >> 2)
252
+#define GPIO_UVWX_DATA_VALUE (0x088 >> 2)
253
+#define GPIO_UVWX_DIRECTION (0x08C >> 2)
254
+#define GPIO_IJKL_COMMAND_SRC_0 (0x090 >> 2)
255
+#define GPIO_IJKL_COMMAND_SRC_1 (0x094 >> 2)
256
+#define GPIO_IJKL_INT_ENABLE (0x098 >> 2)
257
+#define GPIO_IJKL_INT_SENS_0 (0x09C >> 2)
258
+#define GPIO_IJKL_INT_SENS_1 (0x0A0 >> 2)
259
+#define GPIO_IJKL_INT_SENS_2 (0x0A4 >> 2)
260
+#define GPIO_IJKL_INT_STATUS (0x0A8 >> 2)
261
+#define GPIO_IJKL_RESET_TOLERANT (0x0AC >> 2)
262
+#define GPIO_IJKL_DEBOUNCE_1 (0x0B0 >> 2)
263
+#define GPIO_IJKL_DEBOUNCE_2 (0x0B4 >> 2)
264
+#define GPIO_IJKL_INPUT_MASK (0x0B8 >> 2)
265
+#define GPIO_ABCD_DATA_READ (0x0C0 >> 2)
266
+#define GPIO_EFGH_DATA_READ (0x0C4 >> 2)
267
+#define GPIO_IJKL_DATA_READ (0x0C8 >> 2)
268
+#define GPIO_MNOP_DATA_READ (0x0CC >> 2)
269
+#define GPIO_QRST_DATA_READ (0x0D0 >> 2)
270
+#define GPIO_UVWX_DATA_READ (0x0D4 >> 2)
271
+#define GPIO_YZAAAB_DATA_READ (0x0D8 >> 2)
272
+#define GPIO_AC_DATA_READ (0x0DC >> 2)
273
+#define GPIO_MNOP_COMMAND_SRC_0 (0x0E0 >> 2)
274
+#define GPIO_MNOP_COMMAND_SRC_1 (0x0E4 >> 2)
275
+#define GPIO_MNOP_INT_ENABLE (0x0E8 >> 2)
276
+#define GPIO_MNOP_INT_SENS_0 (0x0EC >> 2)
277
+#define GPIO_MNOP_INT_SENS_1 (0x0F0 >> 2)
278
+#define GPIO_MNOP_INT_SENS_2 (0x0F4 >> 2)
279
+#define GPIO_MNOP_INT_STATUS (0x0F8 >> 2)
280
+#define GPIO_MNOP_RESET_TOLERANT (0x0FC >> 2)
281
+#define GPIO_MNOP_DEBOUNCE_1 (0x100 >> 2)
282
+#define GPIO_MNOP_DEBOUNCE_2 (0x104 >> 2)
283
+#define GPIO_MNOP_INPUT_MASK (0x108 >> 2)
284
+#define GPIO_QRST_COMMAND_SRC_0 (0x110 >> 2)
285
+#define GPIO_QRST_COMMAND_SRC_1 (0x114 >> 2)
286
+#define GPIO_QRST_INT_ENABLE (0x118 >> 2)
287
+#define GPIO_QRST_INT_SENS_0 (0x11C >> 2)
288
+#define GPIO_QRST_INT_SENS_1 (0x120 >> 2)
289
+#define GPIO_QRST_INT_SENS_2 (0x124 >> 2)
290
+#define GPIO_QRST_INT_STATUS (0x128 >> 2)
291
+#define GPIO_QRST_RESET_TOLERANT (0x12C >> 2)
292
+#define GPIO_QRST_DEBOUNCE_1 (0x130 >> 2)
293
+#define GPIO_QRST_DEBOUNCE_2 (0x134 >> 2)
294
+#define GPIO_QRST_INPUT_MASK (0x138 >> 2)
295
+#define GPIO_UVWX_COMMAND_SRC_0 (0x140 >> 2)
296
+#define GPIO_UVWX_COMMAND_SRC_1 (0x144 >> 2)
297
+#define GPIO_UVWX_INT_ENABLE (0x148 >> 2)
298
+#define GPIO_UVWX_INT_SENS_0 (0x14C >> 2)
299
+#define GPIO_UVWX_INT_SENS_1 (0x150 >> 2)
300
+#define GPIO_UVWX_INT_SENS_2 (0x154 >> 2)
301
+#define GPIO_UVWX_INT_STATUS (0x158 >> 2)
302
+#define GPIO_UVWX_RESET_TOLERANT (0x15C >> 2)
303
+#define GPIO_UVWX_DEBOUNCE_1 (0x160 >> 2)
304
+#define GPIO_UVWX_DEBOUNCE_2 (0x164 >> 2)
305
+#define GPIO_UVWX_INPUT_MASK (0x168 >> 2)
306
+#define GPIO_YZAAAB_COMMAND_SRC_0 (0x170 >> 2)
307
+#define GPIO_YZAAAB_COMMAND_SRC_1 (0x174 >> 2)
308
+#define GPIO_YZAAAB_INT_ENABLE (0x178 >> 2)
309
+#define GPIO_YZAAAB_INT_SENS_0 (0x17C >> 2)
310
+#define GPIO_YZAAAB_INT_SENS_1 (0x180 >> 2)
311
+#define GPIO_YZAAAB_INT_SENS_2 (0x184 >> 2)
312
+#define GPIO_YZAAAB_INT_STATUS (0x188 >> 2)
313
+#define GPIO_YZAAAB_RESET_TOLERANT (0x18C >> 2)
314
+#define GPIO_YZAAAB_DEBOUNCE_1 (0x190 >> 2)
315
+#define GPIO_YZAAAB_DEBOUNCE_2 (0x194 >> 2)
316
+#define GPIO_YZAAAB_INPUT_MASK (0x198 >> 2)
317
+#define GPIO_AC_COMMAND_SRC_0 (0x1A0 >> 2)
318
+#define GPIO_AC_COMMAND_SRC_1 (0x1A4 >> 2)
319
+#define GPIO_AC_INT_ENABLE (0x1A8 >> 2)
320
+#define GPIO_AC_INT_SENS_0 (0x1AC >> 2)
321
+#define GPIO_AC_INT_SENS_1 (0x1B0 >> 2)
322
+#define GPIO_AC_INT_SENS_2 (0x1B4 >> 2)
323
+#define GPIO_AC_INT_STATUS (0x1B8 >> 2)
324
+#define GPIO_AC_RESET_TOLERANT (0x1BC >> 2)
325
+#define GPIO_AC_DEBOUNCE_1 (0x1C0 >> 2)
326
+#define GPIO_AC_DEBOUNCE_2 (0x1C4 >> 2)
327
+#define GPIO_AC_INPUT_MASK (0x1C8 >> 2)
328
+#define GPIO_ABCD_INPUT_MASK (0x1D0 >> 2)
329
+#define GPIO_EFGH_INPUT_MASK (0x1D4 >> 2)
330
+#define GPIO_YZAAAB_DATA_VALUE (0x1E0 >> 2)
331
+#define GPIO_YZAAAB_DIRECTION (0x1E4 >> 2)
332
+#define GPIO_AC_DATA_VALUE (0x1E8 >> 2)
333
+#define GPIO_AC_DIRECTION (0x1EC >> 2)
334
+#define GPIO_3_6V_MEM_SIZE 0x1F0
335
+#define GPIO_3_6V_REG_ARRAY_SIZE (GPIO_3_6V_MEM_SIZE >> 2)
336
+
337
+static int aspeed_evaluate_irq(GPIOSets *regs, int gpio_prev_high, int gpio)
338
+{
339
+ uint32_t falling_edge = 0, rising_edge = 0;
340
+ uint32_t int_trigger = extract32(regs->int_sens_0, gpio, 1)
341
+ | extract32(regs->int_sens_1, gpio, 1) << 1
342
+ | extract32(regs->int_sens_2, gpio, 1) << 2;
343
+ uint32_t gpio_curr_high = extract32(regs->data_value, gpio, 1);
344
+ uint32_t gpio_int_enabled = extract32(regs->int_enable, gpio, 1);
345
+
346
+ if (!gpio_int_enabled) {
347
+ return 0;
348
+ }
349
+
350
+ /* Detect edges */
351
+ if (gpio_curr_high && !gpio_prev_high) {
352
+ rising_edge = 1;
353
+ } else if (!gpio_curr_high && gpio_prev_high) {
354
+ falling_edge = 1;
355
+ }
356
+
357
+ if (((int_trigger == ASPEED_FALLING_EDGE) && falling_edge) ||
358
+ ((int_trigger == ASPEED_RISING_EDGE) && rising_edge) ||
359
+ ((int_trigger == ASPEED_LEVEL_LOW) && !gpio_curr_high) ||
360
+ ((int_trigger == ASPEED_LEVEL_HIGH) && gpio_curr_high) ||
361
+ ((int_trigger >= ASPEED_DUAL_EDGE) && (rising_edge || falling_edge)))
362
+ {
363
+ regs->int_status = deposit32(regs->int_status, gpio, 1, 1);
364
+ return 1;
365
+ }
366
+ return 0;
367
+}
368
+
369
+#define nested_struct_index(ta, pa, m, tb, pb) \
370
+ (pb - ((tb *)(((char *)pa) + offsetof(ta, m))))
371
+
372
+static ptrdiff_t aspeed_gpio_set_idx(AspeedGPIOState *s, GPIOSets *regs)
373
+{
374
+ return nested_struct_index(AspeedGPIOState, s, sets, GPIOSets, regs);
375
+}
376
+
377
+static void aspeed_gpio_update(AspeedGPIOState *s, GPIOSets *regs,
378
+ uint32_t value)
379
+{
380
+ uint32_t input_mask = regs->input_mask;
381
+ uint32_t direction = regs->direction;
382
+ uint32_t old = regs->data_value;
383
+ uint32_t new = value;
384
+ uint32_t diff;
385
+ int gpio;
386
+
387
+ diff = old ^ new;
388
+ if (diff) {
389
+ for (gpio = 0; gpio < GPIOS_PER_REG; gpio++) {
390
+ uint32_t mask = 1 << gpio;
391
+
392
+ /* If the gpio needs to be updated... */
393
+ if (!(diff & mask)) {
394
+ continue;
395
+ }
396
+
397
+ /* ...and we're output or not input-masked... */
398
+ if (!(direction & mask) && (input_mask & mask)) {
399
+ continue;
400
+ }
401
+
402
+ /* ...then update the state. */
403
+ if (mask & new) {
404
+ regs->data_value |= mask;
405
+ } else {
406
+ regs->data_value &= ~mask;
407
+ }
408
+
409
+ /* If the gpio is set to output... */
410
+ if (direction & mask) {
411
+ /* ...trigger the line-state IRQ */
412
+ ptrdiff_t set = aspeed_gpio_set_idx(s, regs);
413
+ size_t offset = set * GPIOS_PER_SET + gpio;
414
+ qemu_set_irq(s->gpios[offset], !!(new & mask));
415
+ } else {
416
+ /* ...otherwise if we meet the line's current IRQ policy... */
417
+ if (aspeed_evaluate_irq(regs, old & mask, gpio)) {
418
+ /* ...trigger the VIC IRQ */
419
+ s->pending++;
420
+ }
421
+ }
422
+ }
423
+ }
424
+ qemu_set_irq(s->irq, !!(s->pending));
425
+}
426
+
427
+static uint32_t aspeed_adjust_pin(AspeedGPIOState *s, uint32_t pin)
428
+{
429
+ AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
430
+ /*
431
+ * The 2500 has a 4 pin gap in group AB and the 2400 has a 4 pin
432
+ * gap in group Y (and only four pins in AB but this is the last group so
433
+ * it doesn't matter).
434
+ */
435
+ if (agc->gap && pin >= agc->gap) {
436
+ pin += GPIO_PIN_GAP_SIZE;
437
+ }
438
+
439
+ return pin;
440
+}
441
+
442
+static bool aspeed_gpio_get_pin_level(AspeedGPIOState *s, uint32_t set_idx,
443
+ uint32_t pin)
444
+{
445
+ uint32_t reg_val;
446
+ uint32_t pin_mask = 1 << pin;
447
+
448
+ reg_val = s->sets[set_idx].data_value;
449
+
450
+ return !!(reg_val & pin_mask);
451
+}
452
+
453
+static void aspeed_gpio_set_pin_level(AspeedGPIOState *s, uint32_t set_idx,
454
+ uint32_t pin, bool level)
455
+{
456
+ uint32_t value = s->sets[set_idx].data_value;
457
+ uint32_t pin_mask = 1 << pin;
458
+
459
+ if (level) {
460
+ value |= pin_mask;
461
+ } else {
462
+ value &= !pin_mask;
463
+ }
464
+
465
+ aspeed_gpio_update(s, &s->sets[set_idx], value);
466
+}
467
+
468
+/*
469
+ * | src_1 | src_2 | source |
470
+ * |-----------------------------|
471
+ * | 0 | 0 | ARM |
472
+ * | 0 | 1 | LPC |
473
+ * | 1 | 0 | Coprocessor|
474
+ * | 1 | 1 | Reserved |
475
+ *
476
+ * Once the source of a set is programmed, corresponding bits in the
477
+ * data_value, direction, interrupt [enable, sens[0-2]], reset_tol and
478
+ * debounce registers can only be written by the source.
479
+ *
480
+ * Source is ARM by default
481
+ * only bits 24, 16, 8, and 0 can be set
482
+ *
483
+ * we don't currently have a model for the LPC or Coprocessor
484
+ */
485
+static uint32_t update_value_control_source(GPIOSets *regs, uint32_t old_value,
486
+ uint32_t value)
487
+{
488
+ int i;
489
+ int cmd_source;
490
+
491
+ /* assume the source is always ARM for now */
492
+ int source = ASPEED_SOURCE_ARM;
493
+
494
+ uint32_t new_value = 0;
495
+
496
+ /* for each group in set */
497
+ for (i = 0; i < GPIOS_PER_REG; i += GPIOS_PER_GROUP) {
498
+ cmd_source = extract32(regs->cmd_source_0, i, 1)
499
+ | (extract32(regs->cmd_source_1, i, 1) << 1);
500
+
501
+ if (source == cmd_source) {
502
+ new_value |= (0xff << i) & value;
503
+ } else {
504
+ new_value |= (0xff << i) & old_value;
505
+ }
506
+ }
507
+ return new_value;
508
+}
509
+
510
+static const AspeedGPIOReg aspeed_3_6v_gpios[GPIO_3_6V_REG_ARRAY_SIZE] = {
511
+ /* Set ABCD */
512
+ [GPIO_ABCD_DATA_VALUE] = { 0, gpio_reg_data_value },
513
+ [GPIO_ABCD_DIRECTION] = { 0, gpio_reg_direction },
514
+ [GPIO_ABCD_INT_ENABLE] = { 0, gpio_reg_int_enable },
515
+ [GPIO_ABCD_INT_SENS_0] = { 0, gpio_reg_int_sens_0 },
516
+ [GPIO_ABCD_INT_SENS_1] = { 0, gpio_reg_int_sens_1 },
517
+ [GPIO_ABCD_INT_SENS_2] = { 0, gpio_reg_int_sens_2 },
518
+ [GPIO_ABCD_INT_STATUS] = { 0, gpio_reg_int_status },
519
+ [GPIO_ABCD_RESET_TOLERANT] = { 0, gpio_reg_reset_tolerant },
520
+ [GPIO_ABCD_DEBOUNCE_1] = { 0, gpio_reg_debounce_1 },
521
+ [GPIO_ABCD_DEBOUNCE_2] = { 0, gpio_reg_debounce_2 },
522
+ [GPIO_ABCD_COMMAND_SRC_0] = { 0, gpio_reg_cmd_source_0 },
523
+ [GPIO_ABCD_COMMAND_SRC_1] = { 0, gpio_reg_cmd_source_1 },
524
+ [GPIO_ABCD_DATA_READ] = { 0, gpio_reg_data_read },
525
+ [GPIO_ABCD_INPUT_MASK] = { 0, gpio_reg_input_mask },
526
+ /* Set EFGH */
527
+ [GPIO_EFGH_DATA_VALUE] = { 1, gpio_reg_data_value },
528
+ [GPIO_EFGH_DIRECTION] = { 1, gpio_reg_direction },
529
+ [GPIO_EFGH_INT_ENABLE] = { 1, gpio_reg_int_enable },
530
+ [GPIO_EFGH_INT_SENS_0] = { 1, gpio_reg_int_sens_0 },
531
+ [GPIO_EFGH_INT_SENS_1] = { 1, gpio_reg_int_sens_1 },
532
+ [GPIO_EFGH_INT_SENS_2] = { 1, gpio_reg_int_sens_2 },
533
+ [GPIO_EFGH_INT_STATUS] = { 1, gpio_reg_int_status },
534
+ [GPIO_EFGH_RESET_TOLERANT] = { 1, gpio_reg_reset_tolerant },
535
+ [GPIO_EFGH_DEBOUNCE_1] = { 1, gpio_reg_debounce_1 },
536
+ [GPIO_EFGH_DEBOUNCE_2] = { 1, gpio_reg_debounce_2 },
537
+ [GPIO_EFGH_COMMAND_SRC_0] = { 1, gpio_reg_cmd_source_0 },
538
+ [GPIO_EFGH_COMMAND_SRC_1] = { 1, gpio_reg_cmd_source_1 },
539
+ [GPIO_EFGH_DATA_READ] = { 1, gpio_reg_data_read },
540
+ [GPIO_EFGH_INPUT_MASK] = { 1, gpio_reg_input_mask },
541
+ /* Set IJKL */
542
+ [GPIO_IJKL_DATA_VALUE] = { 2, gpio_reg_data_value },
543
+ [GPIO_IJKL_DIRECTION] = { 2, gpio_reg_direction },
544
+ [GPIO_IJKL_INT_ENABLE] = { 2, gpio_reg_int_enable },
545
+ [GPIO_IJKL_INT_SENS_0] = { 2, gpio_reg_int_sens_0 },
546
+ [GPIO_IJKL_INT_SENS_1] = { 2, gpio_reg_int_sens_1 },
547
+ [GPIO_IJKL_INT_SENS_2] = { 2, gpio_reg_int_sens_2 },
548
+ [GPIO_IJKL_INT_STATUS] = { 2, gpio_reg_int_status },
549
+ [GPIO_IJKL_RESET_TOLERANT] = { 2, gpio_reg_reset_tolerant },
550
+ [GPIO_IJKL_DEBOUNCE_1] = { 2, gpio_reg_debounce_1 },
551
+ [GPIO_IJKL_DEBOUNCE_2] = { 2, gpio_reg_debounce_2 },
552
+ [GPIO_IJKL_COMMAND_SRC_0] = { 2, gpio_reg_cmd_source_0 },
553
+ [GPIO_IJKL_COMMAND_SRC_1] = { 2, gpio_reg_cmd_source_1 },
554
+ [GPIO_IJKL_DATA_READ] = { 2, gpio_reg_data_read },
555
+ [GPIO_IJKL_INPUT_MASK] = { 2, gpio_reg_input_mask },
556
+ /* Set MNOP */
557
+ [GPIO_MNOP_DATA_VALUE] = { 3, gpio_reg_data_value },
558
+ [GPIO_MNOP_DIRECTION] = { 3, gpio_reg_direction },
559
+ [GPIO_MNOP_INT_ENABLE] = { 3, gpio_reg_int_enable },
560
+ [GPIO_MNOP_INT_SENS_0] = { 3, gpio_reg_int_sens_0 },
561
+ [GPIO_MNOP_INT_SENS_1] = { 3, gpio_reg_int_sens_1 },
562
+ [GPIO_MNOP_INT_SENS_2] = { 3, gpio_reg_int_sens_2 },
563
+ [GPIO_MNOP_INT_STATUS] = { 3, gpio_reg_int_status },
564
+ [GPIO_MNOP_RESET_TOLERANT] = { 3, gpio_reg_reset_tolerant },
565
+ [GPIO_MNOP_DEBOUNCE_1] = { 3, gpio_reg_debounce_1 },
566
+ [GPIO_MNOP_DEBOUNCE_2] = { 3, gpio_reg_debounce_2 },
567
+ [GPIO_MNOP_COMMAND_SRC_0] = { 3, gpio_reg_cmd_source_0 },
568
+ [GPIO_MNOP_COMMAND_SRC_1] = { 3, gpio_reg_cmd_source_1 },
569
+ [GPIO_MNOP_DATA_READ] = { 3, gpio_reg_data_read },
570
+ [GPIO_MNOP_INPUT_MASK] = { 3, gpio_reg_input_mask },
571
+ /* Set QRST */
572
+ [GPIO_QRST_DATA_VALUE] = { 4, gpio_reg_data_value },
573
+ [GPIO_QRST_DIRECTION] = { 4, gpio_reg_direction },
574
+ [GPIO_QRST_INT_ENABLE] = { 4, gpio_reg_int_enable },
575
+ [GPIO_QRST_INT_SENS_0] = { 4, gpio_reg_int_sens_0 },
576
+ [GPIO_QRST_INT_SENS_1] = { 4, gpio_reg_int_sens_1 },
577
+ [GPIO_QRST_INT_SENS_2] = { 4, gpio_reg_int_sens_2 },
578
+ [GPIO_QRST_INT_STATUS] = { 4, gpio_reg_int_status },
579
+ [GPIO_QRST_RESET_TOLERANT] = { 4, gpio_reg_reset_tolerant },
580
+ [GPIO_QRST_DEBOUNCE_1] = { 4, gpio_reg_debounce_1 },
581
+ [GPIO_QRST_DEBOUNCE_2] = { 4, gpio_reg_debounce_2 },
582
+ [GPIO_QRST_COMMAND_SRC_0] = { 4, gpio_reg_cmd_source_0 },
583
+ [GPIO_QRST_COMMAND_SRC_1] = { 4, gpio_reg_cmd_source_1 },
584
+ [GPIO_QRST_DATA_READ] = { 4, gpio_reg_data_read },
585
+ [GPIO_QRST_INPUT_MASK] = { 4, gpio_reg_input_mask },
586
+ /* Set UVWX */
587
+ [GPIO_UVWX_DATA_VALUE] = { 5, gpio_reg_data_value },
588
+ [GPIO_UVWX_DIRECTION] = { 5, gpio_reg_direction },
589
+ [GPIO_UVWX_INT_ENABLE] = { 5, gpio_reg_int_enable },
590
+ [GPIO_UVWX_INT_SENS_0] = { 5, gpio_reg_int_sens_0 },
591
+ [GPIO_UVWX_INT_SENS_1] = { 5, gpio_reg_int_sens_1 },
592
+ [GPIO_UVWX_INT_SENS_2] = { 5, gpio_reg_int_sens_2 },
593
+ [GPIO_UVWX_INT_STATUS] = { 5, gpio_reg_int_status },
594
+ [GPIO_UVWX_RESET_TOLERANT] = { 5, gpio_reg_reset_tolerant },
595
+ [GPIO_UVWX_DEBOUNCE_1] = { 5, gpio_reg_debounce_1 },
596
+ [GPIO_UVWX_DEBOUNCE_2] = { 5, gpio_reg_debounce_2 },
597
+ [GPIO_UVWX_COMMAND_SRC_0] = { 5, gpio_reg_cmd_source_0 },
598
+ [GPIO_UVWX_COMMAND_SRC_1] = { 5, gpio_reg_cmd_source_1 },
599
+ [GPIO_UVWX_DATA_READ] = { 5, gpio_reg_data_read },
600
+ [GPIO_UVWX_INPUT_MASK] = { 5, gpio_reg_input_mask },
601
+ /* Set YZAAAB */
602
+ [GPIO_YZAAAB_DATA_VALUE] = { 6, gpio_reg_data_value },
603
+ [GPIO_YZAAAB_DIRECTION] = { 6, gpio_reg_direction },
604
+ [GPIO_YZAAAB_INT_ENABLE] = { 6, gpio_reg_int_enable },
605
+ [GPIO_YZAAAB_INT_SENS_0] = { 6, gpio_reg_int_sens_0 },
606
+ [GPIO_YZAAAB_INT_SENS_1] = { 6, gpio_reg_int_sens_1 },
607
+ [GPIO_YZAAAB_INT_SENS_2] = { 6, gpio_reg_int_sens_2 },
608
+ [GPIO_YZAAAB_INT_STATUS] = { 6, gpio_reg_int_status },
609
+ [GPIO_YZAAAB_RESET_TOLERANT] = { 6, gpio_reg_reset_tolerant },
610
+ [GPIO_YZAAAB_DEBOUNCE_1] = { 6, gpio_reg_debounce_1 },
611
+ [GPIO_YZAAAB_DEBOUNCE_2] = { 6, gpio_reg_debounce_2 },
612
+ [GPIO_YZAAAB_COMMAND_SRC_0] = { 6, gpio_reg_cmd_source_0 },
613
+ [GPIO_YZAAAB_COMMAND_SRC_1] = { 6, gpio_reg_cmd_source_1 },
614
+ [GPIO_YZAAAB_DATA_READ] = { 6, gpio_reg_data_read },
615
+ [GPIO_YZAAAB_INPUT_MASK] = { 6, gpio_reg_input_mask },
616
+ /* Set AC (ast2500 only) */
617
+ [GPIO_AC_DATA_VALUE] = { 7, gpio_reg_data_value },
618
+ [GPIO_AC_DIRECTION] = { 7, gpio_reg_direction },
619
+ [GPIO_AC_INT_ENABLE] = { 7, gpio_reg_int_enable },
620
+ [GPIO_AC_INT_SENS_0] = { 7, gpio_reg_int_sens_0 },
621
+ [GPIO_AC_INT_SENS_1] = { 7, gpio_reg_int_sens_1 },
622
+ [GPIO_AC_INT_SENS_2] = { 7, gpio_reg_int_sens_2 },
623
+ [GPIO_AC_INT_STATUS] = { 7, gpio_reg_int_status },
624
+ [GPIO_AC_RESET_TOLERANT] = { 7, gpio_reg_reset_tolerant },
625
+ [GPIO_AC_DEBOUNCE_1] = { 7, gpio_reg_debounce_1 },
626
+ [GPIO_AC_DEBOUNCE_2] = { 7, gpio_reg_debounce_2 },
627
+ [GPIO_AC_COMMAND_SRC_0] = { 7, gpio_reg_cmd_source_0 },
628
+ [GPIO_AC_COMMAND_SRC_1] = { 7, gpio_reg_cmd_source_1 },
629
+ [GPIO_AC_DATA_READ] = { 7, gpio_reg_data_read },
630
+ [GPIO_AC_INPUT_MASK] = { 7, gpio_reg_input_mask },
631
+};
632
+
633
+static uint64_t aspeed_gpio_read(void *opaque, hwaddr offset, uint32_t size)
634
+{
635
+ AspeedGPIOState *s = ASPEED_GPIO(opaque);
636
+ AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
637
+ uint64_t idx = -1;
638
+ const AspeedGPIOReg *reg;
639
+ GPIOSets *set;
640
+
641
+ idx = offset >> 2;
642
+ if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) {
643
+ idx -= GPIO_DEBOUNCE_TIME_1;
644
+ return (uint64_t) s->debounce_regs[idx];
645
+ }
646
+
647
+ reg = &agc->reg_table[idx];
648
+ if (reg->set_idx >= agc->nr_gpio_sets) {
649
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
650
+ HWADDR_PRIx"\n", __func__, offset);
651
+ return 0;
652
+ }
653
+
654
+ set = &s->sets[reg->set_idx];
655
+ switch (reg->type) {
656
+ case gpio_reg_data_value:
657
+ return set->data_value;
658
+ case gpio_reg_direction:
659
+ return set->direction;
660
+ case gpio_reg_int_enable:
661
+ return set->int_enable;
662
+ case gpio_reg_int_sens_0:
663
+ return set->int_sens_0;
664
+ case gpio_reg_int_sens_1:
665
+ return set->int_sens_1;
666
+ case gpio_reg_int_sens_2:
667
+ return set->int_sens_2;
668
+ case gpio_reg_int_status:
669
+ return set->int_status;
670
+ case gpio_reg_reset_tolerant:
671
+ return set->reset_tol;
672
+ case gpio_reg_debounce_1:
673
+ return set->debounce_1;
674
+ case gpio_reg_debounce_2:
675
+ return set->debounce_2;
676
+ case gpio_reg_cmd_source_0:
677
+ return set->cmd_source_0;
678
+ case gpio_reg_cmd_source_1:
679
+ return set->cmd_source_1;
680
+ case gpio_reg_data_read:
681
+ return set->data_read;
682
+ case gpio_reg_input_mask:
683
+ return set->input_mask;
684
+ default:
685
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: no getter for offset 0x%"
686
+ HWADDR_PRIx"\n", __func__, offset);
687
+ return 0;
688
+ };
689
+}
690
+
691
+static void aspeed_gpio_write(void *opaque, hwaddr offset, uint64_t data,
692
+ uint32_t size)
693
+{
694
+ AspeedGPIOState *s = ASPEED_GPIO(opaque);
695
+ AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
696
+ const GPIOSetProperties *props;
697
+ uint64_t idx = -1;
698
+ const AspeedGPIOReg *reg;
699
+ GPIOSets *set;
700
+ uint32_t cleared;
701
+
702
+ idx = offset >> 2;
703
+ if (idx >= GPIO_DEBOUNCE_TIME_1 && idx <= GPIO_DEBOUNCE_TIME_3) {
704
+ idx -= GPIO_DEBOUNCE_TIME_1;
705
+ s->debounce_regs[idx] = (uint32_t) data;
706
+ return;
707
+ }
708
+
709
+ reg = &agc->reg_table[idx];
710
+ if (reg->set_idx >= agc->nr_gpio_sets) {
711
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
712
+ HWADDR_PRIx"\n", __func__, offset);
713
+ return;
714
+ }
715
+
716
+ set = &s->sets[reg->set_idx];
717
+ props = &agc->props[reg->set_idx];
718
+
719
+ switch (reg->type) {
720
+ case gpio_reg_data_value:
721
+ data &= props->output;
722
+ data = update_value_control_source(set, set->data_value, data);
723
+ set->data_read = data;
724
+ aspeed_gpio_update(s, set, data);
725
+ return;
726
+ case gpio_reg_direction:
84
+ /*
727
+ /*
85
+ * T2 encoding ({D0-D31} reglist): v8.1M and up. We choose not
728
+ * where data is the value attempted to be written to the pin:
86
+ * to take the IMPDEF option to make memory accesses to the stack
729
+ * pin type | input mask | output mask | expected value
87
+ * slots that correspond to the D16-D31 registers (discarding
730
+ * ------------------------------------------------------------
88
+ * read data and writing UNKNOWN values), so for us the T2
731
+ * bidirectional | 1 | 1 | data
89
+ * encoding behaves identically to the T1 encoding.
732
+ * input only | 1 | 0 | 0
733
+ * output only | 0 | 1 | 1
734
+ * no pin / gap | 0 | 0 | 0
735
+ *
736
+ * which is captured by:
737
+ * data = ( data | ~input) & output;
90
+ */
738
+ */
91
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
739
+ data = (data | ~props->input) & props->output;
92
+ return false;
740
+ set->direction = update_value_control_source(set, set->direction, data);
741
+ break;
742
+ case gpio_reg_int_enable:
743
+ set->int_enable = update_value_control_source(set, set->int_enable,
744
+ data);
745
+ break;
746
+ case gpio_reg_int_sens_0:
747
+ set->int_sens_0 = update_value_control_source(set, set->int_sens_0,
748
+ data);
749
+ break;
750
+ case gpio_reg_int_sens_1:
751
+ set->int_sens_1 = update_value_control_source(set, set->int_sens_1,
752
+ data);
753
+ break;
754
+ case gpio_reg_int_sens_2:
755
+ set->int_sens_2 = update_value_control_source(set, set->int_sens_2,
756
+ data);
757
+ break;
758
+ case gpio_reg_int_status:
759
+ cleared = ctpop32(data & set->int_status);
760
+ if (s->pending && cleared) {
761
+ assert(s->pending >= cleared);
762
+ s->pending -= cleared;
93
+ }
763
+ }
94
+ } else {
764
+ set->int_status &= ~data;
765
+ break;
766
+ case gpio_reg_reset_tolerant:
767
+ set->reset_tol = update_value_control_source(set, set->reset_tol,
768
+ data);
769
+ return;
770
+ case gpio_reg_debounce_1:
771
+ set->debounce_1 = update_value_control_source(set, set->debounce_1,
772
+ data);
773
+ return;
774
+ case gpio_reg_debounce_2:
775
+ set->debounce_2 = update_value_control_source(set, set->debounce_2,
776
+ data);
777
+ return;
778
+ case gpio_reg_cmd_source_0:
779
+ set->cmd_source_0 = data & ASPEED_CMD_SRC_MASK;
780
+ return;
781
+ case gpio_reg_cmd_source_1:
782
+ set->cmd_source_1 = data & ASPEED_CMD_SRC_MASK;
783
+ return;
784
+ case gpio_reg_data_read:
785
+ /* Read only register */
786
+ return;
787
+ case gpio_reg_input_mask:
95
+ /*
788
+ /*
96
+ * T1 encoding ({D0-D15} reglist); undef if we have 32 Dregs.
789
+ * feeds into interrupt generation
97
+ * This is currently architecturally impossible, but we add the
790
+ * 0: read from data value reg will be updated
98
+ * check to stay in line with the pseudocode. Note that we must
791
+ * 1: read from data value reg will not be updated
99
+ * emit code for the UNDEF so it takes precedence over the NOCP.
100
+ */
792
+ */
101
+ if (dc_isar_feature(aa32_simd_r32, s)) {
793
+ set->input_mask = data & props->input;
102
+ unallocated_encoding(s);
794
+ break;
103
+ return true;
795
+ default:
796
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: no setter for offset 0x%"
797
+ HWADDR_PRIx"\n", __func__, offset);
798
+ return;
799
+ }
800
+ aspeed_gpio_update(s, set, set->data_value);
801
+ return;
802
+}
803
+
804
+static int get_set_idx(AspeedGPIOState *s, const char *group, int *group_idx)
805
+{
806
+ AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
807
+ int set_idx, g_idx = *group_idx;
808
+
809
+ for (set_idx = 0; set_idx < agc->nr_gpio_sets; set_idx++) {
810
+ const GPIOSetProperties *set_props = &agc->props[set_idx];
811
+ for (g_idx = 0; g_idx < ASPEED_GROUPS_PER_SET; g_idx++) {
812
+ if (!strncmp(group, set_props->group_label[g_idx], strlen(group))) {
813
+ *group_idx = g_idx;
814
+ return set_idx;
815
+ }
104
+ }
816
+ }
105
+ }
817
+ }
106
+
818
+ return -1;
107
+ /*
819
+}
108
+ * If not secure, UNDEF. We must emit code for this
820
+
109
+ * rather than returning false so that this takes
821
+static void aspeed_gpio_get_pin(Object *obj, Visitor *v, const char *name,
110
+ * precedence over the m-nocp.decode NOCP fallback.
822
+ void *opaque, Error **errp)
111
+ */
823
+{
112
+ if (!s->v8m_secure) {
824
+ int pin = 0xfff;
113
+ unallocated_encoding(s);
825
+ bool level = true;
114
+ return true;
826
+ char group[3];
115
+ }
827
+ AspeedGPIOState *s = ASPEED_GPIO(obj);
116
+ /* If no fpu, NOP. */
828
+ int set_idx, group_idx = 0;
117
+ if (!dc_isar_feature(aa32_vfp, s)) {
829
+
118
+ return true;
830
+ if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
119
+ }
831
+ error_setg(errp, "%s: error reading %s", __func__, name);
120
+
832
+ return;
121
+ fptr = load_reg(s, a->rn);
833
+ }
122
+ if (a->l) {
834
+ set_idx = get_set_idx(s, group, &group_idx);
123
+ gen_helper_v7m_vlldm(cpu_env, fptr);
835
+ if (set_idx == -1) {
124
+ } else {
836
+ error_setg(errp, "%s: invalid group %s", __func__, group);
125
+ gen_helper_v7m_vlstm(cpu_env, fptr);
837
+ return;
126
+ }
838
+ }
127
+ tcg_temp_free_i32(fptr);
839
+ pin = pin + group_idx * GPIOS_PER_GROUP;
128
+
840
+ level = aspeed_gpio_get_pin_level(s, set_idx, pin);
129
+ /* End the TB, because we have updated FP control bits */
841
+ visit_type_bool(v, name, &level, errp);
130
+ s->base.is_jmp = DISAS_UPDATE_EXIT;
842
+}
131
+ return true;
843
+
132
+}
844
+static void aspeed_gpio_set_pin(Object *obj, Visitor *v, const char *name,
133
+
845
+ void *opaque, Error **errp)
134
+static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
846
+{
135
+{
847
+ Error *local_err = NULL;
136
+ int btmreg, topreg;
848
+ bool level;
137
+ TCGv_i64 zero;
849
+ int pin = 0xfff;
138
+ TCGv_i32 aspen, sfpa;
850
+ char group[3];
139
+
851
+ AspeedGPIOState *s = ASPEED_GPIO(obj);
140
+ if (!dc_isar_feature(aa32_m_sec_state, s)) {
852
+ int set_idx, group_idx = 0;
141
+ /* Before v8.1M, fall through in decode to NOCP check */
853
+
142
+ return false;
854
+ visit_type_bool(v, name, &level, &local_err);
143
+ }
855
+ if (local_err) {
144
+
856
+ error_propagate(errp, local_err);
145
+ /* Explicitly UNDEF because this takes precedence over NOCP */
857
+ return;
146
+ if (!arm_dc_feature(s, ARM_FEATURE_M_MAIN) || !s->v8m_secure) {
858
+ }
147
+ unallocated_encoding(s);
859
+ if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
148
+ return true;
860
+ error_setg(errp, "%s: error reading %s", __func__, name);
149
+ }
861
+ return;
150
+
862
+ }
151
+ if (!dc_isar_feature(aa32_vfp_simd, s)) {
863
+ set_idx = get_set_idx(s, group, &group_idx);
152
+ /* NOP if we have neither FP nor MVE */
864
+ if (set_idx == -1) {
153
+ return true;
865
+ error_setg(errp, "%s: invalid group %s", __func__, group);
154
+ }
866
+ return;
155
+
867
+ }
156
+ /*
868
+ pin = pin + group_idx * GPIOS_PER_GROUP;
157
+ * If FPCCR.ASPEN != 0 && CONTROL_S.SFPA == 0 then there is no
869
+ aspeed_gpio_set_pin_level(s, set_idx, pin, level);
158
+ * active floating point context so we must NOP (without doing
870
+}
159
+ * any lazy state preservation or the NOCP check).
871
+
160
+ */
872
+/****************** Setup functions ******************/
161
+ aspen = load_cpu_field(v7m.fpccr[M_REG_S]);
873
+static const GPIOSetProperties ast2400_set_props[] = {
162
+ sfpa = load_cpu_field(v7m.control[M_REG_S]);
874
+ [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
163
+ tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
875
+ [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
164
+ tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
876
+ [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
165
+ tcg_gen_andi_i32(sfpa, sfpa, R_V7M_CONTROL_SFPA_MASK);
877
+ [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
166
+ tcg_gen_or_i32(sfpa, sfpa, aspen);
878
+ [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} },
167
+ arm_gen_condlabel(s);
879
+ [5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} },
168
+ tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel);
880
+ [6] = {0x0000000f, 0x0fffff0f, {"Y", "Z", "AA", "AB"} },
169
+
881
+};
170
+ if (s->fp_excp_el != 0) {
882
+
171
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
883
+static const GPIOSetProperties ast2500_set_props[] = {
172
+ syn_uncategorized(), s->fp_excp_el);
884
+ [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
173
+ return true;
885
+ [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
174
+ }
886
+ [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
175
+
887
+ [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
176
+ topreg = a->vd + a->imm - 1;
888
+ [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} },
177
+ btmreg = a->vd;
889
+ [5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} },
178
+
890
+ [6] = {0xffffff0f, 0x0fffff0f, {"Y", "Z", "AA", "AB"} },
179
+ /* Convert to Sreg numbers if the insn specified in Dregs */
891
+ [7] = {0x000000ff, 0x000000ff, {"AC"} },
180
+ if (a->size == 3) {
892
+};
181
+ topreg = topreg * 2 + 1;
893
+
182
+ btmreg *= 2;
894
+static const MemoryRegionOps aspeed_gpio_ops = {
183
+ }
895
+ .read = aspeed_gpio_read,
184
+
896
+ .write = aspeed_gpio_write,
185
+ if (topreg > 63 || (topreg > 31 && !(topreg & 1))) {
897
+ .endianness = DEVICE_LITTLE_ENDIAN,
186
+ /* UNPREDICTABLE: we choose to undef */
898
+ .valid.min_access_size = 4,
187
+ unallocated_encoding(s);
899
+ .valid.max_access_size = 4,
188
+ return true;
900
+};
189
+ }
901
+
190
+
902
+static void aspeed_gpio_reset(DeviceState *dev)
191
+ /* Silently ignore requests to clear D16-D31 if they don't exist */
903
+{
192
+ if (topreg > 31 && !dc_isar_feature(aa32_simd_r32, s)) {
904
+ AspeedGPIOState *s = ASPEED_GPIO(dev);
193
+ topreg = 31;
905
+
194
+ }
906
+ /* TODO: respect the reset tolerance registers */
195
+
907
+ memset(s->sets, 0, sizeof(s->sets));
196
+ if (!vfp_access_check(s)) {
908
+}
197
+ return true;
909
+
198
+ }
910
+static void aspeed_gpio_realize(DeviceState *dev, Error **errp)
199
+
911
+{
200
+ /* Zero the Sregs from btmreg to topreg inclusive. */
912
+ AspeedGPIOState *s = ASPEED_GPIO(dev);
201
+ zero = tcg_const_i64(0);
913
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
202
+ if (btmreg & 1) {
914
+ AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
203
+ write_neon_element64(zero, btmreg >> 1, 1, MO_32);
915
+ int pin;
204
+ btmreg++;
916
+
205
+ }
917
+ /* Interrupt parent line */
206
+ for (; btmreg + 1 <= topreg; btmreg += 2) {
918
+ sysbus_init_irq(sbd, &s->irq);
207
+ write_neon_element64(zero, btmreg >> 1, 0, MO_64);
919
+
208
+ }
920
+ /* Individual GPIOs */
209
+ if (btmreg == topreg) {
921
+ for (pin = 0; pin < agc->nr_gpio_pins; pin++) {
210
+ write_neon_element64(zero, btmreg >> 1, 0, MO_32);
922
+ sysbus_init_irq(sbd, &s->gpios[pin]);
211
+ btmreg++;
923
+ }
212
+ }
924
+
213
+ assert(btmreg == topreg + 1);
925
+ memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_gpio_ops, s,
214
+ /* TODO: when MVE is implemented, zero VPR here */
926
+ TYPE_ASPEED_GPIO, GPIO_3_6V_MEM_SIZE);
215
+ return true;
927
+
216
+}
928
+ sysbus_init_mmio(sbd, &s->iomem);
217
+
929
+}
218
+static bool trans_NOCP(DisasContext *s, arg_nocp *a)
930
+
219
+{
931
+static void aspeed_gpio_init(Object *obj)
220
+ /*
932
+{
221
+ * Handle M-profile early check for disabled coprocessor:
933
+ AspeedGPIOState *s = ASPEED_GPIO(obj);
222
+ * all we need to do here is emit the NOCP exception if
934
+ AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
223
+ * the coprocessor is disabled. Otherwise we return false
935
+ int pin;
224
+ * and the real VFP/etc decode will handle the insn.
936
+
225
+ */
937
+ for (pin = 0; pin < agc->nr_gpio_pins; pin++) {
226
+ assert(arm_dc_feature(s, ARM_FEATURE_M));
938
+ char *name;
227
+
939
+ int set_idx = pin / GPIOS_PER_SET;
228
+ if (a->cp == 11) {
940
+ int pin_idx = aspeed_adjust_pin(s, pin) - (set_idx * GPIOS_PER_SET);
229
+ a->cp = 10;
941
+ int group_idx = pin_idx >> GPIO_GROUP_SHIFT;
230
+ }
942
+ const GPIOSetProperties *props = &agc->props[set_idx];
231
+ if (arm_dc_feature(s, ARM_FEATURE_V8_1M) &&
943
+
232
+ (a->cp == 8 || a->cp == 9 || a->cp == 14 || a->cp == 15)) {
944
+ name = g_strdup_printf("gpio%s%d", props->group_label[group_idx],
233
+ /* in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
945
+ pin_idx % GPIOS_PER_GROUP);
234
+ a->cp = 10;
946
+ object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
235
+ }
947
+ aspeed_gpio_set_pin, NULL, NULL, NULL);
236
+
948
+ }
237
+ if (a->cp != 10) {
949
+}
238
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
950
+
239
+ syn_uncategorized(), default_exception_el(s));
951
+static const VMStateDescription vmstate_gpio_regs = {
240
+ return true;
952
+ .name = TYPE_ASPEED_GPIO"/regs",
241
+ }
953
+ .version_id = 1,
242
+
954
+ .minimum_version_id = 1,
243
+ if (s->fp_excp_el != 0) {
955
+ .fields = (VMStateField[]) {
244
+ gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
956
+ VMSTATE_UINT32(data_value, GPIOSets),
245
+ syn_uncategorized(), s->fp_excp_el);
957
+ VMSTATE_UINT32(data_read, GPIOSets),
246
+ return true;
958
+ VMSTATE_UINT32(direction, GPIOSets),
247
+ }
959
+ VMSTATE_UINT32(int_enable, GPIOSets),
248
+
960
+ VMSTATE_UINT32(int_sens_0, GPIOSets),
249
+ return false;
961
+ VMSTATE_UINT32(int_sens_1, GPIOSets),
250
+}
962
+ VMSTATE_UINT32(int_sens_2, GPIOSets),
251
+
963
+ VMSTATE_UINT32(int_status, GPIOSets),
252
+static bool trans_NOCP_8_1(DisasContext *s, arg_nocp *a)
964
+ VMSTATE_UINT32(reset_tol, GPIOSets),
253
+{
965
+ VMSTATE_UINT32(cmd_source_0, GPIOSets),
254
+ /* This range needs a coprocessor check for v8.1M and later only */
966
+ VMSTATE_UINT32(cmd_source_1, GPIOSets),
255
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
967
+ VMSTATE_UINT32(debounce_1, GPIOSets),
256
+ return false;
968
+ VMSTATE_UINT32(debounce_2, GPIOSets),
257
+ }
969
+ VMSTATE_UINT32(input_mask, GPIOSets),
258
+ return trans_NOCP(s, a);
970
+ VMSTATE_END_OF_LIST(),
259
+}
971
+ }
260
diff --git a/target/arm/translate.c b/target/arm/translate.c
972
+};
261
index XXXXXXX..XXXXXXX 100644
973
+
262
--- a/target/arm/translate.c
974
+static const VMStateDescription vmstate_aspeed_gpio = {
263
+++ b/target/arm/translate.c
975
+ .name = TYPE_ASPEED_GPIO,
264
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
976
+ .version_id = 1,
265
#define ARM_CP_RW_BIT (1 << 20)
977
+ .minimum_version_id = 1,
266
978
+ .fields = (VMStateField[]) {
267
/* Include the VFP and Neon decoders */
979
+ VMSTATE_STRUCT_ARRAY(sets, AspeedGPIOState, ASPEED_GPIO_MAX_NR_SETS,
268
-#include "decode-m-nocp.c.inc"
980
+ 1, vmstate_gpio_regs, GPIOSets),
269
#include "translate-vfp.c.inc"
981
+ VMSTATE_UINT32_ARRAY(debounce_regs, AspeedGPIOState,
270
#include "translate-neon.c.inc"
982
+ ASPEED_GPIO_NR_DEBOUNCE_REGS),
271
983
+ VMSTATE_END_OF_LIST(),
272
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
984
+ }
273
index XXXXXXX..XXXXXXX 100644
985
+};
274
--- a/target/arm/translate-vfp.c.inc
986
+
275
+++ b/target/arm/translate-vfp.c.inc
987
+static void aspeed_gpio_class_init(ObjectClass *klass, void *data)
276
@@ -XXX,XX +XXX,XX @@ static bool trans_VCVT_dp_int(DisasContext *s, arg_VCVT_dp_int *a)
988
+{
277
return true;
989
+ DeviceClass *dc = DEVICE_CLASS(klass);
278
}
990
+
279
991
+ dc->realize = aspeed_gpio_realize;
280
-/*
992
+ dc->reset = aspeed_gpio_reset;
281
- * Decode VLLDM and VLSTM are nonstandard because:
993
+ dc->desc = "Aspeed GPIO Controller";
282
- * * if there is no FPU then these insns must NOP in
994
+ dc->vmsd = &vmstate_aspeed_gpio;
283
- * Secure state and UNDEF in Nonsecure state
995
+}
284
- * * if there is an FPU then these insns do not have
996
+
285
- * the usual behaviour that vfp_access_check() provides of
997
+static void aspeed_gpio_ast2400_class_init(ObjectClass *klass, void *data)
286
- * being controlled by CPACR/NSACR enable bits or the
998
+{
287
- * lazy-stacking logic.
999
+ AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
288
- */
1000
+
289
-static bool trans_VLLDM_VLSTM(DisasContext *s, arg_VLLDM_VLSTM *a)
1001
+ agc->props = ast2400_set_props;
290
-{
1002
+ agc->nr_gpio_pins = 216;
291
- TCGv_i32 fptr;
1003
+ agc->nr_gpio_sets = 7;
292
-
1004
+ agc->gap = 196;
293
- if (!arm_dc_feature(s, ARM_FEATURE_M) ||
1005
+ agc->reg_table = aspeed_3_6v_gpios;
294
- !arm_dc_feature(s, ARM_FEATURE_V8)) {
1006
+}
295
- return false;
1007
+
296
- }
1008
+static void aspeed_gpio_2500_class_init(ObjectClass *klass, void *data)
297
-
1009
+{
298
- if (a->op) {
1010
+ AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
299
- /*
1011
+
300
- * T2 encoding ({D0-D31} reglist): v8.1M and up. We choose not
1012
+ agc->props = ast2500_set_props;
301
- * to take the IMPDEF option to make memory accesses to the stack
1013
+ agc->nr_gpio_pins = 228;
302
- * slots that correspond to the D16-D31 registers (discarding
1014
+ agc->nr_gpio_sets = 8;
303
- * read data and writing UNKNOWN values), so for us the T2
1015
+ agc->gap = 220;
304
- * encoding behaves identically to the T1 encoding.
1016
+ agc->reg_table = aspeed_3_6v_gpios;
305
- */
1017
+}
306
- if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
1018
+
307
- return false;
1019
+static const TypeInfo aspeed_gpio_info = {
308
- }
1020
+ .name = TYPE_ASPEED_GPIO,
309
- } else {
1021
+ .parent = TYPE_SYS_BUS_DEVICE,
310
- /*
1022
+ .instance_size = sizeof(AspeedGPIOState),
311
- * T1 encoding ({D0-D15} reglist); undef if we have 32 Dregs.
1023
+ .class_size = sizeof(AspeedGPIOClass),
312
- * This is currently architecturally impossible, but we add the
1024
+ .class_init = aspeed_gpio_class_init,
313
- * check to stay in line with the pseudocode. Note that we must
1025
+ .abstract = true,
314
- * emit code for the UNDEF so it takes precedence over the NOCP.
1026
+};
315
- */
1027
+
316
- if (dc_isar_feature(aa32_simd_r32, s)) {
1028
+static const TypeInfo aspeed_gpio_ast2400_info = {
317
- unallocated_encoding(s);
1029
+ .name = TYPE_ASPEED_GPIO "-ast2400",
318
- return true;
1030
+ .parent = TYPE_ASPEED_GPIO,
319
- }
1031
+ .class_init = aspeed_gpio_ast2400_class_init,
320
- }
1032
+ .instance_init = aspeed_gpio_init,
321
-
1033
+};
322
- /*
1034
+
323
- * If not secure, UNDEF. We must emit code for this
1035
+static const TypeInfo aspeed_gpio_ast2500_info = {
324
- * rather than returning false so that this takes
1036
+ .name = TYPE_ASPEED_GPIO "-ast2500",
325
- * precedence over the m-nocp.decode NOCP fallback.
1037
+ .parent = TYPE_ASPEED_GPIO,
326
- */
1038
+ .class_init = aspeed_gpio_2500_class_init,
327
- if (!s->v8m_secure) {
1039
+ .instance_init = aspeed_gpio_init,
328
- unallocated_encoding(s);
1040
+};
329
- return true;
1041
+
330
- }
1042
+static void aspeed_gpio_register_types(void)
331
- /* If no fpu, NOP. */
1043
+{
332
- if (!dc_isar_feature(aa32_vfp, s)) {
1044
+ type_register_static(&aspeed_gpio_info);
333
- return true;
1045
+ type_register_static(&aspeed_gpio_ast2400_info);
334
- }
1046
+ type_register_static(&aspeed_gpio_ast2500_info);
335
-
1047
+}
336
- fptr = load_reg(s, a->rn);
1048
+
337
- if (a->l) {
1049
+type_init(aspeed_gpio_register_types);
338
- gen_helper_v7m_vlldm(cpu_env, fptr);
339
- } else {
340
- gen_helper_v7m_vlstm(cpu_env, fptr);
341
- }
342
- tcg_temp_free_i32(fptr);
343
-
344
- /* End the TB, because we have updated FP control bits */
345
- s->base.is_jmp = DISAS_UPDATE_EXIT;
346
- return true;
347
-}
348
-
349
-static bool trans_VSCCLRM(DisasContext *s, arg_VSCCLRM *a)
350
-{
351
- int btmreg, topreg;
352
- TCGv_i64 zero;
353
- TCGv_i32 aspen, sfpa;
354
-
355
- if (!dc_isar_feature(aa32_m_sec_state, s)) {
356
- /* Before v8.1M, fall through in decode to NOCP check */
357
- return false;
358
- }
359
-
360
- /* Explicitly UNDEF because this takes precedence over NOCP */
361
- if (!arm_dc_feature(s, ARM_FEATURE_M_MAIN) || !s->v8m_secure) {
362
- unallocated_encoding(s);
363
- return true;
364
- }
365
-
366
- if (!dc_isar_feature(aa32_vfp_simd, s)) {
367
- /* NOP if we have neither FP nor MVE */
368
- return true;
369
- }
370
-
371
- /*
372
- * If FPCCR.ASPEN != 0 && CONTROL_S.SFPA == 0 then there is no
373
- * active floating point context so we must NOP (without doing
374
- * any lazy state preservation or the NOCP check).
375
- */
376
- aspen = load_cpu_field(v7m.fpccr[M_REG_S]);
377
- sfpa = load_cpu_field(v7m.control[M_REG_S]);
378
- tcg_gen_andi_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
379
- tcg_gen_xori_i32(aspen, aspen, R_V7M_FPCCR_ASPEN_MASK);
380
- tcg_gen_andi_i32(sfpa, sfpa, R_V7M_CONTROL_SFPA_MASK);
381
- tcg_gen_or_i32(sfpa, sfpa, aspen);
382
- arm_gen_condlabel(s);
383
- tcg_gen_brcondi_i32(TCG_COND_EQ, sfpa, 0, s->condlabel);
384
-
385
- if (s->fp_excp_el != 0) {
386
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
387
- syn_uncategorized(), s->fp_excp_el);
388
- return true;
389
- }
390
-
391
- topreg = a->vd + a->imm - 1;
392
- btmreg = a->vd;
393
-
394
- /* Convert to Sreg numbers if the insn specified in Dregs */
395
- if (a->size == 3) {
396
- topreg = topreg * 2 + 1;
397
- btmreg *= 2;
398
- }
399
-
400
- if (topreg > 63 || (topreg > 31 && !(topreg & 1))) {
401
- /* UNPREDICTABLE: we choose to undef */
402
- unallocated_encoding(s);
403
- return true;
404
- }
405
-
406
- /* Silently ignore requests to clear D16-D31 if they don't exist */
407
- if (topreg > 31 && !dc_isar_feature(aa32_simd_r32, s)) {
408
- topreg = 31;
409
- }
410
-
411
- if (!vfp_access_check(s)) {
412
- return true;
413
- }
414
-
415
- /* Zero the Sregs from btmreg to topreg inclusive. */
416
- zero = tcg_const_i64(0);
417
- if (btmreg & 1) {
418
- write_neon_element64(zero, btmreg >> 1, 1, MO_32);
419
- btmreg++;
420
- }
421
- for (; btmreg + 1 <= topreg; btmreg += 2) {
422
- write_neon_element64(zero, btmreg >> 1, 0, MO_64);
423
- }
424
- if (btmreg == topreg) {
425
- write_neon_element64(zero, btmreg >> 1, 0, MO_32);
426
- btmreg++;
427
- }
428
- assert(btmreg == topreg + 1);
429
- /* TODO: when MVE is implemented, zero VPR here */
430
- return true;
431
-}
432
-
433
-static bool trans_NOCP(DisasContext *s, arg_nocp *a)
434
-{
435
- /*
436
- * Handle M-profile early check for disabled coprocessor:
437
- * all we need to do here is emit the NOCP exception if
438
- * the coprocessor is disabled. Otherwise we return false
439
- * and the real VFP/etc decode will handle the insn.
440
- */
441
- assert(arm_dc_feature(s, ARM_FEATURE_M));
442
-
443
- if (a->cp == 11) {
444
- a->cp = 10;
445
- }
446
- if (arm_dc_feature(s, ARM_FEATURE_V8_1M) &&
447
- (a->cp == 8 || a->cp == 9 || a->cp == 14 || a->cp == 15)) {
448
- /* in v8.1M cp 8, 9, 14, 15 also are governed by the cp10 enable */
449
- a->cp = 10;
450
- }
451
-
452
- if (a->cp != 10) {
453
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
454
- syn_uncategorized(), default_exception_el(s));
455
- return true;
456
- }
457
-
458
- if (s->fp_excp_el != 0) {
459
- gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
460
- syn_uncategorized(), s->fp_excp_el);
461
- return true;
462
- }
463
-
464
- return false;
465
-}
466
-
467
-static bool trans_NOCP_8_1(DisasContext *s, arg_nocp *a)
468
-{
469
- /* This range needs a coprocessor check for v8.1M and later only */
470
- if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
471
- return false;
472
- }
473
- return trans_NOCP(s, a);
474
-}
475
-
476
static bool trans_VINS(DisasContext *s, arg_VINS *a)
477
{
478
TCGv_i32 rd, rm;
479
diff --git a/target/arm/meson.build b/target/arm/meson.build
480
index XXXXXXX..XXXXXXX 100644
481
--- a/target/arm/meson.build
482
+++ b/target/arm/meson.build
483
@@ -XXX,XX +XXX,XX @@ gen = [
484
decodetree.process('neon-ls.decode', extra_args: '--static-decode=disas_neon_ls'),
485
decodetree.process('vfp.decode', extra_args: '--static-decode=disas_vfp'),
486
decodetree.process('vfp-uncond.decode', extra_args: '--static-decode=disas_vfp_uncond'),
487
- decodetree.process('m-nocp.decode', extra_args: '--static-decode=disas_m_nocp'),
488
+ decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
489
decodetree.process('a32.decode', extra_args: '--static-decode=disas_a32'),
490
decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
491
decodetree.process('t32.decode', extra_args: '--static-decode=disas_t32'),
492
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
493
'op_helper.c',
494
'tlb_helper.c',
495
'translate.c',
496
+ 'translate-m-nocp.c',
497
'vec_helper.c',
498
'vfp_helper.c',
499
'cpu_tcg.c',
500
--
1050
--
501
2.20.1
1051
2.20.1
502
1052
503
1053
diff view generated by jsdifflib
1
On some boards, SCC config register CFG0 bit 0 controls whether
1
From: Rashmica Gupta <rashmica.g@gmail.com>
2
parts of the board memory map are remapped. Support this with:
3
* a device property scc-cfg0 so the board can specify the
4
initial value of the CFG0 register
5
* an outbound GPIO line which tracks bit 0 and which the board
6
can wire up to provide the remapping
7
2
3
Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Message-id: 20190904070506.1052-3-clg@kaod.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
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: 20210504120912.23094-3-peter.maydell@linaro.org
12
---
8
---
13
include/hw/misc/mps2-scc.h | 9 +++++++++
9
include/hw/arm/aspeed_soc.h | 3 +++
14
hw/misc/mps2-scc.c | 13 ++++++++++---
10
hw/arm/aspeed_soc.c | 17 +++++++++++++++++
15
2 files changed, 19 insertions(+), 3 deletions(-)
11
2 files changed, 20 insertions(+)
16
12
17
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
13
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/misc/mps2-scc.h
15
--- a/include/hw/arm/aspeed_soc.h
20
+++ b/include/hw/misc/mps2-scc.h
16
+++ b/include/hw/arm/aspeed_soc.h
21
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@
22
* + QOM property "scc-cfg4": value of the read-only CFG4 register
18
#include "hw/watchdog/wdt_aspeed.h"
23
* + QOM property "scc-aid": value of the read-only SCC_AID register
19
#include "hw/net/ftgmac100.h"
24
* + QOM property "scc-id": value of the read-only SCC_ID register
20
#include "target/arm/cpu.h"
25
+ * + QOM property "scc-cfg0": reset value of the CFG0 register
21
+#include "hw/gpio/aspeed_gpio.h"
26
* + QOM property array "oscclk": reset values of the OSCCLK registers
22
27
* (which are accessed via the SYS_CFG channel provided by this device)
23
#define ASPEED_SPIS_NUM 2
28
+ * + named GPIO output "remap": this tracks the value of CFG0 register
24
#define ASPEED_WDTS_NUM 3
29
+ * bit 0. Boards where this bit controls memory remapping should
25
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
30
+ * connect this GPIO line to a function performing that mapping.
26
AspeedSDMCState sdmc;
31
+ * Boards where bit 0 has no special function should leave the GPIO
27
AspeedWDTState wdt[ASPEED_WDTS_NUM];
32
+ * output disconnected.
28
FTGMAC100State ftgmac100[ASPEED_MACS_NUM];
33
*/
29
+ AspeedGPIOState gpio;
34
#ifndef MPS2_SCC_H
30
} AspeedSoCState;
35
#define MPS2_SCC_H
31
36
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
32
#define TYPE_ASPEED_SOC "aspeed-soc"
37
uint32_t num_oscclk;
33
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCInfo {
38
uint32_t *oscclk;
34
int spis_num;
39
uint32_t *oscclk_reset;
35
const char *fmc_typename;
40
+ uint32_t cfg0_reset;
36
const char **spi_typename;
37
+ const char *gpio_typename;
38
int wdts_num;
39
const int *irqmap;
40
const hwaddr *memmap;
41
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/aspeed_soc.c
44
+++ b/hw/arm/aspeed_soc.c
45
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
46
.spis_num = 1,
47
.fmc_typename = "aspeed.smc.fmc",
48
.spi_typename = aspeed_soc_ast2400_typenames,
49
+ .gpio_typename = "aspeed.gpio-ast2400",
50
.wdts_num = 2,
51
.irqmap = aspeed_soc_ast2400_irqmap,
52
.memmap = aspeed_soc_ast2400_memmap,
53
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
54
.spis_num = 1,
55
.fmc_typename = "aspeed.smc.fmc",
56
.spi_typename = aspeed_soc_ast2400_typenames,
57
+ .gpio_typename = "aspeed.gpio-ast2400",
58
.wdts_num = 2,
59
.irqmap = aspeed_soc_ast2400_irqmap,
60
.memmap = aspeed_soc_ast2400_memmap,
61
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
62
.spis_num = 1,
63
.fmc_typename = "aspeed.smc.fmc",
64
.spi_typename = aspeed_soc_ast2400_typenames,
65
+ .gpio_typename = "aspeed.gpio-ast2400",
66
.wdts_num = 2,
67
.irqmap = aspeed_soc_ast2400_irqmap,
68
.memmap = aspeed_soc_ast2400_memmap,
69
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
70
.spis_num = 2,
71
.fmc_typename = "aspeed.smc.ast2500-fmc",
72
.spi_typename = aspeed_soc_ast2500_typenames,
73
+ .gpio_typename = "aspeed.gpio-ast2500",
74
.wdts_num = 3,
75
.irqmap = aspeed_soc_ast2500_irqmap,
76
.memmap = aspeed_soc_ast2500_memmap,
77
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
78
79
sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
80
TYPE_ASPEED_XDMA);
41
+
81
+
42
+ qemu_irq remap;
82
+ sysbus_init_child_obj(obj, "gpio", OBJECT(&s->gpio), sizeof(s->gpio),
43
};
83
+ sc->info->gpio_typename);
44
45
#endif
46
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/misc/mps2-scc.c
49
+++ b/hw/misc/mps2-scc.c
50
@@ -XXX,XX +XXX,XX @@
51
#include "qemu/bitops.h"
52
#include "trace.h"
53
#include "hw/sysbus.h"
54
+#include "hw/irq.h"
55
#include "migration/vmstate.h"
56
#include "hw/registerfields.h"
57
#include "hw/misc/mps2-scc.h"
58
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
59
switch (offset) {
60
case A_CFG0:
61
/*
62
- * TODO on some boards bit 0 controls RAM remapping;
63
- * on others bit 1 is CPU_WAIT.
64
+ * On some boards bit 0 controls board-specific remapping;
65
+ * we always reflect bit 0 in the 'remap' GPIO output line,
66
+ * and let the board wire it up or not as it chooses.
67
+ * TODO on some boards bit 1 is CPU_WAIT.
68
*/
69
s->cfg0 = value;
70
+ qemu_set_irq(s->remap, s->cfg0 & 1);
71
break;
72
case A_CFG1:
73
s->cfg1 = value;
74
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_reset(DeviceState *dev)
75
int i;
76
77
trace_mps2_scc_reset();
78
- s->cfg0 = 0;
79
+ s->cfg0 = s->cfg0_reset;
80
s->cfg1 = 0;
81
s->cfg2 = 0;
82
s->cfg5 = 0;
83
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_init(Object *obj)
84
85
memory_region_init_io(&s->iomem, obj, &mps2_scc_ops, s, "mps2-scc", 0x1000);
86
sysbus_init_mmio(sbd, &s->iomem);
87
+ qdev_init_gpio_out_named(DEVICE(obj), &s->remap, "remap", 1);
88
}
84
}
89
85
90
static void mps2_scc_realize(DeviceState *dev, Error **errp)
86
static void aspeed_soc_realize(DeviceState *dev, Error **errp)
91
@@ -XXX,XX +XXX,XX @@ static Property mps2_scc_properties[] = {
87
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
92
DEFINE_PROP_UINT32("scc-cfg4", MPS2SCC, cfg4, 0),
88
sc->info->memmap[ASPEED_XDMA]);
93
DEFINE_PROP_UINT32("scc-aid", MPS2SCC, aid, 0),
89
sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0,
94
DEFINE_PROP_UINT32("scc-id", MPS2SCC, id, 0),
90
aspeed_soc_get_irq(s, ASPEED_XDMA));
95
+ /* Reset value for CFG0 register */
91
+
96
+ DEFINE_PROP_UINT32("scc-cfg0", MPS2SCC, cfg0_reset, 0),
92
+ /* GPIO */
97
/*
93
+ object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
98
* These are the initial settings for the source clocks on the board.
94
+ if (err) {
99
* In hardware they can be configured via a config file read by the
95
+ error_propagate(errp, err);
96
+ return;
97
+ }
98
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->info->memmap[ASPEED_GPIO]);
99
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
100
+ aspeed_soc_get_irq(s, ASPEED_GPIO));
101
}
102
static Property aspeed_soc_properties[] = {
103
DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
100
--
104
--
101
2.20.1
105
2.20.1
102
106
103
107
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Cédric Le Goater <clg@kaod.org>
2
2
3
The i.MX25 PDK board has 2 banks for SDRAM, each can
3
There are no QEMU Aspeed machines using the SoCs "ast2400-a0" or
4
address up to 256 MiB. So the total RAM usable for this
4
"ast2400".
5
board is 512M. When we ask for more we get a misleading
6
error message:
7
5
8
$ qemu-system-arm -M imx25-pdk -m 513M
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
qemu-system-arm: Invalid RAM size, should be 128 MiB
7
Message-id: 20190904070506.1052-4-clg@kaod.org
10
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Update the error message to better match the reality:
12
13
$ qemu-system-arm -M imx25-pdk -m 513M
14
qemu-system-arm: RAM size more than 512 MiB is not supported
15
16
Fixes: bf350daae02 ("arm/imx25_pdk: drop RAM size fixup")
17
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
20
Message-id: 20210407225608.1882855-1-f4bug@amsat.org
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
10
---
23
hw/arm/imx25_pdk.c | 5 ++---
11
hw/arm/aspeed_soc.c | 26 --------------------------
24
1 file changed, 2 insertions(+), 3 deletions(-)
12
1 file changed, 26 deletions(-)
25
13
26
diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c
14
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
27
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/arm/imx25_pdk.c
16
--- a/hw/arm/aspeed_soc.c
29
+++ b/hw/arm/imx25_pdk.c
17
+++ b/hw/arm/aspeed_soc.c
30
@@ -XXX,XX +XXX,XX @@ static struct arm_boot_info imx25_pdk_binfo;
18
@@ -XXX,XX +XXX,XX @@ static const char *aspeed_soc_ast2500_typenames[] = {
31
19
32
static void imx25_pdk_init(MachineState *machine)
20
static const AspeedSoCInfo aspeed_socs[] = {
33
{
21
{
34
- MachineClass *mc = MACHINE_GET_CLASS(machine);
22
- .name = "ast2400-a0",
35
IMX25PDK *s = g_new0(IMX25PDK, 1);
23
- .cpu_type = ARM_CPU_TYPE_NAME("arm926"),
36
unsigned int ram_size;
24
- .silicon_rev = AST2400_A0_SILICON_REV,
37
unsigned int alias_offset;
25
- .sram_size = 0x8000,
38
@@ -XXX,XX +XXX,XX @@ static void imx25_pdk_init(MachineState *machine)
26
- .spis_num = 1,
39
27
- .fmc_typename = "aspeed.smc.fmc",
40
/* We need to initialize our memory */
28
- .spi_typename = aspeed_soc_ast2400_typenames,
41
if (machine->ram_size > (FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE)) {
29
- .gpio_typename = "aspeed.gpio-ast2400",
42
- char *sz = size_to_str(mc->default_ram_size);
30
- .wdts_num = 2,
43
- error_report("Invalid RAM size, should be %s", sz);
31
- .irqmap = aspeed_soc_ast2400_irqmap,
44
+ char *sz = size_to_str(FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE);
32
- .memmap = aspeed_soc_ast2400_memmap,
45
+ error_report("RAM size more than %s is not supported", sz);
33
- .num_cpus = 1,
46
g_free(sz);
34
- }, {
47
exit(EXIT_FAILURE);
35
.name = "ast2400-a1",
48
}
36
.cpu_type = ARM_CPU_TYPE_NAME("arm926"),
37
.silicon_rev = AST2400_A1_SILICON_REV,
38
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
39
.irqmap = aspeed_soc_ast2400_irqmap,
40
.memmap = aspeed_soc_ast2400_memmap,
41
.num_cpus = 1,
42
- }, {
43
- .name = "ast2400",
44
- .cpu_type = ARM_CPU_TYPE_NAME("arm926"),
45
- .silicon_rev = AST2400_A0_SILICON_REV,
46
- .sram_size = 0x8000,
47
- .spis_num = 1,
48
- .fmc_typename = "aspeed.smc.fmc",
49
- .spi_typename = aspeed_soc_ast2400_typenames,
50
- .gpio_typename = "aspeed.gpio-ast2400",
51
- .wdts_num = 2,
52
- .irqmap = aspeed_soc_ast2400_irqmap,
53
- .memmap = aspeed_soc_ast2400_memmap,
54
- .num_cpus = 1,
55
}, {
56
.name = "ast2500-a1",
57
.cpu_type = ARM_CPU_TYPE_NAME("arm1176"),
49
--
58
--
50
2.20.1
59
2.20.1
51
60
52
61
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Cédric Le Goater <clg@kaod.org>
2
2
3
A trailing _ makes all the difference to the rendered link.
3
Improve the naming of the different controller models to ease their
4
generation when initializing the SoC. The rename of the SMC types is
5
breaking migration compatibility.
4
6
5
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Message-id: 20210428131316.31390-1-alex.bennee@linaro.org
8
Message-id: 20190904070506.1052-5-clg@kaod.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
11
---
10
docs/system/arm/sbsa.rst | 2 +-
12
include/hw/arm/aspeed_soc.h | 3 ---
11
1 file changed, 1 insertion(+), 1 deletion(-)
13
hw/arm/aspeed_soc.c | 25 ++++++++++++-------------
14
hw/ssi/aspeed_smc.c | 12 ++++++------
15
3 files changed, 18 insertions(+), 22 deletions(-)
12
16
13
diff --git a/docs/system/arm/sbsa.rst b/docs/system/arm/sbsa.rst
17
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/docs/system/arm/sbsa.rst
19
--- a/include/hw/arm/aspeed_soc.h
16
+++ b/docs/system/arm/sbsa.rst
20
+++ b/include/hw/arm/aspeed_soc.h
17
@@ -XXX,XX +XXX,XX @@ Arm Server Base System Architecture Reference board (``sbsa-ref``)
21
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCInfo {
18
While the `virt` board is a generic board platform that doesn't match
22
uint32_t silicon_rev;
19
any real hardware the `sbsa-ref` board intends to look like real
23
uint64_t sram_size;
20
hardware. The `Server Base System Architecture
24
int spis_num;
21
-<https://developer.arm.com/documentation/den0029/latest>` defines a
25
- const char *fmc_typename;
22
+<https://developer.arm.com/documentation/den0029/latest>`_ defines a
26
- const char **spi_typename;
23
minimum base line of hardware support and importantly how the firmware
27
- const char *gpio_typename;
24
reports that to any operating system. It is a static system that
28
int wdts_num;
25
reports a very minimal DT to the firmware for non-discoverable
29
const int *irqmap;
30
const hwaddr *memmap;
31
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/arm/aspeed_soc.c
34
+++ b/hw/arm/aspeed_soc.c
35
@@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast2400_irqmap[] = {
36
37
#define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
38
39
-static const char *aspeed_soc_ast2400_typenames[] = { "aspeed.smc.spi" };
40
-static const char *aspeed_soc_ast2500_typenames[] = {
41
- "aspeed.smc.ast2500-spi1", "aspeed.smc.ast2500-spi2" };
42
-
43
static const AspeedSoCInfo aspeed_socs[] = {
44
{
45
.name = "ast2400-a1",
46
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
47
.silicon_rev = AST2400_A1_SILICON_REV,
48
.sram_size = 0x8000,
49
.spis_num = 1,
50
- .fmc_typename = "aspeed.smc.fmc",
51
- .spi_typename = aspeed_soc_ast2400_typenames,
52
- .gpio_typename = "aspeed.gpio-ast2400",
53
.wdts_num = 2,
54
.irqmap = aspeed_soc_ast2400_irqmap,
55
.memmap = aspeed_soc_ast2400_memmap,
56
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
57
.silicon_rev = AST2500_A1_SILICON_REV,
58
.sram_size = 0x9000,
59
.spis_num = 2,
60
- .fmc_typename = "aspeed.smc.ast2500-fmc",
61
- .spi_typename = aspeed_soc_ast2500_typenames,
62
- .gpio_typename = "aspeed.gpio-ast2500",
63
.wdts_num = 3,
64
.irqmap = aspeed_soc_ast2500_irqmap,
65
.memmap = aspeed_soc_ast2500_memmap,
66
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
67
AspeedSoCState *s = ASPEED_SOC(obj);
68
AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s);
69
int i;
70
+ char socname[8];
71
+ char typename[64];
72
+
73
+ if (sscanf(sc->info->name, "%7s", socname) != 1) {
74
+ g_assert_not_reached();
75
+ }
76
77
for (i = 0; i < sc->info->num_cpus; i++) {
78
object_initialize_child(obj, "cpu[*]", OBJECT(&s->cpu[i]),
79
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
80
sysbus_init_child_obj(obj, "i2c", OBJECT(&s->i2c), sizeof(s->i2c),
81
TYPE_ASPEED_I2C);
82
83
+ snprintf(typename, sizeof(typename), "aspeed.fmc-%s", socname);
84
sysbus_init_child_obj(obj, "fmc", OBJECT(&s->fmc), sizeof(s->fmc),
85
- sc->info->fmc_typename);
86
+ typename);
87
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
88
&error_abort);
89
90
for (i = 0; i < sc->info->spis_num; i++) {
91
+ snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
92
sysbus_init_child_obj(obj, "spi[*]", OBJECT(&s->spi[i]),
93
- sizeof(s->spi[i]), sc->info->spi_typename[i]);
94
+ sizeof(s->spi[i]), typename);
95
}
96
97
sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc),
98
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
99
sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
100
TYPE_ASPEED_XDMA);
101
102
+ snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
103
sysbus_init_child_obj(obj, "gpio", OBJECT(&s->gpio), sizeof(s->gpio),
104
- sc->info->gpio_typename);
105
+ typename);
106
}
107
108
static void aspeed_soc_realize(DeviceState *dev, Error **errp)
109
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
110
index XXXXXXX..XXXXXXX 100644
111
--- a/hw/ssi/aspeed_smc.c
112
+++ b/hw/ssi/aspeed_smc.c
113
@@ -XXX,XX +XXX,XX @@ static const AspeedSegments aspeed_segments_ast2500_spi2[] = {
114
115
static const AspeedSMCController controllers[] = {
116
{
117
- .name = "aspeed.smc.smc",
118
+ .name = "aspeed.smc-ast2400",
119
.r_conf = R_CONF,
120
.r_ce_ctrl = R_CE_CTRL,
121
.r_ctrl0 = R_CTRL0,
122
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
123
.has_dma = false,
124
.nregs = ASPEED_SMC_R_SMC_MAX,
125
}, {
126
- .name = "aspeed.smc.fmc",
127
+ .name = "aspeed.fmc-ast2400",
128
.r_conf = R_CONF,
129
.r_ce_ctrl = R_CE_CTRL,
130
.r_ctrl0 = R_CTRL0,
131
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
132
.has_dma = true,
133
.nregs = ASPEED_SMC_R_MAX,
134
}, {
135
- .name = "aspeed.smc.spi",
136
+ .name = "aspeed.spi1-ast2400",
137
.r_conf = R_SPI_CONF,
138
.r_ce_ctrl = 0xff,
139
.r_ctrl0 = R_SPI_CTRL0,
140
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
141
.has_dma = false,
142
.nregs = ASPEED_SMC_R_SPI_MAX,
143
}, {
144
- .name = "aspeed.smc.ast2500-fmc",
145
+ .name = "aspeed.fmc-ast2500",
146
.r_conf = R_CONF,
147
.r_ce_ctrl = R_CE_CTRL,
148
.r_ctrl0 = R_CTRL0,
149
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
150
.has_dma = true,
151
.nregs = ASPEED_SMC_R_MAX,
152
}, {
153
- .name = "aspeed.smc.ast2500-spi1",
154
+ .name = "aspeed.spi1-ast2500",
155
.r_conf = R_CONF,
156
.r_ce_ctrl = R_CE_CTRL,
157
.r_ctrl0 = R_CTRL0,
158
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
159
.has_dma = false,
160
.nregs = ASPEED_SMC_R_MAX,
161
}, {
162
- .name = "aspeed.smc.ast2500-spi2",
163
+ .name = "aspeed.spi2-ast2500",
164
.r_conf = R_CONF,
165
.r_ce_ctrl = R_CE_CTRL,
166
.r_ctrl0 = R_CTRL0,
26
--
167
--
27
2.20.1
168
2.20.1
28
169
29
170
diff view generated by jsdifflib
1
Some of the constant expanders defined in translate.c are generically
1
From: Cédric Le Goater <clg@kaod.org>
2
useful and will be used by the separate C files for VFP and Neon once
2
3
they are created; move the expander definitions to translate.h.
3
The FMC controller on the Aspeed SoCs support DMA to access the flash
4
4
modules. It can operate in a normal mode, to copy to or from the flash
5
module mapping window, or in a checksum calculation mode, to evaluate
6
the best clock settings for reads.
7
8
The model introduces two custom address spaces for DMAs: one for the
9
AHB window of the FMC flash devices and one for the DRAM. The latter
10
is populated using a "dram" link set from the machine with the RAM
11
container region.
12
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Acked-by: Joel Stanley <joel@jms.id.au>
15
Message-id: 20190904070506.1052-6-clg@kaod.org
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
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: 20210430132740.10391-2-peter.maydell@linaro.org
9
---
18
---
10
target/arm/translate.h | 24 ++++++++++++++++++++++++
19
include/hw/ssi/aspeed_smc.h | 6 +
11
target/arm/translate.c | 24 ------------------------
20
hw/arm/aspeed.c | 2 +
12
2 files changed, 24 insertions(+), 24 deletions(-)
21
hw/arm/aspeed_soc.c | 2 +
13
22
hw/ssi/aspeed_smc.c | 222 +++++++++++++++++++++++++++++++++++-
14
diff --git a/target/arm/translate.h b/target/arm/translate.h
23
4 files changed, 226 insertions(+), 6 deletions(-)
24
25
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
15
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.h
27
--- a/include/hw/ssi/aspeed_smc.h
17
+++ b/target/arm/translate.h
28
+++ b/include/hw/ssi/aspeed_smc.h
18
@@ -XXX,XX +XXX,XX @@ extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCController {
19
extern TCGv_i64 cpu_exclusive_addr;
30
hwaddr flash_window_base;
20
extern TCGv_i64 cpu_exclusive_val;
31
uint32_t flash_window_size;
32
bool has_dma;
33
+ hwaddr dma_flash_mask;
34
+ hwaddr dma_dram_mask;
35
uint32_t nregs;
36
} AspeedSMCController;
37
38
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCState {
39
/* for DMA support */
40
uint64_t sdram_base;
41
42
+ AddressSpace flash_as;
43
+ MemoryRegion *dram_mr;
44
+ AddressSpace dram_as;
45
+
46
AspeedSMCFlash *flashes;
47
48
uint8_t snoop_index;
49
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/aspeed.c
52
+++ b/hw/arm/aspeed.c
53
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
54
&error_abort);
55
object_property_set_int(OBJECT(&bmc->soc), machine->smp.cpus, "num-cpus",
56
&error_abort);
57
+ object_property_set_link(OBJECT(&bmc->soc), OBJECT(&bmc->ram_container),
58
+ "dram", &error_abort);
59
if (machine->kernel_filename) {
60
/*
61
* When booting with a -kernel command line there is no u-boot
62
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/arm/aspeed_soc.c
65
+++ b/hw/arm/aspeed_soc.c
66
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
67
typename);
68
object_property_add_alias(obj, "num-cs", OBJECT(&s->fmc), "num-cs",
69
&error_abort);
70
+ object_property_add_alias(obj, "dram", OBJECT(&s->fmc), "dram",
71
+ &error_abort);
72
73
for (i = 0; i < sc->info->spis_num; i++) {
74
snprintf(typename, sizeof(typename), "aspeed.spi%d-%s", i + 1, socname);
75
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/hw/ssi/aspeed_smc.c
78
+++ b/hw/ssi/aspeed_smc.c
79
@@ -XXX,XX +XXX,XX @@
80
#include "qemu/log.h"
81
#include "qemu/module.h"
82
#include "qemu/error-report.h"
83
+#include "qapi/error.h"
84
+#include "exec/address-spaces.h"
85
86
#include "hw/irq.h"
87
#include "hw/qdev-properties.h"
88
@@ -XXX,XX +XXX,XX @@
89
#define DMA_CTRL_FREQ_SHIFT 4
90
#define DMA_CTRL_MODE (1 << 3)
91
#define DMA_CTRL_CKSUM (1 << 2)
92
-#define DMA_CTRL_DIR (1 << 1)
93
-#define DMA_CTRL_EN (1 << 0)
94
+#define DMA_CTRL_WRITE (1 << 1)
95
+#define DMA_CTRL_ENABLE (1 << 0)
96
97
/* DMA Flash Side Address */
98
#define R_DMA_FLASH_ADDR (0x84 / 4)
99
@@ -XXX,XX +XXX,XX @@
100
#define ASPEED_SOC_SPI_FLASH_BASE 0x30000000
101
#define ASPEED_SOC_SPI2_FLASH_BASE 0x38000000
21
102
22
+/*
103
+/*
23
+ * Constant expanders for the decoders.
104
+ * DMA DRAM addresses should be 4 bytes aligned and the valid address
105
+ * range is 0x40000000 - 0x5FFFFFFF (AST2400)
106
+ * 0x80000000 - 0xBFFFFFFF (AST2500)
107
+ *
108
+ * DMA flash addresses should be 4 bytes aligned and the valid address
109
+ * range is 0x20000000 - 0x2FFFFFFF.
110
+ *
111
+ * DMA length is from 4 bytes to 32MB
112
+ * 0: 4 bytes
113
+ * 0x7FFFFF: 32M bytes
24
+ */
114
+ */
25
+
115
+#define DMA_DRAM_ADDR(s, val) ((s)->sdram_base | \
26
+static inline int negate(DisasContext *s, int x)
116
+ ((val) & (s)->ctrl->dma_dram_mask))
27
+{
117
+#define DMA_FLASH_ADDR(s, val) ((s)->ctrl->flash_window_base | \
28
+ return -x;
118
+ ((val) & (s)->ctrl->dma_flash_mask))
29
+}
119
+#define DMA_LENGTH(val) ((val) & 0x01FFFFFC)
30
+
120
+
31
+static inline int plus_2(DisasContext *s, int x)
121
/* Flash opcodes. */
32
+{
122
#define SPI_OP_READ 0x03 /* Read data bytes (low frequency) */
33
+ return x + 2;
123
34
+}
124
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
35
+
125
.flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
36
+static inline int times_2(DisasContext *s, int x)
126
.flash_window_size = 0x10000000,
37
+{
127
.has_dma = true,
38
+ return x * 2;
128
+ .dma_flash_mask = 0x0FFFFFFC,
39
+}
129
+ .dma_dram_mask = 0x1FFFFFFC,
40
+
130
.nregs = ASPEED_SMC_R_MAX,
41
+static inline int times_4(DisasContext *s, int x)
131
}, {
42
+{
132
.name = "aspeed.spi1-ast2400",
43
+ return x * 4;
133
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
44
+}
134
.flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
45
+
135
.flash_window_size = 0x10000000,
46
static inline int arm_dc_feature(DisasContext *dc, int feature)
136
.has_dma = true,
47
{
137
+ .dma_flash_mask = 0x0FFFFFFC,
48
return (dc->features & (1ULL << feature)) != 0;
138
+ .dma_dram_mask = 0x3FFFFFFC,
49
diff --git a/target/arm/translate.c b/target/arm/translate.c
139
.nregs = ASPEED_SMC_R_MAX,
50
index XXXXXXX..XXXXXXX 100644
140
}, {
51
--- a/target/arm/translate.c
141
.name = "aspeed.spi1-ast2500",
52
+++ b/target/arm/translate.c
142
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
53
@@ -XXX,XX +XXX,XX @@ static void arm_gen_condlabel(DisasContext *s)
143
144
memset(s->regs, 0, sizeof s->regs);
145
146
- /* Pretend DMA is done (u-boot initialization) */
147
- s->regs[R_INTR_CTRL] = INTR_CTRL_DMA_STATUS;
148
-
149
/* Unselect all slaves */
150
for (i = 0; i < s->num_cs; ++i) {
151
s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
152
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
153
addr == s->r_ce_ctrl ||
154
addr == R_INTR_CTRL ||
155
addr == R_DUMMY_DATA ||
156
+ (s->ctrl->has_dma && addr == R_DMA_CTRL) ||
157
+ (s->ctrl->has_dma && addr == R_DMA_FLASH_ADDR) ||
158
+ (s->ctrl->has_dma && addr == R_DMA_DRAM_ADDR) ||
159
+ (s->ctrl->has_dma && addr == R_DMA_LEN) ||
160
+ (s->ctrl->has_dma && addr == R_DMA_CHECKSUM) ||
161
(addr >= R_SEG_ADDR0 && addr < R_SEG_ADDR0 + s->ctrl->max_slaves) ||
162
(addr >= s->r_ctrl0 && addr < s->r_ctrl0 + s->ctrl->max_slaves)) {
163
return s->regs[addr];
164
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
54
}
165
}
55
}
166
}
56
167
57
-/*
168
+/*
58
- * Constant expanders for the decoders.
169
+ * Accumulate the result of the reads to provide a checksum that will
59
- */
170
+ * be used to validate the read timing settings.
60
-
171
+ */
61
-static int negate(DisasContext *s, int x)
172
+static void aspeed_smc_dma_checksum(AspeedSMCState *s)
62
-{
173
+{
63
- return -x;
174
+ MemTxResult result;
64
-}
175
+ uint32_t data;
65
-
176
+
66
-static int plus_2(DisasContext *s, int x)
177
+ if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
67
-{
178
+ qemu_log_mask(LOG_GUEST_ERROR,
68
- return x + 2;
179
+ "%s: invalid direction for DMA checksum\n", __func__);
69
-}
180
+ return;
70
-
181
+ }
71
-static int times_2(DisasContext *s, int x)
182
+
72
-{
183
+ while (s->regs[R_DMA_LEN]) {
73
- return x * 2;
184
+ data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
74
-}
185
+ MEMTXATTRS_UNSPECIFIED, &result);
75
-
186
+ if (result != MEMTX_OK) {
76
-static int times_4(DisasContext *s, int x)
187
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash read failed @%08x\n",
77
-{
188
+ __func__, s->regs[R_DMA_FLASH_ADDR]);
78
- return x * 4;
189
+ return;
79
-}
190
+ }
80
-
191
+
81
/* Flags for the disas_set_da_iss info argument:
192
+ /*
82
* lower bits hold the Rt register number, higher bits are flags.
193
+ * When the DMA is on-going, the DMA registers are updated
83
*/
194
+ * with the current working addresses and length.
195
+ */
196
+ s->regs[R_DMA_CHECKSUM] += data;
197
+ s->regs[R_DMA_FLASH_ADDR] += 4;
198
+ s->regs[R_DMA_LEN] -= 4;
199
+ }
200
+}
201
+
202
+static void aspeed_smc_dma_rw(AspeedSMCState *s)
203
+{
204
+ MemTxResult result;
205
+ uint32_t data;
206
+
207
+ while (s->regs[R_DMA_LEN]) {
208
+ if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
209
+ data = address_space_ldl_le(&s->dram_as, s->regs[R_DMA_DRAM_ADDR],
210
+ MEMTXATTRS_UNSPECIFIED, &result);
211
+ if (result != MEMTX_OK) {
212
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM read failed @%08x\n",
213
+ __func__, s->regs[R_DMA_DRAM_ADDR]);
214
+ return;
215
+ }
216
+
217
+ address_space_stl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
218
+ data, MEMTXATTRS_UNSPECIFIED, &result);
219
+ if (result != MEMTX_OK) {
220
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash write failed @%08x\n",
221
+ __func__, s->regs[R_DMA_FLASH_ADDR]);
222
+ return;
223
+ }
224
+ } else {
225
+ data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
226
+ MEMTXATTRS_UNSPECIFIED, &result);
227
+ if (result != MEMTX_OK) {
228
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash read failed @%08x\n",
229
+ __func__, s->regs[R_DMA_FLASH_ADDR]);
230
+ return;
231
+ }
232
+
233
+ address_space_stl_le(&s->dram_as, s->regs[R_DMA_DRAM_ADDR],
234
+ data, MEMTXATTRS_UNSPECIFIED, &result);
235
+ if (result != MEMTX_OK) {
236
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed @%08x\n",
237
+ __func__, s->regs[R_DMA_DRAM_ADDR]);
238
+ return;
239
+ }
240
+ }
241
+
242
+ /*
243
+ * When the DMA is on-going, the DMA registers are updated
244
+ * with the current working addresses and length.
245
+ */
246
+ s->regs[R_DMA_FLASH_ADDR] += 4;
247
+ s->regs[R_DMA_DRAM_ADDR] += 4;
248
+ s->regs[R_DMA_LEN] -= 4;
249
+ }
250
+}
251
+
252
+static void aspeed_smc_dma_stop(AspeedSMCState *s)
253
+{
254
+ /*
255
+ * When the DMA is disabled, INTR_CTRL_DMA_STATUS=0 means the
256
+ * engine is idle
257
+ */
258
+ s->regs[R_INTR_CTRL] &= ~INTR_CTRL_DMA_STATUS;
259
+ s->regs[R_DMA_CHECKSUM] = 0;
260
+
261
+ /*
262
+ * Lower the DMA irq in any case. The IRQ control register could
263
+ * have been cleared before disabling the DMA.
264
+ */
265
+ qemu_irq_lower(s->irq);
266
+}
267
+
268
+/*
269
+ * When INTR_CTRL_DMA_STATUS=1, the DMA has completed and a new DMA
270
+ * can start even if the result of the previous was not collected.
271
+ */
272
+static bool aspeed_smc_dma_in_progress(AspeedSMCState *s)
273
+{
274
+ return s->regs[R_DMA_CTRL] & DMA_CTRL_ENABLE &&
275
+ !(s->regs[R_INTR_CTRL] & INTR_CTRL_DMA_STATUS);
276
+}
277
+
278
+static void aspeed_smc_dma_done(AspeedSMCState *s)
279
+{
280
+ s->regs[R_INTR_CTRL] |= INTR_CTRL_DMA_STATUS;
281
+ if (s->regs[R_INTR_CTRL] & INTR_CTRL_DMA_EN) {
282
+ qemu_irq_raise(s->irq);
283
+ }
284
+}
285
+
286
+static void aspeed_smc_dma_ctrl(AspeedSMCState *s, uint64_t dma_ctrl)
287
+{
288
+ if (!(dma_ctrl & DMA_CTRL_ENABLE)) {
289
+ s->regs[R_DMA_CTRL] = dma_ctrl;
290
+
291
+ aspeed_smc_dma_stop(s);
292
+ return;
293
+ }
294
+
295
+ if (aspeed_smc_dma_in_progress(s)) {
296
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: DMA in progress\n", __func__);
297
+ return;
298
+ }
299
+
300
+ s->regs[R_DMA_CTRL] = dma_ctrl;
301
+
302
+ if (s->regs[R_DMA_CTRL] & DMA_CTRL_CKSUM) {
303
+ aspeed_smc_dma_checksum(s);
304
+ } else {
305
+ aspeed_smc_dma_rw(s);
306
+ }
307
+
308
+ aspeed_smc_dma_done(s);
309
+}
310
+
311
static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
312
unsigned int size)
313
{
314
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
315
}
316
} else if (addr == R_DUMMY_DATA) {
317
s->regs[addr] = value & 0xff;
318
+ } else if (addr == R_INTR_CTRL) {
319
+ s->regs[addr] = value;
320
+ } else if (s->ctrl->has_dma && addr == R_DMA_CTRL) {
321
+ aspeed_smc_dma_ctrl(s, value);
322
+ } else if (s->ctrl->has_dma && addr == R_DMA_DRAM_ADDR) {
323
+ s->regs[addr] = DMA_DRAM_ADDR(s, value);
324
+ } else if (s->ctrl->has_dma && addr == R_DMA_FLASH_ADDR) {
325
+ s->regs[addr] = DMA_FLASH_ADDR(s, value);
326
+ } else if (s->ctrl->has_dma && addr == R_DMA_LEN) {
327
+ s->regs[addr] = DMA_LENGTH(value);
328
} else {
329
qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
330
__func__, addr);
331
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps aspeed_smc_ops = {
332
.valid.unaligned = true,
333
};
334
335
+
336
+/*
337
+ * Initialize the custom address spaces for DMAs
338
+ */
339
+static void aspeed_smc_dma_setup(AspeedSMCState *s, Error **errp)
340
+{
341
+ char *name;
342
+
343
+ if (!s->dram_mr) {
344
+ error_setg(errp, TYPE_ASPEED_SMC ": 'dram' link not set");
345
+ return;
346
+ }
347
+
348
+ name = g_strdup_printf("%s-dma-flash", s->ctrl->name);
349
+ address_space_init(&s->flash_as, &s->mmio_flash, name);
350
+ g_free(name);
351
+
352
+ name = g_strdup_printf("%s-dma-dram", s->ctrl->name);
353
+ address_space_init(&s->dram_as, s->dram_mr, name);
354
+ g_free(name);
355
+}
356
+
357
static void aspeed_smc_realize(DeviceState *dev, Error **errp)
358
{
359
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
360
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
361
s->num_cs = s->ctrl->max_slaves;
362
}
363
364
+ /* DMA irq. Keep it first for the initialization in the SoC */
365
+ sysbus_init_irq(sbd, &s->irq);
366
+
367
s->spi = ssi_create_bus(dev, "spi");
368
369
/* Setup cs_lines for slaves */
370
- sysbus_init_irq(sbd, &s->irq);
371
s->cs_lines = g_new0(qemu_irq, s->num_cs);
372
ssi_auto_connect_slaves(dev, s->cs_lines, s->spi);
373
374
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
375
memory_region_add_subregion(&s->mmio_flash, offset, &fl->mmio);
376
offset += fl->size;
377
}
378
+
379
+ /* DMA support */
380
+ if (s->ctrl->has_dma) {
381
+ aspeed_smc_dma_setup(s, errp);
382
+ }
383
}
384
385
static const VMStateDescription vmstate_aspeed_smc = {
386
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_smc = {
387
static Property aspeed_smc_properties[] = {
388
DEFINE_PROP_UINT32("num-cs", AspeedSMCState, num_cs, 1),
389
DEFINE_PROP_UINT64("sdram-base", AspeedSMCState, sdram_base, 0),
390
+ DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
391
+ TYPE_MEMORY_REGION, MemoryRegion *),
392
DEFINE_PROP_END_OF_LIST(),
393
};
394
84
--
395
--
85
2.20.1
396
2.20.1
86
397
87
398
diff view generated by jsdifflib
1
The functions vfp_load_reg32(), vfp_load_reg64(), vfp_store_reg32()
1
From: Cédric Le Goater <clg@kaod.org>
2
and vfp_store_reg64() are used only in translate-vfp.c.inc. Move
3
them to that file.
4
2
3
When doing calibration, the SPI clock rate in the CE0 Control Register
4
and the read delay cycles in the Read Timing Compensation Register are
5
set using bit[11:4] of the DMA Control Register.
6
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Acked-by: Joel Stanley <joel@jms.id.au>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20190904070506.1052-7-clg@kaod.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: 20210430132740.10391-7-peter.maydell@linaro.org
9
---
12
---
10
target/arm/translate.c | 20 --------------------
13
hw/ssi/aspeed_smc.c | 64 ++++++++++++++++++++++++++++++++++++++++++++-
11
target/arm/translate-vfp.c.inc | 20 ++++++++++++++++++++
14
1 file changed, 63 insertions(+), 1 deletion(-)
12
2 files changed, 20 insertions(+), 20 deletions(-)
13
15
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
18
--- a/hw/ssi/aspeed_smc.c
17
+++ b/target/arm/translate.c
19
+++ b/hw/ssi/aspeed_smc.c
18
@@ -XXX,XX +XXX,XX @@ static long vfp_reg_offset(bool dp, unsigned reg)
20
@@ -XXX,XX +XXX,XX @@
21
#define CTRL_CMD_MASK 0xff
22
#define CTRL_DUMMY_HIGH_SHIFT 14
23
#define CTRL_AST2400_SPI_4BYTE (1 << 13)
24
+#define CE_CTRL_CLOCK_FREQ_SHIFT 8
25
+#define CE_CTRL_CLOCK_FREQ_MASK 0xf
26
+#define CE_CTRL_CLOCK_FREQ(div) \
27
+ (((div) & CE_CTRL_CLOCK_FREQ_MASK) << CE_CTRL_CLOCK_FREQ_SHIFT)
28
#define CTRL_DUMMY_LOW_SHIFT 6 /* 2 bits [7:6] */
29
#define CTRL_CE_STOP_ACTIVE (1 << 2)
30
#define CTRL_CMD_MODE_MASK 0x3
31
@@ -XXX,XX +XXX,XX @@
32
#define DMA_CTRL_DELAY_SHIFT 8
33
#define DMA_CTRL_FREQ_MASK 0xf
34
#define DMA_CTRL_FREQ_SHIFT 4
35
-#define DMA_CTRL_MODE (1 << 3)
36
+#define DMA_CTRL_CALIB (1 << 3)
37
#define DMA_CTRL_CKSUM (1 << 2)
38
#define DMA_CTRL_WRITE (1 << 1)
39
#define DMA_CTRL_ENABLE (1 << 0)
40
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
19
}
41
}
20
}
42
}
21
43
22
-static inline void vfp_load_reg64(TCGv_i64 var, int reg)
44
+static uint8_t aspeed_smc_hclk_divisor(uint8_t hclk_mask)
23
-{
24
- tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
25
-}
26
-
27
-static inline void vfp_store_reg64(TCGv_i64 var, int reg)
28
-{
29
- tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
30
-}
31
-
32
-static inline void vfp_load_reg32(TCGv_i32 var, int reg)
33
-{
34
- tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
35
-}
36
-
37
-static inline void vfp_store_reg32(TCGv_i32 var, int reg)
38
-{
39
- tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
40
-}
41
-
42
void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
43
{
44
long off = neon_element_offset(reg, ele, memop);
45
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/arm/translate-vfp.c.inc
48
+++ b/target/arm/translate-vfp.c.inc
49
@@ -XXX,XX +XXX,XX @@
50
#include "decode-vfp.c.inc"
51
#include "decode-vfp-uncond.c.inc"
52
53
+static inline void vfp_load_reg64(TCGv_i64 var, int reg)
54
+{
45
+{
55
+ tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
46
+ /* HCLK/1 .. HCLK/16 */
47
+ const uint8_t hclk_divisors[] = {
48
+ 15, 7, 14, 6, 13, 5, 12, 4, 11, 3, 10, 2, 9, 1, 8, 0
49
+ };
50
+ int i;
51
+
52
+ for (i = 0; i < ARRAY_SIZE(hclk_divisors); i++) {
53
+ if (hclk_mask == hclk_divisors[i]) {
54
+ return i + 1;
55
+ }
56
+ }
57
+
58
+ qemu_log_mask(LOG_GUEST_ERROR, "invalid HCLK mask %x", hclk_mask);
59
+ return 0;
56
+}
60
+}
57
+
61
+
58
+static inline void vfp_store_reg64(TCGv_i64 var, int reg)
62
+/*
63
+ * When doing calibration, the SPI clock rate in the CE0 Control
64
+ * Register and the read delay cycles in the Read Timing Compensation
65
+ * Register are set using bit[11:4] of the DMA Control Register.
66
+ */
67
+static void aspeed_smc_dma_calibration(AspeedSMCState *s)
59
+{
68
+{
60
+ tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
69
+ uint8_t delay =
61
+}
70
+ (s->regs[R_DMA_CTRL] >> DMA_CTRL_DELAY_SHIFT) & DMA_CTRL_DELAY_MASK;
71
+ uint8_t hclk_mask =
72
+ (s->regs[R_DMA_CTRL] >> DMA_CTRL_FREQ_SHIFT) & DMA_CTRL_FREQ_MASK;
73
+ uint8_t hclk_div = aspeed_smc_hclk_divisor(hclk_mask);
74
+ uint32_t hclk_shift = (hclk_div - 1) << 2;
75
+ uint8_t cs;
62
+
76
+
63
+static inline void vfp_load_reg32(TCGv_i32 var, int reg)
77
+ /*
64
+{
78
+ * The Read Timing Compensation Register values apply to all CS on
65
+ tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
79
+ * the SPI bus and only HCLK/1 - HCLK/5 can have tunable delays
66
+}
80
+ */
81
+ if (hclk_div && hclk_div < 6) {
82
+ s->regs[s->r_timings] &= ~(0xf << hclk_shift);
83
+ s->regs[s->r_timings] |= delay << hclk_shift;
84
+ }
67
+
85
+
68
+static inline void vfp_store_reg32(TCGv_i32 var, int reg)
86
+ /*
69
+{
87
+ * TODO: compute the CS from the DMA address and the segment
70
+ tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
88
+ * registers. This is not really a problem for now because the
89
+ * Timing Register values apply to all CS and software uses CS0 to
90
+ * do calibration.
91
+ */
92
+ cs = 0;
93
+ s->regs[s->r_ctrl0 + cs] &=
94
+ ~(CE_CTRL_CLOCK_FREQ_MASK << CE_CTRL_CLOCK_FREQ_SHIFT);
95
+ s->regs[s->r_ctrl0 + cs] |= CE_CTRL_CLOCK_FREQ(hclk_div);
71
+}
96
+}
72
+
97
+
73
/*
98
/*
74
* The imm8 encodes the sign bit, enough bits to represent an exponent in
99
* Accumulate the result of the reads to provide a checksum that will
75
* the range 01....1xx to 10....0xx, and the most significant 4 bits of
100
* be used to validate the read timing settings.
101
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
102
return;
103
}
104
105
+ if (s->regs[R_DMA_CTRL] & DMA_CTRL_CALIB) {
106
+ aspeed_smc_dma_calibration(s);
107
+ }
108
+
109
while (s->regs[R_DMA_LEN]) {
110
data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
111
MEMTXATTRS_UNSPECIFIED, &result);
76
--
112
--
77
2.20.1
113
2.20.1
78
114
79
115
diff view generated by jsdifflib
1
Move the various gen_aa32* functions and macros out of translate.c
1
From: Cédric Le Goater <clg@kaod.org>
2
and into translate-a32.h.
3
2
3
Emulate read errors in the DMA Checksum Register for high frequencies
4
and optimistic settings of the Read Timing Compensation Register. This
5
will help in tuning the SPI timing calibration algorithm. Errors are
6
only injected when the property "inject_failure" is set to true as
7
suggested by Philippe.
8
9
The values below are those to expect from the first flash device of
10
the FMC controller of a palmetto-bmc machine.
11
12
Cc: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Signed-off-by: Cédric Le Goater <clg@kaod.org>
14
Reviewed-by: Joel Stanley <joel@jms.id.au>
15
Message-id: 20190904070506.1052-8-clg@kaod.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: 20210430132740.10391-6-peter.maydell@linaro.org
8
---
17
---
9
target/arm/translate-a32.h | 53 ++++++++++++++++++++++++++++++++++++++
18
include/hw/ssi/aspeed_smc.h | 1 +
10
target/arm/translate.c | 51 ++++++++++++------------------------
19
hw/ssi/aspeed_smc.c | 36 ++++++++++++++++++++++++++++++++++++
11
2 files changed, 69 insertions(+), 35 deletions(-)
20
2 files changed, 37 insertions(+)
12
21
13
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
22
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
14
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a32.h
24
--- a/include/hw/ssi/aspeed_smc.h
16
+++ b/target/arm/translate-a32.h
25
+++ b/include/hw/ssi/aspeed_smc.h
17
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 load_reg(DisasContext *s, int reg)
26
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCState {
18
return tmp;
27
28
uint32_t num_cs;
29
qemu_irq *cs_lines;
30
+ bool inject_failure;
31
32
SSIBus *spi;
33
34
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/ssi/aspeed_smc.c
37
+++ b/hw/ssi/aspeed_smc.c
38
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_dma_calibration(AspeedSMCState *s)
39
s->regs[s->r_ctrl0 + cs] |= CE_CTRL_CLOCK_FREQ(hclk_div);
19
}
40
}
20
41
21
+void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
42
+/*
22
+ TCGv_i32 a32, int index, MemOp opc);
43
+ * Emulate read errors in the DMA Checksum Register for high
23
+void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
44
+ * frequencies and optimistic settings of the Read Timing Compensation
24
+ TCGv_i32 a32, int index, MemOp opc);
45
+ * Register. This will help in tuning the SPI timing calibration
25
+void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
46
+ * algorithm.
26
+ TCGv_i32 a32, int index, MemOp opc);
47
+ */
27
+void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
48
+static bool aspeed_smc_inject_read_failure(AspeedSMCState *s)
28
+ TCGv_i32 a32, int index, MemOp opc);
49
+{
29
+void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
50
+ uint8_t delay =
30
+ int index, MemOp opc);
51
+ (s->regs[R_DMA_CTRL] >> DMA_CTRL_DELAY_SHIFT) & DMA_CTRL_DELAY_MASK;
31
+void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
52
+ uint8_t hclk_mask =
32
+ int index, MemOp opc);
53
+ (s->regs[R_DMA_CTRL] >> DMA_CTRL_FREQ_SHIFT) & DMA_CTRL_FREQ_MASK;
33
+void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
34
+ int index, MemOp opc);
35
+void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
36
+ int index, MemOp opc);
37
+
54
+
38
+#define DO_GEN_LD(SUFF, OPC) \
55
+ /*
39
+ static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
56
+ * Typical values of a palmetto-bmc machine.
40
+ TCGv_i32 a32, int index) \
57
+ */
41
+ { \
58
+ switch (aspeed_smc_hclk_divisor(hclk_mask)) {
42
+ gen_aa32_ld_i32(s, val, a32, index, OPC); \
59
+ case 4 ... 16:
60
+ return false;
61
+ case 3: /* at least one HCLK cycle delay */
62
+ return (delay & 0x7) < 1;
63
+ case 2: /* at least two HCLK cycle delay */
64
+ return (delay & 0x7) < 2;
65
+ case 1: /* (> 100MHz) is above the max freq of the controller */
66
+ return true;
67
+ default:
68
+ g_assert_not_reached();
69
+ }
70
+}
71
+
72
/*
73
* Accumulate the result of the reads to provide a checksum that will
74
* be used to validate the read timing settings.
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
76
s->regs[R_DMA_FLASH_ADDR] += 4;
77
s->regs[R_DMA_LEN] -= 4;
78
}
79
+
80
+ if (s->inject_failure && aspeed_smc_inject_read_failure(s)) {
81
+ s->regs[R_DMA_CHECKSUM] = 0xbadc0de;
43
+ }
82
+ }
44
+
83
+
45
+#define DO_GEN_ST(SUFF, OPC) \
46
+ static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
47
+ TCGv_i32 a32, int index) \
48
+ { \
49
+ gen_aa32_st_i32(s, val, a32, index, OPC); \
50
+ }
51
+
52
+static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
53
+ TCGv_i32 a32, int index)
54
+{
55
+ gen_aa32_ld_i64(s, val, a32, index, MO_Q);
56
+}
57
+
58
+static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
59
+ TCGv_i32 a32, int index)
60
+{
61
+ gen_aa32_st_i64(s, val, a32, index, MO_Q);
62
+}
63
+
64
+DO_GEN_LD(8u, MO_UB)
65
+DO_GEN_LD(16u, MO_UW)
66
+DO_GEN_LD(32u, MO_UL)
67
+DO_GEN_ST(8, MO_UB)
68
+DO_GEN_ST(16, MO_UW)
69
+DO_GEN_ST(32, MO_UL)
70
+
71
+#undef DO_GEN_LD
72
+#undef DO_GEN_ST
73
+
74
#endif
75
diff --git a/target/arm/translate.c b/target/arm/translate.c
76
index XXXXXXX..XXXXXXX 100644
77
--- a/target/arm/translate.c
78
+++ b/target/arm/translate.c
79
@@ -XXX,XX +XXX,XX @@ static TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
80
* Internal routines are used for NEON cases where the endianness
81
* and/or alignment has already been taken into account and manipulated.
82
*/
83
-static void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
84
- TCGv_i32 a32, int index, MemOp opc)
85
+void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
86
+ TCGv_i32 a32, int index, MemOp opc)
87
{
88
TCGv addr = gen_aa32_addr(s, a32, opc);
89
tcg_gen_qemu_ld_i32(val, addr, index, opc);
90
tcg_temp_free(addr);
91
}
84
}
92
85
93
-static void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
86
static void aspeed_smc_dma_rw(AspeedSMCState *s)
94
- TCGv_i32 a32, int index, MemOp opc)
87
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_smc = {
95
+void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
88
96
+ TCGv_i32 a32, int index, MemOp opc)
89
static Property aspeed_smc_properties[] = {
97
{
90
DEFINE_PROP_UINT32("num-cs", AspeedSMCState, num_cs, 1),
98
TCGv addr = gen_aa32_addr(s, a32, opc);
91
+ DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure, false),
99
tcg_gen_qemu_st_i32(val, addr, index, opc);
92
DEFINE_PROP_UINT64("sdram-base", AspeedSMCState, sdram_base, 0),
100
tcg_temp_free(addr);
93
DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
101
}
94
TYPE_MEMORY_REGION, MemoryRegion *),
102
103
-static void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
104
- TCGv_i32 a32, int index, MemOp opc)
105
+void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
106
+ TCGv_i32 a32, int index, MemOp opc)
107
{
108
TCGv addr = gen_aa32_addr(s, a32, opc);
109
110
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
111
tcg_temp_free(addr);
112
}
113
114
-static void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
115
- TCGv_i32 a32, int index, MemOp opc)
116
+void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
117
+ TCGv_i32 a32, int index, MemOp opc)
118
{
119
TCGv addr = gen_aa32_addr(s, a32, opc);
120
121
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
122
tcg_temp_free(addr);
123
}
124
125
-static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
126
- int index, MemOp opc)
127
+void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
128
+ int index, MemOp opc)
129
{
130
gen_aa32_ld_internal_i32(s, val, a32, index, finalize_memop(s, opc));
131
}
132
133
-static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
134
- int index, MemOp opc)
135
+void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
136
+ int index, MemOp opc)
137
{
138
gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
139
}
140
141
-static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
142
- int index, MemOp opc)
143
+void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
144
+ int index, MemOp opc)
145
{
146
gen_aa32_ld_internal_i64(s, val, a32, index, finalize_memop(s, opc));
147
}
148
149
-static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
150
- int index, MemOp opc)
151
+void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
152
+ int index, MemOp opc)
153
{
154
gen_aa32_st_internal_i64(s, val, a32, index, finalize_memop(s, opc));
155
}
156
@@ -XXX,XX +XXX,XX @@ static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
157
gen_aa32_st_i32(s, val, a32, index, OPC); \
158
}
159
160
-static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
161
- TCGv_i32 a32, int index)
162
-{
163
- gen_aa32_ld_i64(s, val, a32, index, MO_Q);
164
-}
165
-
166
-static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
167
- TCGv_i32 a32, int index)
168
-{
169
- gen_aa32_st_i64(s, val, a32, index, MO_Q);
170
-}
171
-
172
-DO_GEN_LD(8u, MO_UB)
173
-DO_GEN_LD(16u, MO_UW)
174
-DO_GEN_LD(32u, MO_UL)
175
-DO_GEN_ST(8, MO_UB)
176
-DO_GEN_ST(16, MO_UW)
177
-DO_GEN_ST(32, MO_UL)
178
-
179
static inline void gen_hvc(DisasContext *s, int imm16)
180
{
181
/* The pre HVC helper handles cases when HVC gets trapped
182
--
95
--
183
2.20.1
96
2.20.1
184
97
185
98
diff view generated by jsdifflib
1
The unallocated_encoding() function is the same in both
1
From: Christian Svensson <bluecmd@google.com>
2
translate-a64.c and translate.c; make the translate.c function global
3
and drop the translate-a64.c version. To do this we need to also
4
share gen_exception_insn(), which currently exists in two slightly
5
different versions for A32 and A64: merge those into a single
6
function that can work for both.
7
2
8
This will be useful for splitting up translate.c, which will require
3
This patch adds the missing checksum calculation on normal DMA transfer.
9
unallocated_encoding() to no longer be file-local. It's also
4
According to the datasheet this is how the SMC should behave.
10
hopefully less confusing to have only one version of the function
11
rather than two.
12
5
6
Verified on AST1250 that the hardware matches the behaviour.
7
8
Signed-off-by: Christian Svensson <bluecmd@google.com>
9
Reviewed-by: Joel Stanley <joel@jms.id.au>
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20190904070506.1052-9-clg@kaod.org
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20210430132740.10391-3-peter.maydell@linaro.org
16
---
13
---
17
target/arm/translate-a64.h | 2 --
14
hw/ssi/aspeed_smc.c | 1 +
18
target/arm/translate.h | 3 +++
15
1 file changed, 1 insertion(+)
19
target/arm/translate-a64.c | 15 ---------------
20
target/arm/translate.c | 14 +++++++++-----
21
4 files changed, 12 insertions(+), 22 deletions(-)
22
16
23
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
17
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
24
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/translate-a64.h
19
--- a/hw/ssi/aspeed_smc.c
26
+++ b/target/arm/translate-a64.h
20
+++ b/hw/ssi/aspeed_smc.c
27
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_dma_rw(AspeedSMCState *s)
28
#ifndef TARGET_ARM_TRANSLATE_A64_H
22
s->regs[R_DMA_FLASH_ADDR] += 4;
29
#define TARGET_ARM_TRANSLATE_A64_H
23
s->regs[R_DMA_DRAM_ADDR] += 4;
30
24
s->regs[R_DMA_LEN] -= 4;
31
-void unallocated_encoding(DisasContext *s);
25
+ s->regs[R_DMA_CHECKSUM] += data;
32
-
33
#define unsupported_encoding(s, insn) \
34
do { \
35
qemu_log_mask(LOG_UNIMP, \
36
diff --git a/target/arm/translate.h b/target/arm/translate.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/arm/translate.h
39
+++ b/target/arm/translate.h
40
@@ -XXX,XX +XXX,XX @@ void arm_free_cc(DisasCompare *cmp);
41
void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
42
void arm_gen_test_cc(int cc, TCGLabel *label);
43
MemOp pow2_align(unsigned i);
44
+void unallocated_encoding(DisasContext *s);
45
+void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
46
+ uint32_t syn, uint32_t target_el);
47
48
/* Return state of Alternate Half-precision flag, caller frees result */
49
static inline TCGv_i32 get_ahp_flag(void)
50
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/translate-a64.c
53
+++ b/target/arm/translate-a64.c
54
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, uint64_t pc, int excp)
55
s->base.is_jmp = DISAS_NORETURN;
56
}
57
58
-static void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
59
- uint32_t syndrome, uint32_t target_el)
60
-{
61
- gen_a64_set_pc_im(pc);
62
- gen_exception(excp, syndrome, target_el);
63
- s->base.is_jmp = DISAS_NORETURN;
64
-}
65
-
66
static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syndrome)
67
{
68
TCGv_i32 tcg_syn;
69
@@ -XXX,XX +XXX,XX @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
70
}
26
}
71
}
27
}
72
28
73
-void unallocated_encoding(DisasContext *s)
74
-{
75
- /* Unallocated and reserved encodings are uncategorized */
76
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
77
- default_exception_el(s));
78
-}
79
-
80
static void init_tmp_a64_array(DisasContext *s)
81
{
82
#ifdef CONFIG_DEBUG_TCG
83
diff --git a/target/arm/translate.c b/target/arm/translate.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/arm/translate.c
86
+++ b/target/arm/translate.c
87
@@ -XXX,XX +XXX,XX @@ static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
88
s->base.is_jmp = DISAS_NORETURN;
89
}
90
91
-static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
92
- int syn, uint32_t target_el)
93
+void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
94
+ uint32_t syn, uint32_t target_el)
95
{
96
- gen_set_condexec(s);
97
- gen_set_pc_im(s, pc);
98
+ if (s->aarch64) {
99
+ gen_a64_set_pc_im(pc);
100
+ } else {
101
+ gen_set_condexec(s);
102
+ gen_set_pc_im(s, pc);
103
+ }
104
gen_exception(excp, syn, target_el);
105
s->base.is_jmp = DISAS_NORETURN;
106
}
107
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
108
s->base.is_jmp = DISAS_NORETURN;
109
}
110
111
-static void unallocated_encoding(DisasContext *s)
112
+void unallocated_encoding(DisasContext *s)
113
{
114
/* Unallocated and reserved encodings are uncategorized */
115
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
116
--
29
--
117
2.20.1
30
2.20.1
118
31
119
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Cédric Le Goater <clg@kaod.org>
2
2
3
These three features are already enabled by TCG, but are missing
3
and use a class AspeedSCUClass to define each SoC characteristics.
4
their hwcap bits. Update HWCAP2 from linux v5.12.
4
5
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Cc: qemu-stable@nongnu.org (for 6.0.1)
6
Message-id: 20190904070506.1052-10-clg@kaod.org
7
Buglink: https://bugs.launchpad.net/bugs/1926044
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210427214108.88503-1-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
linux-user/elfload.c | 13 +++++++++++++
10
include/hw/misc/aspeed_scu.h | 15 +++++++
13
1 file changed, 13 insertions(+)
11
hw/arm/aspeed_soc.c | 3 +-
14
12
hw/misc/aspeed_scu.c | 83 ++++++++++++++++++++----------------
15
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
13
3 files changed, 64 insertions(+), 37 deletions(-)
14
15
diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/elfload.c
17
--- a/include/hw/misc/aspeed_scu.h
18
+++ b/linux-user/elfload.c
18
+++ b/include/hw/misc/aspeed_scu.h
19
@@ -XXX,XX +XXX,XX @@ enum {
19
@@ -XXX,XX +XXX,XX @@
20
ARM_HWCAP2_A64_SVESM4 = 1 << 6,
20
21
ARM_HWCAP2_A64_FLAGM2 = 1 << 7,
21
#define TYPE_ASPEED_SCU "aspeed.scu"
22
ARM_HWCAP2_A64_FRINT = 1 << 8,
22
#define ASPEED_SCU(obj) OBJECT_CHECK(AspeedSCUState, (obj), TYPE_ASPEED_SCU)
23
+ ARM_HWCAP2_A64_SVEI8MM = 1 << 9,
23
+#define TYPE_ASPEED_2400_SCU TYPE_ASPEED_SCU "-ast2400"
24
+ ARM_HWCAP2_A64_SVEF32MM = 1 << 10,
24
+#define TYPE_ASPEED_2500_SCU TYPE_ASPEED_SCU "-ast2500"
25
+ ARM_HWCAP2_A64_SVEF64MM = 1 << 11,
25
26
+ ARM_HWCAP2_A64_SVEBF16 = 1 << 12,
26
#define ASPEED_SCU_NR_REGS (0x1A8 >> 2)
27
+ ARM_HWCAP2_A64_I8MM = 1 << 13,
27
28
+ ARM_HWCAP2_A64_BF16 = 1 << 14,
28
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSCUState {
29
+ ARM_HWCAP2_A64_DGH = 1 << 15,
29
30
+ ARM_HWCAP2_A64_RNG = 1 << 16,
30
extern bool is_supported_silicon_rev(uint32_t silicon_rev);
31
+ ARM_HWCAP2_A64_BTI = 1 << 17,
31
32
+ ARM_HWCAP2_A64_MTE = 1 << 18,
32
+#define ASPEED_SCU_CLASS(klass) \
33
+ OBJECT_CLASS_CHECK(AspeedSCUClass, (klass), TYPE_ASPEED_SCU)
34
+#define ASPEED_SCU_GET_CLASS(obj) \
35
+ OBJECT_GET_CLASS(AspeedSCUClass, (obj), TYPE_ASPEED_SCU)
36
+
37
+typedef struct AspeedSCUClass {
38
+ SysBusDeviceClass parent_class;
39
+
40
+ const uint32_t *resets;
41
+ uint32_t (*calc_hpll)(AspeedSCUState *s);
42
+ uint32_t apb_divider;
43
+} AspeedSCUClass;
44
+
45
#define ASPEED_SCU_PROT_KEY 0x1688A8A8
46
47
/*
48
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/arm/aspeed_soc.c
51
+++ b/hw/arm/aspeed_soc.c
52
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
53
&error_abort, NULL);
54
}
55
56
+ snprintf(typename, sizeof(typename), "aspeed.scu-%s", socname);
57
sysbus_init_child_obj(obj, "scu", OBJECT(&s->scu), sizeof(s->scu),
58
- TYPE_ASPEED_SCU);
59
+ typename);
60
qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev",
61
sc->info->silicon_rev);
62
object_property_add_alias(obj, "hw-strap1", OBJECT(&s->scu),
63
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/misc/aspeed_scu.c
66
+++ b/hw/misc/aspeed_scu.c
67
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_scu_get_random(void)
68
69
static void aspeed_scu_set_apb_freq(AspeedSCUState *s)
70
{
71
- uint32_t apb_divider;
72
-
73
- switch (s->silicon_rev) {
74
- case AST2400_A0_SILICON_REV:
75
- case AST2400_A1_SILICON_REV:
76
- apb_divider = 2;
77
- break;
78
- case AST2500_A0_SILICON_REV:
79
- case AST2500_A1_SILICON_REV:
80
- apb_divider = 4;
81
- break;
82
- default:
83
- g_assert_not_reached();
84
- }
85
+ AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
86
87
s->apb_freq = s->hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[CLK_SEL]) + 1)
88
- / apb_divider;
89
+ / asc->apb_divider;
90
}
91
92
static uint64_t aspeed_scu_read(void *opaque, hwaddr offset, unsigned size)
93
@@ -XXX,XX +XXX,XX @@ static const uint32_t hpll_ast2400_freqs[][4] = {
94
{ 400, 375, 350, 425 }, /* 25MHz */
33
};
95
};
34
96
35
#define ELF_HWCAP get_elf_hwcap()
97
-static uint32_t aspeed_scu_calc_hpll_ast2400(AspeedSCUState *s)
36
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap2(void)
98
+static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s)
37
GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
99
{
38
GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
100
uint32_t hpll_reg = s->regs[HPLL_PARAM];
39
GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
101
uint8_t freq_select;
40
+ GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
102
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_scu_calc_hpll_ast2400(AspeedSCUState *s)
41
+ GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
103
return hpll_ast2400_freqs[clk_25m_in][freq_select] * 1000000;
42
+ GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
104
}
43
105
44
return hwcaps;
106
-static uint32_t aspeed_scu_calc_hpll_ast2500(AspeedSCUState *s)
45
}
107
+static uint32_t aspeed_2500_scu_calc_hpll(AspeedSCUState *s)
108
{
109
uint32_t hpll_reg = s->regs[HPLL_PARAM];
110
uint32_t multiplier = 1;
111
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_scu_calc_hpll_ast2500(AspeedSCUState *s)
112
static void aspeed_scu_reset(DeviceState *dev)
113
{
114
AspeedSCUState *s = ASPEED_SCU(dev);
115
- const uint32_t *reset;
116
- uint32_t (*calc_hpll)(AspeedSCUState *s);
117
+ AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(dev);
118
119
- switch (s->silicon_rev) {
120
- case AST2400_A0_SILICON_REV:
121
- case AST2400_A1_SILICON_REV:
122
- reset = ast2400_a0_resets;
123
- calc_hpll = aspeed_scu_calc_hpll_ast2400;
124
- break;
125
- case AST2500_A0_SILICON_REV:
126
- case AST2500_A1_SILICON_REV:
127
- reset = ast2500_a1_resets;
128
- calc_hpll = aspeed_scu_calc_hpll_ast2500;
129
- break;
130
- default:
131
- g_assert_not_reached();
132
- }
133
-
134
- memcpy(s->regs, reset, sizeof(s->regs));
135
+ memcpy(s->regs, asc->resets, sizeof(s->regs));
136
s->regs[SILICON_REV] = s->silicon_rev;
137
s->regs[HW_STRAP1] = s->hw_strap1;
138
s->regs[HW_STRAP2] = s->hw_strap2;
139
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_reset(DeviceState *dev)
140
* All registers are set. Now compute the frequencies of the main clocks
141
*/
142
s->clkin = aspeed_scu_get_clkin(s);
143
- s->hpll = calc_hpll(s);
144
+ s->hpll = asc->calc_hpll(s);
145
aspeed_scu_set_apb_freq(s);
146
}
147
148
@@ -XXX,XX +XXX,XX @@ static const TypeInfo aspeed_scu_info = {
149
.parent = TYPE_SYS_BUS_DEVICE,
150
.instance_size = sizeof(AspeedSCUState),
151
.class_init = aspeed_scu_class_init,
152
+ .class_size = sizeof(AspeedSCUClass),
153
+ .abstract = true,
154
+};
155
+
156
+static void aspeed_2400_scu_class_init(ObjectClass *klass, void *data)
157
+{
158
+ DeviceClass *dc = DEVICE_CLASS(klass);
159
+ AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass);
160
+
161
+ dc->desc = "ASPEED 2400 System Control Unit";
162
+ asc->resets = ast2400_a0_resets;
163
+ asc->calc_hpll = aspeed_2400_scu_calc_hpll;
164
+ asc->apb_divider = 2;
165
+}
166
+
167
+static const TypeInfo aspeed_2400_scu_info = {
168
+ .name = TYPE_ASPEED_2400_SCU,
169
+ .parent = TYPE_ASPEED_SCU,
170
+ .instance_size = sizeof(AspeedSCUState),
171
+ .class_init = aspeed_2400_scu_class_init,
172
+};
173
+
174
+static void aspeed_2500_scu_class_init(ObjectClass *klass, void *data)
175
+{
176
+ DeviceClass *dc = DEVICE_CLASS(klass);
177
+ AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass);
178
+
179
+ dc->desc = "ASPEED 2500 System Control Unit";
180
+ asc->resets = ast2500_a1_resets;
181
+ asc->calc_hpll = aspeed_2500_scu_calc_hpll;
182
+ asc->apb_divider = 4;
183
+}
184
+
185
+static const TypeInfo aspeed_2500_scu_info = {
186
+ .name = TYPE_ASPEED_2500_SCU,
187
+ .parent = TYPE_ASPEED_SCU,
188
+ .instance_size = sizeof(AspeedSCUState),
189
+ .class_init = aspeed_2500_scu_class_init,
190
};
191
192
static void aspeed_scu_register_types(void)
193
{
194
type_register_static(&aspeed_scu_info);
195
+ type_register_static(&aspeed_2400_scu_info);
196
+ type_register_static(&aspeed_2500_scu_info);
197
}
198
199
type_init(aspeed_scu_register_types);
46
--
200
--
47
2.20.1
201
2.20.1
48
202
49
203
diff view generated by jsdifflib
Deleted patch
1
In tlbi_aa64_vae2is_write() the calculation
2
bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_E2 : ARMMMUIdx_SE2,
3
pageaddr)
4
1
5
has the two arms of the ?: expression reversed. Fix the bug.
6
7
Fixes: b6ad6062f1e5
8
Reported-by: Rebecca Cran <rebecca@nuviainc.com>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Reviewed-by: Rémi Denis-Courmont <remi.denis.courmont@huawei.com>
12
Reviewed-by: Rebecca Cran <rebecca@nuviainc.com>
13
Message-id: 20210420123106.10861-1-peter.maydell@linaro.org
14
---
15
target/arm/helper.c | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
17
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
21
+++ b/target/arm/helper.c
22
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2is_write(CPUARMState *env, const ARMCPRegInfo *ri,
23
uint64_t pageaddr = sextract64(value << 12, 0, 56);
24
bool secure = arm_is_secure_below_el3(env);
25
int mask = secure ? ARMMMUIdxBit_SE2 : ARMMMUIdxBit_E2;
26
- int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_E2 : ARMMMUIdx_SE2,
27
+ int bits = tlbbits_for_regime(env, secure ? ARMMMUIdx_SE2 : ARMMMUIdx_E2,
28
pageaddr);
29
30
tlb_flush_page_bits_by_mmuidx_all_cpus_synced(cs, pageaddr, mask, bits);
31
--
32
2.20.1
33
34
diff view generated by jsdifflib
1
The AN524 FPGA image supports two memory maps, which differ in where
1
From: Cédric Le Goater <clg@kaod.org>
2
the QSPI and BRAM are. In the default map, the BRAM is at
3
0x0000_0000, and the QSPI at 0x2800_0000. In the second map, they
4
are the other way around.
5
2
6
In hardware, the initial mapping can be selected by the user by
3
The APB frequency can be calculated directly when needed from the
7
writing either "REMAP: BRAM" (the default) or "REMAP: QSPI" in the
4
HPLL_PARAM and CLK_SEL register values. This removes useless state in
8
board configuration file. The board config file is acted on by the
5
the model.
9
"Motherboard Configuration Controller", which is an entirely separate
10
microcontroller on the dev board but outside the FPGA.
11
6
12
The guest can also dynamically change the mapping via the SCC
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
13
CFG_REG0 register.
8
Message-id: 20190904070506.1052-11-clg@kaod.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/misc/aspeed_scu.h | 8 +++-----
13
hw/misc/aspeed_scu.c | 25 +++++++++----------------
14
hw/timer/aspeed_timer.c | 3 ++-
15
3 files changed, 14 insertions(+), 22 deletions(-)
14
16
15
Implement this functionality for QEMU, using a machine property
17
diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
16
"remap" with valid values "BRAM" and "QSPI" to allow the user to set
17
the initial mapping, in the same way they can on the FPGA, and
18
wiring up the bit from the SCC register to also switch the mapping.
19
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
23
Message-id: 20210504120912.23094-4-peter.maydell@linaro.org
24
---
25
docs/system/arm/mps2.rst | 10 ++++
26
hw/arm/mps2-tz.c | 108 ++++++++++++++++++++++++++++++++++++++-
27
2 files changed, 117 insertions(+), 1 deletion(-)
28
29
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
30
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
31
--- a/docs/system/arm/mps2.rst
19
--- a/include/hw/misc/aspeed_scu.h
32
+++ b/docs/system/arm/mps2.rst
20
+++ b/include/hw/misc/aspeed_scu.h
33
@@ -XXX,XX +XXX,XX @@ Differences between QEMU and real hardware:
21
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSCUState {
34
flash, but only as simple ROM, so attempting to rewrite the flash
22
uint32_t hw_strap1;
35
from the guest will fail
23
uint32_t hw_strap2;
36
- QEMU does not model the USB controller in MPS3 boards
24
uint32_t hw_prot_key;
25
-
26
- uint32_t clkin;
27
- uint32_t hpll;
28
- uint32_t apb_freq;
29
} AspeedSCUState;
30
31
#define AST2400_A0_SILICON_REV 0x02000303U
32
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSCUClass {
33
SysBusDeviceClass parent_class;
34
35
const uint32_t *resets;
36
- uint32_t (*calc_hpll)(AspeedSCUState *s);
37
+ uint32_t (*calc_hpll)(AspeedSCUState *s, uint32_t hpll_reg);
38
uint32_t apb_divider;
39
} AspeedSCUClass;
40
41
#define ASPEED_SCU_PROT_KEY 0x1688A8A8
42
43
+uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s);
37
+
44
+
38
+Machine-specific options
45
/*
39
+""""""""""""""""""""""""
46
* Extracted from Aspeed SDK v00.03.21. Fixes and extra definitions
40
+
47
* were added.
41
+The following machine-specific options are supported:
48
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
42
+
43
+remap
44
+ Supported for ``mps3-an524`` only.
45
+ Set ``BRAM``/``QSPI`` to select the initial memory mapping. The
46
+ default is ``BRAM``.
47
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
48
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/mps2-tz.c
50
--- a/hw/misc/aspeed_scu.c
50
+++ b/hw/arm/mps2-tz.c
51
+++ b/hw/misc/aspeed_scu.c
51
@@ -XXX,XX +XXX,XX @@
52
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_scu_get_random(void)
52
#include "hw/boards.h"
53
return num;
53
#include "exec/address-spaces.h"
54
}
54
#include "sysemu/sysemu.h"
55
55
+#include "sysemu/reset.h"
56
-static void aspeed_scu_set_apb_freq(AspeedSCUState *s)
56
#include "hw/misc/unimp.h"
57
+uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s)
57
#include "hw/char/cmsdk-apb-uart.h"
58
{
58
#include "hw/timer/cmsdk-apb-timer.h"
59
AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
59
@@ -XXX,XX +XXX,XX @@
60
+ uint32_t hpll = asc->calc_hpll(s, s->regs[HPLL_PARAM]);
60
#include "hw/core/split-irq.h"
61
61
#include "hw/qdev-clock.h"
62
- s->apb_freq = s->hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[CLK_SEL]) + 1)
62
#include "qom/object.h"
63
+ return hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[CLK_SEL]) + 1)
63
+#include "hw/irq.h"
64
/ asc->apb_divider;
64
65
}
65
#define MPS2TZ_NUMIRQ_MAX 96
66
66
#define MPS2TZ_RAM_MAX 5
67
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
67
@@ -XXX,XX +XXX,XX @@ struct MPS2TZMachineState {
68
return;
68
SplitIRQ cpu_irq_splitter[MPS2TZ_NUMIRQ_MAX];
69
case CLK_SEL:
69
Clock *sysclk;
70
s->regs[reg] = data;
70
Clock *s32kclk;
71
- aspeed_scu_set_apb_freq(s);
71
+
72
break;
72
+ bool remap;
73
case HW_STRAP1:
73
+ qemu_irq remap_irq;
74
if (ASPEED_IS_AST2500(s->regs[SILICON_REV])) {
75
@@ -XXX,XX +XXX,XX @@ static const uint32_t hpll_ast2400_freqs[][4] = {
76
{ 400, 375, 350, 425 }, /* 25MHz */
74
};
77
};
75
78
76
#define TYPE_MPS2TZ_MACHINE "mps2tz"
79
-static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s)
77
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an505_raminfo[] = { {
80
+static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s, uint32_t hpll_reg)
78
},
81
{
79
};
82
- uint32_t hpll_reg = s->regs[HPLL_PARAM];
80
83
uint8_t freq_select;
81
+/*
84
bool clk_25m_in;
82
+ * Note that the addresses and MPC numbering here should match up
85
+ uint32_t clkin = aspeed_scu_get_clkin(s);
83
+ * with those used in remap_memory(), which can swap the BRAM and QSPI.
86
84
+ */
87
if (hpll_reg & SCU_AST2400_H_PLL_OFF) {
85
static const RAMInfo an524_raminfo[] = { {
88
return 0;
86
.name = "bram",
89
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s)
87
.base = 0x00000000,
90
multiplier = (2 - od) * ((n + 2) / (d + 1));
88
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_scc(MPS2TZMachineState *mms, void *opaque,
91
}
89
92
90
object_initialize_child(OBJECT(mms), "scc", scc, TYPE_MPS2_SCC);
93
- return s->clkin * multiplier;
91
sccdev = DEVICE(scc);
94
+ return clkin * multiplier;
92
+ qdev_prop_set_uint32(sccdev, "scc-cfg0", mms->remap ? 1 : 0);
95
}
93
qdev_prop_set_uint32(sccdev, "scc-cfg4", 0x2);
96
94
qdev_prop_set_uint32(sccdev, "scc-aid", 0x00200008);
97
/* HW strapping */
95
qdev_prop_set_uint32(sccdev, "scc-id", mmc->scc_id);
98
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s)
96
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
99
return hpll_ast2400_freqs[clk_25m_in][freq_select] * 1000000;
97
return sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 0);
98
}
100
}
99
101
100
+static hwaddr boot_mem_base(MPS2TZMachineState *mms)
102
-static uint32_t aspeed_2500_scu_calc_hpll(AspeedSCUState *s)
101
+{
103
+static uint32_t aspeed_2500_scu_calc_hpll(AspeedSCUState *s, uint32_t hpll_reg)
102
+ /*
104
{
103
+ * Return the canonical address of the block which will be mapped
105
- uint32_t hpll_reg = s->regs[HPLL_PARAM];
104
+ * at address 0x0 (i.e. where the vector table is).
106
uint32_t multiplier = 1;
105
+ * This is usually 0, but if the AN524 alternate memory map is
107
+ uint32_t clkin = aspeed_scu_get_clkin(s);
106
+ * enabled it will be the base address of the QSPI block.
108
107
+ */
109
if (hpll_reg & SCU_H_PLL_OFF) {
108
+ return mms->remap ? 0x28000000 : 0;
110
return 0;
109
+}
111
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_2500_scu_calc_hpll(AspeedSCUState *s)
110
+
112
multiplier = ((m + 1) / (n + 1)) / (p + 1);
111
+static void remap_memory(MPS2TZMachineState *mms, int map)
112
+{
113
+ /*
114
+ * Remap the memory for the AN524. 'map' is the value of
115
+ * SCC CFG_REG0 bit 0, i.e. 0 for the default map and 1
116
+ * for the "option 1" mapping where QSPI is at address 0.
117
+ *
118
+ * Effectively we need to swap around the "upstream" ends of
119
+ * MPC 0 and MPC 1.
120
+ */
121
+ MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
122
+ int i;
123
+
124
+ if (mmc->fpga_type != FPGA_AN524) {
125
+ return;
126
+ }
127
+
128
+ memory_region_transaction_begin();
129
+ for (i = 0; i < 2; i++) {
130
+ TZMPC *mpc = &mms->mpc[i];
131
+ MemoryRegion *upstream = sysbus_mmio_get_region(SYS_BUS_DEVICE(mpc), 1);
132
+ hwaddr addr = (i ^ map) ? 0x28000000 : 0;
133
+
134
+ memory_region_set_address(upstream, addr);
135
+ }
136
+ memory_region_transaction_commit();
137
+}
138
+
139
+static void remap_irq_fn(void *opaque, int n, int level)
140
+{
141
+ MPS2TZMachineState *mms = opaque;
142
+
143
+ remap_memory(mms, level);
144
+}
145
+
146
static MemoryRegion *make_dma(MPS2TZMachineState *mms, void *opaque,
147
const char *name, hwaddr size,
148
const int *irqs)
149
@@ -XXX,XX +XXX,XX @@ static uint32_t boot_ram_size(MPS2TZMachineState *mms)
150
MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_GET_CLASS(mms);
151
152
for (p = mmc->raminfo; p->name; p++) {
153
- if (p->base == 0) {
154
+ if (p->base == boot_mem_base(mms)) {
155
return p->size;
156
}
157
}
113
}
158
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
114
159
115
- return s->clkin * multiplier;
160
create_non_mpc_ram(mms);
116
+ return clkin * multiplier;
161
162
+ if (mmc->fpga_type == FPGA_AN524) {
163
+ /*
164
+ * Connect the line from the SCC so that we can remap when the
165
+ * guest updates that register.
166
+ */
167
+ mms->remap_irq = qemu_allocate_irq(remap_irq_fn, mms, 0);
168
+ qdev_connect_gpio_out_named(DEVICE(&mms->scc), "remap", 0,
169
+ mms->remap_irq);
170
+ }
171
+
172
armv7m_load_kernel(ARM_CPU(first_cpu), machine->kernel_filename,
173
boot_ram_size(mms));
174
}
117
}
175
@@ -XXX,XX +XXX,XX @@ static void mps2_tz_idau_check(IDAUInterface *ii, uint32_t address,
118
176
*iregion = region;
119
static void aspeed_scu_reset(DeviceState *dev)
120
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_reset(DeviceState *dev)
121
s->regs[HW_STRAP1] = s->hw_strap1;
122
s->regs[HW_STRAP2] = s->hw_strap2;
123
s->regs[PROT_KEY] = s->hw_prot_key;
124
-
125
- /*
126
- * All registers are set. Now compute the frequencies of the main clocks
127
- */
128
- s->clkin = aspeed_scu_get_clkin(s);
129
- s->hpll = asc->calc_hpll(s);
130
- aspeed_scu_set_apb_freq(s);
177
}
131
}
178
132
179
+static char *mps2_get_remap(Object *obj, Error **errp)
133
static uint32_t aspeed_silicon_revs[] = {
180
+{
134
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
181
+ MPS2TZMachineState *mms = MPS2TZ_MACHINE(obj);
135
index XXXXXXX..XXXXXXX 100644
182
+ const char *val = mms->remap ? "QSPI" : "BRAM";
136
--- a/hw/timer/aspeed_timer.c
183
+ return g_strdup(val);
137
+++ b/hw/timer/aspeed_timer.c
184
+}
138
@@ -XXX,XX +XXX,XX @@ static inline uint32_t calculate_rate(struct AspeedTimer *t)
185
+
186
+static void mps2_set_remap(Object *obj, const char *value, Error **errp)
187
+{
188
+ MPS2TZMachineState *mms = MPS2TZ_MACHINE(obj);
189
+
190
+ if (!strcmp(value, "BRAM")) {
191
+ mms->remap = false;
192
+ } else if (!strcmp(value, "QSPI")) {
193
+ mms->remap = true;
194
+ } else {
195
+ error_setg(errp, "Invalid remap value");
196
+ error_append_hint(errp, "Valid values are BRAM and QSPI.\n");
197
+ }
198
+}
199
+
200
+static void mps2_machine_reset(MachineState *machine)
201
+{
202
+ MPS2TZMachineState *mms = MPS2TZ_MACHINE(machine);
203
+
204
+ /*
205
+ * Set the initial memory mapping before triggering the reset of
206
+ * the rest of the system, so that the guest image loader and CPU
207
+ * reset see the correct mapping.
208
+ */
209
+ remap_memory(mms, mms->remap);
210
+ qemu_devices_reset();
211
+}
212
+
213
static void mps2tz_class_init(ObjectClass *oc, void *data)
214
{
139
{
215
MachineClass *mc = MACHINE_CLASS(oc);
140
AspeedTimerCtrlState *s = timer_to_ctrl(t);
216
IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(oc);
141
217
142
- return timer_external_clock(t) ? TIMER_CLOCK_EXT_HZ : s->scu->apb_freq;
218
mc->init = mps2tz_common_init;
143
+ return timer_external_clock(t) ? TIMER_CLOCK_EXT_HZ :
219
+ mc->reset = mps2_machine_reset;
144
+ aspeed_scu_get_apb_freq(s->scu);
220
iic->check = mps2_tz_idau_check;
221
}
145
}
222
146
223
@@ -XXX,XX +XXX,XX @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data)
147
static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns)
224
mmc->raminfo = an524_raminfo;
225
mmc->armsse_type = TYPE_SSE200;
226
mps2tz_set_default_ram_info(mmc);
227
+
228
+ object_class_property_add_str(oc, "remap", mps2_get_remap, mps2_set_remap);
229
+ object_class_property_set_description(oc, "remap",
230
+ "Set memory mapping. Valid values "
231
+ "are BRAM (default) and QSPI.");
232
}
233
234
static void mps3tz_an547_class_init(ObjectClass *oc, void *data)
235
--
148
--
236
2.20.1
149
2.20.1
237
150
238
151
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: "Emilio G. Cota" <cota@braap.org>
2
2
3
Commit dfc388797cc4 ("hw/arm: xlnx: Set all boards' GEM 'phy-addr'
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
property value to 23") configured the PHY address for xilinx-zynq-a9
4
Signed-off-by: Emilio G. Cota <cota@braap.org>
5
to 23. When trying to boot xilinx-zynq-a9 with zynq-zc702.dtb or
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
zynq-zc706.dtb, this results in the following error message when
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
trying to use the Ethernet interface.
8
9
macb e000b000.ethernet eth0: Could not attach PHY (-19)
10
11
The devicetree files for ZC702 and ZC706 configure PHY address 7. The
12
documentation for the ZC702 and ZC706 evaluation boards suggest that the
13
PHY address is 7, not 23. Other boards use PHY address 0, 1, 3, or 7.
14
I was unable to find a documentation or a devicetree file suggesting
15
or using PHY address 23. The Ethernet interface starts working with
16
zynq-zc702.dtb and zynq-zc706.dtb when setting the PHY address to 7,
17
so let's use it.
18
19
Cc: Bin Meng <bin.meng@windriver.com>
20
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
21
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
22
Acked-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
23
Message-id: 20210504124140.1100346-1-linux@roeck-us.net
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
8
---
26
hw/arm/xilinx_zynq.c | 2 +-
9
accel/tcg/atomic_template.h | 2 +-
27
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
28
11
29
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
12
diff --git a/accel/tcg/atomic_template.h b/accel/tcg/atomic_template.h
30
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/xilinx_zynq.c
14
--- a/accel/tcg/atomic_template.h
32
+++ b/hw/arm/xilinx_zynq.c
15
+++ b/accel/tcg/atomic_template.h
33
@@ -XXX,XX +XXX,XX @@ static void gem_init(NICInfo *nd, uint32_t base, qemu_irq irq)
16
@@ -XXX,XX +XXX,XX @@ ABI_TYPE ATOMIC_NAME(xchg)(CPUArchState *env, target_ulong addr,
34
qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
17
35
qdev_set_nic_properties(dev, nd);
18
#define GEN_ATOMIC_HELPER(X) \
36
}
19
ABI_TYPE ATOMIC_NAME(X)(CPUArchState *env, target_ulong addr, \
37
- object_property_set_int(OBJECT(dev), "phy-addr", 23, &error_abort);
20
- ABI_TYPE val EXTRA_ARGS) \
38
+ object_property_set_int(OBJECT(dev), "phy-addr", 7, &error_abort);
21
+ ABI_TYPE val EXTRA_ARGS) \
39
s = SYS_BUS_DEVICE(dev);
22
{ \
40
sysbus_realize_and_unref(s, &error_fatal);
23
ATOMIC_MMU_DECLS; \
41
sysbus_mmio_map(s, 0, base);
24
DATA_TYPE *haddr = ATOMIC_MMU_LOOKUP; \
42
--
25
--
43
2.20.1
26
2.20.1
44
27
45
28
diff view generated by jsdifflib
1
We want to split out the .c.inc files which are currently included
1
The qemu-ga documentation is currently in qemu-ga.texi in
2
into translate.c so they are separate compilation units. To do this
2
Texinfo format, which we present to the user as:
3
we need to make some functions which are currently file-local to
3
* a qemu-ga manpage
4
translate.c have global scope; create a translate-a32.h paralleling
4
* a section of the main qemu-doc HTML documentation
5
the existing translate-a64.h as a place for these declarations to
6
live, so that code moved into the new compilation units can call
7
them.
8
5
9
The functions made global here are those required by the
6
Convert the documentation to rST format, and present it to
10
m-nocp.decode functions, except that I have converted the whole
7
the user as:
11
family of {read,write}_neon_element* and also both the load_cpu and
8
* a qemu-ga manpage
12
store_cpu functions for consistency, even though m-nocp only wants a
9
* part of the interop/ Sphinx manual
13
few functions from each.
14
10
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
17
Message-id: 20210430132740.10391-4-peter.maydell@linaro.org
13
Tested-by: Michael Roth <mdroth@linux.vnet.ibm.com>
14
Message-id: 20190905131040.8350-1-peter.maydell@linaro.org
18
---
15
---
19
target/arm/translate-a32.h | 57 ++++++++++++++++++++++++++++++++++
16
Makefile | 24 ++++---
20
target/arm/translate.c | 39 +++++------------------
17
MAINTAINERS | 2 +-
21
target/arm/translate-vfp.c.inc | 2 +-
18
docs/conf.py | 18 ++---
22
3 files changed, 65 insertions(+), 33 deletions(-)
19
docs/interop/conf.py | 7 ++
23
create mode 100644 target/arm/translate-a32.h
20
docs/interop/index.rst | 1 +
21
docs/interop/qemu-ga.rst | 133 +++++++++++++++++++++++++++++++++++++
22
qemu-doc.texi | 5 --
23
qemu-ga.texi | 137 ---------------------------------------
24
8 files changed, 166 insertions(+), 161 deletions(-)
25
create mode 100644 docs/interop/qemu-ga.rst
26
delete mode 100644 qemu-ga.texi
24
27
25
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
28
diff --git a/Makefile b/Makefile
29
index XXXXXXX..XXXXXXX 100644
30
--- a/Makefile
31
+++ b/Makefile
32
@@ -XXX,XX +XXX,XX @@ endif
33
endif
34
35
ifdef BUILD_DOCS
36
-DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
37
+DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8 docs/interop/qemu-ga.8
38
DOCS+=docs/interop/qemu-qmp-ref.html docs/interop/qemu-qmp-ref.txt docs/interop/qemu-qmp-ref.7
39
DOCS+=docs/interop/qemu-ga-ref.html docs/interop/qemu-ga-ref.txt docs/interop/qemu-ga-ref.7
40
DOCS+=docs/qemu-block-drivers.7
41
@@ -XXX,XX +XXX,XX @@ DESCS=
42
endif
43
44
# Note that we manually filter-out the non-Sphinx documentation which
45
-# is currently built into the docs/interop directory in the build tree.
46
+# is currently built into the docs/interop directory in the build tree,
47
+# and also any sphinx-built manpages.
48
define install-manual =
49
for d in $$(cd $(MANUAL_BUILDDIR) && find $1 -type d); do $(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)/$$d"; done
50
-for f in $$(cd $(MANUAL_BUILDDIR) && find $1 -type f -a '!' '(' -name 'qemu-*-qapi.*' -o -name 'qemu-*-ref.*' ')' ); do $(INSTALL_DATA) "$(MANUAL_BUILDDIR)/$$f" "$(DESTDIR)$(qemu_docdir)/$$f"; done
51
+for f in $$(cd $(MANUAL_BUILDDIR) && find $1 -type f -a '!' '(' -name '*.[0-9]' -o -name 'qemu-*-qapi.*' -o -name 'qemu-*-ref.*' ')' ); do $(INSTALL_DATA) "$(MANUAL_BUILDDIR)/$$f" "$(DESTDIR)$(qemu_docdir)/$$f"; done
52
endef
53
54
# Note that we deliberately do not install the "devel" manual: it is
55
@@ -XXX,XX +XXX,XX @@ ifdef CONFIG_TRACE_SYSTEMTAP
56
    $(INSTALL_DATA) scripts/qemu-trace-stap.1 "$(DESTDIR)$(mandir)/man1"
57
endif
58
ifneq (,$(findstring qemu-ga,$(TOOLS)))
59
-    $(INSTALL_DATA) qemu-ga.8 "$(DESTDIR)$(mandir)/man8"
60
+    $(INSTALL_DATA) docs/interop/qemu-ga.8 "$(DESTDIR)$(mandir)/man8"
61
    $(INSTALL_DATA) docs/interop/qemu-ga-ref.html "$(DESTDIR)$(qemu_docdir)"
62
    $(INSTALL_DATA) docs/interop/qemu-ga-ref.txt "$(DESTDIR)$(qemu_docdir)"
63
    $(INSTALL_DATA) docs/interop/qemu-ga-ref.7 "$(DESTDIR)$(mandir)/man7"
64
@@ -XXX,XX +XXX,XX @@ docs/version.texi: $(SRC_PATH)/VERSION config-host.mak
65
sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html $(MANUAL_BUILDDIR)/interop/index.html $(MANUAL_BUILDDIR)/specs/index.html
66
67
# Canned command to build a single manual
68
-build-manual = $(call quiet-command,sphinx-build $(if $(V),,-q) -W -n -b html -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
69
+# Arguments: $1 = manual name, $2 = Sphinx builder ('html' or 'man')
70
+build-manual = $(call quiet-command,CONFDIR="$(qemu_confdir)" sphinx-build $(if $(V),,-q) -W -n -b $2 -D version=$(VERSION) -D release="$(FULL_VERSION)" -d .doctrees/$1 $(SRC_PATH)/docs/$1 $(MANUAL_BUILDDIR)/$1 ,"SPHINX","$(MANUAL_BUILDDIR)/$1")
71
# We assume all RST files in the manual's directory are used in it
72
manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py
73
74
$(MANUAL_BUILDDIR)/devel/index.html: $(call manual-deps,devel)
75
-    $(call build-manual,devel)
76
+    $(call build-manual,devel,html)
77
78
$(MANUAL_BUILDDIR)/interop/index.html: $(call manual-deps,interop)
79
-    $(call build-manual,interop)
80
+    $(call build-manual,interop,html)
81
82
$(MANUAL_BUILDDIR)/specs/index.html: $(call manual-deps,specs)
83
-    $(call build-manual,specs)
84
+    $(call build-manual,specs,html)
85
+
86
+$(MANUAL_BUILDDIR)/interop/qemu-ga.8: $(call manual-deps,interop)
87
+    $(call build-manual,interop,man)
88
89
qemu-options.texi: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool
90
    $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"GEN","$@")
91
@@ -XXX,XX +XXX,XX @@ qemu.1: qemu-option-trace.texi
92
qemu-img.1: qemu-img.texi qemu-option-trace.texi qemu-img-cmds.texi
93
fsdev/virtfs-proxy-helper.1: fsdev/virtfs-proxy-helper.texi
94
qemu-nbd.8: qemu-nbd.texi qemu-option-trace.texi
95
-qemu-ga.8: qemu-ga.texi
96
docs/qemu-block-drivers.7: docs/qemu-block-drivers.texi
97
docs/qemu-cpu-models.7: docs/qemu-cpu-models.texi
98
scripts/qemu-trace-stap.1: scripts/qemu-trace-stap.texi
99
@@ -XXX,XX +XXX,XX @@ txt: qemu-doc.txt docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
100
qemu-doc.html qemu-doc.info qemu-doc.pdf qemu-doc.txt: \
101
    qemu-img.texi qemu-nbd.texi qemu-options.texi \
102
    qemu-tech.texi qemu-option-trace.texi \
103
-    qemu-deprecated.texi qemu-monitor.texi qemu-img-cmds.texi qemu-ga.texi \
104
+    qemu-deprecated.texi qemu-monitor.texi qemu-img-cmds.texi \
105
    qemu-monitor-info.texi docs/qemu-block-drivers.texi \
106
    docs/qemu-cpu-models.texi docs/security.texi
107
108
diff --git a/MAINTAINERS b/MAINTAINERS
109
index XXXXXXX..XXXXXXX 100644
110
--- a/MAINTAINERS
111
+++ b/MAINTAINERS
112
@@ -XXX,XX +XXX,XX @@ QEMU Guest Agent
113
M: Michael Roth <mdroth@linux.vnet.ibm.com>
114
S: Maintained
115
F: qga/
116
-F: qemu-ga.texi
117
+F: docs/interop/qemu-ga.rst
118
F: scripts/qemu-guest-agent/
119
F: tests/test-qga.c
120
F: docs/interop/qemu-ga-ref.texi
121
diff --git a/docs/conf.py b/docs/conf.py
122
index XXXXXXX..XXXXXXX 100644
123
--- a/docs/conf.py
124
+++ b/docs/conf.py
125
@@ -XXX,XX +XXX,XX @@ todo_include_todos = False
126
# with "option::" in the document being processed. Turn that off.
127
suppress_warnings = ["ref.option"]
128
129
+# The rst_epilog fragment is effectively included in every rST file.
130
+# We use it to define substitutions based on build config that
131
+# can then be used in the documentation. The fallback if the
132
+# environment variable is not set is for the benefit of readthedocs
133
+# style document building; our Makefile always sets the variable.
134
+confdir = os.getenv('CONFDIR', "/etc/qemu")
135
+rst_epilog = ".. |CONFDIR| replace:: ``" + confdir + "``\n"
136
+
137
# -- Options for HTML output ----------------------------------------------
138
139
# The theme to use for HTML and HTML Help pages. See the documentation for
140
@@ -XXX,XX +XXX,XX @@ latex_documents = [
141
142
143
# -- Options for manual page output ---------------------------------------
144
-
145
-# One entry per manual page. List of tuples
146
-# (source start file, name, description, authors, manual section).
147
-man_pages = [
148
- (master_doc, 'qemu', u'QEMU Documentation',
149
- [author], 1)
150
-]
151
-
152
+# Individual manual/conf.py can override this to create man pages
153
+man_pages = []
154
155
# -- Options for Texinfo output -------------------------------------------
156
157
diff --git a/docs/interop/conf.py b/docs/interop/conf.py
158
index XXXXXXX..XXXXXXX 100644
159
--- a/docs/interop/conf.py
160
+++ b/docs/interop/conf.py
161
@@ -XXX,XX +XXX,XX @@ exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
162
# This slightly misuses the 'description', but is the best way to get
163
# the manual title to appear in the sidebar.
164
html_theme_options['description'] = u'System Emulation Management and Interoperability Guide'
165
+
166
+# One entry per manual page. List of tuples
167
+# (source start file, name, description, authors, manual section).
168
+man_pages = [
169
+ ('qemu-ga', 'qemu-ga', u'QEMU Guest Agent',
170
+ ['Michael Roth <mdroth@linux.vnet.ibm.com>'], 8)
171
+]
172
diff --git a/docs/interop/index.rst b/docs/interop/index.rst
173
index XXXXXXX..XXXXXXX 100644
174
--- a/docs/interop/index.rst
175
+++ b/docs/interop/index.rst
176
@@ -XXX,XX +XXX,XX @@ Contents:
177
bitmaps
178
live-block-operations
179
pr-helper
180
+ qemu-ga
181
vhost-user
182
vhost-user-gpu
183
diff --git a/docs/interop/qemu-ga.rst b/docs/interop/qemu-ga.rst
26
new file mode 100644
184
new file mode 100644
27
index XXXXXXX..XXXXXXX
185
index XXXXXXX..XXXXXXX
28
--- /dev/null
186
--- /dev/null
29
+++ b/target/arm/translate-a32.h
187
+++ b/docs/interop/qemu-ga.rst
30
@@ -XXX,XX +XXX,XX @@
188
@@ -XXX,XX +XXX,XX @@
31
+/*
189
+QEMU Guest Agent
32
+ * AArch32 translation, common definitions.
190
+================
33
+ *
191
+
34
+ * Copyright (c) 2021 Linaro, Ltd.
192
+Synopsis
35
+ *
193
+--------
36
+ * This library is free software; you can redistribute it and/or
194
+
37
+ * modify it under the terms of the GNU Lesser General Public
195
+**qemu-ga** [*OPTIONS*]
38
+ * License as published by the Free Software Foundation; either
196
+
39
+ * version 2.1 of the License, or (at your option) any later version.
197
+Description
40
+ *
198
+-----------
41
+ * This library is distributed in the hope that it will be useful,
199
+
42
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
200
+The QEMU Guest Agent is a daemon intended to be run within virtual
43
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
201
+machines. It allows the hypervisor host to perform various operations
44
+ * Lesser General Public License for more details.
202
+in the guest, such as:
45
+ *
203
+
46
+ * You should have received a copy of the GNU Lesser General Public
204
+- get information from the guest
47
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
205
+- set the guest's system time
48
+ */
206
+- read/write a file
49
+
207
+- sync and freeze the filesystems
50
+#ifndef TARGET_ARM_TRANSLATE_A64_H
208
+- suspend the guest
51
+#define TARGET_ARM_TRANSLATE_A64_H
209
+- reconfigure guest local processors
52
+
210
+- set user's password
53
+void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
211
+- ...
54
+void arm_gen_condlabel(DisasContext *s);
212
+
55
+bool vfp_access_check(DisasContext *s);
213
+qemu-ga will read a system configuration file on startup (located at
56
+void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop);
214
+|CONFDIR|\ ``/qemu-ga.conf`` by default), then parse remaining
57
+void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop);
215
+configuration options on the command line. For the same key, the last
58
+void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop);
216
+option wins, but the lists accumulate (see below for configuration
59
+void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop);
217
+file format).
60
+
218
+
61
+static inline TCGv_i32 load_cpu_offset(int offset)
219
+Options
62
+{
220
+-------
63
+ TCGv_i32 tmp = tcg_temp_new_i32();
221
+
64
+ tcg_gen_ld_i32(tmp, cpu_env, offset);
222
+.. program:: qemu-ga
65
+ return tmp;
223
+
66
+}
224
+.. option:: -m, --method=METHOD
67
+
225
+
68
+#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
226
+ Transport method: one of ``unix-listen``, ``virtio-serial``, or
69
+
227
+ ``isa-serial`` (``virtio-serial`` is the default).
70
+static inline void store_cpu_offset(TCGv_i32 var, int offset)
228
+
71
+{
229
+.. option:: -p, --path=PATH
72
+ tcg_gen_st_i32(var, cpu_env, offset);
230
+
73
+ tcg_temp_free_i32(var);
231
+ Device/socket path (the default for virtio-serial is
74
+}
232
+ ``/dev/virtio-ports/org.qemu.guest_agent.0``,
75
+
233
+ the default for isa-serial is ``/dev/ttyS0``)
76
+#define store_cpu_field(var, name) \
234
+
77
+ store_cpu_offset(var, offsetof(CPUARMState, name))
235
+.. option:: -l, --logfile=PATH
78
+
236
+
79
+/* Create a new temporary and set it to the value of a CPU register. */
237
+ Set log file path (default is stderr).
80
+static inline TCGv_i32 load_reg(DisasContext *s, int reg)
238
+
81
+{
239
+.. option:: -f, --pidfile=PATH
82
+ TCGv_i32 tmp = tcg_temp_new_i32();
240
+
83
+ load_reg_var(s, tmp, reg);
241
+ Specify pid file (default is ``/var/run/qemu-ga.pid``).
84
+ return tmp;
242
+
85
+}
243
+.. option:: -F, --fsfreeze-hook=PATH
86
+
244
+
87
+#endif
245
+ Enable fsfreeze hook. Accepts an optional argument that specifies
88
diff --git a/target/arm/translate.c b/target/arm/translate.c
246
+ script to run on freeze/thaw. Script will be called with
89
index XXXXXXX..XXXXXXX 100644
247
+ 'freeze'/'thaw' arguments accordingly (default is
90
--- a/target/arm/translate.c
248
+ |CONFDIR|\ ``/fsfreeze-hook``). If using -F with an argument, do
91
+++ b/target/arm/translate.c
249
+ not follow -F with a space (for example:
250
+ ``-F/var/run/fsfreezehook.sh``).
251
+
252
+.. option:: -t, --statedir=PATH
253
+
254
+ Specify the directory to store state information (absolute paths only,
255
+ default is ``/var/run``).
256
+
257
+.. option:: -v, --verbose
258
+
259
+ Log extra debugging information.
260
+
261
+.. option:: -V, --version
262
+
263
+ Print version information and exit.
264
+
265
+.. option:: -d, --daemon
266
+
267
+ Daemonize after startup (detach from terminal).
268
+
269
+.. option:: -b, --blacklist=LIST
270
+
271
+ Comma-separated list of RPCs to disable (no spaces, ``?`` to list
272
+ available RPCs).
273
+
274
+.. option:: -D, --dump-conf
275
+
276
+ Dump the configuration in a format compatible with ``qemu-ga.conf``
277
+ and exit.
278
+
279
+.. option:: -h, --help
280
+
281
+ Display this help and exit.
282
+
283
+Files
284
+-----
285
+
286
+
287
+The syntax of the ``qemu-ga.conf`` configuration file follows the
288
+Desktop Entry Specification, here is a quick summary: it consists of
289
+groups of key-value pairs, interspersed with comments.
290
+
291
+::
292
+
293
+ # qemu-ga configuration sample
294
+ [general]
295
+ daemonize = 0
296
+ pidfile = /var/run/qemu-ga.pid
297
+ verbose = 0
298
+ method = virtio-serial
299
+ path = /dev/virtio-ports/org.qemu.guest_agent.0
300
+ statedir = /var/run
301
+
302
+The list of keys follows the command line options:
303
+
304
+============= ===========
305
+Key Key type
306
+============= ===========
307
+daemon boolean
308
+method string
309
+path string
310
+logfile string
311
+pidfile string
312
+fsfreeze-hook string
313
+statedir string
314
+verbose boolean
315
+blacklist string list
316
+============= ===========
317
+
318
+See also
319
+--------
320
+
321
+:manpage:`qemu(1)`
322
diff --git a/qemu-doc.texi b/qemu-doc.texi
323
index XXXXXXX..XXXXXXX 100644
324
--- a/qemu-doc.texi
325
+++ b/qemu-doc.texi
326
@@ -XXX,XX +XXX,XX @@ so should only be used with trusted guest OS.
327
328
@c man end
329
330
-@node QEMU Guest Agent
331
-@chapter QEMU Guest Agent invocation
332
-
333
-@include qemu-ga.texi
334
-
335
@node QEMU User space emulator
336
@chapter QEMU User space emulator
337
338
diff --git a/qemu-ga.texi b/qemu-ga.texi
339
deleted file mode 100644
340
index XXXXXXX..XXXXXXX
341
--- a/qemu-ga.texi
342
+++ /dev/null
92
@@ -XXX,XX +XXX,XX @@
343
@@ -XXX,XX +XXX,XX @@
93
#define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
344
-@example
94
345
-@c man begin SYNOPSIS
95
#include "translate.h"
346
-@command{qemu-ga} [@var{OPTIONS}]
96
+#include "translate-a32.h"
347
-@c man end
97
348
-@end example
98
#if defined(CONFIG_USER_ONLY)
349
-
99
#define IS_USER(s) 1
350
-@c man begin DESCRIPTION
100
@@ -XXX,XX +XXX,XX @@ void arm_translate_init(void)
351
-
101
}
352
-The QEMU Guest Agent is a daemon intended to be run within virtual
102
353
-machines. It allows the hypervisor host to perform various operations
103
/* Generate a label used for skipping this instruction */
354
-in the guest, such as:
104
-static void arm_gen_condlabel(DisasContext *s)
355
-
105
+void arm_gen_condlabel(DisasContext *s)
356
-@itemize
106
{
357
-@item
107
if (!s->condjmp) {
358
-get information from the guest
108
s->condlabel = gen_new_label();
359
-@item
109
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
360
-set the guest's system time
110
}
361
-@item
111
}
362
-read/write a file
112
363
-@item
113
-static inline TCGv_i32 load_cpu_offset(int offset)
364
-sync and freeze the filesystems
114
-{
365
-@item
115
- TCGv_i32 tmp = tcg_temp_new_i32();
366
-suspend the guest
116
- tcg_gen_ld_i32(tmp, cpu_env, offset);
367
-@item
117
- return tmp;
368
-reconfigure guest local processors
118
-}
369
-@item
119
-
370
-set user's password
120
-#define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
371
-@item
121
-
372
-...
122
-static inline void store_cpu_offset(TCGv_i32 var, int offset)
373
-@end itemize
123
-{
374
-
124
- tcg_gen_st_i32(var, cpu_env, offset);
375
-qemu-ga will read a system configuration file on startup (located at
125
- tcg_temp_free_i32(var);
376
-@file{@value{CONFDIR}/qemu-ga.conf} by default), then parse remaining
126
-}
377
-configuration options on the command line. For the same key, the last
127
-
378
-option wins, but the lists accumulate (see below for configuration
128
-#define store_cpu_field(var, name) \
379
-file format).
129
- store_cpu_offset(var, offsetof(CPUARMState, name))
380
-
130
-
381
-@c man end
131
/* The architectural value of PC. */
382
-
132
static uint32_t read_pc(DisasContext *s)
383
-@c man begin OPTIONS
133
{
384
-@table @option
134
@@ -XXX,XX +XXX,XX @@ static uint32_t read_pc(DisasContext *s)
385
-@item -m, --method=@var{method}
135
}
386
- Transport method: one of @samp{unix-listen}, @samp{virtio-serial}, or
136
387
- @samp{isa-serial} (@samp{virtio-serial} is the default).
137
/* Set a variable to the value of a CPU register. */
388
-
138
-static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
389
-@item -p, --path=@var{path}
139
+void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
390
- Device/socket path (the default for virtio-serial is
140
{
391
- @samp{/dev/virtio-ports/org.qemu.guest_agent.0},
141
if (reg == 15) {
392
- the default for isa-serial is @samp{/dev/ttyS0})
142
tcg_gen_movi_i32(var, read_pc(s));
393
-
143
@@ -XXX,XX +XXX,XX @@ static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
394
-@item -l, --logfile=@var{path}
144
}
395
- Set log file path (default is stderr).
145
}
396
-
146
397
-@item -f, --pidfile=@var{path}
147
-/* Create a new temporary and set it to the value of a CPU register. */
398
- Specify pid file (default is @samp{/var/run/qemu-ga.pid}).
148
-static inline TCGv_i32 load_reg(DisasContext *s, int reg)
399
-
149
-{
400
-@item -F, --fsfreeze-hook=@var{path}
150
- TCGv_i32 tmp = tcg_temp_new_i32();
401
- Enable fsfreeze hook. Accepts an optional argument that specifies
151
- load_reg_var(s, tmp, reg);
402
- script to run on freeze/thaw. Script will be called with
152
- return tmp;
403
- 'freeze'/'thaw' arguments accordingly (default is
153
-}
404
- @samp{@value{CONFDIR}/fsfreeze-hook}). If using -F with an argument, do
154
-
405
- not follow -F with a space (for example:
155
/*
406
- @samp{-F/var/run/fsfreezehook.sh}).
156
* Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
407
-
157
* This is used for load/store for which use of PC implies (literal),
408
-@item -t, --statedir=@var{path}
158
@@ -XXX,XX +XXX,XX @@ static inline void vfp_store_reg32(TCGv_i32 var, int reg)
409
- Specify the directory to store state information (absolute paths only,
159
tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
410
- default is @samp{/var/run}).
160
}
411
-
161
412
-@item -v, --verbose
162
-static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
413
- Log extra debugging information.
163
+void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
414
-
164
{
415
-@item -V, --version
165
long off = neon_element_offset(reg, ele, memop);
416
- Print version information and exit.
166
417
-
167
@@ -XXX,XX +XXX,XX @@ static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
418
-@item -d, --daemon
168
}
419
- Daemonize after startup (detach from terminal).
169
}
420
-
170
421
-@item -b, --blacklist=@var{list}
171
-static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
422
- Comma-separated list of RPCs to disable (no spaces, @samp{?} to list
172
+void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
423
- available RPCs).
173
{
424
-
174
long off = neon_element_offset(reg, ele, memop);
425
-@item -D, --dump-conf
175
426
- Dump the configuration in a format compatible with @file{qemu-ga.conf}
176
@@ -XXX,XX +XXX,XX @@ static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
427
- and exit.
177
}
428
-
178
}
429
-@item -h, --help
179
430
- Display this help and exit.
180
-static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
431
-@end table
181
+void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
432
-
182
{
433
-@c man end
183
long off = neon_element_offset(reg, ele, memop);
434
-
184
435
-@c man begin FILES
185
@@ -XXX,XX +XXX,XX @@ static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
436
-
186
}
437
-The syntax of the @file{qemu-ga.conf} configuration file follows the
187
}
438
-Desktop Entry Specification, here is a quick summary: it consists of
188
439
-groups of key-value pairs, interspersed with comments.
189
-static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
440
-
190
+void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
441
-@example
191
{
442
-# qemu-ga configuration sample
192
long off = neon_element_offset(reg, ele, memop);
443
-[general]
193
444
-daemonize = 0
194
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c.inc
445
-pidfile = /var/run/qemu-ga.pid
195
index XXXXXXX..XXXXXXX 100644
446
-verbose = 0
196
--- a/target/arm/translate-vfp.c.inc
447
-method = virtio-serial
197
+++ b/target/arm/translate-vfp.c.inc
448
-path = /dev/virtio-ports/org.qemu.guest_agent.0
198
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
449
-statedir = /var/run
199
* The most usual kind of VFP access check, for everything except
450
-@end example
200
* FMXR/FMRX to the always-available special registers.
451
-
201
*/
452
-The list of keys follows the command line options:
202
-static bool vfp_access_check(DisasContext *s)
453
-@table @option
203
+bool vfp_access_check(DisasContext *s)
454
-@item daemon= boolean
204
{
455
-@item method= string
205
return full_vfp_access_check(s, false);
456
-@item path= string
206
}
457
-@item logfile= string
458
-@item pidfile= string
459
-@item fsfreeze-hook= string
460
-@item statedir= string
461
-@item verbose= boolean
462
-@item blacklist= string list
463
-@end table
464
-
465
-@c man end
466
-
467
-@ignore
468
-
469
-@setfilename qemu-ga
470
-@settitle QEMU Guest Agent
471
-
472
-@c man begin AUTHOR
473
-Michael Roth <mdroth@linux.vnet.ibm.com>
474
-@c man end
475
-
476
-@c man begin SEEALSO
477
-qemu(1)
478
-@c man end
479
-
480
-@end ignore
207
--
481
--
208
2.20.1
482
2.20.1
209
483
210
484
diff view generated by jsdifflib
Deleted patch
1
Make the remaining functions which are needed by translate-vfp.c.inc
2
global.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-8-peter.maydell@linaro.org
8
---
9
target/arm/translate-a32.h | 18 ++++++++++++++++++
10
target/arm/translate.c | 25 ++++++++-----------------
11
2 files changed, 26 insertions(+), 17 deletions(-)
12
13
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a32.h
16
+++ b/target/arm/translate-a32.h
17
@@ -XXX,XX +XXX,XX @@ void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop);
18
void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop);
19
void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop);
20
void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop);
21
+TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs);
22
+void gen_set_cpsr(TCGv_i32 var, uint32_t mask);
23
+void gen_set_condexec(DisasContext *s);
24
+void gen_set_pc_im(DisasContext *s, target_ulong val);
25
+void gen_lookup_tb(DisasContext *s);
26
+long vfp_reg_offset(bool dp, unsigned reg);
27
+long neon_full_reg_offset(unsigned reg);
28
29
static inline TCGv_i32 load_cpu_offset(int offset)
30
{
31
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 load_reg(DisasContext *s, int reg)
32
return tmp;
33
}
34
35
+void store_reg(DisasContext *s, int reg, TCGv_i32 var);
36
+
37
void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
38
TCGv_i32 a32, int index, MemOp opc);
39
void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
40
@@ -XXX,XX +XXX,XX @@ DO_GEN_ST(32, MO_UL)
41
#undef DO_GEN_LD
42
#undef DO_GEN_ST
43
44
+#if defined(CONFIG_USER_ONLY)
45
+#define IS_USER(s) 1
46
+#else
47
+#define IS_USER(s) (s->user)
48
+#endif
49
+
50
+/* Set NZCV flags from the high 4 bits of var. */
51
+#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
52
+
53
#endif
54
diff --git a/target/arm/translate.c b/target/arm/translate.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/translate.c
57
+++ b/target/arm/translate.c
58
@@ -XXX,XX +XXX,XX @@
59
#include "translate.h"
60
#include "translate-a32.h"
61
62
-#if defined(CONFIG_USER_ONLY)
63
-#define IS_USER(s) 1
64
-#else
65
-#define IS_USER(s) (s->user)
66
-#endif
67
-
68
/* These are TCG temporaries used only by the legacy iwMMXt decoder */
69
static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
70
/* These are TCG globals which alias CPUARMState fields */
71
@@ -XXX,XX +XXX,XX @@ void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
72
* This is used for load/store for which use of PC implies (literal),
73
* or ADD that implies ADR.
74
*/
75
-static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
76
+TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
77
{
78
TCGv_i32 tmp = tcg_temp_new_i32();
79
80
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
81
82
/* Set a CPU register. The source must be a temporary and will be
83
marked as dead. */
84
-static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
85
+void store_reg(DisasContext *s, int reg, TCGv_i32 var)
86
{
87
if (reg == 15) {
88
/* In Thumb mode, we must ignore bit 0.
89
@@ -XXX,XX +XXX,XX @@ static void store_sp_checked(DisasContext *s, TCGv_i32 var)
90
#define gen_sxtb16(var) gen_helper_sxtb16(var, var)
91
#define gen_uxtb16(var) gen_helper_uxtb16(var, var)
92
93
-
94
-static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
95
+void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
96
{
97
TCGv_i32 tmp_mask = tcg_const_i32(mask);
98
gen_helper_cpsr_write(cpu_env, var, tmp_mask);
99
tcg_temp_free_i32(tmp_mask);
100
}
101
-/* Set NZCV flags from the high 4 bits of var. */
102
-#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
103
104
static void gen_exception_internal(int excp)
105
{
106
@@ -XXX,XX +XXX,XX @@ void arm_gen_test_cc(int cc, TCGLabel *label)
107
arm_free_cc(&cmp);
108
}
109
110
-static inline void gen_set_condexec(DisasContext *s)
111
+void gen_set_condexec(DisasContext *s)
112
{
113
if (s->condexec_mask) {
114
uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
115
@@ -XXX,XX +XXX,XX @@ static inline void gen_set_condexec(DisasContext *s)
116
}
117
}
118
119
-static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
120
+void gen_set_pc_im(DisasContext *s, target_ulong val)
121
{
122
tcg_gen_movi_i32(cpu_R[15], val);
123
}
124
@@ -XXX,XX +XXX,XX @@ static void gen_exception_el(DisasContext *s, int excp, uint32_t syn,
125
}
126
127
/* Force a TB lookup after an instruction that changes the CPU state. */
128
-static inline void gen_lookup_tb(DisasContext *s)
129
+void gen_lookup_tb(DisasContext *s)
130
{
131
tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
132
s->base.is_jmp = DISAS_EXIT;
133
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
134
/*
135
* Return the offset of a "full" NEON Dreg.
136
*/
137
-static long neon_full_reg_offset(unsigned reg)
138
+long neon_full_reg_offset(unsigned reg)
139
{
140
return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
141
}
142
@@ -XXX,XX +XXX,XX @@ static long neon_element_offset(int reg, int element, MemOp memop)
143
}
144
145
/* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
146
-static long vfp_reg_offset(bool dp, unsigned reg)
147
+long vfp_reg_offset(bool dp, unsigned reg)
148
{
149
if (dp) {
150
return neon_element_offset(reg, 0, MO_64);
151
--
152
2.20.1
153
154
diff view generated by jsdifflib
Deleted patch
1
Switch translate-vfp.c.inc from being #included into translate.c
2
to being its own compilation unit.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-9-peter.maydell@linaro.org
8
---
9
target/arm/translate-a32.h | 2 ++
10
target/arm/{translate-vfp.c.inc => translate-vfp.c} | 12 +++++++-----
11
target/arm/translate.c | 3 +--
12
target/arm/meson.build | 5 +++--
13
4 files changed, 13 insertions(+), 9 deletions(-)
14
rename target/arm/{translate-vfp.c.inc => translate-vfp.c} (99%)
15
16
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a32.h
19
+++ b/target/arm/translate-a32.h
20
@@ -XXX,XX +XXX,XX @@
21
22
/* Prototypes for autogenerated disassembler functions */
23
bool disas_m_nocp(DisasContext *dc, uint32_t insn);
24
+bool disas_vfp(DisasContext *s, uint32_t insn);
25
+bool disas_vfp_uncond(DisasContext *s, uint32_t insn);
26
27
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
28
void arm_gen_condlabel(DisasContext *s);
29
diff --git a/target/arm/translate-vfp.c.inc b/target/arm/translate-vfp.c
30
similarity index 99%
31
rename from target/arm/translate-vfp.c.inc
32
rename to target/arm/translate-vfp.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate-vfp.c.inc
35
+++ b/target/arm/translate-vfp.c
36
@@ -XXX,XX +XXX,XX @@
37
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
38
*/
39
40
-/*
41
- * This file is intended to be included from translate.c; it uses
42
- * some macros and definitions provided by that file.
43
- * It might be possible to convert it to a standalone .c file eventually.
44
- */
45
+#include "qemu/osdep.h"
46
+#include "tcg/tcg-op.h"
47
+#include "tcg/tcg-op-gvec.h"
48
+#include "exec/exec-all.h"
49
+#include "exec/gen-icount.h"
50
+#include "translate.h"
51
+#include "translate-a32.h"
52
53
/* Include the generated VFP decoder */
54
#include "decode-vfp.c.inc"
55
diff --git a/target/arm/translate.c b/target/arm/translate.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/arm/translate.c
58
+++ b/target/arm/translate.c
59
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
60
61
#define ARM_CP_RW_BIT (1 << 20)
62
63
-/* Include the VFP and Neon decoders */
64
-#include "translate-vfp.c.inc"
65
+/* Include the Neon decoder */
66
#include "translate-neon.c.inc"
67
68
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
69
diff --git a/target/arm/meson.build b/target/arm/meson.build
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/meson.build
72
+++ b/target/arm/meson.build
73
@@ -XXX,XX +XXX,XX @@ gen = [
74
decodetree.process('neon-shared.decode', extra_args: '--static-decode=disas_neon_shared'),
75
decodetree.process('neon-dp.decode', extra_args: '--static-decode=disas_neon_dp'),
76
decodetree.process('neon-ls.decode', extra_args: '--static-decode=disas_neon_ls'),
77
- decodetree.process('vfp.decode', extra_args: '--static-decode=disas_vfp'),
78
- decodetree.process('vfp-uncond.decode', extra_args: '--static-decode=disas_vfp_uncond'),
79
+ decodetree.process('vfp.decode', extra_args: '--decode=disas_vfp'),
80
+ decodetree.process('vfp-uncond.decode', extra_args: '--decode=disas_vfp_uncond'),
81
decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
82
decodetree.process('a32.decode', extra_args: '--static-decode=disas_a32'),
83
decodetree.process('a32-uncond.decode', extra_args: '--static-decode=disas_a32_uncond'),
84
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
85
'tlb_helper.c',
86
'translate.c',
87
'translate-m-nocp.c',
88
+ 'translate-vfp.c',
89
'vec_helper.c',
90
'vfp_helper.c',
91
'cpu_tcg.c',
92
--
93
2.20.1
94
95
diff view generated by jsdifflib
Deleted patch
1
The function vfp_reg_ptr() is used only in translate-neon.c.inc;
2
move it there.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-10-peter.maydell@linaro.org
8
---
9
target/arm/translate.c | 7 -------
10
target/arm/translate-neon.c.inc | 7 +++++++
11
2 files changed, 7 insertions(+), 7 deletions(-)
12
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
16
+++ b/target/arm/translate.c
17
@@ -XXX,XX +XXX,XX @@ void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
18
}
19
}
20
21
-static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
22
-{
23
- TCGv_ptr ret = tcg_temp_new_ptr();
24
- tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
25
- return ret;
26
-}
27
-
28
#define ARM_CP_RW_BIT (1 << 20)
29
30
/* Include the Neon decoder */
31
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c.inc
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate-neon.c.inc
34
+++ b/target/arm/translate-neon.c.inc
35
@@ -XXX,XX +XXX,XX @@ static inline int neon_3same_fp_size(DisasContext *s, int x)
36
#include "decode-neon-ls.c.inc"
37
#include "decode-neon-shared.c.inc"
38
39
+static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
40
+{
41
+ TCGv_ptr ret = tcg_temp_new_ptr();
42
+ tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
43
+ return ret;
44
+}
45
+
46
static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
47
{
48
long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
49
--
50
2.20.1
51
52
diff view generated by jsdifflib
Deleted patch
1
The VFPGenFixPointFn typedef is unused; delete it.
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210430132740.10391-11-peter.maydell@linaro.org
7
---
8
target/arm/translate.c | 2 --
9
1 file changed, 2 deletions(-)
10
11
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate.c
14
+++ b/target/arm/translate.c
15
@@ -XXX,XX +XXX,XX @@ static const char * const regnames[] =
16
/* Function prototypes for gen_ functions calling Neon helpers. */
17
typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
18
TCGv_i32, TCGv_i32);
19
-/* Function prototypes for gen_ functions for fix point conversions */
20
-typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
21
22
/* initialize TCG globals. */
23
void arm_translate_init(void)
24
--
25
2.20.1
26
27
diff view generated by jsdifflib
Deleted patch
1
Move the NeonGenThreeOpEnvFn typedef to translate.h together
2
with the other similar typedefs.
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: 20210430132740.10391-12-peter.maydell@linaro.org
8
---
9
target/arm/translate.h | 2 ++
10
target/arm/translate.c | 3 ---
11
2 files changed, 2 insertions(+), 3 deletions(-)
12
13
diff --git a/target/arm/translate.h b/target/arm/translate.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.h
16
+++ b/target/arm/translate.h
17
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenOneOpFn(TCGv_i32, TCGv_i32);
18
typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
19
typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
20
typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
21
+typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
22
+ TCGv_i32, TCGv_i32);
23
typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
24
typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
25
typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
26
diff --git a/target/arm/translate.c b/target/arm/translate.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate.c
29
+++ b/target/arm/translate.c
30
@@ -XXX,XX +XXX,XX @@ static const char * const regnames[] =
31
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
32
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
33
34
-/* Function prototypes for gen_ functions calling Neon helpers. */
35
-typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
36
- TCGv_i32, TCGv_i32);
37
38
/* initialize TCG globals. */
39
void arm_translate_init(void)
40
--
41
2.20.1
42
43
diff view generated by jsdifflib
Deleted patch
1
Make the remaining functions needed by the translate-neon code
2
global.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-13-peter.maydell@linaro.org
8
---
9
target/arm/translate-a32.h | 8 ++++++++
10
target/arm/translate.c | 10 ++--------
11
2 files changed, 10 insertions(+), 8 deletions(-)
12
13
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a32.h
16
+++ b/target/arm/translate-a32.h
17
@@ -XXX,XX +XXX,XX @@ void gen_set_pc_im(DisasContext *s, target_ulong val);
18
void gen_lookup_tb(DisasContext *s);
19
long vfp_reg_offset(bool dp, unsigned reg);
20
long neon_full_reg_offset(unsigned reg);
21
+long neon_element_offset(int reg, int element, MemOp memop);
22
+void gen_rev16(TCGv_i32 dest, TCGv_i32 var);
23
24
static inline TCGv_i32 load_cpu_offset(int offset)
25
{
26
@@ -XXX,XX +XXX,XX @@ DO_GEN_ST(32, MO_UL)
27
/* Set NZCV flags from the high 4 bits of var. */
28
#define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
29
30
+/* Swap low and high halfwords. */
31
+static inline void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
32
+{
33
+ tcg_gen_rotri_i32(dest, var, 16);
34
+}
35
+
36
#endif
37
diff --git a/target/arm/translate.c b/target/arm/translate.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/translate.c
40
+++ b/target/arm/translate.c
41
@@ -XXX,XX +XXX,XX @@ static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
42
}
43
44
/* Byteswap each halfword. */
45
-static void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
46
+void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
47
{
48
TCGv_i32 tmp = tcg_temp_new_i32();
49
TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
50
@@ -XXX,XX +XXX,XX @@ static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
51
tcg_gen_ext16s_i32(dest, var);
52
}
53
54
-/* Swap low and high halfwords. */
55
-static void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
56
-{
57
- tcg_gen_rotri_i32(dest, var, 16);
58
-}
59
-
60
/* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
61
tmp = (t0 ^ t1) & 0x8000;
62
t0 &= ~0x8000;
63
@@ -XXX,XX +XXX,XX @@ long neon_full_reg_offset(unsigned reg)
64
* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
65
* where 0 is the least significant end of the register.
66
*/
67
-static long neon_element_offset(int reg, int element, MemOp memop)
68
+long neon_element_offset(int reg, int element, MemOp memop)
69
{
70
int element_size = 1 << (memop & MO_SIZE);
71
int ofs = element * element_size;
72
--
73
2.20.1
74
75
diff view generated by jsdifflib
Deleted patch
1
Switch translate-neon.c.inc from being #included into translate.c
2
to being its own compilation unit.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210430132740.10391-14-peter.maydell@linaro.org
8
---
9
target/arm/translate-a32.h | 3 +++
10
.../arm/{translate-neon.c.inc => translate-neon.c} | 12 +++++++-----
11
target/arm/translate.c | 3 ---
12
target/arm/meson.build | 7 ++++---
13
4 files changed, 14 insertions(+), 11 deletions(-)
14
rename target/arm/{translate-neon.c.inc => translate-neon.c} (99%)
15
16
diff --git a/target/arm/translate-a32.h b/target/arm/translate-a32.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a32.h
19
+++ b/target/arm/translate-a32.h
20
@@ -XXX,XX +XXX,XX @@
21
bool disas_m_nocp(DisasContext *dc, uint32_t insn);
22
bool disas_vfp(DisasContext *s, uint32_t insn);
23
bool disas_vfp_uncond(DisasContext *s, uint32_t insn);
24
+bool disas_neon_dp(DisasContext *s, uint32_t insn);
25
+bool disas_neon_ls(DisasContext *s, uint32_t insn);
26
+bool disas_neon_shared(DisasContext *s, uint32_t insn);
27
28
void load_reg_var(DisasContext *s, TCGv_i32 var, int reg);
29
void arm_gen_condlabel(DisasContext *s);
30
diff --git a/target/arm/translate-neon.c.inc b/target/arm/translate-neon.c
31
similarity index 99%
32
rename from target/arm/translate-neon.c.inc
33
rename to target/arm/translate-neon.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-neon.c.inc
36
+++ b/target/arm/translate-neon.c
37
@@ -XXX,XX +XXX,XX @@
38
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
39
*/
40
41
-/*
42
- * This file is intended to be included from translate.c; it uses
43
- * some macros and definitions provided by that file.
44
- * It might be possible to convert it to a standalone .c file eventually.
45
- */
46
+#include "qemu/osdep.h"
47
+#include "tcg/tcg-op.h"
48
+#include "tcg/tcg-op-gvec.h"
49
+#include "exec/exec-all.h"
50
+#include "exec/gen-icount.h"
51
+#include "translate.h"
52
+#include "translate-a32.h"
53
54
static inline int plus1(DisasContext *s, int x)
55
{
56
diff --git a/target/arm/translate.c b/target/arm/translate.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate.c
59
+++ b/target/arm/translate.c
60
@@ -XXX,XX +XXX,XX @@ void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
61
62
#define ARM_CP_RW_BIT (1 << 20)
63
64
-/* Include the Neon decoder */
65
-#include "translate-neon.c.inc"
66
-
67
static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
68
{
69
tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
70
diff --git a/target/arm/meson.build b/target/arm/meson.build
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/arm/meson.build
73
+++ b/target/arm/meson.build
74
@@ -XXX,XX +XXX,XX @@
75
gen = [
76
decodetree.process('sve.decode', extra_args: '--decode=disas_sve'),
77
- decodetree.process('neon-shared.decode', extra_args: '--static-decode=disas_neon_shared'),
78
- decodetree.process('neon-dp.decode', extra_args: '--static-decode=disas_neon_dp'),
79
- decodetree.process('neon-ls.decode', extra_args: '--static-decode=disas_neon_ls'),
80
+ decodetree.process('neon-shared.decode', extra_args: '--decode=disas_neon_shared'),
81
+ decodetree.process('neon-dp.decode', extra_args: '--decode=disas_neon_dp'),
82
+ decodetree.process('neon-ls.decode', extra_args: '--decode=disas_neon_ls'),
83
decodetree.process('vfp.decode', extra_args: '--decode=disas_vfp'),
84
decodetree.process('vfp-uncond.decode', extra_args: '--decode=disas_vfp_uncond'),
85
decodetree.process('m-nocp.decode', extra_args: '--decode=disas_m_nocp'),
86
@@ -XXX,XX +XXX,XX @@ arm_ss.add(files(
87
'tlb_helper.c',
88
'translate.c',
89
'translate-m-nocp.c',
90
+ 'translate-neon.c',
91
'translate-vfp.c',
92
'vec_helper.c',
93
'vfp_helper.c',
94
--
95
2.20.1
96
97
diff view generated by jsdifflib
Deleted patch
1
The WFI insn is not system-mode only, though it doesn't usually make
2
a huge amount of sense for userspace code to execute it. Currently
3
if you try it in qemu-arm then the helper function will raise an
4
EXCP_HLT exception, which is not covered by the switch in cpu_loop()
5
and results in an abort:
6
1
7
qemu: unhandled CPU exception 0x10001 - aborting
8
R00=00000001 R01=408003e4 R02=408003ec R03=000102ec
9
R04=00010a28 R05=00010158 R06=00087460 R07=00010158
10
R08=00000000 R09=00000000 R10=00085b7c R11=408002a4
11
R12=408002b8 R13=408002a0 R14=0001057c R15=000102f8
12
PSR=60000010 -ZC- A usr32
13
qemu:handle_cpu_signal received signal outside vCPU context @ pc=0x7fcbfa4f0a12
14
15
Make the WFI helper function return immediately in the usermode
16
emulator. This turns WFI into a NOP, which is OK because:
17
* architecturally "WFI is a NOP" is a permitted implementation
18
* aarch64 Linux kernels use the SCTLR_EL1.nTWI bit to trap
19
userspace WFI and NOP it (though aarch32 kernels currently
20
just let WFI do whatever it would do)
21
22
We could in theory make the translate.c code special case user-mode
23
emulation and NOP the insn entirely rather than making the helper
24
do nothing, but because no real world code will be trying to
25
execute WFI we don't care about efficiency and the helper provides
26
a single place where we can make the change rather than having
27
to touch multiple places in translate.c and translate-a64.c.
28
29
Fixes: https://bugs.launchpad.net/qemu/+bug/1926759
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
32
Message-id: 20210430162212.825-1-peter.maydell@linaro.org
33
---
34
target/arm/op_helper.c | 12 ++++++++++++
35
1 file changed, 12 insertions(+)
36
37
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/op_helper.c
40
+++ b/target/arm/op_helper.c
41
@@ -XXX,XX +XXX,XX @@ static inline int check_wfx_trap(CPUARMState *env, bool is_wfe)
42
43
void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
44
{
45
+#ifdef CONFIG_USER_ONLY
46
+ /*
47
+ * WFI in the user-mode emulator is technically permitted but not
48
+ * something any real-world code would do. AArch64 Linux kernels
49
+ * trap it via SCTRL_EL1.nTWI and make it an (expensive) NOP;
50
+ * AArch32 kernels don't trap it so it will delay a bit.
51
+ * For QEMU, make it NOP here, because trying to raise EXCP_HLT
52
+ * would trigger an abort.
53
+ */
54
+ return;
55
+#else
56
CPUState *cs = env_cpu(env);
57
int target_el = check_wfx_trap(env, false);
58
59
@@ -XXX,XX +XXX,XX @@ void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
60
cs->exception_index = EXCP_HLT;
61
cs->halted = 1;
62
cpu_loop_exit(cs);
63
+#endif
64
}
65
66
void HELPER(wfe)(CPUARMState *env)
67
--
68
2.20.1
69
70
diff view generated by jsdifflib
Deleted patch
1
The omap_mmc_reset() function resets its SD card via
2
device_legacy_reset(). We know that the SD card does not have a qbus
3
of its own, so the new device_cold_reset() function (which resets
4
both the device and its child buses) is equivalent here to
5
device_legacy_reset() and we can just switch to the new API.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210430222348.8514-1-peter.maydell@linaro.org
10
---
11
hw/sd/omap_mmc.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/sd/omap_mmc.c
17
+++ b/hw/sd/omap_mmc.c
18
@@ -XXX,XX +XXX,XX @@ void omap_mmc_reset(struct omap_mmc_s *host)
19
* into any bus, and we must reset it manually. When omap_mmc is
20
* QOMified this must move into the QOM reset function.
21
*/
22
- device_legacy_reset(DEVICE(host->card));
23
+ device_cold_reset(DEVICE(host->card));
24
}
25
26
static uint64_t omap_mmc_read(void *opaque, hwaddr offset,
27
--
28
2.20.1
29
30
diff view generated by jsdifflib
Deleted patch
1
Both os-win32.h and os-posix.h include system header files. Instead
2
of having osdep.h include them inside its 'extern "C"' block, make
3
these headers handle that themselves, so that we don't include the
4
system headers inside 'extern "C"'.
5
1
6
This doesn't fix any current problems, but it's conceptually the
7
right way to handle system headers.
8
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
---
12
include/qemu/osdep.h | 8 ++++----
13
include/sysemu/os-posix.h | 8 ++++++++
14
include/sysemu/os-win32.h | 8 ++++++++
15
3 files changed, 20 insertions(+), 4 deletions(-)
16
17
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/qemu/osdep.h
20
+++ b/include/qemu/osdep.h
21
@@ -XXX,XX +XXX,XX @@ QEMU_EXTERN_C int daemon(int, int);
22
*/
23
#include "glib-compat.h"
24
25
-#ifdef __cplusplus
26
-extern "C" {
27
-#endif
28
-
29
#ifdef _WIN32
30
#include "sysemu/os-win32.h"
31
#endif
32
@@ -XXX,XX +XXX,XX @@ extern "C" {
33
#include "sysemu/os-posix.h"
34
#endif
35
36
+#ifdef __cplusplus
37
+extern "C" {
38
+#endif
39
+
40
#include "qemu/typedefs.h"
41
42
/*
43
diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/include/sysemu/os-posix.h
46
+++ b/include/sysemu/os-posix.h
47
@@ -XXX,XX +XXX,XX @@
48
#include <sys/sysmacros.h>
49
#endif
50
51
+#ifdef __cplusplus
52
+extern "C" {
53
+#endif
54
+
55
void os_set_line_buffering(void);
56
void os_set_proc_name(const char *s);
57
void os_setup_signal_handling(void);
58
@@ -XXX,XX +XXX,XX @@ static inline void qemu_funlockfile(FILE *f)
59
funlockfile(f);
60
}
61
62
+#ifdef __cplusplus
63
+}
64
+#endif
65
+
66
#endif
67
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
68
index XXXXXXX..XXXXXXX 100644
69
--- a/include/sysemu/os-win32.h
70
+++ b/include/sysemu/os-win32.h
71
@@ -XXX,XX +XXX,XX @@
72
#include <windows.h>
73
#include <ws2tcpip.h>
74
75
+#ifdef __cplusplus
76
+extern "C" {
77
+#endif
78
+
79
#if defined(_WIN64)
80
/* On w64, setjmp is implemented by _setjmp which needs a second parameter.
81
* If this parameter is NULL, longjump does no stack unwinding.
82
@@ -XXX,XX +XXX,XX @@ ssize_t qemu_recv_wrap(int sockfd, void *buf, size_t len, int flags);
83
ssize_t qemu_recvfrom_wrap(int sockfd, void *buf, size_t len, int flags,
84
struct sockaddr *addr, socklen_t *addrlen);
85
86
+#ifdef __cplusplus
87
+}
88
+#endif
89
+
90
#endif
91
--
92
2.20.1
93
94
diff view generated by jsdifflib
Deleted patch
1
Make bswap.h handle being included outside an 'extern "C"' block:
2
all system headers are included first, then all declarations are
3
put inside an 'extern "C"' block.
4
1
5
This requires a little rearrangement as currently we have an ifdef
6
ladder that has some system includes and some local declarations
7
or definitions, and we need to separate those out.
8
9
We want to do this because dis-asm.h includes bswap.h, dis-asm.h
10
may need to be included from C++ files, and system headers should
11
not be included within 'extern "C"' blocks.
12
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
---
16
include/qemu/bswap.h | 26 ++++++++++++++++++++++----
17
1 file changed, 22 insertions(+), 4 deletions(-)
18
19
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/include/qemu/bswap.h
22
+++ b/include/qemu/bswap.h
23
@@ -XXX,XX +XXX,XX @@
24
#ifndef BSWAP_H
25
#define BSWAP_H
26
27
-#include "fpu/softfloat-types.h"
28
-
29
#ifdef CONFIG_MACHINE_BSWAP_H
30
# include <sys/endian.h>
31
# include <machine/bswap.h>
32
@@ -XXX,XX +XXX,XX @@
33
# include <endian.h>
34
#elif defined(CONFIG_BYTESWAP_H)
35
# include <byteswap.h>
36
+#define BSWAP_FROM_BYTESWAP
37
+# else
38
+#define BSWAP_FROM_FALLBACKS
39
+#endif /* ! CONFIG_MACHINE_BSWAP_H */
40
41
+#ifdef __cplusplus
42
+extern "C" {
43
+#endif
44
+
45
+#include "fpu/softfloat-types.h"
46
+
47
+#ifdef BSWAP_FROM_BYTESWAP
48
static inline uint16_t bswap16(uint16_t x)
49
{
50
return bswap_16(x);
51
@@ -XXX,XX +XXX,XX @@ static inline uint64_t bswap64(uint64_t x)
52
{
53
return bswap_64(x);
54
}
55
-# else
56
+#endif
57
+
58
+#ifdef BSWAP_FROM_FALLBACKS
59
static inline uint16_t bswap16(uint16_t x)
60
{
61
return (((x & 0x00ff) << 8) |
62
@@ -XXX,XX +XXX,XX @@ static inline uint64_t bswap64(uint64_t x)
63
((x & 0x00ff000000000000ULL) >> 40) |
64
((x & 0xff00000000000000ULL) >> 56));
65
}
66
-#endif /* ! CONFIG_MACHINE_BSWAP_H */
67
+#endif
68
+
69
+#undef BSWAP_FROM_BYTESWAP
70
+#undef BSWAP_FROM_FALLBACKS
71
72
static inline void bswap16s(uint16_t *s)
73
{
74
@@ -XXX,XX +XXX,XX @@ DO_STN_LDN_P(be)
75
#undef le_bswaps
76
#undef be_bswaps
77
78
+#ifdef __cplusplus
79
+}
80
+#endif
81
+
82
#endif /* BSWAP_H */
83
--
84
2.20.1
85
86
diff view generated by jsdifflib
Deleted patch
1
Make dis-asm.h handle being included outside an 'extern "C"' block;
2
this allows us to remove the 'extern "C"' blocks that our two C++
3
files that include it are using.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
---
8
include/disas/dis-asm.h | 12 ++++++++++--
9
disas/arm-a64.cc | 2 --
10
disas/nanomips.cpp | 2 --
11
3 files changed, 10 insertions(+), 6 deletions(-)
12
13
diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/include/disas/dis-asm.h
16
+++ b/include/disas/dis-asm.h
17
@@ -XXX,XX +XXX,XX @@
18
#ifndef DISAS_DIS_ASM_H
19
#define DISAS_DIS_ASM_H
20
21
+#include "qemu/bswap.h"
22
+
23
+#ifdef __cplusplus
24
+extern "C" {
25
+#endif
26
+
27
typedef void *PTR;
28
typedef uint64_t bfd_vma;
29
typedef int64_t bfd_signed_vma;
30
@@ -XXX,XX +XXX,XX @@ bool cap_disas_plugin(disassemble_info *info, uint64_t pc, size_t size);
31
32
/* from libbfd */
33
34
-#include "qemu/bswap.h"
35
-
36
static inline bfd_vma bfd_getl64(const bfd_byte *addr)
37
{
38
return ldq_le_p(addr);
39
@@ -XXX,XX +XXX,XX @@ static inline bfd_vma bfd_getb16(const bfd_byte *addr)
40
41
typedef bool bfd_boolean;
42
43
+#ifdef __cplusplus
44
+}
45
+#endif
46
+
47
#endif /* DISAS_DIS_ASM_H */
48
diff --git a/disas/arm-a64.cc b/disas/arm-a64.cc
49
index XXXXXXX..XXXXXXX 100644
50
--- a/disas/arm-a64.cc
51
+++ b/disas/arm-a64.cc
52
@@ -XXX,XX +XXX,XX @@
53
*/
54
55
#include "qemu/osdep.h"
56
-extern "C" {
57
#include "disas/dis-asm.h"
58
-}
59
60
#include "vixl/a64/disasm-a64.h"
61
62
diff --git a/disas/nanomips.cpp b/disas/nanomips.cpp
63
index XXXXXXX..XXXXXXX 100644
64
--- a/disas/nanomips.cpp
65
+++ b/disas/nanomips.cpp
66
@@ -XXX,XX +XXX,XX @@
67
*/
68
69
#include "qemu/osdep.h"
70
-extern "C" {
71
#include "disas/dis-asm.h"
72
-}
73
74
#include <cstring>
75
#include <stdexcept>
76
--
77
2.20.1
78
79
diff view generated by jsdifflib
Deleted patch
1
The MPS2 SCC device doesn't have any documentation of its properties;
2
add a "QEMU interface" format comment describing them.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20210504120912.23094-2-peter.maydell@linaro.org
7
---
8
include/hw/misc/mps2-scc.h | 12 ++++++++++++
9
1 file changed, 12 insertions(+)
10
11
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/include/hw/misc/mps2-scc.h
14
+++ b/include/hw/misc/mps2-scc.h
15
@@ -XXX,XX +XXX,XX @@
16
* (at your option) any later version.
17
*/
18
19
+/*
20
+ * This is a model of the Serial Communication Controller (SCC)
21
+ * block found in most MPS FPGA images.
22
+ *
23
+ * QEMU interface:
24
+ * + sysbus MMIO region 0: the register bank
25
+ * + QOM property "scc-cfg4": value of the read-only CFG4 register
26
+ * + QOM property "scc-aid": value of the read-only SCC_AID register
27
+ * + QOM property "scc-id": value of the read-only SCC_ID register
28
+ * + QOM property array "oscclk": reset values of the OSCCLK registers
29
+ * (which are accessed via the SYS_CFG channel provided by this device)
30
+ */
31
#ifndef MPS2_SCC_H
32
#define MPS2_SCC_H
33
34
--
35
2.20.1
36
37
diff view generated by jsdifflib