1
target-arm queue: this time around is all small fixes
1
target-arm queue: mostly aspeed changes from Cédric.
2
and changes.
3
2
4
thanks
3
thanks
5
-- PMM
4
-- PMM
6
5
7
The following changes since commit fec105c2abda8567ec15230429c41429b5ee307c:
6
The following changes since commit 85182c96de61f0b600bbe834d5a23e713162e892:
8
7
9
Merge remote-tracking branch 'remotes/kraxel/tags/audio-20190828-pull-request' into staging (2019-09-03 14:03:15 +0100)
8
Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20190912a' into staging (2019-09-13 14:37:48 +0100)
10
9
11
are available in the Git repository at:
10
are available in the Git repository at:
12
11
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190903
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190913
14
13
15
for you to fetch changes up to 5e5584c89f36b302c666bc6db535fd3f7ff35ad2:
14
for you to fetch changes up to 27a296fce9821e3608d537756cffa6e43a46df3b:
16
15
17
target/arm: Don't abort on M-profile exception return in linux-user mode (2019-09-03 16:20:35 +0100)
16
qemu-ga: Convert invocation documentation to rST (2019-09-13 16:05:01 +0100)
18
17
19
----------------------------------------------------------------
18
----------------------------------------------------------------
20
target-arm queue:
19
target-arm queue:
21
* Revert and correctly fix refactoring of unallocated_encoding()
20
* aspeed: add a GPIO controller to the SoC
22
* Take exceptions on ATS instructions when needed
21
* aspeed: Various refactorings
23
* aspeed/timer: Provide back-pressure information for short periods
22
* aspeed: Improve DMA controller modelling
24
* memory: Remove unused memory_region_iommu_replay_all()
25
* hw/arm/smmuv3: Log a guest error when decoding an invalid STE
26
* hw/arm/smmuv3: Remove spurious error messages on IOVA invalidations
27
* target/arm: Fix SMMLS argument order
28
* hw/arm: Use ARM_CPU_TYPE_NAME() macro when appropriate
29
* hw/arm: Correct reference counting for creation of various objects
30
* includes: remove stale [smp|max]_cpus externs
31
* tcg/README: fix typo
32
* atomic_template: fix indentation in GEN_ATOMIC_HELPER
23
* atomic_template: fix indentation in GEN_ATOMIC_HELPER
33
* include/exec/cpu-defs.h: fix typo
24
* qemu-ga: Convert invocation documentation to rST
34
* target/arm: Free TCG temps in trans_VMOV_64_sp()
35
* target/arm: Don't abort on M-profile exception return in linux-user mode
36
25
37
----------------------------------------------------------------
26
----------------------------------------------------------------
38
Alex Bennée (2):
27
Christian Svensson (1):
39
includes: remove stale [smp|max]_cpus externs
28
aspeed/smc: Calculate checksum on normal DMA
40
include/exec/cpu-defs.h: fix typo
41
29
42
Andrew Jeffery (1):
30
Cédric Le Goater (7):
43
aspeed/timer: Provide back-pressure information for short periods
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
44
38
45
Emilio G. Cota (2):
39
Emilio G. Cota (1):
46
tcg/README: fix typo s/afterwise/afterwards/
47
atomic_template: fix indentation in GEN_ATOMIC_HELPER
40
atomic_template: fix indentation in GEN_ATOMIC_HELPER
48
41
49
Eric Auger (3):
42
Peter Maydell (1):
50
memory: Remove unused memory_region_iommu_replay_all()
43
qemu-ga: Convert invocation documentation to rST
51
hw/arm/smmuv3: Log a guest error when decoding an invalid STE
52
hw/arm/smmuv3: Remove spurious error messages on IOVA invalidations
53
44
54
Peter Maydell (4):
45
Rashmica Gupta (2):
55
target/arm: Allow ARMCPRegInfo read/write functions to throw exceptions
46
hw/gpio: Add basic Aspeed GPIO model for AST2400 and AST2500
56
target/arm: Take exceptions on ATS instructions when needed
47
aspeed: add a GPIO controller to the SoC
57
target/arm: Free TCG temps in trans_VMOV_64_sp()
58
target/arm: Don't abort on M-profile exception return in linux-user mode
59
48
60
Philippe Mathieu-Daudé (6):
49
Makefile | 24 +-
61
hw/arm: Use ARM_CPU_TYPE_NAME() macro when appropriate
50
hw/gpio/Makefile.objs | 1 +
62
hw/arm: Use object_initialize_child for correct reference counting
51
accel/tcg/atomic_template.h | 2 +-
63
hw/arm: Use sysbus_init_child_obj for correct reference counting
52
include/hw/arm/aspeed_soc.h | 4 +-
64
hw/arm/fsl-imx: Add the cpu as child of the SoC object
53
include/hw/gpio/aspeed_gpio.h | 100 +++++
65
hw/dma/xilinx_axi: Use object_initialize_child for correct ref. counting
54
include/hw/misc/aspeed_scu.h | 21 +-
66
hw/net/xilinx_axi: Use object_initialize_child for correct ref. counting
55
include/hw/ssi/aspeed_smc.h | 7 +
56
hw/arm/aspeed.c | 2 +
57
hw/arm/aspeed_soc.c | 63 ++-
58
hw/gpio/aspeed_gpio.c | 884 ++++++++++++++++++++++++++++++++++++++++++
59
hw/misc/aspeed_scu.c | 102 ++---
60
hw/ssi/aspeed_smc.c | 335 +++++++++++++++-
61
hw/timer/aspeed_timer.c | 3 +-
62
MAINTAINERS | 2 +-
63
docs/conf.py | 18 +-
64
docs/interop/conf.py | 7 +
65
docs/interop/index.rst | 1 +
66
docs/interop/qemu-ga.rst | 133 +++++++
67
qemu-doc.texi | 5 -
68
qemu-ga.texi | 137 -------
69
20 files changed, 1585 insertions(+), 266 deletions(-)
70
create mode 100644 include/hw/gpio/aspeed_gpio.h
71
create mode 100644 hw/gpio/aspeed_gpio.c
72
create mode 100644 docs/interop/qemu-ga.rst
73
delete mode 100644 qemu-ga.texi
67
74
68
Richard Henderson (3):
69
Revert "target/arm: Use unallocated_encoding for aarch32"
70
target/arm: Factor out unallocated_encoding for aarch32
71
target/arm: Fix SMMLS argument order
72
73
accel/tcg/atomic_template.h | 2 +-
74
hw/arm/smmuv3-internal.h | 1 +
75
include/exec/cpu-defs.h | 2 +-
76
include/exec/memory.h | 10 ----
77
include/sysemu/sysemu.h | 2 -
78
target/arm/cpu.h | 6 ++-
79
target/arm/translate-a64.h | 2 +
80
target/arm/translate.h | 2 -
81
hw/arm/allwinner-a10.c | 3 +-
82
hw/arm/cubieboard.c | 3 +-
83
hw/arm/digic.c | 3 +-
84
hw/arm/exynos4_boards.c | 4 +-
85
hw/arm/fsl-imx25.c | 4 +-
86
hw/arm/fsl-imx31.c | 4 +-
87
hw/arm/fsl-imx6.c | 3 +-
88
hw/arm/fsl-imx6ul.c | 2 +-
89
hw/arm/mcimx7d-sabre.c | 9 ++--
90
hw/arm/mps2-tz.c | 15 +++---
91
hw/arm/musca.c | 9 ++--
92
hw/arm/smmuv3.c | 18 ++++---
93
hw/arm/xlnx-zynqmp.c | 8 +--
94
hw/dma/xilinx_axidma.c | 16 +++---
95
hw/net/xilinx_axienet.c | 17 +++----
96
hw/timer/aspeed_timer.c | 17 ++++++-
97
memory.c | 9 ----
98
target/arm/helper.c | 107 +++++++++++++++++++++++++++++++++++------
99
target/arm/translate-a64.c | 13 +++++
100
target/arm/translate-vfp.inc.c | 2 +
101
target/arm/translate.c | 50 +++++++++++++++++--
102
tcg/README | 2 +-
103
30 files changed, 244 insertions(+), 101 deletions(-)
104
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
From: Rashmica Gupta <rashmica.g@gmail.com>
2
2
3
Afterwise is "wise after the fact", as in "hindsight".
3
GPIO pins are arranged in groups of 8 pins labeled A,B,..,Y,Z,AA,AB,AC.
4
Here we meant "afterwards" (as in "subsequently"). Fix it.
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.
5
8
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
These registers operate on a per pin level where each bit in the register
7
Signed-off-by: Emilio G. Cota <cota@braap.org>
10
corresponds to a pin, except for the command source registers. The command
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
source registers operate on a per group level where bits 24, 16, 8 and 0
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
12
correspond to each group in the set.
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
11
Message-id: 20190828165307.18321-7-alex.bennee@linaro.org
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>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
37
---
14
tcg/README | 2 +-
38
hw/gpio/Makefile.objs | 1 +
15
1 file changed, 1 insertion(+), 1 deletion(-)
39
include/hw/gpio/aspeed_gpio.h | 100 ++++
40
hw/gpio/aspeed_gpio.c | 884 ++++++++++++++++++++++++++++++++++
41
3 files changed, 985 insertions(+)
42
create mode 100644 include/hw/gpio/aspeed_gpio.h
43
create mode 100644 hw/gpio/aspeed_gpio.c
16
44
17
diff --git a/tcg/README b/tcg/README
45
diff --git a/hw/gpio/Makefile.objs b/hw/gpio/Makefile.objs
18
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
19
--- a/tcg/README
47
--- a/hw/gpio/Makefile.objs
20
+++ b/tcg/README
48
+++ b/hw/gpio/Makefile.objs
21
@@ -XXX,XX +XXX,XX @@ This can be overridden using the following function modifiers:
49
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_OMAP) += omap_gpio.o
22
canonical locations before calling the helper.
50
obj-$(CONFIG_IMX) += imx_gpio.o
23
- TCG_CALL_NO_WRITE_GLOBALS means that the helper does not modify any globals.
51
obj-$(CONFIG_RASPI) += bcm2835_gpio.o
24
They will only be saved to their canonical location before calling helpers,
52
obj-$(CONFIG_NRF51_SOC) += nrf51_gpio.o
25
- but they won't be reloaded afterwise.
53
+obj-$(CONFIG_ASPEED_SOC) += aspeed_gpio.o
26
+ but they won't be reloaded afterwards.
54
diff --git a/include/hw/gpio/aspeed_gpio.h b/include/hw/gpio/aspeed_gpio.h
27
- TCG_CALL_NO_SIDE_EFFECTS means that the call to the function is removed if
55
new file mode 100644
28
the return value is not used.
56
index XXXXXXX..XXXXXXX
29
57
--- /dev/null
58
+++ b/include/hw/gpio/aspeed_gpio.h
59
@@ -XXX,XX +XXX,XX @@
60
+/*
61
+ * ASPEED GPIO Controller
62
+ *
63
+ * Copyright (C) 2017-2018 IBM Corp.
64
+ *
65
+ * This code is licensed under the GPL version 2 or later. See
66
+ * the COPYING file in the top-level directory.
67
+ */
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
168
+ *
169
+ * Copyright (C) 2017-2019 IBM Corp.
170
+ *
171
+ * SPDX-License-Identifier: GPL-2.0-or-later
172
+ */
173
+
174
+#include <assert.h>
175
+
176
+#include "qemu/osdep.h"
177
+#include "qemu/host-utils.h"
178
+#include "qemu/log.h"
179
+#include "hw/gpio/aspeed_gpio.h"
180
+#include "include/hw/misc/aspeed_scu.h"
181
+#include "qapi/error.h"
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 */
200
+/*
201
+ * For each set of gpios there are three sensitivity registers that control
202
+ * the interrupt trigger mode.
203
+ *
204
+ * | 2 | 1 | 0 | trigger mode
205
+ * -----------------------------
206
+ * | 0 | 0 | 0 | falling-edge
207
+ * | 0 | 0 | 1 | rising-edge
208
+ * | 0 | 1 | 0 | level-low
209
+ * | 0 | 1 | 1 | level-high
210
+ * | 1 | X | X | dual-edge
211
+ */
212
+#define ASPEED_FALLING_EDGE 0
213
+#define ASPEED_RISING_EDGE 1
214
+#define ASPEED_LEVEL_LOW 2
215
+#define ASPEED_LEVEL_HIGH 3
216
+#define ASPEED_DUAL_EDGE 4
217
+
218
+/* GPIO Register Address Offsets */
219
+#define GPIO_ABCD_DATA_VALUE (0x000 >> 2)
220
+#define GPIO_ABCD_DIRECTION (0x004 >> 2)
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:
727
+ /*
728
+ * where data is the value attempted to be written to the pin:
729
+ * pin type | input mask | output mask | expected value
730
+ * ------------------------------------------------------------
731
+ * bidirectional | 1 | 1 | data
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;
738
+ */
739
+ data = (data | ~props->input) & props->output;
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;
763
+ }
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:
788
+ /*
789
+ * feeds into interrupt generation
790
+ * 0: read from data value reg will be updated
791
+ * 1: read from data value reg will not be updated
792
+ */
793
+ set->input_mask = data & props->input;
794
+ break;
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
+ }
816
+ }
817
+ }
818
+ return -1;
819
+}
820
+
821
+static void aspeed_gpio_get_pin(Object *obj, Visitor *v, const char *name,
822
+ void *opaque, Error **errp)
823
+{
824
+ int pin = 0xfff;
825
+ bool level = true;
826
+ char group[3];
827
+ AspeedGPIOState *s = ASPEED_GPIO(obj);
828
+ int set_idx, group_idx = 0;
829
+
830
+ if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
831
+ error_setg(errp, "%s: error reading %s", __func__, name);
832
+ return;
833
+ }
834
+ set_idx = get_set_idx(s, group, &group_idx);
835
+ if (set_idx == -1) {
836
+ error_setg(errp, "%s: invalid group %s", __func__, group);
837
+ return;
838
+ }
839
+ pin = pin + group_idx * GPIOS_PER_GROUP;
840
+ level = aspeed_gpio_get_pin_level(s, set_idx, pin);
841
+ visit_type_bool(v, name, &level, errp);
842
+}
843
+
844
+static void aspeed_gpio_set_pin(Object *obj, Visitor *v, const char *name,
845
+ void *opaque, Error **errp)
846
+{
847
+ Error *local_err = NULL;
848
+ bool level;
849
+ int pin = 0xfff;
850
+ char group[3];
851
+ AspeedGPIOState *s = ASPEED_GPIO(obj);
852
+ int set_idx, group_idx = 0;
853
+
854
+ visit_type_bool(v, name, &level, &local_err);
855
+ if (local_err) {
856
+ error_propagate(errp, local_err);
857
+ return;
858
+ }
859
+ if (sscanf(name, "gpio%2[A-Z]%1d", group, &pin) != 2) {
860
+ error_setg(errp, "%s: error reading %s", __func__, name);
861
+ return;
862
+ }
863
+ set_idx = get_set_idx(s, group, &group_idx);
864
+ if (set_idx == -1) {
865
+ error_setg(errp, "%s: invalid group %s", __func__, group);
866
+ return;
867
+ }
868
+ pin = pin + group_idx * GPIOS_PER_GROUP;
869
+ aspeed_gpio_set_pin_level(s, set_idx, pin, level);
870
+}
871
+
872
+/****************** Setup functions ******************/
873
+static const GPIOSetProperties ast2400_set_props[] = {
874
+ [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
875
+ [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
876
+ [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
877
+ [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
878
+ [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} },
879
+ [5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} },
880
+ [6] = {0x0000000f, 0x0fffff0f, {"Y", "Z", "AA", "AB"} },
881
+};
882
+
883
+static const GPIOSetProperties ast2500_set_props[] = {
884
+ [0] = {0xffffffff, 0xffffffff, {"A", "B", "C", "D"} },
885
+ [1] = {0xffffffff, 0xffffffff, {"E", "F", "G", "H"} },
886
+ [2] = {0xffffffff, 0xffffffff, {"I", "J", "K", "L"} },
887
+ [3] = {0xffffffff, 0xffffffff, {"M", "N", "O", "P"} },
888
+ [4] = {0xffffffff, 0xffffffff, {"Q", "R", "S", "T"} },
889
+ [5] = {0xffffffff, 0x0000ffff, {"U", "V", "W", "X"} },
890
+ [6] = {0xffffff0f, 0x0fffff0f, {"Y", "Z", "AA", "AB"} },
891
+ [7] = {0x000000ff, 0x000000ff, {"AC"} },
892
+};
893
+
894
+static const MemoryRegionOps aspeed_gpio_ops = {
895
+ .read = aspeed_gpio_read,
896
+ .write = aspeed_gpio_write,
897
+ .endianness = DEVICE_LITTLE_ENDIAN,
898
+ .valid.min_access_size = 4,
899
+ .valid.max_access_size = 4,
900
+};
901
+
902
+static void aspeed_gpio_reset(DeviceState *dev)
903
+{
904
+ AspeedGPIOState *s = ASPEED_GPIO(dev);
905
+
906
+ /* TODO: respect the reset tolerance registers */
907
+ memset(s->sets, 0, sizeof(s->sets));
908
+}
909
+
910
+static void aspeed_gpio_realize(DeviceState *dev, Error **errp)
911
+{
912
+ AspeedGPIOState *s = ASPEED_GPIO(dev);
913
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
914
+ AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
915
+ int pin;
916
+
917
+ /* Interrupt parent line */
918
+ sysbus_init_irq(sbd, &s->irq);
919
+
920
+ /* Individual GPIOs */
921
+ for (pin = 0; pin < agc->nr_gpio_pins; pin++) {
922
+ sysbus_init_irq(sbd, &s->gpios[pin]);
923
+ }
924
+
925
+ memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_gpio_ops, s,
926
+ TYPE_ASPEED_GPIO, GPIO_3_6V_MEM_SIZE);
927
+
928
+ sysbus_init_mmio(sbd, &s->iomem);
929
+}
930
+
931
+static void aspeed_gpio_init(Object *obj)
932
+{
933
+ AspeedGPIOState *s = ASPEED_GPIO(obj);
934
+ AspeedGPIOClass *agc = ASPEED_GPIO_GET_CLASS(s);
935
+ int pin;
936
+
937
+ for (pin = 0; pin < agc->nr_gpio_pins; pin++) {
938
+ char *name;
939
+ int set_idx = pin / GPIOS_PER_SET;
940
+ int pin_idx = aspeed_adjust_pin(s, pin) - (set_idx * GPIOS_PER_SET);
941
+ int group_idx = pin_idx >> GPIO_GROUP_SHIFT;
942
+ const GPIOSetProperties *props = &agc->props[set_idx];
943
+
944
+ name = g_strdup_printf("gpio%s%d", props->group_label[group_idx],
945
+ pin_idx % GPIOS_PER_GROUP);
946
+ object_property_add(obj, name, "bool", aspeed_gpio_get_pin,
947
+ aspeed_gpio_set_pin, NULL, NULL, NULL);
948
+ }
949
+}
950
+
951
+static const VMStateDescription vmstate_gpio_regs = {
952
+ .name = TYPE_ASPEED_GPIO"/regs",
953
+ .version_id = 1,
954
+ .minimum_version_id = 1,
955
+ .fields = (VMStateField[]) {
956
+ VMSTATE_UINT32(data_value, GPIOSets),
957
+ VMSTATE_UINT32(data_read, GPIOSets),
958
+ VMSTATE_UINT32(direction, GPIOSets),
959
+ VMSTATE_UINT32(int_enable, GPIOSets),
960
+ VMSTATE_UINT32(int_sens_0, GPIOSets),
961
+ VMSTATE_UINT32(int_sens_1, GPIOSets),
962
+ VMSTATE_UINT32(int_sens_2, GPIOSets),
963
+ VMSTATE_UINT32(int_status, GPIOSets),
964
+ VMSTATE_UINT32(reset_tol, GPIOSets),
965
+ VMSTATE_UINT32(cmd_source_0, GPIOSets),
966
+ VMSTATE_UINT32(cmd_source_1, GPIOSets),
967
+ VMSTATE_UINT32(debounce_1, GPIOSets),
968
+ VMSTATE_UINT32(debounce_2, GPIOSets),
969
+ VMSTATE_UINT32(input_mask, GPIOSets),
970
+ VMSTATE_END_OF_LIST(),
971
+ }
972
+};
973
+
974
+static const VMStateDescription vmstate_aspeed_gpio = {
975
+ .name = TYPE_ASPEED_GPIO,
976
+ .version_id = 1,
977
+ .minimum_version_id = 1,
978
+ .fields = (VMStateField[]) {
979
+ VMSTATE_STRUCT_ARRAY(sets, AspeedGPIOState, ASPEED_GPIO_MAX_NR_SETS,
980
+ 1, vmstate_gpio_regs, GPIOSets),
981
+ VMSTATE_UINT32_ARRAY(debounce_regs, AspeedGPIOState,
982
+ ASPEED_GPIO_NR_DEBOUNCE_REGS),
983
+ VMSTATE_END_OF_LIST(),
984
+ }
985
+};
986
+
987
+static void aspeed_gpio_class_init(ObjectClass *klass, void *data)
988
+{
989
+ DeviceClass *dc = DEVICE_CLASS(klass);
990
+
991
+ dc->realize = aspeed_gpio_realize;
992
+ dc->reset = aspeed_gpio_reset;
993
+ dc->desc = "Aspeed GPIO Controller";
994
+ dc->vmsd = &vmstate_aspeed_gpio;
995
+}
996
+
997
+static void aspeed_gpio_ast2400_class_init(ObjectClass *klass, void *data)
998
+{
999
+ AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1000
+
1001
+ agc->props = ast2400_set_props;
1002
+ agc->nr_gpio_pins = 216;
1003
+ agc->nr_gpio_sets = 7;
1004
+ agc->gap = 196;
1005
+ agc->reg_table = aspeed_3_6v_gpios;
1006
+}
1007
+
1008
+static void aspeed_gpio_2500_class_init(ObjectClass *klass, void *data)
1009
+{
1010
+ AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass);
1011
+
1012
+ agc->props = ast2500_set_props;
1013
+ agc->nr_gpio_pins = 228;
1014
+ agc->nr_gpio_sets = 8;
1015
+ agc->gap = 220;
1016
+ agc->reg_table = aspeed_3_6v_gpios;
1017
+}
1018
+
1019
+static const TypeInfo aspeed_gpio_info = {
1020
+ .name = TYPE_ASPEED_GPIO,
1021
+ .parent = TYPE_SYS_BUS_DEVICE,
1022
+ .instance_size = sizeof(AspeedGPIOState),
1023
+ .class_size = sizeof(AspeedGPIOClass),
1024
+ .class_init = aspeed_gpio_class_init,
1025
+ .abstract = true,
1026
+};
1027
+
1028
+static const TypeInfo aspeed_gpio_ast2400_info = {
1029
+ .name = TYPE_ASPEED_GPIO "-ast2400",
1030
+ .parent = TYPE_ASPEED_GPIO,
1031
+ .class_init = aspeed_gpio_ast2400_class_init,
1032
+ .instance_init = aspeed_gpio_init,
1033
+};
1034
+
1035
+static const TypeInfo aspeed_gpio_ast2500_info = {
1036
+ .name = TYPE_ASPEED_GPIO "-ast2500",
1037
+ .parent = TYPE_ASPEED_GPIO,
1038
+ .class_init = aspeed_gpio_2500_class_init,
1039
+ .instance_init = aspeed_gpio_init,
1040
+};
1041
+
1042
+static void aspeed_gpio_register_types(void)
1043
+{
1044
+ type_register_static(&aspeed_gpio_info);
1045
+ type_register_static(&aspeed_gpio_ast2400_info);
1046
+ type_register_static(&aspeed_gpio_ast2500_info);
1047
+}
1048
+
1049
+type_init(aspeed_gpio_register_types);
30
--
1050
--
31
2.20.1
1051
2.20.1
32
1052
33
1053
diff view generated by jsdifflib
1
An attempt to do an exception-return (branch to one of the magic
1
From: Rashmica Gupta <rashmica.g@gmail.com>
2
addresses) in linux-user mode for M-profile should behave like
3
a normal branch, because linux-user mode is always going to be
4
in 'handler' mode. This used to work, but we broke it when we added
5
support for the M-profile security extension in commit d02a8698d7ae2bfed.
6
2
7
In that commit we allowed even handler-mode calls to magic return
3
Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
8
values to be checked for and dealt with by causing an
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
9
EXCP_EXCEPTION_EXIT exception to be taken, because this is
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
10
needed for the FNC_RETURN return-from-non-secure-function-call
6
Message-id: 20190904070506.1052-3-clg@kaod.org
11
handling. For system mode we added a check in do_v7m_exception_exit()
12
to make any spurious calls from Handler mode behave correctly, but
13
forgot that linux-user mode would also be affected.
14
15
How an attempted return-from-non-secure-function-call in linux-user
16
mode should be handled is not clear -- on real hardware it would
17
result in return to secure code (not to the Linux kernel) which
18
could then handle the error in any way it chose. For QEMU we take
19
the simple approach of treating this erroneous return the same way
20
it would be handled on a CPU without the security extensions --
21
treat it as a normal branch.
22
23
The upshot of all this is that for linux-user mode we should never
24
do any of the bx_excret magic, so the code change is simple.
25
26
This ought to be a weird corner case that only affects broken guest
27
code (because Linux user processes should never be attempting to do
28
exception returns or NS function returns), except that the code that
29
assigns addresses in RAM for the process and stack in our linux-user
30
code does not attempt to avoid this magic address range, so
31
legitimate code attempting to return to a trampoline routine on the
32
stack can fall into this case. This change fixes those programs,
33
but we should also look at restricting the range of memory we
34
use for M-profile linux-user guests to the area that would be
35
real RAM in hardware.
36
37
Cc: qemu-stable@nongnu.org
38
Reported-by: Christophe Lyon <christophe.lyon@linaro.org>
39
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
40
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
41
Message-id: 20190822131534.16602-1-peter.maydell@linaro.org
42
Fixes: https://bugs.launchpad.net/qemu/+bug/1840922
43
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
44
---
8
---
45
target/arm/translate.c | 21 ++++++++++++++++++++-
9
include/hw/arm/aspeed_soc.h | 3 +++
46
1 file changed, 20 insertions(+), 1 deletion(-)
10
hw/arm/aspeed_soc.c | 17 +++++++++++++++++
11
2 files changed, 20 insertions(+)
47
12
48
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
49
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/translate.c
15
--- a/include/hw/arm/aspeed_soc.h
51
+++ b/target/arm/translate.c
16
+++ b/include/hw/arm/aspeed_soc.h
52
@@ -XXX,XX +XXX,XX @@ static inline void gen_bx(DisasContext *s, TCGv_i32 var)
17
@@ -XXX,XX +XXX,XX @@
53
store_cpu_field(var, thumb);
18
#include "hw/watchdog/wdt_aspeed.h"
19
#include "hw/net/ftgmac100.h"
20
#include "target/arm/cpu.h"
21
+#include "hw/gpio/aspeed_gpio.h"
22
23
#define ASPEED_SPIS_NUM 2
24
#define ASPEED_WDTS_NUM 3
25
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
26
AspeedSDMCState sdmc;
27
AspeedWDTState wdt[ASPEED_WDTS_NUM];
28
FTGMAC100State ftgmac100[ASPEED_MACS_NUM];
29
+ AspeedGPIOState gpio;
30
} AspeedSoCState;
31
32
#define TYPE_ASPEED_SOC "aspeed-soc"
33
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCInfo {
34
int spis_num;
35
const char *fmc_typename;
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);
81
+
82
+ sysbus_init_child_obj(obj, "gpio", OBJECT(&s->gpio), sizeof(s->gpio),
83
+ sc->info->gpio_typename);
54
}
84
}
55
85
56
-/* Set PC and Thumb state from var. var is marked as dead.
86
static void aspeed_soc_realize(DeviceState *dev, Error **errp)
57
+/*
87
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
58
+ * Set PC and Thumb state from var. var is marked as dead.
88
sc->info->memmap[ASPEED_XDMA]);
59
* For M-profile CPUs, include logic to detect exception-return
89
sysbus_connect_irq(SYS_BUS_DEVICE(&s->xdma), 0,
60
* branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
90
aspeed_soc_get_irq(s, ASPEED_XDMA));
61
* and BX reg, and no others, and happens only for code in Handler mode.
91
+
62
+ * The Security Extension also requires us to check for the FNC_RETURN
92
+ /* GPIO */
63
+ * which signals a function return from non-secure state; this can happen
93
+ object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
64
+ * in both Handler and Thread mode.
94
+ if (err) {
65
+ * To avoid having to do multiple comparisons in inline generated code,
95
+ error_propagate(errp, err);
66
+ * we make the check we do here loose, so it will match for EXC_RETURN
96
+ return;
67
+ * in Thread mode. For system emulation do_v7m_exception_exit() checks
97
+ }
68
+ * for these spurious cases and returns without doing anything (giving
98
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, sc->info->memmap[ASPEED_GPIO]);
69
+ * the same behaviour as for a branch to a non-magic address).
99
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), 0,
70
+ *
100
+ aspeed_soc_get_irq(s, ASPEED_GPIO));
71
+ * In linux-user mode it is unclear what the right behaviour for an
72
+ * attempted FNC_RETURN should be, because in real hardware this will go
73
+ * directly to Secure code (ie not the Linux kernel) which will then treat
74
+ * the error in any way it chooses. For QEMU we opt to make the FNC_RETURN
75
+ * attempt behave the way it would on a CPU without the security extension,
76
+ * which is to say "like a normal branch". That means we can simply treat
77
+ * all branches as normal with no magic address behaviour.
78
*/
79
static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
80
{
81
@@ -XXX,XX +XXX,XX @@ static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
82
* s->base.is_jmp that we need to do the rest of the work later.
83
*/
84
gen_bx(s, var);
85
+#ifndef CONFIG_USER_ONLY
86
if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
87
(s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
88
s->base.is_jmp = DISAS_BX_EXCRET;
89
}
90
+#endif
91
}
101
}
92
102
static Property aspeed_soc_properties[] = {
93
static inline void gen_bx_excret_final_code(DisasContext *s)
103
DEFINE_PROP_UINT32("num-cpus", AspeedSoCState, num_cpus, 0),
94
--
104
--
95
2.20.1
105
2.20.1
96
106
97
107
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
The previous simplification got the order of operands to the
3
There are no QEMU Aspeed machines using the SoCs "ast2400-a0" or
4
subtraction wrong. Since the 64-bit product is the subtrahend,
4
"ast2400".
5
we must use a 64-bit subtract to properly compute the borrow
6
from the low-part of the product.
7
5
8
Fixes: 5f8cd06ebcf5 ("target/arm: Simplify SMMLA, SMMLAR, SMMLS, SMMLSR")
6
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Message-id: 20190904070506.1052-4-clg@kaod.org
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
12
Message-id: 20190829013258.16102-1-richard.henderson@linaro.org
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
10
---
16
target/arm/translate.c | 20 ++++++++++++++++++--
11
hw/arm/aspeed_soc.c | 26 --------------------------
17
1 file changed, 18 insertions(+), 2 deletions(-)
12
1 file changed, 26 deletions(-)
18
13
19
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate.c
16
--- a/hw/arm/aspeed_soc.c
22
+++ b/target/arm/translate.c
17
+++ b/hw/arm/aspeed_soc.c
23
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
18
@@ -XXX,XX +XXX,XX @@ static const char *aspeed_soc_ast2500_typenames[] = {
24
if (rd != 15) {
19
25
tmp3 = load_reg(s, rd);
20
static const AspeedSoCInfo aspeed_socs[] = {
26
if (insn & (1 << 6)) {
21
{
27
- tcg_gen_sub_i32(tmp, tmp, tmp3);
22
- .name = "ast2400-a0",
28
+ /*
23
- .cpu_type = ARM_CPU_TYPE_NAME("arm926"),
29
+ * For SMMLS, we need a 64-bit subtract.
24
- .silicon_rev = AST2400_A0_SILICON_REV,
30
+ * Borrow caused by a non-zero multiplicand
25
- .sram_size = 0x8000,
31
+ * lowpart, and the correct result lowpart
26
- .spis_num = 1,
32
+ * for rounding.
27
- .fmc_typename = "aspeed.smc.fmc",
33
+ */
28
- .spi_typename = aspeed_soc_ast2400_typenames,
34
+ TCGv_i32 zero = tcg_const_i32(0);
29
- .gpio_typename = "aspeed.gpio-ast2400",
35
+ tcg_gen_sub2_i32(tmp2, tmp, zero, tmp3,
30
- .wdts_num = 2,
36
+ tmp2, tmp);
31
- .irqmap = aspeed_soc_ast2400_irqmap,
37
+ tcg_temp_free_i32(zero);
32
- .memmap = aspeed_soc_ast2400_memmap,
38
} else {
33
- .num_cpus = 1,
39
tcg_gen_add_i32(tmp, tmp, tmp3);
34
- }, {
40
}
35
.name = "ast2400-a1",
41
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
36
.cpu_type = ARM_CPU_TYPE_NAME("arm926"),
42
if (insn & (1 << 20)) {
37
.silicon_rev = AST2400_A1_SILICON_REV,
43
tcg_gen_add_i32(tmp, tmp, tmp3);
38
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
44
} else {
39
.irqmap = aspeed_soc_ast2400_irqmap,
45
- tcg_gen_sub_i32(tmp, tmp, tmp3);
40
.memmap = aspeed_soc_ast2400_memmap,
46
+ /*
41
.num_cpus = 1,
47
+ * For SMMLS, we need a 64-bit subtract.
42
- }, {
48
+ * Borrow caused by a non-zero multiplicand lowpart,
43
- .name = "ast2400",
49
+ * and the correct result lowpart for rounding.
44
- .cpu_type = ARM_CPU_TYPE_NAME("arm926"),
50
+ */
45
- .silicon_rev = AST2400_A0_SILICON_REV,
51
+ TCGv_i32 zero = tcg_const_i32(0);
46
- .sram_size = 0x8000,
52
+ tcg_gen_sub2_i32(tmp2, tmp, zero, tmp3, tmp2, tmp);
47
- .spis_num = 1,
53
+ tcg_temp_free_i32(zero);
48
- .fmc_typename = "aspeed.smc.fmc",
54
}
49
- .spi_typename = aspeed_soc_ast2400_typenames,
55
tcg_temp_free_i32(tmp3);
50
- .gpio_typename = "aspeed.gpio-ast2400",
56
}
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"),
57
--
58
--
58
2.20.1
59
2.20.1
59
60
60
61
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Cédric Le Goater <clg@kaod.org>
2
2
3
An IOVA/ASID invalidation is notified to all IOMMU Memory Regions
3
Improve the naming of the different controller models to ease their
4
through smmuv3_inv_notifiers_iova/smmuv3_notify_iova.
4
generation when initializing the SoC. The rename of the SMC types is
5
breaking migration compatibility.
5
6
6
When the notification occurs it is possible that some of the
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
PCIe devices associated to the notified regions do not have a
8
Message-id: 20190904070506.1052-5-clg@kaod.org
8
valid stream table entry. In that case we output a LOG_GUEST_ERROR
9
message, for example:
10
11
invalid sid=<SID> (L1STD span=0)
12
"smmuv3_notify_iova error decoding the configuration for iommu mr=<MR>
13
14
This is unfortunate as the user gets the impression that there
15
are some translation decoding errors whereas there are not.
16
17
This patch adds a new field in SMMUEventInfo that tells whether
18
the detection of an invalid STE must lead to an error report.
19
invalid_ste_allowed is set before doing the invalidations and
20
kept unset on actual translation.
21
22
The other configuration decoding error messages are kept since if the
23
STE is valid then the rest of the config must be correct.
24
25
Signed-off-by: Eric Auger <eric.auger@redhat.com>
26
Message-id: 20190822172350.12008-6-eric.auger@redhat.com
27
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
---
11
---
30
hw/arm/smmuv3-internal.h | 1 +
12
include/hw/arm/aspeed_soc.h | 3 ---
31
hw/arm/smmuv3.c | 19 +++++++++++--------
13
hw/arm/aspeed_soc.c | 25 ++++++++++++-------------
32
2 files changed, 12 insertions(+), 8 deletions(-)
14
hw/ssi/aspeed_smc.c | 12 ++++++------
15
3 files changed, 18 insertions(+), 22 deletions(-)
33
16
34
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
17
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
35
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/smmuv3-internal.h
19
--- a/include/hw/arm/aspeed_soc.h
37
+++ b/hw/arm/smmuv3-internal.h
20
+++ b/include/hw/arm/aspeed_soc.h
38
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUEventInfo {
21
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCInfo {
39
uint32_t sid;
22
uint32_t silicon_rev;
40
bool recorded;
23
uint64_t sram_size;
41
bool record_trans_faults;
24
int spis_num;
42
+ bool inval_ste_allowed;
25
- const char *fmc_typename;
43
union {
26
- const char **spi_typename;
44
struct {
27
- const char *gpio_typename;
45
uint32_t ssid;
28
int wdts_num;
46
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
29
const int *irqmap;
30
const hwaddr *memmap;
31
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
47
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/smmuv3.c
33
--- a/hw/arm/aspeed_soc.c
49
+++ b/hw/arm/smmuv3.c
34
+++ b/hw/arm/aspeed_soc.c
50
@@ -XXX,XX +XXX,XX @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
35
@@ -XXX,XX +XXX,XX @@ static const int aspeed_soc_ast2400_irqmap[] = {
51
uint32_t config;
36
52
37
#define aspeed_soc_ast2500_irqmap aspeed_soc_ast2400_irqmap
53
if (!STE_VALID(ste)) {
38
54
- qemu_log_mask(LOG_GUEST_ERROR, "invalid STE\n");
39
-static const char *aspeed_soc_ast2400_typenames[] = { "aspeed.smc.spi" };
55
+ if (!event->inval_ste_allowed) {
40
-static const char *aspeed_soc_ast2500_typenames[] = {
56
+ qemu_log_mask(LOG_GUEST_ERROR, "invalid STE\n");
41
- "aspeed.smc.ast2500-spi1", "aspeed.smc.ast2500-spi2" };
57
+ }
42
-
58
goto bad_ste;
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);
59
}
95
}
60
96
61
@@ -XXX,XX +XXX,XX @@ static int smmu_find_ste(SMMUv3State *s, uint32_t sid, STE *ste,
97
sysbus_init_child_obj(obj, "sdmc", OBJECT(&s->sdmc), sizeof(s->sdmc),
62
98
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
63
if (!span) {
99
sysbus_init_child_obj(obj, "xdma", OBJECT(&s->xdma), sizeof(s->xdma),
64
/* l2ptr is not valid */
100
TYPE_ASPEED_XDMA);
65
- qemu_log_mask(LOG_GUEST_ERROR,
101
66
- "invalid sid=%d (L1STD span=0)\n", sid);
102
+ snprintf(typename, sizeof(typename), "aspeed.gpio-%s", socname);
67
+ if (!event->inval_ste_allowed) {
103
sysbus_init_child_obj(obj, "gpio", OBJECT(&s->gpio), sizeof(s->gpio),
68
+ qemu_log_mask(LOG_GUEST_ERROR,
104
- sc->info->gpio_typename);
69
+ "invalid sid=%d (L1STD span=0)\n", sid);
105
+ typename);
70
+ }
106
}
71
event->type = SMMU_EVT_C_BAD_STREAMID;
107
72
return -EINVAL;
108
static void aspeed_soc_realize(DeviceState *dev, Error **errp)
73
}
109
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
74
@@ -XXX,XX +XXX,XX @@ static IOMMUTLBEntry smmuv3_translate(IOMMUMemoryRegion *mr, hwaddr addr,
110
index XXXXXXX..XXXXXXX 100644
75
SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
111
--- a/hw/ssi/aspeed_smc.c
76
SMMUv3State *s = sdev->smmu;
112
+++ b/hw/ssi/aspeed_smc.c
77
uint32_t sid = smmu_get_sid(sdev);
113
@@ -XXX,XX +XXX,XX @@ static const AspeedSegments aspeed_segments_ast2500_spi2[] = {
78
- SMMUEventInfo event = {.type = SMMU_EVT_NONE, .sid = sid};
114
79
+ SMMUEventInfo event = {.type = SMMU_EVT_NONE,
115
static const AspeedSMCController controllers[] = {
80
+ .sid = sid,
116
{
81
+ .inval_ste_allowed = false};
117
- .name = "aspeed.smc.smc",
82
SMMUPTWEventInfo ptw_info = {};
118
+ .name = "aspeed.smc-ast2400",
83
SMMUTranslationStatus status;
119
.r_conf = R_CONF,
84
SMMUState *bs = ARM_SMMU(s);
120
.r_ce_ctrl = R_CE_CTRL,
85
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
121
.r_ctrl0 = R_CTRL0,
86
dma_addr_t iova)
122
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
87
{
123
.has_dma = false,
88
SMMUDevice *sdev = container_of(mr, SMMUDevice, iommu);
124
.nregs = ASPEED_SMC_R_SMC_MAX,
89
- SMMUEventInfo event = {};
125
}, {
90
+ SMMUEventInfo event = {.inval_ste_allowed = true};
126
- .name = "aspeed.smc.fmc",
91
SMMUTransTableInfo *tt;
127
+ .name = "aspeed.fmc-ast2400",
92
SMMUTransCfg *cfg;
128
.r_conf = R_CONF,
93
IOMMUTLBEntry entry;
129
.r_ce_ctrl = R_CE_CTRL,
94
130
.r_ctrl0 = R_CTRL0,
95
cfg = smmuv3_get_config(sdev, &event);
131
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
96
if (!cfg) {
132
.has_dma = true,
97
- qemu_log_mask(LOG_GUEST_ERROR,
133
.nregs = ASPEED_SMC_R_MAX,
98
- "%s error decoding the configuration for iommu mr=%s\n",
134
}, {
99
- __func__, mr->parent_obj.name);
135
- .name = "aspeed.smc.spi",
100
return;
136
+ .name = "aspeed.spi1-ast2400",
101
}
137
.r_conf = R_SPI_CONF,
102
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,
103
--
167
--
104
2.20.1
168
2.20.1
105
169
106
170
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Cédric Le Goater <clg@kaod.org>
2
2
3
memory_region_iommu_replay_all is not used. Remove it.
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
Signed-off-by: Eric Auger <eric.auger@redhat.com>
5
module mapping window, or in a checksum calculation mode, to evaluate
6
Reported-by: Peter Maydell <peter.maydell@linaro.org>
6
the best clock settings for reads.
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
8
Reviewed-by: Peter Xu <peterx@redhat.com>
8
The model introduces two custom address spaces for DMAs: one for the
9
Message-id: 20190822172350.12008-2-eric.auger@redhat.com
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>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
18
---
12
include/exec/memory.h | 10 ----------
19
include/hw/ssi/aspeed_smc.h | 6 +
13
memory.c | 9 ---------
20
hw/arm/aspeed.c | 2 +
14
2 files changed, 19 deletions(-)
21
hw/arm/aspeed_soc.c | 2 +
15
22
hw/ssi/aspeed_smc.c | 222 +++++++++++++++++++++++++++++++++++-
16
diff --git a/include/exec/memory.h b/include/exec/memory.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
17
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
18
--- a/include/exec/memory.h
27
--- a/include/hw/ssi/aspeed_smc.h
19
+++ b/include/exec/memory.h
28
+++ b/include/hw/ssi/aspeed_smc.h
20
@@ -XXX,XX +XXX,XX @@ void memory_region_register_iommu_notifier(MemoryRegion *mr,
29
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCController {
21
*/
30
hwaddr flash_window_base;
22
void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n);
31
uint32_t flash_window_size;
23
32
bool has_dma;
24
-/**
33
+ hwaddr dma_flash_mask;
25
- * memory_region_iommu_replay_all: replay existing IOMMU translations
34
+ hwaddr dma_dram_mask;
26
- * to all the notifiers registered.
35
uint32_t nregs;
27
- *
36
} AspeedSMCController;
28
- * Note: this is not related to record-and-replay functionality.
37
29
- *
38
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCState {
30
- * @iommu_mr: the memory region to observe
39
/* for DMA support */
31
- */
40
uint64_t sdram_base;
32
-void memory_region_iommu_replay_all(IOMMUMemoryRegion *iommu_mr);
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
102
103
+/*
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
114
+ */
115
+#define DMA_DRAM_ADDR(s, val) ((s)->sdram_base | \
116
+ ((val) & (s)->ctrl->dma_dram_mask))
117
+#define DMA_FLASH_ADDR(s, val) ((s)->ctrl->flash_window_base | \
118
+ ((val) & (s)->ctrl->dma_flash_mask))
119
+#define DMA_LENGTH(val) ((val) & 0x01FFFFFC)
120
+
121
/* Flash opcodes. */
122
#define SPI_OP_READ 0x03 /* Read data bytes (low frequency) */
123
124
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
125
.flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
126
.flash_window_size = 0x10000000,
127
.has_dma = true,
128
+ .dma_flash_mask = 0x0FFFFFFC,
129
+ .dma_dram_mask = 0x1FFFFFFC,
130
.nregs = ASPEED_SMC_R_MAX,
131
}, {
132
.name = "aspeed.spi1-ast2400",
133
@@ -XXX,XX +XXX,XX @@ static const AspeedSMCController controllers[] = {
134
.flash_window_base = ASPEED_SOC_FMC_FLASH_BASE,
135
.flash_window_size = 0x10000000,
136
.has_dma = true,
137
+ .dma_flash_mask = 0x0FFFFFFC,
138
+ .dma_dram_mask = 0x3FFFFFFC,
139
.nregs = ASPEED_SMC_R_MAX,
140
}, {
141
.name = "aspeed.spi1-ast2500",
142
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_reset(DeviceState *d)
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;
33
-
148
-
34
/**
149
/* Unselect all slaves */
35
* memory_region_unregister_iommu_notifier: unregister a notifier for
150
for (i = 0; i < s->num_cs; ++i) {
36
* changes to IOMMU translation entries.
151
s->regs[s->r_ctrl0 + i] |= CTRL_CE_STOP_ACTIVE;
37
diff --git a/memory.c b/memory.c
152
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
38
index XXXXXXX..XXXXXXX 100644
153
addr == s->r_ce_ctrl ||
39
--- a/memory.c
154
addr == R_INTR_CTRL ||
40
+++ b/memory.c
155
addr == R_DUMMY_DATA ||
41
@@ -XXX,XX +XXX,XX @@ void memory_region_iommu_replay(IOMMUMemoryRegion *iommu_mr, IOMMUNotifier *n)
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)
42
}
165
}
43
}
166
}
44
167
45
-void memory_region_iommu_replay_all(IOMMUMemoryRegion *iommu_mr)
168
+/*
46
-{
169
+ * Accumulate the result of the reads to provide a checksum that will
47
- IOMMUNotifier *notifier;
170
+ * be used to validate the read timing settings.
48
-
171
+ */
49
- IOMMU_NOTIFIER_FOREACH(notifier, iommu_mr) {
172
+static void aspeed_smc_dma_checksum(AspeedSMCState *s)
50
- memory_region_iommu_replay(iommu_mr, notifier);
173
+{
51
- }
174
+ MemTxResult result;
52
-}
175
+ uint32_t data;
53
-
176
+
54
void memory_region_unregister_iommu_notifier(MemoryRegion *mr,
177
+ if (s->regs[R_DMA_CTRL] & DMA_CTRL_WRITE) {
55
IOMMUNotifier *n)
178
+ qemu_log_mask(LOG_GUEST_ERROR,
179
+ "%s: invalid direction for DMA checksum\n", __func__);
180
+ return;
181
+ }
182
+
183
+ while (s->regs[R_DMA_LEN]) {
184
+ data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
185
+ MEMTXATTRS_UNSPECIFIED, &result);
186
+ if (result != MEMTX_OK) {
187
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: Flash read failed @%08x\n",
188
+ __func__, s->regs[R_DMA_FLASH_ADDR]);
189
+ return;
190
+ }
191
+
192
+ /*
193
+ * When the DMA is on-going, the DMA registers are updated
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)
56
{
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
57
--
395
--
58
2.20.1
396
2.20.1
59
397
60
398
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
This reverts commit 3cb36637157088892e9e33ddb1034bffd1251d3b.
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.
4
6
5
Despite the fact that the text for the call to gen_exception_insn
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
is identical for aarch64 and aarch32, the implementation inside
8
Acked-by: Joel Stanley <joel@jms.id.au>
7
gen_exception_insn is totally different.
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
10
Message-id: 20190904070506.1052-7-clg@kaod.org
9
This fixes exceptions raised from aarch64.
10
11
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
14
Message-id: 20190826151536.6771-2-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
12
---
17
target/arm/translate-a64.h | 2 ++
13
hw/ssi/aspeed_smc.c | 64 ++++++++++++++++++++++++++++++++++++++++++++-
18
target/arm/translate.h | 2 --
14
1 file changed, 63 insertions(+), 1 deletion(-)
19
target/arm/translate-a64.c | 7 +++++++
20
target/arm/translate-vfp.inc.c | 3 ++-
21
target/arm/translate.c | 22 ++++++++++------------
22
5 files changed, 21 insertions(+), 15 deletions(-)
23
15
24
diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
16
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/translate-a64.h
18
--- a/hw/ssi/aspeed_smc.c
27
+++ b/target/arm/translate-a64.h
19
+++ b/hw/ssi/aspeed_smc.c
28
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
29
#ifndef TARGET_ARM_TRANSLATE_A64_H
21
#define CTRL_CMD_MASK 0xff
30
#define TARGET_ARM_TRANSLATE_A64_H
22
#define CTRL_DUMMY_HIGH_SHIFT 14
31
23
#define CTRL_AST2400_SPI_4BYTE (1 << 13)
32
+void unallocated_encoding(DisasContext *s);
24
+#define CE_CTRL_CLOCK_FREQ_SHIFT 8
33
+
25
+#define CE_CTRL_CLOCK_FREQ_MASK 0xf
34
#define unsupported_encoding(s, insn) \
26
+#define CE_CTRL_CLOCK_FREQ(div) \
35
do { \
27
+ (((div) & CE_CTRL_CLOCK_FREQ_MASK) << CE_CTRL_CLOCK_FREQ_SHIFT)
36
qemu_log_mask(LOG_UNIMP, \
28
#define CTRL_DUMMY_LOW_SHIFT 6 /* 2 bits [7:6] */
37
diff --git a/target/arm/translate.h b/target/arm/translate.h
29
#define CTRL_CE_STOP_ACTIVE (1 << 2)
38
index XXXXXXX..XXXXXXX 100644
30
#define CTRL_CMD_MODE_MASK 0x3
39
--- a/target/arm/translate.h
31
@@ -XXX,XX +XXX,XX @@
40
+++ b/target/arm/translate.h
32
#define DMA_CTRL_DELAY_SHIFT 8
41
@@ -XXX,XX +XXX,XX @@ typedef struct DisasCompare {
33
#define DMA_CTRL_FREQ_MASK 0xf
42
bool value_global;
34
#define DMA_CTRL_FREQ_SHIFT 4
43
} DisasCompare;
35
-#define DMA_CTRL_MODE (1 << 3)
44
36
+#define DMA_CTRL_CALIB (1 << 3)
45
-void unallocated_encoding(DisasContext *s);
37
#define DMA_CTRL_CKSUM (1 << 2)
46
-
38
#define DMA_CTRL_WRITE (1 << 1)
47
/* Share the TCG temporaries common between 32 and 64 bit modes. */
39
#define DMA_CTRL_ENABLE (1 << 0)
48
extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
40
@@ -XXX,XX +XXX,XX @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
49
extern TCGv_i64 cpu_exclusive_addr;
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 inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
55
}
41
}
56
}
42
}
57
43
58
+void unallocated_encoding(DisasContext *s)
44
+static uint8_t aspeed_smc_hclk_divisor(uint8_t hclk_mask)
59
+{
45
+{
60
+ /* Unallocated and reserved encodings are uncategorized */
46
+ /* HCLK/1 .. HCLK/16 */
61
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
47
+ const uint8_t hclk_divisors[] = {
62
+ default_exception_el(s));
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;
63
+}
60
+}
64
+
61
+
65
static void init_tmp_a64_array(DisasContext *s)
62
+/*
66
{
63
+ * When doing calibration, the SPI clock rate in the CE0 Control
67
#ifdef CONFIG_DEBUG_TCG
64
+ * Register and the read delay cycles in the Read Timing Compensation
68
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
65
+ * Register are set using bit[11:4] of the DMA Control Register.
69
index XXXXXXX..XXXXXXX 100644
66
+ */
70
--- a/target/arm/translate-vfp.inc.c
67
+static void aspeed_smc_dma_calibration(AspeedSMCState *s)
71
+++ b/target/arm/translate-vfp.inc.c
68
+{
72
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
69
+ uint8_t delay =
73
70
+ (s->regs[R_DMA_CTRL] >> DMA_CTRL_DELAY_SHIFT) & DMA_CTRL_DELAY_MASK;
74
if (!s->vfp_enabled && !ignore_vfp_enabled) {
71
+ uint8_t hclk_mask =
75
assert(!arm_dc_feature(s, ARM_FEATURE_M));
72
+ (s->regs[R_DMA_CTRL] >> DMA_CTRL_FREQ_SHIFT) & DMA_CTRL_FREQ_MASK;
76
- unallocated_encoding(s);
73
+ uint8_t hclk_div = aspeed_smc_hclk_divisor(hclk_mask);
77
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
74
+ uint32_t hclk_shift = (hclk_div - 1) << 2;
78
+ default_exception_el(s));
75
+ uint8_t cs;
79
return false;
76
+
80
}
77
+ /*
81
78
+ * The Read Timing Compensation Register values apply to all CS on
82
diff --git a/target/arm/translate.c b/target/arm/translate.c
79
+ * the SPI bus and only HCLK/1 - HCLK/5 can have tunable delays
83
index XXXXXXX..XXXXXXX 100644
80
+ */
84
--- a/target/arm/translate.c
81
+ if (hclk_div && hclk_div < 6) {
85
+++ b/target/arm/translate.c
82
+ s->regs[s->r_timings] &= ~(0xf << hclk_shift);
86
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
83
+ s->regs[s->r_timings] |= delay << hclk_shift;
87
s->base.is_jmp = DISAS_NORETURN;
84
+ }
88
}
85
+
89
86
+ /*
90
-void unallocated_encoding(DisasContext *s)
87
+ * TODO: compute the CS from the DMA address and the segment
91
-{
88
+ * registers. This is not really a problem for now because the
92
- /* Unallocated and reserved encodings are uncategorized */
89
+ * Timing Register values apply to all CS and software uses CS0 to
93
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
90
+ * do calibration.
94
- default_exception_el(s));
91
+ */
95
-}
92
+ cs = 0;
96
-
93
+ s->regs[s->r_ctrl0 + cs] &=
97
/* Force a TB lookup after an instruction that changes the CPU state. */
94
+ ~(CE_CTRL_CLOCK_FREQ_MASK << CE_CTRL_CLOCK_FREQ_SHIFT);
98
static inline void gen_lookup_tb(DisasContext *s)
95
+ s->regs[s->r_ctrl0 + cs] |= CE_CTRL_CLOCK_FREQ(hclk_div);
99
{
96
+}
100
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
97
+
98
/*
99
* Accumulate the result of the reads to provide a checksum that will
100
* be used to validate the read timing settings.
101
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
101
return;
102
return;
102
}
103
}
103
104
104
- unallocated_encoding(s);
105
+ if (s->regs[R_DMA_CTRL] & DMA_CTRL_CALIB) {
105
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
106
+ aspeed_smc_dma_calibration(s);
106
+ default_exception_el(s));
107
+ }
107
}
108
+
108
109
while (s->regs[R_DMA_LEN]) {
109
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
110
data = address_space_ldl_le(&s->flash_as, s->regs[R_DMA_FLASH_ADDR],
110
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
111
MEMTXATTRS_UNSPECIFIED, &result);
111
}
112
113
if (undef) {
114
- unallocated_encoding(s);
115
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
116
+ default_exception_el(s));
117
return;
118
}
119
120
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
121
break;
122
default:
123
illegal_op:
124
- unallocated_encoding(s);
125
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
126
+ default_exception_el(s));
127
break;
128
}
129
}
130
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
131
}
132
return;
133
illegal_op:
134
- unallocated_encoding(s);
135
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
136
+ default_exception_el(s));
137
}
138
139
static void disas_thumb_insn(DisasContext *s, uint32_t insn)
140
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
141
return;
142
illegal_op:
143
undef:
144
- unallocated_encoding(s);
145
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
146
+ default_exception_el(s));
147
}
148
149
static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
150
--
112
--
151
2.20.1
113
2.20.1
152
114
153
115
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
Make this a static function private to translate.c.
3
Emulate read errors in the DMA Checksum Register for high frequencies
4
Thus we can use the same idiom between aarch64 and aarch32
4
and optimistic settings of the Read Timing Compensation Register. This
5
without actually sharing function implementations.
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.
6
8
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
The values below are those to expect from the first flash device of
8
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
the FMC controller of a palmetto-bmc machine.
9
Message-id: 20190826151536.6771-3-richard.henderson@linaro.org
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
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
17
---
12
target/arm/translate-vfp.inc.c | 3 +--
18
include/hw/ssi/aspeed_smc.h | 1 +
13
target/arm/translate.c | 22 ++++++++++++----------
19
hw/ssi/aspeed_smc.c | 36 ++++++++++++++++++++++++++++++++++++
14
2 files changed, 13 insertions(+), 12 deletions(-)
20
2 files changed, 37 insertions(+)
15
21
16
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
22
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-vfp.inc.c
24
--- a/include/hw/ssi/aspeed_smc.h
19
+++ b/target/arm/translate-vfp.inc.c
25
+++ b/include/hw/ssi/aspeed_smc.h
20
@@ -XXX,XX +XXX,XX @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
26
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSMCState {
21
27
22
if (!s->vfp_enabled && !ignore_vfp_enabled) {
28
uint32_t num_cs;
23
assert(!arm_dc_feature(s, ARM_FEATURE_M));
29
qemu_irq *cs_lines;
24
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
30
+ bool inject_failure;
25
- default_exception_el(s));
31
26
+ unallocated_encoding(s);
32
SSIBus *spi;
27
return false;
33
28
}
34
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
29
30
diff --git a/target/arm/translate.c b/target/arm/translate.c
31
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate.c
36
--- a/hw/ssi/aspeed_smc.c
33
+++ b/target/arm/translate.c
37
+++ b/hw/ssi/aspeed_smc.c
34
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
38
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_dma_calibration(AspeedSMCState *s)
35
s->base.is_jmp = DISAS_NORETURN;
39
s->regs[s->r_ctrl0 + cs] |= CE_CTRL_CLOCK_FREQ(hclk_div);
36
}
40
}
37
41
38
+static void unallocated_encoding(DisasContext *s)
42
+/*
43
+ * Emulate read errors in the DMA Checksum Register for high
44
+ * frequencies and optimistic settings of the Read Timing Compensation
45
+ * Register. This will help in tuning the SPI timing calibration
46
+ * algorithm.
47
+ */
48
+static bool aspeed_smc_inject_read_failure(AspeedSMCState *s)
39
+{
49
+{
40
+ /* Unallocated and reserved encodings are uncategorized */
50
+ uint8_t delay =
41
+ gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
51
+ (s->regs[R_DMA_CTRL] >> DMA_CTRL_DELAY_SHIFT) & DMA_CTRL_DELAY_MASK;
42
+ default_exception_el(s));
52
+ uint8_t hclk_mask =
53
+ (s->regs[R_DMA_CTRL] >> DMA_CTRL_FREQ_SHIFT) & DMA_CTRL_FREQ_MASK;
54
+
55
+ /*
56
+ * Typical values of a palmetto-bmc machine.
57
+ */
58
+ switch (aspeed_smc_hclk_divisor(hclk_mask)) {
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
+ }
43
+}
70
+}
44
+
71
+
45
/* Force a TB lookup after an instruction that changes the CPU state. */
72
/*
46
static inline void gen_lookup_tb(DisasContext *s)
73
* Accumulate the result of the reads to provide a checksum that will
47
{
74
* be used to validate the read timing settings.
48
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
75
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_dma_checksum(AspeedSMCState *s)
49
return;
76
s->regs[R_DMA_FLASH_ADDR] += 4;
77
s->regs[R_DMA_LEN] -= 4;
50
}
78
}
51
79
+
52
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
80
+ if (s->inject_failure && aspeed_smc_inject_read_failure(s)) {
53
- default_exception_el(s));
81
+ s->regs[R_DMA_CHECKSUM] = 0xbadc0de;
54
+ unallocated_encoding(s);
82
+ }
83
+
55
}
84
}
56
85
57
static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
86
static void aspeed_smc_dma_rw(AspeedSMCState *s)
58
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
87
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_smc = {
59
}
88
60
89
static Property aspeed_smc_properties[] = {
61
if (undef) {
90
DEFINE_PROP_UINT32("num-cs", AspeedSMCState, num_cs, 1),
62
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
91
+ DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure, false),
63
- default_exception_el(s));
92
DEFINE_PROP_UINT64("sdram-base", AspeedSMCState, sdram_base, 0),
64
+ unallocated_encoding(s);
93
DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
65
return;
94
TYPE_MEMORY_REGION, MemoryRegion *),
66
}
67
68
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
69
break;
70
default:
71
illegal_op:
72
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
73
- default_exception_el(s));
74
+ unallocated_encoding(s);
75
break;
76
}
77
}
78
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
79
}
80
return;
81
illegal_op:
82
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
83
- default_exception_el(s));
84
+ unallocated_encoding(s);
85
}
86
87
static void disas_thumb_insn(DisasContext *s, uint32_t insn)
88
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
89
return;
90
illegal_op:
91
undef:
92
- gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
93
- default_exception_el(s));
94
+ unallocated_encoding(s);
95
}
96
97
static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
98
--
95
--
99
2.20.1
96
2.20.1
100
97
101
98
diff view generated by jsdifflib
Deleted patch
1
Currently the only part of an ARMCPRegInfo which is allowed to cause
2
a CPU exception is the access function, which returns a value indicating
3
that some flavour of UNDEF should be generated.
4
1
5
For the ATS system instructions, we would like to conditionally
6
generate exceptions as part of the writefn, because some faults
7
during the page table walk (like external aborts) should cause
8
an exception to be raised rather than returning a value.
9
10
There are several ways we could do this:
11
* plumb the GETPC() value from the top level set_cp_reg/get_cp_reg
12
helper functions through into the readfn and writefn hooks
13
* add extra readfn_with_ra/writefn_with_ra hooks that take the GETPC()
14
value
15
* require the ATS instructions to provide a dummy accessfn,
16
which serves no purpose except to cause the code generation
17
to emit TCG ops to sync the CPU state
18
* add an ARM_CP_ flag to mark the ARMCPRegInfo as possibly
19
throwing an exception in its read/write hooks, and make the
20
codegen sync the CPU state before calling the hooks if the
21
flag is set
22
23
This patch opts for the last of these, as it is fairly simple
24
to implement and doesn't require invasive changes like updating
25
the readfn/writefn hook function prototype signature.
26
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
29
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
30
Message-id: 20190816125802.25877-2-peter.maydell@linaro.org
31
---
32
target/arm/cpu.h | 6 +++++-
33
target/arm/translate-a64.c | 6 ++++++
34
target/arm/translate.c | 7 +++++++
35
3 files changed, 18 insertions(+), 1 deletion(-)
36
37
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/cpu.h
40
+++ b/target/arm/cpu.h
41
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
42
* IO indicates that this register does I/O and therefore its accesses
43
* need to be surrounded by gen_io_start()/gen_io_end(). In particular,
44
* registers which implement clocks or timers require this.
45
+ * RAISES_EXC is for when the read or write hook might raise an exception;
46
+ * the generated code will synchronize the CPU state before calling the hook
47
+ * so that it is safe for the hook to call raise_exception().
48
*/
49
#define ARM_CP_SPECIAL 0x0001
50
#define ARM_CP_CONST 0x0002
51
@@ -XXX,XX +XXX,XX @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
52
#define ARM_CP_FPU 0x1000
53
#define ARM_CP_SVE 0x2000
54
#define ARM_CP_NO_GDB 0x4000
55
+#define ARM_CP_RAISES_EXC 0x8000
56
/* Used only as a terminator for ARMCPRegInfo lists */
57
#define ARM_CP_SENTINEL 0xffff
58
/* Mask of only the flag bits in a type field */
59
-#define ARM_CP_FLAG_MASK 0x70ff
60
+#define ARM_CP_FLAG_MASK 0xf0ff
61
62
/* Valid values for ARMCPRegInfo state field, indicating which of
63
* the AArch32 and AArch64 execution states this register is visible in.
64
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate-a64.c
67
+++ b/target/arm/translate-a64.c
68
@@ -XXX,XX +XXX,XX @@ static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
69
tcg_temp_free_ptr(tmpptr);
70
tcg_temp_free_i32(tcg_syn);
71
tcg_temp_free_i32(tcg_isread);
72
+ } else if (ri->type & ARM_CP_RAISES_EXC) {
73
+ /*
74
+ * The readfn or writefn might raise an exception;
75
+ * synchronize the CPU state in case it does.
76
+ */
77
+ gen_a64_set_pc_im(s->pc_curr);
78
}
79
80
/* Handle special cases first */
81
diff --git a/target/arm/translate.c b/target/arm/translate.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/arm/translate.c
84
+++ b/target/arm/translate.c
85
@@ -XXX,XX +XXX,XX @@ static int disas_coproc_insn(DisasContext *s, uint32_t insn)
86
tcg_temp_free_ptr(tmpptr);
87
tcg_temp_free_i32(tcg_syn);
88
tcg_temp_free_i32(tcg_isread);
89
+ } else if (ri->type & ARM_CP_RAISES_EXC) {
90
+ /*
91
+ * The readfn or writefn might raise an exception;
92
+ * synchronize the CPU state in case it does.
93
+ */
94
+ gen_set_condexec(s);
95
+ gen_set_pc_im(s, s->pc_curr);
96
}
97
98
/* Handle special cases first */
99
--
100
2.20.1
101
102
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Christian Svensson <bluecmd@google.com>
2
2
3
Log a guest error when encountering an invalid STE.
3
This patch adds the missing checksum calculation on normal DMA transfer.
4
According to the datasheet this is how the SMC should behave.
4
5
5
Signed-off-by: Eric Auger <eric.auger@redhat.com>
6
Verified on AST1250 that the hardware matches the behaviour.
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
7
Message-id: 20190822172350.12008-5-eric.auger@redhat.com
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
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
13
---
10
hw/arm/smmuv3.c | 1 +
14
hw/ssi/aspeed_smc.c | 1 +
11
1 file changed, 1 insertion(+)
15
1 file changed, 1 insertion(+)
12
16
13
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
17
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
14
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/smmuv3.c
19
--- a/hw/ssi/aspeed_smc.c
16
+++ b/hw/arm/smmuv3.c
20
+++ b/hw/ssi/aspeed_smc.c
17
@@ -XXX,XX +XXX,XX @@ static int decode_ste(SMMUv3State *s, SMMUTransCfg *cfg,
21
@@ -XXX,XX +XXX,XX @@ static void aspeed_smc_dma_rw(AspeedSMCState *s)
18
uint32_t config;
22
s->regs[R_DMA_FLASH_ADDR] += 4;
19
23
s->regs[R_DMA_DRAM_ADDR] += 4;
20
if (!STE_VALID(ste)) {
24
s->regs[R_DMA_LEN] -= 4;
21
+ qemu_log_mask(LOG_GUEST_ERROR, "invalid STE\n");
25
+ s->regs[R_DMA_CHECKSUM] += data;
22
goto bad_ste;
23
}
26
}
27
}
24
28
25
--
29
--
26
2.20.1
30
2.20.1
27
31
28
32
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
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
3
and use a class AspeedSCUClass to define each SoC characteristics.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Cédric Le Goater <clg@kaod.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20190904070506.1052-10-clg@kaod.org
7
Message-id: 20190828165307.18321-10-alex.bennee@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
include/exec/cpu-defs.h | 2 +-
10
include/hw/misc/aspeed_scu.h | 15 +++++++
11
1 file changed, 1 insertion(+), 1 deletion(-)
11
hw/arm/aspeed_soc.c | 3 +-
12
12
hw/misc/aspeed_scu.c | 83 ++++++++++++++++++++----------------
13
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
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
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/include/exec/cpu-defs.h
17
--- a/include/hw/misc/aspeed_scu.h
16
+++ b/include/exec/cpu-defs.h
18
+++ b/include/hw/misc/aspeed_scu.h
17
@@ -XXX,XX +XXX,XX @@ typedef struct CPUTLB { } CPUTLB;
19
@@ -XXX,XX +XXX,XX @@
18
#endif /* !CONFIG_USER_ONLY && CONFIG_TCG */
20
21
#define TYPE_ASPEED_SCU "aspeed.scu"
22
#define ASPEED_SCU(obj) OBJECT_CHECK(AspeedSCUState, (obj), TYPE_ASPEED_SCU)
23
+#define TYPE_ASPEED_2400_SCU TYPE_ASPEED_SCU "-ast2400"
24
+#define TYPE_ASPEED_2500_SCU TYPE_ASPEED_SCU "-ast2500"
25
26
#define ASPEED_SCU_NR_REGS (0x1A8 >> 2)
27
28
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSCUState {
29
30
extern bool is_supported_silicon_rev(uint32_t silicon_rev);
31
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
19
46
20
/*
47
/*
21
- * This structure must be placed in ArchCPU immedately
48
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
22
+ * This structure must be placed in ArchCPU immediately
49
index XXXXXXX..XXXXXXX 100644
23
* before CPUArchState, as a field named "neg".
50
--- a/hw/arm/aspeed_soc.c
24
*/
51
+++ b/hw/arm/aspeed_soc.c
25
typedef struct CPUNegativeOffsetState {
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 */
95
};
96
97
-static uint32_t aspeed_scu_calc_hpll_ast2400(AspeedSCUState *s)
98
+static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s)
99
{
100
uint32_t hpll_reg = s->regs[HPLL_PARAM];
101
uint8_t freq_select;
102
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_scu_calc_hpll_ast2400(AspeedSCUState *s)
103
return hpll_ast2400_freqs[clk_25m_in][freq_select] * 1000000;
104
}
105
106
-static uint32_t aspeed_scu_calc_hpll_ast2500(AspeedSCUState *s)
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);
26
--
200
--
27
2.20.1
201
2.20.1
28
202
29
203
diff view generated by jsdifflib
1
From: Andrew Jeffery <andrew@aj.id.au>
1
From: Cédric Le Goater <clg@kaod.org>
2
2
3
First up: This is not the way the hardware behaves.
3
The APB frequency can be calculated directly when needed from the
4
HPLL_PARAM and CLK_SEL register values. This removes useless state in
5
the model.
4
6
5
However, it helps resolve real-world problems with short periods being
6
used under Linux. Commit 4451d3f59f2a ("clocksource/drivers/fttmr010:
7
Fix set_next_event handler") in Linux fixed the timer driver to
8
correctly schedule the next event for the Aspeed controller, and in
9
combination with 5daa8212c08e ("ARM: dts: aspeed: Describe random number
10
device") Linux will now set a timer with a period as low as 1us.
11
12
Configuring a qemu timer with such a short period results in spending
13
time handling the interrupt in the model rather than executing guest
14
code, leading to noticeable "sticky" behaviour in the guest.
15
16
The behaviour of Linux is correct with respect to the hardware, so we
17
need to improve our handling under emulation. The approach chosen is to
18
provide back-pressure information by calculating an acceptable minimum
19
number of ticks to be set on the model. Under Linux an additional read
20
is added in the timer configuration path to detect back-pressure, which
21
will never occur on hardware. However if back-pressure is observed, the
22
driver alerts the clock event subsystem, which then performs its own
23
next event dilation via a config option - d1748302f70b ("clockevents:
24
Make minimum delay adjustments configurable")
25
26
A minimum period of 5us was experimentally determined on a Lenovo
27
T480s, which I've increased to 20us for "safety".
28
29
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
30
Reviewed-by: Joel Stanley <joel@jms.id.au>
31
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
32
Tested-by: Joel Stanley <joel@jms.id.au>
33
Signed-off-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
34
Message-id: 20190704055150.4899-1-clg@kaod.org
8
Message-id: 20190904070506.1052-11-clg@kaod.org
35
[clg: - changed the computation of min_ticks to be done each time the
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
36
timer value is reloaded. It removes the ordering issue of the
37
timer and scu reset handlers but is slightly slower ]
38
- introduced TIMER_MIN_NS
39
- introduced calculate_min_ticks() ]
40
Signed-off-by: Cédric Le Goater <clg@kaod.org>
41
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
42
---
11
---
43
hw/timer/aspeed_timer.c | 17 ++++++++++++++++-
12
include/hw/misc/aspeed_scu.h | 8 +++-----
44
1 file changed, 16 insertions(+), 1 deletion(-)
13
hw/misc/aspeed_scu.c | 25 +++++++++----------------
14
hw/timer/aspeed_timer.c | 3 ++-
15
3 files changed, 14 insertions(+), 22 deletions(-)
45
16
17
diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/misc/aspeed_scu.h
20
+++ b/include/hw/misc/aspeed_scu.h
21
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSCUState {
22
uint32_t hw_strap1;
23
uint32_t hw_strap2;
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);
44
+
45
/*
46
* Extracted from Aspeed SDK v00.03.21. Fixes and extra definitions
47
* were added.
48
diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/misc/aspeed_scu.c
51
+++ b/hw/misc/aspeed_scu.c
52
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_scu_get_random(void)
53
return num;
54
}
55
56
-static void aspeed_scu_set_apb_freq(AspeedSCUState *s)
57
+uint32_t aspeed_scu_get_apb_freq(AspeedSCUState *s)
58
{
59
AspeedSCUClass *asc = ASPEED_SCU_GET_CLASS(s);
60
+ uint32_t hpll = asc->calc_hpll(s, s->regs[HPLL_PARAM]);
61
62
- s->apb_freq = s->hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[CLK_SEL]) + 1)
63
+ return hpll / (SCU_CLK_GET_PCLK_DIV(s->regs[CLK_SEL]) + 1)
64
/ asc->apb_divider;
65
}
66
67
@@ -XXX,XX +XXX,XX @@ static void aspeed_scu_write(void *opaque, hwaddr offset, uint64_t data,
68
return;
69
case CLK_SEL:
70
s->regs[reg] = data;
71
- aspeed_scu_set_apb_freq(s);
72
break;
73
case HW_STRAP1:
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 */
77
};
78
79
-static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s)
80
+static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s, uint32_t hpll_reg)
81
{
82
- uint32_t hpll_reg = s->regs[HPLL_PARAM];
83
uint8_t freq_select;
84
bool clk_25m_in;
85
+ uint32_t clkin = aspeed_scu_get_clkin(s);
86
87
if (hpll_reg & SCU_AST2400_H_PLL_OFF) {
88
return 0;
89
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s)
90
multiplier = (2 - od) * ((n + 2) / (d + 1));
91
}
92
93
- return s->clkin * multiplier;
94
+ return clkin * multiplier;
95
}
96
97
/* HW strapping */
98
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_2400_scu_calc_hpll(AspeedSCUState *s)
99
return hpll_ast2400_freqs[clk_25m_in][freq_select] * 1000000;
100
}
101
102
-static uint32_t aspeed_2500_scu_calc_hpll(AspeedSCUState *s)
103
+static uint32_t aspeed_2500_scu_calc_hpll(AspeedSCUState *s, uint32_t hpll_reg)
104
{
105
- uint32_t hpll_reg = s->regs[HPLL_PARAM];
106
uint32_t multiplier = 1;
107
+ uint32_t clkin = aspeed_scu_get_clkin(s);
108
109
if (hpll_reg & SCU_H_PLL_OFF) {
110
return 0;
111
@@ -XXX,XX +XXX,XX @@ static uint32_t aspeed_2500_scu_calc_hpll(AspeedSCUState *s)
112
multiplier = ((m + 1) / (n + 1)) / (p + 1);
113
}
114
115
- return s->clkin * multiplier;
116
+ return clkin * multiplier;
117
}
118
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);
131
}
132
133
static uint32_t aspeed_silicon_revs[] = {
46
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
134
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
47
index XXXXXXX..XXXXXXX 100644
135
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/timer/aspeed_timer.c
136
--- a/hw/timer/aspeed_timer.c
49
+++ b/hw/timer/aspeed_timer.c
137
+++ b/hw/timer/aspeed_timer.c
50
@@ -XXX,XX +XXX,XX @@ enum timer_ctrl_op {
138
@@ -XXX,XX +XXX,XX @@ static inline uint32_t calculate_rate(struct AspeedTimer *t)
51
op_pulse_enable
139
{
52
};
140
AspeedTimerCtrlState *s = timer_to_ctrl(t);
53
141
54
+/*
142
- return timer_external_clock(t) ? TIMER_CLOCK_EXT_HZ : s->scu->apb_freq;
55
+ * Minimum value of the reload register to filter out short period
143
+ return timer_external_clock(t) ? TIMER_CLOCK_EXT_HZ :
56
+ * timers which have a noticeable impact in emulation. 5us should be
144
+ aspeed_scu_get_apb_freq(s->scu);
57
+ * enough, use 20us for "safety".
58
+ */
59
+#define TIMER_MIN_NS (20 * SCALE_US)
60
+
61
/**
62
* Avoid mutual references between AspeedTimerCtrlState and AspeedTimer
63
* structs, as it's a waste of memory. The ptimer BH callback needs to know
64
@@ -XXX,XX +XXX,XX @@ static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns)
65
return t->reload - MIN(t->reload, ticks);
66
}
145
}
67
146
68
+static uint32_t calculate_min_ticks(AspeedTimer *t, uint32_t value)
147
static inline uint32_t calculate_ticks(struct AspeedTimer *t, uint64_t now_ns)
69
+{
70
+ uint32_t rate = calculate_rate(t);
71
+ uint32_t min_ticks = muldiv64(TIMER_MIN_NS, rate, NANOSECONDS_PER_SECOND);
72
+
73
+ return value < min_ticks ? min_ticks : value;
74
+}
75
+
76
static inline uint64_t calculate_time(struct AspeedTimer *t, uint32_t ticks)
77
{
78
uint64_t delta_ns;
79
@@ -XXX,XX +XXX,XX @@ static void aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int reg,
80
switch (reg) {
81
case TIMER_REG_RELOAD:
82
old_reload = t->reload;
83
- t->reload = value;
84
+ t->reload = calculate_min_ticks(t, value);
85
86
/* If the reload value was not previously set, or zero, and
87
* the current value is valid, try to start the timer if it is
88
--
148
--
89
2.20.1
149
2.20.1
90
150
91
151
diff view generated by jsdifflib
1
From: "Emilio G. Cota" <cota@braap.org>
1
From: "Emilio G. Cota" <cota@braap.org>
2
2
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
3
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
Signed-off-by: Emilio G. Cota <cota@braap.org>
4
Signed-off-by: Emilio G. Cota <cota@braap.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Message-id: 20190828165307.18321-8-alex.bennee@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
8
---
11
accel/tcg/atomic_template.h | 2 +-
9
accel/tcg/atomic_template.h | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
13
11
...
...
diff view generated by jsdifflib
1
The translation table walk for an ATS instruction can result in
1
The qemu-ga documentation is currently in qemu-ga.texi in
2
various faults. In general these are just reported back via the
2
Texinfo format, which we present to the user as:
3
PAR_EL1 fault status fields, but in some cases the architecture
3
* a qemu-ga manpage
4
requires that the fault is turned into an exception:
4
* a section of the main qemu-doc HTML documentation
5
* synchronous stage 2 faults of any kind during AT S1E0* and
6
AT S1E1* instructions executed from NS EL1 fault to EL2 or EL3
7
* synchronous external aborts are taken as Data Abort exceptions
8
5
9
(This is documented in the v8A Arm ARM DDI0487A.e D5.2.11 and
6
Convert the documentation to rST format, and present it to
10
G5.13.4.)
7
the user as:
8
* a qemu-ga manpage
9
* part of the interop/ Sphinx manual
11
10
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Michael Roth <mdroth@linux.vnet.ibm.com>
14
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Tested-by: Michael Roth <mdroth@linux.vnet.ibm.com>
15
Message-id: 20190816125802.25877-3-peter.maydell@linaro.org
14
Message-id: 20190905131040.8350-1-peter.maydell@linaro.org
16
---
15
---
17
target/arm/helper.c | 107 +++++++++++++++++++++++++++++++++++++-------
16
Makefile | 24 ++++---
18
1 file changed, 92 insertions(+), 15 deletions(-)
17
MAINTAINERS | 2 +-
18
docs/conf.py | 18 ++---
19
docs/interop/conf.py | 7 ++
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
19
27
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
28
diff --git a/Makefile b/Makefile
21
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
30
--- a/Makefile
23
+++ b/target/arm/helper.c
31
+++ b/Makefile
24
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
32
@@ -XXX,XX +XXX,XX @@ endif
25
ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs,
33
endif
26
&prot, &page_size, &fi, &cacheattrs);
34
27
35
ifdef BUILD_DOCS
28
+ if (ret) {
36
-DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8 qemu-ga.8
29
+ /*
37
+DOCS=qemu-doc.html qemu-doc.txt qemu.1 qemu-img.1 qemu-nbd.8 docs/interop/qemu-ga.8
30
+ * Some kinds of translation fault must cause exceptions rather
38
DOCS+=docs/interop/qemu-qmp-ref.html docs/interop/qemu-qmp-ref.txt docs/interop/qemu-qmp-ref.7
31
+ * than being reported in the PAR.
39
DOCS+=docs/interop/qemu-ga-ref.html docs/interop/qemu-ga-ref.txt docs/interop/qemu-ga-ref.7
32
+ */
40
DOCS+=docs/qemu-block-drivers.7
33
+ int current_el = arm_current_el(env);
41
@@ -XXX,XX +XXX,XX @@ DESCS=
34
+ int target_el;
42
endif
35
+ uint32_t syn, fsr, fsc;
43
36
+ bool take_exc = false;
44
# Note that we manually filter-out the non-Sphinx documentation which
37
+
45
-# is currently built into the docs/interop directory in the build tree.
38
+ if (fi.s1ptw && current_el == 1 && !arm_is_secure(env)
46
+# is currently built into the docs/interop directory in the build tree,
39
+ && (mmu_idx == ARMMMUIdx_S1NSE1 || mmu_idx == ARMMMUIdx_S1NSE0)) {
47
+# and also any sphinx-built manpages.
40
+ /*
48
define install-manual =
41
+ * Synchronous stage 2 fault on an access made as part of the
49
for d in $$(cd $(MANUAL_BUILDDIR) && find $1 -type d); do $(INSTALL_DIR) "$(DESTDIR)$(qemu_docdir)/$$d"; done
42
+ * translation table walk for AT S1E0* or AT S1E1* insn
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
43
+ * executed from NS EL1. If this is a synchronous external abort
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
44
+ * and SCR_EL3.EA == 1, then we take a synchronous external abort
52
endef
45
+ * to EL3. Otherwise the fault is taken as an exception to EL2,
53
46
+ * and HPFAR_EL2 holds the faulting IPA.
54
# Note that we deliberately do not install the "devel" manual: it is
47
+ */
55
@@ -XXX,XX +XXX,XX @@ ifdef CONFIG_TRACE_SYSTEMTAP
48
+ if (fi.type == ARMFault_SyncExternalOnWalk &&
56
    $(INSTALL_DATA) scripts/qemu-trace-stap.1 "$(DESTDIR)$(mandir)/man1"
49
+ (env->cp15.scr_el3 & SCR_EA)) {
57
endif
50
+ target_el = 3;
58
ifneq (,$(findstring qemu-ga,$(TOOLS)))
51
+ } else {
59
-    $(INSTALL_DATA) qemu-ga.8 "$(DESTDIR)$(mandir)/man8"
52
+ env->cp15.hpfar_el2 = extract64(fi.s2addr, 12, 47) << 4;
60
+    $(INSTALL_DATA) docs/interop/qemu-ga.8 "$(DESTDIR)$(mandir)/man8"
53
+ target_el = 2;
61
    $(INSTALL_DATA) docs/interop/qemu-ga-ref.html "$(DESTDIR)$(qemu_docdir)"
54
+ }
62
    $(INSTALL_DATA) docs/interop/qemu-ga-ref.txt "$(DESTDIR)$(qemu_docdir)"
55
+ take_exc = true;
63
    $(INSTALL_DATA) docs/interop/qemu-ga-ref.7 "$(DESTDIR)$(mandir)/man7"
56
+ } else if (fi.type == ARMFault_SyncExternalOnWalk) {
64
@@ -XXX,XX +XXX,XX @@ docs/version.texi: $(SRC_PATH)/VERSION config-host.mak
57
+ /*
65
sphinxdocs: $(MANUAL_BUILDDIR)/devel/index.html $(MANUAL_BUILDDIR)/interop/index.html $(MANUAL_BUILDDIR)/specs/index.html
58
+ * Synchronous external aborts during a translation table walk
66
59
+ * are taken as Data Abort exceptions.
67
# Canned command to build a single manual
60
+ */
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")
61
+ if (fi.stage2) {
69
+# Arguments: $1 = manual name, $2 = Sphinx builder ('html' or 'man')
62
+ if (current_el == 3) {
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")
63
+ target_el = 3;
71
# We assume all RST files in the manual's directory are used in it
64
+ } else {
72
manual-deps = $(wildcard $(SRC_PATH)/docs/$1/*.rst) $(SRC_PATH)/docs/$1/conf.py $(SRC_PATH)/docs/conf.py
65
+ target_el = 2;
73
66
+ }
74
$(MANUAL_BUILDDIR)/devel/index.html: $(call manual-deps,devel)
67
+ } else {
75
-    $(call build-manual,devel)
68
+ target_el = exception_target_el(env);
76
+    $(call build-manual,devel,html)
69
+ }
77
70
+ take_exc = true;
78
$(MANUAL_BUILDDIR)/interop/index.html: $(call manual-deps,interop)
71
+ }
79
-    $(call build-manual,interop)
72
+
80
+    $(call build-manual,interop,html)
73
+ if (take_exc) {
81
74
+ /* Construct FSR and FSC using same logic as arm_deliver_fault() */
82
$(MANUAL_BUILDDIR)/specs/index.html: $(call manual-deps,specs)
75
+ if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
83
-    $(call build-manual,specs)
76
+ arm_s1_regime_using_lpae_format(env, mmu_idx)) {
84
+    $(call build-manual,specs,html)
77
+ fsr = arm_fi_to_lfsc(&fi);
85
+
78
+ fsc = extract32(fsr, 0, 6);
86
+$(MANUAL_BUILDDIR)/interop/qemu-ga.8: $(call manual-deps,interop)
79
+ } else {
87
+    $(call build-manual,interop,man)
80
+ fsr = arm_fi_to_sfsc(&fi);
88
81
+ fsc = 0x3f;
89
qemu-options.texi: $(SRC_PATH)/qemu-options.hx $(SRC_PATH)/scripts/hxtool
82
+ }
90
    $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -t < $< > $@,"GEN","$@")
83
+ /*
91
@@ -XXX,XX +XXX,XX @@ qemu.1: qemu-option-trace.texi
84
+ * Report exception with ESR indicating a fault due to a
92
qemu-img.1: qemu-img.texi qemu-option-trace.texi qemu-img-cmds.texi
85
+ * translation table walk for a cache maintenance instruction.
93
fsdev/virtfs-proxy-helper.1: fsdev/virtfs-proxy-helper.texi
86
+ */
94
qemu-nbd.8: qemu-nbd.texi qemu-option-trace.texi
87
+ syn = syn_data_abort_no_iss(current_el == target_el,
95
-qemu-ga.8: qemu-ga.texi
88
+ fi.ea, 1, fi.s1ptw, 1, fsc);
96
docs/qemu-block-drivers.7: docs/qemu-block-drivers.texi
89
+ env->exception.vaddress = value;
97
docs/qemu-cpu-models.7: docs/qemu-cpu-models.texi
90
+ env->exception.fsr = fsr;
98
scripts/qemu-trace-stap.1: scripts/qemu-trace-stap.texi
91
+ raise_exception(env, EXCP_DATA_ABORT, syn, target_el);
99
@@ -XXX,XX +XXX,XX @@ txt: qemu-doc.txt docs/interop/qemu-qmp-ref.txt docs/interop/qemu-ga-ref.txt
92
+ }
100
qemu-doc.html qemu-doc.info qemu-doc.pdf qemu-doc.txt: \
93
+ }
101
    qemu-img.texi qemu-nbd.texi qemu-options.texi \
94
+
102
    qemu-tech.texi qemu-option-trace.texi \
95
if (is_a64(env)) {
103
-    qemu-deprecated.texi qemu-monitor.texi qemu-img-cmds.texi qemu-ga.texi \
96
format64 = true;
104
+    qemu-deprecated.texi qemu-monitor.texi qemu-img-cmds.texi \
97
} else if (arm_feature(env, ARM_FEATURE_LPAE)) {
105
    qemu-monitor-info.texi docs/qemu-block-drivers.texi \
98
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vapa_cp_reginfo[] = {
106
    docs/qemu-cpu-models.texi docs/security.texi
99
/* This underdecoding is safe because the reginfo is NO_RAW. */
107
100
{ .name = "ATS", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = CP_ANY,
108
diff --git a/MAINTAINERS b/MAINTAINERS
101
.access = PL1_W, .accessfn = ats_access,
109
index XXXXXXX..XXXXXXX 100644
102
- .writefn = ats_write, .type = ARM_CP_NO_RAW },
110
--- a/MAINTAINERS
103
+ .writefn = ats_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
111
+++ b/MAINTAINERS
104
#endif
112
@@ -XXX,XX +XXX,XX @@ QEMU Guest Agent
105
REGINFO_SENTINEL
113
M: Michael Roth <mdroth@linux.vnet.ibm.com>
106
};
114
S: Maintained
107
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
115
F: qga/
108
/* 64 bit address translation operations */
116
-F: qemu-ga.texi
109
{ .name = "AT_S1E1R", .state = ARM_CP_STATE_AA64,
117
+F: docs/interop/qemu-ga.rst
110
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 0,
118
F: scripts/qemu-guest-agent/
111
- .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 },
119
F: tests/test-qga.c
112
+ .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
120
F: docs/interop/qemu-ga-ref.texi
113
+ .writefn = ats_write64 },
121
diff --git a/docs/conf.py b/docs/conf.py
114
{ .name = "AT_S1E1W", .state = ARM_CP_STATE_AA64,
122
index XXXXXXX..XXXXXXX 100644
115
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 1,
123
--- a/docs/conf.py
116
- .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 },
124
+++ b/docs/conf.py
117
+ .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
125
@@ -XXX,XX +XXX,XX @@ todo_include_todos = False
118
+ .writefn = ats_write64 },
126
# with "option::" in the document being processed. Turn that off.
119
{ .name = "AT_S1E0R", .state = ARM_CP_STATE_AA64,
127
suppress_warnings = ["ref.option"]
120
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 2,
128
121
- .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 },
129
+# The rst_epilog fragment is effectively included in every rST file.
122
+ .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
130
+# We use it to define substitutions based on build config that
123
+ .writefn = ats_write64 },
131
+# can then be used in the documentation. The fallback if the
124
{ .name = "AT_S1E0W", .state = ARM_CP_STATE_AA64,
132
+# environment variable is not set is for the benefit of readthedocs
125
.opc0 = 1, .opc1 = 0, .crn = 7, .crm = 8, .opc2 = 3,
133
+# style document building; our Makefile always sets the variable.
126
- .access = PL1_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 },
134
+confdir = os.getenv('CONFDIR', "/etc/qemu")
127
+ .access = PL1_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
135
+rst_epilog = ".. |CONFDIR| replace:: ``" + confdir + "``\n"
128
+ .writefn = ats_write64 },
136
+
129
{ .name = "AT_S12E1R", .state = ARM_CP_STATE_AA64,
137
# -- Options for HTML output ----------------------------------------------
130
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 4,
138
131
- .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 },
139
# The theme to use for HTML and HTML Help pages. See the documentation for
132
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
140
@@ -XXX,XX +XXX,XX @@ latex_documents = [
133
+ .writefn = ats_write64 },
141
134
{ .name = "AT_S12E1W", .state = ARM_CP_STATE_AA64,
142
135
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 5,
143
# -- Options for manual page output ---------------------------------------
136
- .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 },
144
-
137
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
145
-# One entry per manual page. List of tuples
138
+ .writefn = ats_write64 },
146
-# (source start file, name, description, authors, manual section).
139
{ .name = "AT_S12E0R", .state = ARM_CP_STATE_AA64,
147
-man_pages = [
140
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 6,
148
- (master_doc, 'qemu', u'QEMU Documentation',
141
- .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 },
149
- [author], 1)
142
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
150
-]
143
+ .writefn = ats_write64 },
151
-
144
{ .name = "AT_S12E0W", .state = ARM_CP_STATE_AA64,
152
+# Individual manual/conf.py can override this to create man pages
145
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 7,
153
+man_pages = []
146
- .access = PL2_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 },
154
147
+ .access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
155
# -- Options for Texinfo output -------------------------------------------
148
+ .writefn = ats_write64 },
156
149
/* AT S1E2* are elsewhere as they UNDEF from EL3 if EL2 is not present */
157
diff --git a/docs/interop/conf.py b/docs/interop/conf.py
150
{ .name = "AT_S1E3R", .state = ARM_CP_STATE_AA64,
158
index XXXXXXX..XXXXXXX 100644
151
.opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 0,
159
--- a/docs/interop/conf.py
152
- .access = PL3_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 },
160
+++ b/docs/interop/conf.py
153
+ .access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
161
@@ -XXX,XX +XXX,XX @@ exec(compile(open(parent_config, "rb").read(), parent_config, 'exec'))
154
+ .writefn = ats_write64 },
162
# This slightly misuses the 'description', but is the best way to get
155
{ .name = "AT_S1E3W", .state = ARM_CP_STATE_AA64,
163
# the manual title to appear in the sidebar.
156
.opc0 = 1, .opc1 = 6, .crn = 7, .crm = 8, .opc2 = 1,
164
html_theme_options['description'] = u'System Emulation Management and Interoperability Guide'
157
- .access = PL3_W, .type = ARM_CP_NO_RAW, .writefn = ats_write64 },
165
+
158
+ .access = PL3_W, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC,
166
+# One entry per manual page. List of tuples
159
+ .writefn = ats_write64 },
167
+# (source start file, name, description, authors, manual section).
160
{ .name = "PAR_EL1", .state = ARM_CP_STATE_AA64,
168
+man_pages = [
161
.type = ARM_CP_ALIAS,
169
+ ('qemu-ga', 'qemu-ga', u'QEMU Guest Agent',
162
.opc0 = 3, .opc1 = 0, .crn = 7, .crm = 4, .opc2 = 0,
170
+ ['Michael Roth <mdroth@linux.vnet.ibm.com>'], 8)
163
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
171
+]
164
{ .name = "AT_S1E2R", .state = ARM_CP_STATE_AA64,
172
diff --git a/docs/interop/index.rst b/docs/interop/index.rst
165
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0,
173
index XXXXXXX..XXXXXXX 100644
166
.access = PL2_W, .accessfn = at_s1e2_access,
174
--- a/docs/interop/index.rst
167
- .type = ARM_CP_NO_RAW, .writefn = ats_write64 },
175
+++ b/docs/interop/index.rst
168
+ .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 },
176
@@ -XXX,XX +XXX,XX @@ Contents:
169
{ .name = "AT_S1E2W", .state = ARM_CP_STATE_AA64,
177
bitmaps
170
.opc0 = 1, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1,
178
live-block-operations
171
.access = PL2_W, .accessfn = at_s1e2_access,
179
pr-helper
172
- .type = ARM_CP_NO_RAW, .writefn = ats_write64 },
180
+ qemu-ga
173
+ .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC, .writefn = ats_write64 },
181
vhost-user
174
/* The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE
182
vhost-user-gpu
175
* if EL2 is not implemented; we choose to UNDEF. Behaviour at EL3
183
diff --git a/docs/interop/qemu-ga.rst b/docs/interop/qemu-ga.rst
176
* with SCR.NS == 0 outside Monitor mode is UNPREDICTABLE; we choose
184
new file mode 100644
177
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
185
index XXXXXXX..XXXXXXX
178
*/
186
--- /dev/null
179
{ .name = "ATS1HR", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 0,
187
+++ b/docs/interop/qemu-ga.rst
180
.access = PL2_W,
188
@@ -XXX,XX +XXX,XX @@
181
- .writefn = ats1h_write, .type = ARM_CP_NO_RAW },
189
+QEMU Guest Agent
182
+ .writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
190
+================
183
{ .name = "ATS1HW", .cp = 15, .opc1 = 4, .crn = 7, .crm = 8, .opc2 = 1,
191
+
184
.access = PL2_W,
192
+Synopsis
185
- .writefn = ats1h_write, .type = ARM_CP_NO_RAW },
193
+--------
186
+ .writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
194
+
187
{ .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH,
195
+**qemu-ga** [*OPTIONS*]
188
.opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0,
196
+
189
/* ARMv7 requires bit 0 and 1 to reset to 1. ARMv8 defines the
197
+Description
198
+-----------
199
+
200
+The QEMU Guest Agent is a daemon intended to be run within virtual
201
+machines. It allows the hypervisor host to perform various operations
202
+in the guest, such as:
203
+
204
+- get information from the guest
205
+- set the guest's system time
206
+- read/write a file
207
+- sync and freeze the filesystems
208
+- suspend the guest
209
+- reconfigure guest local processors
210
+- set user's password
211
+- ...
212
+
213
+qemu-ga will read a system configuration file on startup (located at
214
+|CONFDIR|\ ``/qemu-ga.conf`` by default), then parse remaining
215
+configuration options on the command line. For the same key, the last
216
+option wins, but the lists accumulate (see below for configuration
217
+file format).
218
+
219
+Options
220
+-------
221
+
222
+.. program:: qemu-ga
223
+
224
+.. option:: -m, --method=METHOD
225
+
226
+ Transport method: one of ``unix-listen``, ``virtio-serial``, or
227
+ ``isa-serial`` (``virtio-serial`` is the default).
228
+
229
+.. option:: -p, --path=PATH
230
+
231
+ Device/socket path (the default for virtio-serial is
232
+ ``/dev/virtio-ports/org.qemu.guest_agent.0``,
233
+ the default for isa-serial is ``/dev/ttyS0``)
234
+
235
+.. option:: -l, --logfile=PATH
236
+
237
+ Set log file path (default is stderr).
238
+
239
+.. option:: -f, --pidfile=PATH
240
+
241
+ Specify pid file (default is ``/var/run/qemu-ga.pid``).
242
+
243
+.. option:: -F, --fsfreeze-hook=PATH
244
+
245
+ Enable fsfreeze hook. Accepts an optional argument that specifies
246
+ script to run on freeze/thaw. Script will be called with
247
+ 'freeze'/'thaw' arguments accordingly (default is
248
+ |CONFDIR|\ ``/fsfreeze-hook``). If using -F with an argument, do
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
343
@@ -XXX,XX +XXX,XX @@
344
-@example
345
-@c man begin SYNOPSIS
346
-@command{qemu-ga} [@var{OPTIONS}]
347
-@c man end
348
-@end example
349
-
350
-@c man begin DESCRIPTION
351
-
352
-The QEMU Guest Agent is a daemon intended to be run within virtual
353
-machines. It allows the hypervisor host to perform various operations
354
-in the guest, such as:
355
-
356
-@itemize
357
-@item
358
-get information from the guest
359
-@item
360
-set the guest's system time
361
-@item
362
-read/write a file
363
-@item
364
-sync and freeze the filesystems
365
-@item
366
-suspend the guest
367
-@item
368
-reconfigure guest local processors
369
-@item
370
-set user's password
371
-@item
372
-...
373
-@end itemize
374
-
375
-qemu-ga will read a system configuration file on startup (located at
376
-@file{@value{CONFDIR}/qemu-ga.conf} by default), then parse remaining
377
-configuration options on the command line. For the same key, the last
378
-option wins, but the lists accumulate (see below for configuration
379
-file format).
380
-
381
-@c man end
382
-
383
-@c man begin OPTIONS
384
-@table @option
385
-@item -m, --method=@var{method}
386
- Transport method: one of @samp{unix-listen}, @samp{virtio-serial}, or
387
- @samp{isa-serial} (@samp{virtio-serial} is the default).
388
-
389
-@item -p, --path=@var{path}
390
- Device/socket path (the default for virtio-serial is
391
- @samp{/dev/virtio-ports/org.qemu.guest_agent.0},
392
- the default for isa-serial is @samp{/dev/ttyS0})
393
-
394
-@item -l, --logfile=@var{path}
395
- Set log file path (default is stderr).
396
-
397
-@item -f, --pidfile=@var{path}
398
- Specify pid file (default is @samp{/var/run/qemu-ga.pid}).
399
-
400
-@item -F, --fsfreeze-hook=@var{path}
401
- Enable fsfreeze hook. Accepts an optional argument that specifies
402
- script to run on freeze/thaw. Script will be called with
403
- 'freeze'/'thaw' arguments accordingly (default is
404
- @samp{@value{CONFDIR}/fsfreeze-hook}). If using -F with an argument, do
405
- not follow -F with a space (for example:
406
- @samp{-F/var/run/fsfreezehook.sh}).
407
-
408
-@item -t, --statedir=@var{path}
409
- Specify the directory to store state information (absolute paths only,
410
- default is @samp{/var/run}).
411
-
412
-@item -v, --verbose
413
- Log extra debugging information.
414
-
415
-@item -V, --version
416
- Print version information and exit.
417
-
418
-@item -d, --daemon
419
- Daemonize after startup (detach from terminal).
420
-
421
-@item -b, --blacklist=@var{list}
422
- Comma-separated list of RPCs to disable (no spaces, @samp{?} to list
423
- available RPCs).
424
-
425
-@item -D, --dump-conf
426
- Dump the configuration in a format compatible with @file{qemu-ga.conf}
427
- and exit.
428
-
429
-@item -h, --help
430
- Display this help and exit.
431
-@end table
432
-
433
-@c man end
434
-
435
-@c man begin FILES
436
-
437
-The syntax of the @file{qemu-ga.conf} configuration file follows the
438
-Desktop Entry Specification, here is a quick summary: it consists of
439
-groups of key-value pairs, interspersed with comments.
440
-
441
-@example
442
-# qemu-ga configuration sample
443
-[general]
444
-daemonize = 0
445
-pidfile = /var/run/qemu-ga.pid
446
-verbose = 0
447
-method = virtio-serial
448
-path = /dev/virtio-ports/org.qemu.guest_agent.0
449
-statedir = /var/run
450
-@end example
451
-
452
-The list of keys follows the command line options:
453
-@table @option
454
-@item daemon= boolean
455
-@item method= string
456
-@item path= string
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
190
--
481
--
191
2.20.1
482
2.20.1
192
483
193
484
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Commit ba1ba5cca introduce the ARM_CPU_TYPE_NAME() macro.
4
Unify the code base by use it in all places.
5
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190823143249.8096-2-philmd@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/allwinner-a10.c | 3 ++-
13
hw/arm/cubieboard.c | 3 ++-
14
hw/arm/digic.c | 3 ++-
15
hw/arm/fsl-imx25.c | 2 +-
16
hw/arm/fsl-imx31.c | 2 +-
17
hw/arm/fsl-imx6.c | 3 ++-
18
hw/arm/fsl-imx6ul.c | 2 +-
19
hw/arm/xlnx-zynqmp.c | 8 ++++----
20
8 files changed, 15 insertions(+), 11 deletions(-)
21
22
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
23
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/arm/allwinner-a10.c
25
+++ b/hw/arm/allwinner-a10.c
26
@@ -XXX,XX +XXX,XX @@ static void aw_a10_init(Object *obj)
27
AwA10State *s = AW_A10(obj);
28
29
object_initialize_child(obj, "cpu", &s->cpu, sizeof(s->cpu),
30
- "cortex-a8-" TYPE_ARM_CPU, &error_abort, NULL);
31
+ ARM_CPU_TYPE_NAME("cortex-a8"),
32
+ &error_abort, NULL);
33
34
sysbus_init_child_obj(obj, "intc", &s->intc, sizeof(s->intc),
35
TYPE_AW_A10_PIC);
36
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/cubieboard.c
39
+++ b/hw/arm/cubieboard.c
40
@@ -XXX,XX +XXX,XX @@ static void cubieboard_init(MachineState *machine)
41
42
static void cubieboard_machine_init(MachineClass *mc)
43
{
44
- mc->desc = "cubietech cubieboard";
45
+ mc->desc = "cubietech cubieboard (Cortex-A9)";
46
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
47
mc->init = cubieboard_init;
48
mc->block_default_type = IF_IDE;
49
mc->units_per_default_bus = 1;
50
diff --git a/hw/arm/digic.c b/hw/arm/digic.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/hw/arm/digic.c
53
+++ b/hw/arm/digic.c
54
@@ -XXX,XX +XXX,XX @@ static void digic_init(Object *obj)
55
int i;
56
57
object_initialize_child(obj, "cpu", &s->cpu, sizeof(s->cpu),
58
- "arm946-" TYPE_ARM_CPU, &error_abort, NULL);
59
+ ARM_CPU_TYPE_NAME("arm946"),
60
+ &error_abort, NULL);
61
62
for (i = 0; i < DIGIC4_NB_TIMERS; i++) {
63
#define DIGIC_TIMER_NAME_MLEN 11
64
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/arm/fsl-imx25.c
67
+++ b/hw/arm/fsl-imx25.c
68
@@ -XXX,XX +XXX,XX @@ static void fsl_imx25_init(Object *obj)
69
FslIMX25State *s = FSL_IMX25(obj);
70
int i;
71
72
- object_initialize(&s->cpu, sizeof(s->cpu), "arm926-" TYPE_ARM_CPU);
73
+ object_initialize(&s->cpu, sizeof(s->cpu), ARM_CPU_TYPE_NAME("arm926"));
74
75
sysbus_init_child_obj(obj, "avic", &s->avic, sizeof(s->avic),
76
TYPE_IMX_AVIC);
77
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/fsl-imx31.c
80
+++ b/hw/arm/fsl-imx31.c
81
@@ -XXX,XX +XXX,XX @@ static void fsl_imx31_init(Object *obj)
82
FslIMX31State *s = FSL_IMX31(obj);
83
int i;
84
85
- object_initialize(&s->cpu, sizeof(s->cpu), "arm1136-" TYPE_ARM_CPU);
86
+ object_initialize(&s->cpu, sizeof(s->cpu), ARM_CPU_TYPE_NAME("arm1136"));
87
88
sysbus_init_child_obj(obj, "avic", &s->avic, sizeof(s->avic),
89
TYPE_IMX_AVIC);
90
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/hw/arm/fsl-imx6.c
93
+++ b/hw/arm/fsl-imx6.c
94
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_init(Object *obj)
95
for (i = 0; i < MIN(ms->smp.cpus, FSL_IMX6_NUM_CPUS); i++) {
96
snprintf(name, NAME_SIZE, "cpu%d", i);
97
object_initialize_child(obj, name, &s->cpu[i], sizeof(s->cpu[i]),
98
- "cortex-a9-" TYPE_ARM_CPU, &error_abort, NULL);
99
+ ARM_CPU_TYPE_NAME("cortex-a9"),
100
+ &error_abort, NULL);
101
}
102
103
sysbus_init_child_obj(obj, "a9mpcore", &s->a9mpcore, sizeof(s->a9mpcore),
104
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/arm/fsl-imx6ul.c
107
+++ b/hw/arm/fsl-imx6ul.c
108
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
109
int i;
110
111
object_initialize_child(obj, "cpu0", &s->cpu, sizeof(s->cpu),
112
- "cortex-a7-" TYPE_ARM_CPU, &error_abort, NULL);
113
+ ARM_CPU_TYPE_NAME("cortex-a7"), &error_abort, NULL);
114
115
/*
116
* A7MPCORE
117
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/hw/arm/xlnx-zynqmp.c
120
+++ b/hw/arm/xlnx-zynqmp.c
121
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_rpu(MachineState *ms, XlnxZynqMPState *s,
122
123
object_initialize_child(OBJECT(&s->rpu_cluster), "rpu-cpu[*]",
124
&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]),
125
- "cortex-r5f-" TYPE_ARM_CPU, &error_abort,
126
- NULL);
127
+ ARM_CPU_TYPE_NAME("cortex-r5f"),
128
+ &error_abort, NULL);
129
130
name = object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i]));
131
if (strcmp(name, boot_cpu)) {
132
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_init(Object *obj)
133
for (i = 0; i < num_apus; i++) {
134
object_initialize_child(OBJECT(&s->apu_cluster), "apu-cpu[*]",
135
&s->apu_cpu[i], sizeof(s->apu_cpu[i]),
136
- "cortex-a53-" TYPE_ARM_CPU, &error_abort,
137
- NULL);
138
+ ARM_CPU_TYPE_NAME("cortex-a53"),
139
+ &error_abort, NULL);
140
}
141
142
sysbus_init_child_obj(obj, "gic", &s->gic, sizeof(s->gic),
143
--
144
2.20.1
145
146
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
As explained in commit aff39be0ed97:
4
5
Both functions, object_initialize() and object_property_add_child()
6
increase the reference counter of the new object, so one of the
7
references has to be dropped afterwards to get the reference
8
counting right. Otherwise the child object will not be properly
9
cleaned up when the parent gets destroyed.
10
Thus let's use now object_initialize_child() instead to get the
11
reference counting here right.
12
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Reviewed-by: Thomas Huth <thuth@redhat.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190823143249.8096-3-philmd@redhat.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
hw/arm/mcimx7d-sabre.c | 9 ++++-----
21
hw/arm/mps2-tz.c | 15 +++++++--------
22
hw/arm/musca.c | 9 +++++----
23
3 files changed, 16 insertions(+), 17 deletions(-)
24
25
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/mcimx7d-sabre.c
28
+++ b/hw/arm/mcimx7d-sabre.c
29
@@ -XXX,XX +XXX,XX @@ static void mcimx7d_sabre_init(MachineState *machine)
30
{
31
static struct arm_boot_info boot_info;
32
MCIMX7Sabre *s = g_new0(MCIMX7Sabre, 1);
33
- Object *soc;
34
int i;
35
36
if (machine->ram_size > FSL_IMX7_MMDC_SIZE) {
37
@@ -XXX,XX +XXX,XX @@ static void mcimx7d_sabre_init(MachineState *machine)
38
.nb_cpus = machine->smp.cpus,
39
};
40
41
- object_initialize(&s->soc, sizeof(s->soc), TYPE_FSL_IMX7);
42
- soc = OBJECT(&s->soc);
43
- object_property_add_child(OBJECT(machine), "soc", soc, &error_fatal);
44
- object_property_set_bool(soc, true, "realized", &error_fatal);
45
+ object_initialize_child(OBJECT(machine), "soc",
46
+ &s->soc, sizeof(s->soc),
47
+ TYPE_FSL_IMX7, &error_fatal, NULL);
48
+ object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);
49
50
memory_region_allocate_system_memory(&s->ram, NULL, "mcimx7d-sabre.ram",
51
machine->ram_size);
52
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/arm/mps2-tz.c
55
+++ b/hw/arm/mps2-tz.c
56
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
57
/* The sec_resp_cfg output from the IoTKit must be split into multiple
58
* lines, one for each of the PPCs we create here, plus one per MSC.
59
*/
60
- object_initialize(&mms->sec_resp_splitter, sizeof(mms->sec_resp_splitter),
61
- TYPE_SPLIT_IRQ);
62
- object_property_add_child(OBJECT(machine), "sec-resp-splitter",
63
- OBJECT(&mms->sec_resp_splitter), &error_abort);
64
+ object_initialize_child(OBJECT(machine), "sec-resp-splitter",
65
+ &mms->sec_resp_splitter,
66
+ sizeof(mms->sec_resp_splitter),
67
+ TYPE_SPLIT_IRQ, &error_abort, NULL);
68
object_property_set_int(OBJECT(&mms->sec_resp_splitter),
69
ARRAY_SIZE(mms->ppc) + ARRAY_SIZE(mms->msc),
70
"num-lines", &error_fatal);
71
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
72
* Tx, Rx and "combined" IRQs are sent to the NVIC separately.
73
* Create the OR gate for this.
74
*/
75
- object_initialize(&mms->uart_irq_orgate, sizeof(mms->uart_irq_orgate),
76
- TYPE_OR_IRQ);
77
- object_property_add_child(OBJECT(mms), "uart-irq-orgate",
78
- OBJECT(&mms->uart_irq_orgate), &error_abort);
79
+ object_initialize_child(OBJECT(mms), "uart-irq-orgate",
80
+ &mms->uart_irq_orgate, sizeof(mms->uart_irq_orgate),
81
+ TYPE_OR_IRQ, &error_abort, NULL);
82
object_property_set_int(OBJECT(&mms->uart_irq_orgate), 10, "num-lines",
83
&error_fatal);
84
object_property_set_bool(OBJECT(&mms->uart_irq_orgate), true,
85
diff --git a/hw/arm/musca.c b/hw/arm/musca.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/arm/musca.c
88
+++ b/hw/arm/musca.c
89
@@ -XXX,XX +XXX,XX @@ static void musca_init(MachineState *machine)
90
* The sec_resp_cfg output from the SSE-200 must be split into multiple
91
* lines, one for each of the PPCs we create here.
92
*/
93
- object_initialize(&mms->sec_resp_splitter, sizeof(mms->sec_resp_splitter),
94
- TYPE_SPLIT_IRQ);
95
- object_property_add_child(OBJECT(machine), "sec-resp-splitter",
96
- OBJECT(&mms->sec_resp_splitter), &error_fatal);
97
+ object_initialize_child(OBJECT(machine), "sec-resp-splitter",
98
+ &mms->sec_resp_splitter,
99
+ sizeof(mms->sec_resp_splitter),
100
+ TYPE_SPLIT_IRQ, &error_fatal, NULL);
101
+
102
object_property_set_int(OBJECT(&mms->sec_resp_splitter),
103
ARRAY_SIZE(mms->ppc), "num-lines", &error_fatal);
104
object_property_set_bool(OBJECT(&mms->sec_resp_splitter), true,
105
--
106
2.20.1
107
108
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Both object_initialize() and qdev_set_parent_bus() increase the
4
reference counter of the new object, so one of the references has
5
to be dropped afterwards to get the reference counting right.
6
In machine model code this refcount leak is not particularly
7
problematic because (unlike devices) machines will never be
8
created on demand via QMP, and they are never destroyed.
9
But in any case let's use the new sysbus_init_child_obj() instead
10
to get the reference counting here right.
11
12
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190823143249.8096-4-philmd@redhat.com
15
[PMM: rewrote commit message]
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
hw/arm/exynos4_boards.c | 4 ++--
19
1 file changed, 2 insertions(+), 2 deletions(-)
20
21
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/exynos4_boards.c
24
+++ b/hw/arm/exynos4_boards.c
25
@@ -XXX,XX +XXX,XX @@ exynos4_boards_init_common(MachineState *machine,
26
exynos4_boards_init_ram(s, get_system_memory(),
27
exynos4_board_ram_size[board_type]);
28
29
- object_initialize(&s->soc, sizeof(s->soc), TYPE_EXYNOS4210_SOC);
30
- qdev_set_parent_bus(DEVICE(&s->soc), sysbus_get_default());
31
+ sysbus_init_child_obj(OBJECT(machine), "soc",
32
+ &s->soc, sizeof(s->soc), TYPE_EXYNOS4210_SOC);
33
object_property_set_bool(OBJECT(&s->soc), true, "realized",
34
&error_fatal);
35
36
--
37
2.20.1
38
39
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
Child properties form the composition tree. All objects need to be
4
a child of another object. Objects can only be a child of one object.
5
6
Respect this with the i.MX SoC, to get a cleaner composition tree.
7
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20190823143249.8096-5-philmd@redhat.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/fsl-imx25.c | 4 +++-
14
hw/arm/fsl-imx31.c | 4 +++-
15
2 files changed, 6 insertions(+), 2 deletions(-)
16
17
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/fsl-imx25.c
20
+++ b/hw/arm/fsl-imx25.c
21
@@ -XXX,XX +XXX,XX @@ static void fsl_imx25_init(Object *obj)
22
FslIMX25State *s = FSL_IMX25(obj);
23
int i;
24
25
- object_initialize(&s->cpu, sizeof(s->cpu), ARM_CPU_TYPE_NAME("arm926"));
26
+ object_initialize_child(obj, "cpu", &s->cpu, sizeof(s->cpu),
27
+ ARM_CPU_TYPE_NAME("arm926"),
28
+ &error_abort, NULL);
29
30
sysbus_init_child_obj(obj, "avic", &s->avic, sizeof(s->avic),
31
TYPE_IMX_AVIC);
32
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/arm/fsl-imx31.c
35
+++ b/hw/arm/fsl-imx31.c
36
@@ -XXX,XX +XXX,XX @@ static void fsl_imx31_init(Object *obj)
37
FslIMX31State *s = FSL_IMX31(obj);
38
int i;
39
40
- object_initialize(&s->cpu, sizeof(s->cpu), ARM_CPU_TYPE_NAME("arm1136"));
41
+ object_initialize_child(obj, "cpu", &s->cpu, sizeof(s->cpu),
42
+ ARM_CPU_TYPE_NAME("arm1136"),
43
+ &error_abort, NULL);
44
45
sysbus_init_child_obj(obj, "avic", &s->avic, sizeof(s->avic),
46
TYPE_IMX_AVIC);
47
--
48
2.20.1
49
50
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
As explained in commit aff39be0ed97:
4
5
Both functions, object_initialize() and object_property_add_child()
6
increase the reference counter of the new object, so one of the
7
references has to be dropped afterwards to get the reference
8
counting right. Otherwise the child object will not be properly
9
cleaned up when the parent gets destroyed.
10
Thus let's use now object_initialize_child() instead to get the
11
reference counting here right.
12
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Reviewed-by: Thomas Huth <thuth@redhat.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190823143249.8096-6-philmd@redhat.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
hw/dma/xilinx_axidma.c | 16 ++++++++--------
21
1 file changed, 8 insertions(+), 8 deletions(-)
22
23
diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/dma/xilinx_axidma.c
26
+++ b/hw/dma/xilinx_axidma.c
27
@@ -XXX,XX +XXX,XX @@ static void xilinx_axidma_init(Object *obj)
28
XilinxAXIDMA *s = XILINX_AXI_DMA(obj);
29
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
30
31
- object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
32
- TYPE_XILINX_AXI_DMA_DATA_STREAM);
33
- object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev),
34
- TYPE_XILINX_AXI_DMA_CONTROL_STREAM);
35
- object_property_add_child(OBJECT(s), "axistream-connected-target",
36
- (Object *)&s->rx_data_dev, &error_abort);
37
- object_property_add_child(OBJECT(s), "axistream-control-connected-target",
38
- (Object *)&s->rx_control_dev, &error_abort);
39
+ object_initialize_child(OBJECT(s), "axistream-connected-target",
40
+ &s->rx_data_dev, sizeof(s->rx_data_dev),
41
+ TYPE_XILINX_AXI_DMA_DATA_STREAM, &error_abort,
42
+ NULL);
43
+ object_initialize_child(OBJECT(s), "axistream-control-connected-target",
44
+ &s->rx_control_dev, sizeof(s->rx_control_dev),
45
+ TYPE_XILINX_AXI_DMA_CONTROL_STREAM, &error_abort,
46
+ NULL);
47
48
sysbus_init_irq(sbd, &s->streams[0].irq);
49
sysbus_init_irq(sbd, &s->streams[1].irq);
50
--
51
2.20.1
52
53
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
2
1
3
As explained in commit aff39be0ed97:
4
5
Both functions, object_initialize() and object_property_add_child()
6
increase the reference counter of the new object, so one of the
7
references has to be dropped afterwards to get the reference
8
counting right. Otherwise the child object will not be properly
9
cleaned up when the parent gets destroyed.
10
Thus let's use now object_initialize_child() instead to get the
11
reference counting here right.
12
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Reviewed-by: Thomas Huth <thuth@redhat.com>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190823143249.8096-7-philmd@redhat.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
hw/net/xilinx_axienet.c | 17 ++++++++---------
21
1 file changed, 8 insertions(+), 9 deletions(-)
22
23
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/net/xilinx_axienet.c
26
+++ b/hw/net/xilinx_axienet.c
27
@@ -XXX,XX +XXX,XX @@ static void xilinx_enet_init(Object *obj)
28
XilinxAXIEnet *s = XILINX_AXI_ENET(obj);
29
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
30
31
- object_initialize(&s->rx_data_dev, sizeof(s->rx_data_dev),
32
- TYPE_XILINX_AXI_ENET_DATA_STREAM);
33
- object_initialize(&s->rx_control_dev, sizeof(s->rx_control_dev),
34
- TYPE_XILINX_AXI_ENET_CONTROL_STREAM);
35
- object_property_add_child(OBJECT(s), "axistream-connected-target",
36
- (Object *)&s->rx_data_dev, &error_abort);
37
- object_property_add_child(OBJECT(s), "axistream-control-connected-target",
38
- (Object *)&s->rx_control_dev, &error_abort);
39
-
40
+ object_initialize_child(OBJECT(s), "axistream-connected-target",
41
+ &s->rx_data_dev, sizeof(s->rx_data_dev),
42
+ TYPE_XILINX_AXI_ENET_DATA_STREAM, &error_abort,
43
+ NULL);
44
+ object_initialize_child(OBJECT(s), "axistream-control-connected-target",
45
+ &s->rx_control_dev, sizeof(s->rx_control_dev),
46
+ TYPE_XILINX_AXI_ENET_CONTROL_STREAM, &error_abort,
47
+ NULL);
48
sysbus_init_irq(sbd, &s->irq);
49
50
memory_region_init_io(&s->iomem, OBJECT(s), &enet_ops, s, "enet", 0x40000);
51
--
52
2.20.1
53
54
diff view generated by jsdifflib
Deleted patch
1
From: Alex Bennée <alex.bennee@linaro.org>
2
1
3
Commit a5e0b3311 removed these in favour of querying machine
4
properties. Remove the extern declarations as well.
5
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190828165307.18321-6-alex.bennee@linaro.org
10
Cc: Like Xu <like.xu@linux.intel.com>
11
Message-Id: <20190711130546.18578-1-alex.bennee@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
include/sysemu/sysemu.h | 2 --
15
1 file changed, 2 deletions(-)
16
17
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/sysemu/sysemu.h
20
+++ b/include/sysemu/sysemu.h
21
@@ -XXX,XX +XXX,XX @@ extern const char *keyboard_layout;
22
extern int win2k_install_hack;
23
extern int alt_grab;
24
extern int ctrl_grab;
25
-extern int smp_cpus;
26
-extern unsigned int max_cpus;
27
extern int cursor_hide;
28
extern int graphic_rotate;
29
extern int no_quit;
30
--
31
2.20.1
32
33
diff view generated by jsdifflib
Deleted patch
1
The function neon_store_reg32() doesn't free the TCG temp that it
2
is passed, so the caller must do that. We got this right in most
3
places but forgot to free the TCG temps in trans_VMOV_64_sp().
4
1
5
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190827121931.26836-1-peter.maydell@linaro.org
10
---
11
target/arm/translate-vfp.inc.c | 2 ++
12
1 file changed, 2 insertions(+)
13
14
diff --git a/target/arm/translate-vfp.inc.c b/target/arm/translate-vfp.inc.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-vfp.inc.c
17
+++ b/target/arm/translate-vfp.inc.c
18
@@ -XXX,XX +XXX,XX @@ static bool trans_VMOV_64_sp(DisasContext *s, arg_VMOV_64_sp *a)
19
/* gpreg to fpreg */
20
tmp = load_reg(s, a->rt);
21
neon_store_reg32(tmp, a->vm);
22
+ tcg_temp_free_i32(tmp);
23
tmp = load_reg(s, a->rt2);
24
neon_store_reg32(tmp, a->vm + 1);
25
+ tcg_temp_free_i32(tmp);
26
}
27
28
return true;
29
--
30
2.20.1
31
32
diff view generated by jsdifflib