1
Arm queue built up to a point where it seems worth sending:
1
target-arm queue: the big things here are the new nRF51
2
various bug fixes, plus RTH's refactoring in preparation for SVE.
2
(microbit) devices and Luc's gdbstub multiprocess work.
3
3
4
thanks
4
thanks
5
-- PMM
5
-- PMM
6
7
8
The following changes since commit 0f79bfe38a2cf0f43c7ea4959da7f8ebd7858f3d:
9
6
10
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-2.12-pull-request' into staging (2018-01-25 09:53:53 +0000)
7
The following changes since commit a29644590f95166c8a13e5797f8e7701134b31d0:
11
8
12
are available in the git repository at:
9
Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2019-01-05' into staging (2019-01-07 11:55:52 +0000)
13
10
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180125
11
are available in the Git repository at:
15
12
16
for you to fetch changes up to 24da047af0e99a83fcc0d50b86c0f2627f7418b3:
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190107
17
14
18
pl110: Implement vertical compare/next base interrupts (2018-01-25 11:45:30 +0000)
15
for you to fetch changes up to f831f955d420966471f5f8b316ba50d2523b1ff0:
16
17
Support u-boot noload images for arm as used by, NetBSD/evbarm GENERIC kernel. (2019-01-07 15:46:20 +0000)
19
18
20
----------------------------------------------------------------
19
----------------------------------------------------------------
21
target-arm queue:
20
target-arm queue:
22
* target/arm: Fix address truncation in 64-bit pagetable walks
21
* Support u-boot 'noload' images for Arm (as used by NetBSD/evbarm GENERIC kernel)
23
* i.MX: Fix FEC/ENET receive functions
22
* hw/misc/tz-mpc: Fix value of BLK_MAX register
24
* target/arm: preparatory refactoring for SVE emulation
23
* target/arm: Emit barriers for A32/T32 load-acquire/store-release insns
25
* hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
24
* nRF51 SoC: add timer, GPIO, RNG peripherals
26
* hw/intc/arm_gic: Fix C_RPR value on idle priority
25
* hw/arm/allwinner-a10: Add the 'A' SRAM and the SRAM controller
27
* hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
26
* cpus.c: Fix race condition in cpu_stop_current()
28
* hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1
27
* hw/arm: versal: Plug memory leaks
29
* hw/arm/virt: Check that the CPU realize method succeeded
28
* Allow M profile boards to run even if -kernel not specified
30
* sdhci: fix a NULL pointer dereference due to uninitialized AddressSpace object
29
* gdbstub: Add multiprocess extension support for use when the
31
* xilinx_spips: Correct usage of an uninitialized local variable
30
board has multiple CPUs of different types (like the Xilinx Zynq boards)
32
* pl110: Implement vertical compare/next base interrupts
31
* target/arm: Don't decode S bit in SVE brk[ab] merging insns
32
* target/arm: Convert ARM_TBFLAG_* to FIELDs
33
33
34
----------------------------------------------------------------
34
----------------------------------------------------------------
35
Ard Biesheuvel (1):
35
Edgar E. Iglesias (1):
36
target/arm: Fix 32-bit address truncation
36
hw/arm: versal: Plug memory leaks
37
37
38
Francisco Iglesias (1):
38
Luc Michel (16):
39
xilinx_spips: Correct usage of an uninitialized local variable
39
hw/cpu: introduce CPU clusters
40
gdbstub: introduce GDB processes
41
gdbstub: add multiprocess support to '?' packets
42
gdbstub: add multiprocess support to 'H' and 'T' packets
43
gdbstub: add multiprocess support to vCont packets
44
gdbstub: add multiprocess support to 'sC' packets
45
gdbstub: add multiprocess support to (f|s)ThreadInfo and ThreadExtraInfo
46
gdbstub: add multiprocess support to Xfer:features:read:
47
gdbstub: add multiprocess support to gdb_vm_state_change()
48
gdbstub: add multiprocess support to 'D' packets
49
gdbstub: add support for extended mode packet
50
gdbstub: add support for vAttach packets
51
gdbstub: processes initialization on new peer connection
52
gdbstub: gdb_set_stop_cpu: ignore request when process is not attached
53
gdbstub: add multiprocess extension support
54
arm/xlnx-zynqmp: put APUs and RPUs in separate CPU clusters
40
55
41
Jean-Christophe Dubois (1):
56
Nick Hudson (1):
42
i.MX: Fix FEC/ENET receive funtions
57
Support u-boot noload images for arm as used by, NetBSD/evbarm GENERIC kernel.
43
58
44
Linus Walleij (1):
59
Peter Maydell (3):
45
pl110: Implement vertical compare/next base interrupts
60
cpus.c: Fix race condition in cpu_stop_current()
46
61
target/arm: Emit barriers for A32/T32 load-acquire/store-release insns
47
Luc MICHEL (4):
62
hw/misc/tz-mpc: Fix value of BLK_MAX register
48
hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
49
hw/intc/arm_gic: Fix C_RPR value on idle priority
50
hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
51
hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1
52
53
Peter Maydell (1):
54
hw/arm/virt: Check that the CPU realize method succeeded
55
63
56
Philippe Mathieu-Daudé (1):
64
Philippe Mathieu-Daudé (1):
57
sdhci: fix a NULL pointer dereference due to uninitialized AddresSpace object
65
hw/arm/allwinner-a10: Add the 'A' SRAM and the SRAM controller
58
66
59
Richard Henderson (11):
67
Richard Henderson (2):
60
target/arm: Mark disas_set_insn_syndrome inline
68
target/arm: Convert ARM_TBFLAG_* to FIELDs
61
target/arm: Use pointers in crypto helpers
69
target/arm: SVE brk[ab] merging does not have s bit
62
target/arm: Use pointers in neon zip/uzp helpers
63
target/arm: Use pointers in neon tbl helper
64
target/arm: Change the type of vfp.regs
65
target/arm: Add aa{32, 64}_vfp_{dreg, qreg} helpers
66
vmstate: Add VMSTATE_UINT64_SUB_ARRAY
67
target/arm: Add ARM_FEATURE_SVE
68
target/arm: Move cpu_get_tb_cpu_state out of line
69
target/arm: Hoist store to flags output in cpu_get_tb_cpu_state
70
target/arm: Simplify fp_exception_el for user-only
71
70
72
include/hw/sd/sdhci.h | 1 +
71
Stefan Hajnoczi (1):
73
include/migration/vmstate.h | 9 ++-
72
Revert "armv7m: Guard against no -kernel argument"
74
target/arm/cpu.h | 157 ++++++++-----------------------------
75
target/arm/helper.h | 46 +++++------
76
target/arm/translate.h | 2 +-
77
hw/arm/virt.c | 2 +-
78
hw/display/pl110.c | 30 +++++++-
79
hw/intc/arm_gic.c | 25 +++++-
80
hw/net/imx_fec.c | 8 +-
81
hw/sd/sdhci.c | 1 +
82
hw/ssi/xilinx_spips.c | 18 ++++-
83
linux-user/signal.c | 22 +++---
84
target/arm/arch_dump.c | 8 +-
85
target/arm/crypto_helper.c | 184 +++++++++++++++++---------------------------
86
target/arm/helper-a64.c | 5 +-
87
target/arm/helper.c | 164 +++++++++++++++++++++++++++++++++++----
88
target/arm/kvm32.c | 4 +-
89
target/arm/kvm64.c | 31 +++-----
90
target/arm/machine.c | 2 +-
91
target/arm/neon_helper.c | 162 ++++++++++++++++++++------------------
92
target/arm/op_helper.c | 17 ++--
93
target/arm/translate-a64.c | 100 ++++++++++++------------
94
target/arm/translate.c | 134 +++++++++++++++++---------------
95
23 files changed, 607 insertions(+), 525 deletions(-)
96
73
74
Steffen Görtz (11):
75
qtest: Add set_irq_in command to set IRQ/GPIO level
76
arm: Add header to host common definition for nRF51 SOC peripherals
77
hw/misc/nrf51_rng: Add NRF51 random number generator peripheral
78
arm: Instantiate NRF51 random number generator
79
hw/gpio/nrf51_gpio: Add nRF51 GPIO peripheral
80
arm: Instantiate NRF51 general purpose I/O
81
tests/microbit-test: Add Tests for nRF51 GPIO
82
hw/timer/nrf51_timer: Add nRF51 Timer peripheral
83
arm: Instantiate NRF51 Timers
84
tests/microbit-test: Add Tests for nRF51 Timer
85
arm: Add Clock peripheral stub to NRF51 SOC
86
87
Thomas Huth (1):
88
MAINTAINERS: Add ARM-related files for hw/[misc|input|timer]/
89
90
Makefile.objs | 1 +
91
hw/cpu/Makefile.objs | 2 +-
92
hw/gpio/Makefile.objs | 1 +
93
hw/misc/Makefile.objs | 1 +
94
hw/timer/Makefile.objs | 1 +
95
tests/Makefile.include | 2 +
96
hw/core/uboot_image.h | 1 +
97
include/hw/arm/allwinner-a10.h | 1 +
98
include/hw/arm/nrf51.h | 45 +++
99
include/hw/arm/nrf51_soc.h | 9 +
100
include/hw/arm/xlnx-zynqmp.h | 3 +
101
include/hw/char/nrf51_uart.h | 1 -
102
include/hw/cpu/cluster.h | 58 ++++
103
include/hw/gpio/nrf51_gpio.h | 69 +++++
104
include/hw/loader.h | 7 +-
105
include/hw/misc/nrf51_rng.h | 83 +++++
106
include/hw/timer/nrf51_timer.h | 80 +++++
107
target/arm/cpu.h | 102 ++-----
108
tests/libqtest.h | 13 +
109
cpus.c | 3 +-
110
gdbstub.c | 672 ++++++++++++++++++++++++++++++++++++-----
111
hw/arm/allwinner-a10.c | 6 +
112
hw/arm/armv7m.c | 5 -
113
hw/arm/boot.c | 8 +-
114
hw/arm/nrf51_soc.c | 117 +++++--
115
hw/arm/xlnx-versal-virt.c | 2 +
116
hw/arm/xlnx-zynqmp.c | 23 +-
117
hw/core/loader.c | 19 +-
118
hw/cpu/cluster.c | 50 +++
119
hw/gpio/nrf51_gpio.c | 300 ++++++++++++++++++
120
hw/microblaze/boot.c | 2 +-
121
hw/misc/nrf51_rng.c | 262 ++++++++++++++++
122
hw/misc/tz-mpc.c | 2 +-
123
hw/nios2/boot.c | 2 +-
124
hw/ppc/e500.c | 1 +
125
hw/ppc/ppc440_bamboo.c | 2 +-
126
hw/ppc/sam460ex.c | 2 +-
127
hw/timer/nrf51_timer.c | 393 ++++++++++++++++++++++++
128
qtest.c | 43 +++
129
target/arm/helper.c | 49 ++-
130
target/arm/translate-a64.c | 22 +-
131
target/arm/translate.c | 73 +++--
132
tests/libqtest.c | 10 +
133
tests/microbit-test.c | 255 ++++++++++++++++
134
MAINTAINERS | 18 +-
135
hw/gpio/trace-events | 7 +
136
hw/timer/trace-events | 5 +
137
target/arm/sve.decode | 5 +-
138
48 files changed, 2567 insertions(+), 271 deletions(-)
139
create mode 100644 include/hw/arm/nrf51.h
140
create mode 100644 include/hw/cpu/cluster.h
141
create mode 100644 include/hw/gpio/nrf51_gpio.h
142
create mode 100644 include/hw/misc/nrf51_rng.h
143
create mode 100644 include/hw/timer/nrf51_timer.h
144
create mode 100644 hw/cpu/cluster.c
145
create mode 100644 hw/gpio/nrf51_gpio.c
146
create mode 100644 hw/misc/nrf51_rng.c
147
create mode 100644 hw/timer/nrf51_timer.c
148
create mode 100644 tests/microbit-test.c
149
create mode 100644 hw/gpio/trace-events
150
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use "register" TBFLAG_ANY to indicate shared state between
4
A32 and A64, and "registers" TBFLAG_A32 & TBFLAG_A64 for
5
fields that are specific to the given cpu state.
6
7
Move ARM_TBFLAG_BE_DATA to shared state, instead of its current
8
placement within "Bit usage when in AArch32 state".
9
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20180119045438.28582-15-richard.henderson@linaro.org
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Message-id: 20181218164348.7127-1-richard.henderson@linaro.org
13
[PMM: removed the renaming of BE_DATA flag to BE]
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
16
---
9
target/arm/helper.c | 35 +++++++++++++++++++----------------
17
target/arm/cpu.h | 102 ++++++++-----------------------------
10
1 file changed, 19 insertions(+), 16 deletions(-)
18
target/arm/helper.c | 49 +++++++++---------
11
19
target/arm/translate-a64.c | 22 ++++----
20
target/arm/translate.c | 40 ++++++++-------
21
4 files changed, 78 insertions(+), 135 deletions(-)
22
23
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/cpu.h
26
+++ b/target/arm/cpu.h
27
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
28
* We put flags which are shared between 32 and 64 bit mode at the top
29
* of the word, and flags which apply to only one mode at the bottom.
30
*/
31
-#define ARM_TBFLAG_AARCH64_STATE_SHIFT 31
32
-#define ARM_TBFLAG_AARCH64_STATE_MASK (1U << ARM_TBFLAG_AARCH64_STATE_SHIFT)
33
-#define ARM_TBFLAG_MMUIDX_SHIFT 28
34
-#define ARM_TBFLAG_MMUIDX_MASK (0x7 << ARM_TBFLAG_MMUIDX_SHIFT)
35
-#define ARM_TBFLAG_SS_ACTIVE_SHIFT 27
36
-#define ARM_TBFLAG_SS_ACTIVE_MASK (1 << ARM_TBFLAG_SS_ACTIVE_SHIFT)
37
-#define ARM_TBFLAG_PSTATE_SS_SHIFT 26
38
-#define ARM_TBFLAG_PSTATE_SS_MASK (1 << ARM_TBFLAG_PSTATE_SS_SHIFT)
39
+FIELD(TBFLAG_ANY, AARCH64_STATE, 31, 1)
40
+FIELD(TBFLAG_ANY, MMUIDX, 28, 3)
41
+FIELD(TBFLAG_ANY, SS_ACTIVE, 27, 1)
42
+FIELD(TBFLAG_ANY, PSTATE_SS, 26, 1)
43
/* Target EL if we take a floating-point-disabled exception */
44
-#define ARM_TBFLAG_FPEXC_EL_SHIFT 24
45
-#define ARM_TBFLAG_FPEXC_EL_MASK (0x3 << ARM_TBFLAG_FPEXC_EL_SHIFT)
46
+FIELD(TBFLAG_ANY, FPEXC_EL, 24, 2)
47
+FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
48
49
/* Bit usage when in AArch32 state: */
50
-#define ARM_TBFLAG_THUMB_SHIFT 0
51
-#define ARM_TBFLAG_THUMB_MASK (1 << ARM_TBFLAG_THUMB_SHIFT)
52
-#define ARM_TBFLAG_VECLEN_SHIFT 1
53
-#define ARM_TBFLAG_VECLEN_MASK (0x7 << ARM_TBFLAG_VECLEN_SHIFT)
54
-#define ARM_TBFLAG_VECSTRIDE_SHIFT 4
55
-#define ARM_TBFLAG_VECSTRIDE_MASK (0x3 << ARM_TBFLAG_VECSTRIDE_SHIFT)
56
-#define ARM_TBFLAG_VFPEN_SHIFT 7
57
-#define ARM_TBFLAG_VFPEN_MASK (1 << ARM_TBFLAG_VFPEN_SHIFT)
58
-#define ARM_TBFLAG_CONDEXEC_SHIFT 8
59
-#define ARM_TBFLAG_CONDEXEC_MASK (0xff << ARM_TBFLAG_CONDEXEC_SHIFT)
60
-#define ARM_TBFLAG_SCTLR_B_SHIFT 16
61
-#define ARM_TBFLAG_SCTLR_B_MASK (1 << ARM_TBFLAG_SCTLR_B_SHIFT)
62
+FIELD(TBFLAG_A32, THUMB, 0, 1)
63
+FIELD(TBFLAG_A32, VECLEN, 1, 3)
64
+FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
65
+FIELD(TBFLAG_A32, VFPEN, 7, 1)
66
+FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
67
+FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
68
/* We store the bottom two bits of the CPAR as TB flags and handle
69
* checks on the other bits at runtime
70
*/
71
-#define ARM_TBFLAG_XSCALE_CPAR_SHIFT 17
72
-#define ARM_TBFLAG_XSCALE_CPAR_MASK (3 << ARM_TBFLAG_XSCALE_CPAR_SHIFT)
73
+FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
74
/* Indicates whether cp register reads and writes by guest code should access
75
* the secure or nonsecure bank of banked registers; note that this is not
76
* the same thing as the current security state of the processor!
77
*/
78
-#define ARM_TBFLAG_NS_SHIFT 19
79
-#define ARM_TBFLAG_NS_MASK (1 << ARM_TBFLAG_NS_SHIFT)
80
-#define ARM_TBFLAG_BE_DATA_SHIFT 20
81
-#define ARM_TBFLAG_BE_DATA_MASK (1 << ARM_TBFLAG_BE_DATA_SHIFT)
82
+FIELD(TBFLAG_A32, NS, 19, 1)
83
/* For M profile only, Handler (ie not Thread) mode */
84
-#define ARM_TBFLAG_HANDLER_SHIFT 21
85
-#define ARM_TBFLAG_HANDLER_MASK (1 << ARM_TBFLAG_HANDLER_SHIFT)
86
+FIELD(TBFLAG_A32, HANDLER, 21, 1)
87
/* For M profile only, whether we should generate stack-limit checks */
88
-#define ARM_TBFLAG_STACKCHECK_SHIFT 22
89
-#define ARM_TBFLAG_STACKCHECK_MASK (1 << ARM_TBFLAG_STACKCHECK_SHIFT)
90
+FIELD(TBFLAG_A32, STACKCHECK, 22, 1)
91
92
/* Bit usage when in AArch64 state */
93
-#define ARM_TBFLAG_TBI0_SHIFT 0 /* TBI0 for EL0/1 or TBI for EL2/3 */
94
-#define ARM_TBFLAG_TBI0_MASK (0x1ull << ARM_TBFLAG_TBI0_SHIFT)
95
-#define ARM_TBFLAG_TBI1_SHIFT 1 /* TBI1 for EL0/1 */
96
-#define ARM_TBFLAG_TBI1_MASK (0x1ull << ARM_TBFLAG_TBI1_SHIFT)
97
-#define ARM_TBFLAG_SVEEXC_EL_SHIFT 2
98
-#define ARM_TBFLAG_SVEEXC_EL_MASK (0x3 << ARM_TBFLAG_SVEEXC_EL_SHIFT)
99
-#define ARM_TBFLAG_ZCR_LEN_SHIFT 4
100
-#define ARM_TBFLAG_ZCR_LEN_MASK (0xf << ARM_TBFLAG_ZCR_LEN_SHIFT)
101
-
102
-/* some convenience accessor macros */
103
-#define ARM_TBFLAG_AARCH64_STATE(F) \
104
- (((F) & ARM_TBFLAG_AARCH64_STATE_MASK) >> ARM_TBFLAG_AARCH64_STATE_SHIFT)
105
-#define ARM_TBFLAG_MMUIDX(F) \
106
- (((F) & ARM_TBFLAG_MMUIDX_MASK) >> ARM_TBFLAG_MMUIDX_SHIFT)
107
-#define ARM_TBFLAG_SS_ACTIVE(F) \
108
- (((F) & ARM_TBFLAG_SS_ACTIVE_MASK) >> ARM_TBFLAG_SS_ACTIVE_SHIFT)
109
-#define ARM_TBFLAG_PSTATE_SS(F) \
110
- (((F) & ARM_TBFLAG_PSTATE_SS_MASK) >> ARM_TBFLAG_PSTATE_SS_SHIFT)
111
-#define ARM_TBFLAG_FPEXC_EL(F) \
112
- (((F) & ARM_TBFLAG_FPEXC_EL_MASK) >> ARM_TBFLAG_FPEXC_EL_SHIFT)
113
-#define ARM_TBFLAG_THUMB(F) \
114
- (((F) & ARM_TBFLAG_THUMB_MASK) >> ARM_TBFLAG_THUMB_SHIFT)
115
-#define ARM_TBFLAG_VECLEN(F) \
116
- (((F) & ARM_TBFLAG_VECLEN_MASK) >> ARM_TBFLAG_VECLEN_SHIFT)
117
-#define ARM_TBFLAG_VECSTRIDE(F) \
118
- (((F) & ARM_TBFLAG_VECSTRIDE_MASK) >> ARM_TBFLAG_VECSTRIDE_SHIFT)
119
-#define ARM_TBFLAG_VFPEN(F) \
120
- (((F) & ARM_TBFLAG_VFPEN_MASK) >> ARM_TBFLAG_VFPEN_SHIFT)
121
-#define ARM_TBFLAG_CONDEXEC(F) \
122
- (((F) & ARM_TBFLAG_CONDEXEC_MASK) >> ARM_TBFLAG_CONDEXEC_SHIFT)
123
-#define ARM_TBFLAG_SCTLR_B(F) \
124
- (((F) & ARM_TBFLAG_SCTLR_B_MASK) >> ARM_TBFLAG_SCTLR_B_SHIFT)
125
-#define ARM_TBFLAG_XSCALE_CPAR(F) \
126
- (((F) & ARM_TBFLAG_XSCALE_CPAR_MASK) >> ARM_TBFLAG_XSCALE_CPAR_SHIFT)
127
-#define ARM_TBFLAG_NS(F) \
128
- (((F) & ARM_TBFLAG_NS_MASK) >> ARM_TBFLAG_NS_SHIFT)
129
-#define ARM_TBFLAG_BE_DATA(F) \
130
- (((F) & ARM_TBFLAG_BE_DATA_MASK) >> ARM_TBFLAG_BE_DATA_SHIFT)
131
-#define ARM_TBFLAG_HANDLER(F) \
132
- (((F) & ARM_TBFLAG_HANDLER_MASK) >> ARM_TBFLAG_HANDLER_SHIFT)
133
-#define ARM_TBFLAG_STACKCHECK(F) \
134
- (((F) & ARM_TBFLAG_STACKCHECK_MASK) >> ARM_TBFLAG_STACKCHECK_SHIFT)
135
-#define ARM_TBFLAG_TBI0(F) \
136
- (((F) & ARM_TBFLAG_TBI0_MASK) >> ARM_TBFLAG_TBI0_SHIFT)
137
-#define ARM_TBFLAG_TBI1(F) \
138
- (((F) & ARM_TBFLAG_TBI1_MASK) >> ARM_TBFLAG_TBI1_SHIFT)
139
-#define ARM_TBFLAG_SVEEXC_EL(F) \
140
- (((F) & ARM_TBFLAG_SVEEXC_EL_MASK) >> ARM_TBFLAG_SVEEXC_EL_SHIFT)
141
-#define ARM_TBFLAG_ZCR_LEN(F) \
142
- (((F) & ARM_TBFLAG_ZCR_LEN_MASK) >> ARM_TBFLAG_ZCR_LEN_SHIFT)
143
+FIELD(TBFLAG_A64, TBI0, 0, 1)
144
+FIELD(TBFLAG_A64, TBI1, 1, 1)
145
+FIELD(TBFLAG_A64, SVEEXC_EL, 2, 2)
146
+FIELD(TBFLAG_A64, ZCR_LEN, 4, 4)
147
148
static inline bool bswap_code(bool sctlr_b)
149
{
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
150
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
151
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
152
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
153
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static inline int fp_exception_el(CPUARMState *env)
154
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
17
}
18
19
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
20
- target_ulong *cs_base, uint32_t *flags)
21
+ target_ulong *cs_base, uint32_t *pflags)
22
{
23
ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
155
ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
24
+ uint32_t flags;
156
int current_el = arm_current_el(env);
25
+
157
int fp_el = fp_exception_el(env, current_el);
158
- uint32_t flags;
159
+ uint32_t flags = 0;
160
26
if (is_a64(env)) {
161
if (is_a64(env)) {
162
ARMCPU *cpu = arm_env_get_cpu(env);
163
27
*pc = env->pc;
164
*pc = env->pc;
28
- *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
165
- flags = ARM_TBFLAG_AARCH64_STATE_MASK;
29
+ flags = ARM_TBFLAG_AARCH64_STATE_MASK;
166
+ flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
30
/* Get control bits for tagged addresses */
167
/* Get control bits for tagged addresses */
31
- *flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
168
- flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
32
- *flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
169
- flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
33
+ flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
170
+ flags = FIELD_DP32(flags, TBFLAG_A64, TBI0,
34
+ flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
171
+ arm_regime_tbi0(env, mmu_idx));
172
+ flags = FIELD_DP32(flags, TBFLAG_A64, TBI1,
173
+ arm_regime_tbi1(env, mmu_idx));
174
175
if (cpu_isar_feature(aa64_sve, cpu)) {
176
int sve_el = sve_exception_el(env, current_el);
177
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
178
} else {
179
zcr_len = sve_zcr_len_for_el(env, current_el);
180
}
181
- flags |= sve_el << ARM_TBFLAG_SVEEXC_EL_SHIFT;
182
- flags |= zcr_len << ARM_TBFLAG_ZCR_LEN_SHIFT;
183
+ flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
184
+ flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
185
}
35
} else {
186
} else {
36
*pc = env->regs[15];
187
*pc = env->regs[15];
37
- *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
188
- flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
38
+ flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
189
- | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
39
| (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
190
- | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
40
| (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
191
- | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
41
| (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
192
- | (arm_sctlr_b(env) << ARM_TBFLAG_SCTLR_B_SHIFT);
42
| (arm_sctlr_b(env) << ARM_TBFLAG_SCTLR_B_SHIFT);
193
- if (!(access_secure_reg(env))) {
43
if (!(access_secure_reg(env))) {
194
- flags |= ARM_TBFLAG_NS_MASK;
44
- *flags |= ARM_TBFLAG_NS_MASK;
195
- }
45
+ flags |= ARM_TBFLAG_NS_MASK;
196
+ flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
46
}
197
+ flags = FIELD_DP32(flags, TBFLAG_A32, VECLEN, env->vfp.vec_len);
198
+ flags = FIELD_DP32(flags, TBFLAG_A32, VECSTRIDE, env->vfp.vec_stride);
199
+ flags = FIELD_DP32(flags, TBFLAG_A32, CONDEXEC, env->condexec_bits);
200
+ flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
201
+ flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
47
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
202
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
48
|| arm_el_is_aa64(env, 1)) {
203
|| arm_el_is_aa64(env, 1)) {
49
- *flags |= ARM_TBFLAG_VFPEN_MASK;
204
- flags |= ARM_TBFLAG_VFPEN_MASK;
50
+ flags |= ARM_TBFLAG_VFPEN_MASK;
205
+ flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
51
}
206
}
52
- *flags |= (extract32(env->cp15.c15_cpar, 0, 2)
207
- flags |= (extract32(env->cp15.c15_cpar, 0, 2)
53
- << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
208
- << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
54
+ flags |= (extract32(env->cp15.c15_cpar, 0, 2)
209
+ flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
55
+ << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
210
}
56
}
211
57
212
- flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
58
- *flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
213
+ flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
59
+ flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
60
214
61
/* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
215
/* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
62
* states defined in the ARM ARM for software singlestep:
216
* states defined in the ARM ARM for software singlestep:
63
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
217
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
64
* 1 1 Active-not-pending
218
* 1 1 Active-not-pending
65
*/
219
*/
66
if (arm_singlestep_active(env)) {
220
if (arm_singlestep_active(env)) {
67
- *flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
221
- flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
68
+ flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
222
+ flags = FIELD_DP32(flags, TBFLAG_ANY, SS_ACTIVE, 1);
69
if (is_a64(env)) {
223
if (is_a64(env)) {
70
if (env->pstate & PSTATE_SS) {
224
if (env->pstate & PSTATE_SS) {
71
- *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
225
- flags |= ARM_TBFLAG_PSTATE_SS_MASK;
72
+ flags |= ARM_TBFLAG_PSTATE_SS_MASK;
226
+ flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
73
}
227
}
74
} else {
228
} else {
75
if (env->uncached_cpsr & PSTATE_SS) {
229
if (env->uncached_cpsr & PSTATE_SS) {
76
- *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
230
- flags |= ARM_TBFLAG_PSTATE_SS_MASK;
77
+ flags |= ARM_TBFLAG_PSTATE_SS_MASK;
231
+ flags = FIELD_DP32(flags, TBFLAG_ANY, PSTATE_SS, 1);
78
}
232
}
79
}
233
}
80
}
234
}
81
if (arm_cpu_data_is_big_endian(env)) {
235
if (arm_cpu_data_is_big_endian(env)) {
82
- *flags |= ARM_TBFLAG_BE_DATA_MASK;
236
- flags |= ARM_TBFLAG_BE_DATA_MASK;
83
+ flags |= ARM_TBFLAG_BE_DATA_MASK;
237
+ flags = FIELD_DP32(flags, TBFLAG_ANY, BE_DATA, 1);
84
}
238
}
85
- *flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
239
- flags |= fp_el << ARM_TBFLAG_FPEXC_EL_SHIFT;
86
+ flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
240
+ flags = FIELD_DP32(flags, TBFLAG_ANY, FPEXC_EL, fp_el);
87
241
88
if (arm_v7m_is_handler_mode(env)) {
242
if (arm_v7m_is_handler_mode(env)) {
89
- *flags |= ARM_TBFLAG_HANDLER_MASK;
243
- flags |= ARM_TBFLAG_HANDLER_MASK;
90
+ flags |= ARM_TBFLAG_HANDLER_MASK;
244
+ flags = FIELD_DP32(flags, TBFLAG_A32, HANDLER, 1);
91
}
245
}
92
246
93
+ *pflags = flags;
247
/* v8M always applies stack limit checks unless CCR.STKOFHFNMIGN is
94
*cs_base = 0;
248
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
95
}
249
arm_feature(env, ARM_FEATURE_M) &&
250
!((mmu_idx & ARM_MMU_IDX_M_NEGPRI) &&
251
(env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_STKOFHFNMIGN_MASK))) {
252
- flags |= ARM_TBFLAG_STACKCHECK_MASK;
253
+ flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
254
}
255
256
*pflags = flags;
257
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
258
index XXXXXXX..XXXXXXX 100644
259
--- a/target/arm/translate-a64.c
260
+++ b/target/arm/translate-a64.c
261
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
262
DisasContext *dc = container_of(dcbase, DisasContext, base);
263
CPUARMState *env = cpu->env_ptr;
264
ARMCPU *arm_cpu = arm_env_get_cpu(env);
265
- int bound;
266
+ uint32_t tb_flags = dc->base.tb->flags;
267
+ int bound, core_mmu_idx;
268
269
dc->isar = &arm_cpu->isar;
270
dc->pc = dc->base.pc_first;
271
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
272
!arm_el_is_aa64(env, 3);
273
dc->thumb = 0;
274
dc->sctlr_b = 0;
275
- dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
276
+ dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
277
dc->condexec_mask = 0;
278
dc->condexec_cond = 0;
279
- dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
280
- dc->tbi0 = ARM_TBFLAG_TBI0(dc->base.tb->flags);
281
- dc->tbi1 = ARM_TBFLAG_TBI1(dc->base.tb->flags);
282
+ core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
283
+ dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
284
+ dc->tbi0 = FIELD_EX32(tb_flags, TBFLAG_A64, TBI0);
285
+ dc->tbi1 = FIELD_EX32(tb_flags, TBFLAG_A64, TBI1);
286
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
287
#if !defined(CONFIG_USER_ONLY)
288
dc->user = (dc->current_el == 0);
289
#endif
290
- dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
291
- dc->sve_excp_el = ARM_TBFLAG_SVEEXC_EL(dc->base.tb->flags);
292
- dc->sve_len = (ARM_TBFLAG_ZCR_LEN(dc->base.tb->flags) + 1) * 16;
293
+ dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
294
+ dc->sve_excp_el = FIELD_EX32(tb_flags, TBFLAG_A64, SVEEXC_EL);
295
+ dc->sve_len = (FIELD_EX32(tb_flags, TBFLAG_A64, ZCR_LEN) + 1) * 16;
296
dc->vec_len = 0;
297
dc->vec_stride = 0;
298
dc->cp_regs = arm_cpu->cp_regs;
299
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
300
* emit code to generate a software step exception
301
* end the TB
302
*/
303
- dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
304
- dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
305
+ dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
306
+ dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
307
dc->is_ldex = false;
308
dc->ss_same_el = (arm_debug_target_el(env) == dc->current_el);
309
310
diff --git a/target/arm/translate.c b/target/arm/translate.c
311
index XXXXXXX..XXXXXXX 100644
312
--- a/target/arm/translate.c
313
+++ b/target/arm/translate.c
314
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
315
DisasContext *dc = container_of(dcbase, DisasContext, base);
316
CPUARMState *env = cs->env_ptr;
317
ARMCPU *cpu = arm_env_get_cpu(env);
318
+ uint32_t tb_flags = dc->base.tb->flags;
319
+ uint32_t condexec, core_mmu_idx;
320
321
dc->isar = &cpu->isar;
322
dc->pc = dc->base.pc_first;
323
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
324
*/
325
dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
326
!arm_el_is_aa64(env, 3);
327
- dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
328
- dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
329
- dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
330
- dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
331
- dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
332
- dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
333
+ dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
334
+ dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
335
+ dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
336
+ condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
337
+ dc->condexec_mask = (condexec & 0xf) << 1;
338
+ dc->condexec_cond = condexec >> 4;
339
+ core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
340
+ dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
341
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
342
#if !defined(CONFIG_USER_ONLY)
343
dc->user = (dc->current_el == 0);
344
#endif
345
- dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
346
- dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
347
- dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
348
- dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
349
- dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
350
- dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
351
- dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
352
+ dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
353
+ dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
354
+ dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
355
+ dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
356
+ dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
357
+ dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
358
+ dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
359
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
360
regime_is_secure(env, dc->mmu_idx);
361
- dc->v8m_stackcheck = ARM_TBFLAG_STACKCHECK(dc->base.tb->flags);
362
+ dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
363
dc->cp_regs = cpu->cp_regs;
364
dc->features = env->features;
365
366
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
367
* emit code to generate a software step exception
368
* end the TB
369
*/
370
- dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
371
- dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
372
+ dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
373
+ dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
374
dc->is_ldex = false;
375
dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
376
377
@@ -XXX,XX +XXX,XX @@ void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
378
DisasContext dc;
379
const TranslatorOps *ops = &arm_translator_ops;
380
381
- if (ARM_TBFLAG_THUMB(tb->flags)) {
382
+ if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
383
ops = &thumb_translator_ops;
384
}
385
#ifdef TARGET_AARCH64
386
- if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
387
+ if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
388
ops = &aarch64_translator_ops;
389
}
390
#endif
96
--
391
--
97
2.7.4
392
2.19.2
98
393
99
394
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Not enabled anywhere so far.
3
While brk[ab] zeroing has a flags setting option, the merging variant
4
does not. Retain the same argument structure, to share expansion but
5
force the flag zero and do not decode bit 22.
4
6
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180119045438.28582-11-richard.henderson@linaro.org
9
Message-id: 20181226215003.31438-1-richard.henderson@linaro.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/cpu.h | 1 +
13
target/arm/sve.decode | 5 +++--
12
1 file changed, 1 insertion(+)
14
1 file changed, 3 insertions(+), 2 deletions(-)
13
15
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
18
--- a/target/arm/sve.decode
17
+++ b/target/arm/cpu.h
19
+++ b/target/arm/sve.decode
18
@@ -XXX,XX +XXX,XX @@ enum arm_features {
20
@@ -XXX,XX +XXX,XX @@
19
ARM_FEATURE_VBAR, /* has cp15 VBAR */
21
20
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
22
# Two operand with governing predicate, flags setting
21
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
23
@pd_pg_pn_s ........ . s:1 ...... .. pg:4 . rn:4 . rd:4 &rpr_s
22
+ ARM_FEATURE_SVE, /* has Scalable Vector Extension */
24
+@pd_pg_pn_s0 ........ . . ...... .. pg:4 . rn:4 . rd:4 &rpr_s s=0
23
};
25
24
26
# Three operand with unused vector element size
25
static inline int arm_feature(CPUARMState *env, int feature)
27
@rd_rn_rm_e0 ........ ... rm:5 ... ... rn:5 rd:5 &rrr_esz esz=0
28
@@ -XXX,XX +XXX,XX @@ BRKPB 00100101 0. 00 .... 11 .... 0 .... 1 .... @pd_pg_pn_pm_s
29
# SVE partition break condition
30
BRKA_z 00100101 0. 01000001 .... 0 .... 0 .... @pd_pg_pn_s
31
BRKB_z 00100101 1. 01000001 .... 0 .... 0 .... @pd_pg_pn_s
32
-BRKA_m 00100101 0. 01000001 .... 0 .... 1 .... @pd_pg_pn_s
33
-BRKB_m 00100101 1. 01000001 .... 0 .... 1 .... @pd_pg_pn_s
34
+BRKA_m 00100101 00 01000001 .... 0 .... 1 .... @pd_pg_pn_s0
35
+BRKB_m 00100101 10 01000001 .... 0 .... 1 .... @pd_pg_pn_s0
36
37
# SVE propagate break to next partition
38
BRKN 00100101 0. 01100001 .... 0 .... 0 .... @pd_pg_pn_s
26
--
39
--
27
2.7.4
40
2.19.2
28
41
29
42
diff view generated by jsdifflib
New patch
1
From: Luc Michel <luc.michel@greensocs.com>
1
2
3
This commit adds the cpu-cluster type. It aims at gathering CPUs from
4
the same cluster in a machine.
5
6
For now it only has a `cluster-id` property.
7
8
Documentation in cluster.h written with the help of Peter Maydell.
9
10
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
14
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
15
Message-id: 20181207090135.7651-2-luc.michel@greensocs.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
hw/cpu/Makefile.objs | 2 +-
19
include/hw/cpu/cluster.h | 58 ++++++++++++++++++++++++++++++++++++++++
20
hw/cpu/cluster.c | 50 ++++++++++++++++++++++++++++++++++
21
MAINTAINERS | 2 ++
22
4 files changed, 111 insertions(+), 1 deletion(-)
23
create mode 100644 include/hw/cpu/cluster.h
24
create mode 100644 hw/cpu/cluster.c
25
26
diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/cpu/Makefile.objs
29
+++ b/hw/cpu/Makefile.objs
30
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_ARM11MPCORE) += arm11mpcore.o
31
obj-$(CONFIG_REALVIEW) += realview_mpcore.o
32
obj-$(CONFIG_A9MPCORE) += a9mpcore.o
33
obj-$(CONFIG_A15MPCORE) += a15mpcore.o
34
-common-obj-y += core.o
35
+common-obj-y += core.o cluster.o
36
diff --git a/include/hw/cpu/cluster.h b/include/hw/cpu/cluster.h
37
new file mode 100644
38
index XXXXXXX..XXXXXXX
39
--- /dev/null
40
+++ b/include/hw/cpu/cluster.h
41
@@ -XXX,XX +XXX,XX @@
42
+/*
43
+ * QEMU CPU cluster
44
+ *
45
+ * Copyright (c) 2018 GreenSocs SAS
46
+ *
47
+ * This program is free software; you can redistribute it and/or
48
+ * modify it under the terms of the GNU General Public License
49
+ * as published by the Free Software Foundation; either version 2
50
+ * of the License, or (at your option) any later version.
51
+ *
52
+ * This program is distributed in the hope that it will be useful,
53
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
54
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55
+ * GNU General Public License for more details.
56
+ *
57
+ * You should have received a copy of the GNU General Public License
58
+ * along with this program; if not, see
59
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
60
+ */
61
+#ifndef HW_CPU_CLUSTER_H
62
+#define HW_CPU_CLUSTER_H
63
+
64
+#include "qemu/osdep.h"
65
+#include "hw/qdev.h"
66
+
67
+/*
68
+ * CPU Cluster type
69
+ *
70
+ * A cluster is a group of CPUs which are all identical and have the same view
71
+ * of the rest of the system. It is mainly an internal QEMU representation and
72
+ * does not necessarily match with the notion of clusters on the real hardware.
73
+ *
74
+ * If CPUs are not identical (for example, Cortex-A53 and Cortex-A57 CPUs in an
75
+ * Arm big.LITTLE system) they should be in different clusters. If the CPUs do
76
+ * not have the same view of memory (for example the main CPU and a management
77
+ * controller processor) they should be in different clusters.
78
+ */
79
+
80
+#define TYPE_CPU_CLUSTER "cpu-cluster"
81
+#define CPU_CLUSTER(obj) \
82
+ OBJECT_CHECK(CPUClusterState, (obj), TYPE_CPU_CLUSTER)
83
+
84
+/**
85
+ * CPUClusterState:
86
+ * @cluster_id: The cluster ID. This value is for internal use only and should
87
+ * not be exposed directly to the user or to the guest.
88
+ *
89
+ * State of a CPU cluster.
90
+ */
91
+typedef struct CPUClusterState {
92
+ /*< private >*/
93
+ DeviceState parent_obj;
94
+
95
+ /*< public >*/
96
+ uint32_t cluster_id;
97
+} CPUClusterState;
98
+
99
+#endif
100
diff --git a/hw/cpu/cluster.c b/hw/cpu/cluster.c
101
new file mode 100644
102
index XXXXXXX..XXXXXXX
103
--- /dev/null
104
+++ b/hw/cpu/cluster.c
105
@@ -XXX,XX +XXX,XX @@
106
+/*
107
+ * QEMU CPU cluster
108
+ *
109
+ * Copyright (c) 2018 GreenSocs SAS
110
+ *
111
+ * This program is free software; you can redistribute it and/or
112
+ * modify it under the terms of the GNU General Public License
113
+ * as published by the Free Software Foundation; either version 2
114
+ * of the License, or (at your option) any later version.
115
+ *
116
+ * This program is distributed in the hope that it will be useful,
117
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
118
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
119
+ * GNU General Public License for more details.
120
+ *
121
+ * You should have received a copy of the GNU General Public License
122
+ * along with this program; if not, see
123
+ * <http://www.gnu.org/licenses/gpl-2.0.html>
124
+ */
125
+
126
+#include "qemu/osdep.h"
127
+#include "hw/cpu/cluster.h"
128
+#include "qapi/error.h"
129
+#include "qemu/module.h"
130
+
131
+static Property cpu_cluster_properties[] = {
132
+ DEFINE_PROP_UINT32("cluster-id", CPUClusterState, cluster_id, 0),
133
+ DEFINE_PROP_END_OF_LIST()
134
+};
135
+
136
+static void cpu_cluster_class_init(ObjectClass *klass, void *data)
137
+{
138
+ DeviceClass *dc = DEVICE_CLASS(klass);
139
+
140
+ dc->props = cpu_cluster_properties;
141
+}
142
+
143
+static const TypeInfo cpu_cluster_type_info = {
144
+ .name = TYPE_CPU_CLUSTER,
145
+ .parent = TYPE_DEVICE,
146
+ .instance_size = sizeof(CPUClusterState),
147
+ .class_init = cpu_cluster_class_init,
148
+};
149
+
150
+static void cpu_cluster_register_types(void)
151
+{
152
+ type_register_static(&cpu_cluster_type_info);
153
+}
154
+
155
+type_init(cpu_cluster_register_types)
156
diff --git a/MAINTAINERS b/MAINTAINERS
157
index XXXXXXX..XXXXXXX 100644
158
--- a/MAINTAINERS
159
+++ b/MAINTAINERS
160
@@ -XXX,XX +XXX,XX @@ M: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
161
S: Supported
162
F: hw/core/machine.c
163
F: hw/core/null-machine.c
164
+F: hw/cpu/cluster.c
165
F: include/hw/boards.h
166
+F: include/hw/cpu/cluster.h
167
T: git https://github.com/ehabkost/qemu.git machine-next
168
169
Xtensa Machines
170
--
171
2.19.2
172
173
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Luc Michel <luc.michel@greensocs.com>
2
2
3
Rather than passing regnos to the helpers, pass pointers to the
3
Add a structure GDBProcess that represents processes from the GDB
4
vector registers directly. This eliminates the need to pass in
4
semantic point of view.
5
the environment pointer and reduces the number of places that
6
directly access env->vfp.regs[].
7
5
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
CPUs can be split into different processes, by grouping them under
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
different cpu-cluster objects. Each occurrence of a cpu-cluster object
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
implies the existence of the corresponding process in the GDB stub. The
11
Message-id: 20180119045438.28582-3-richard.henderson@linaro.org
9
GDB process ID is derived from the corresponding cluster ID as follows:
10
11
GDB PID = cluster ID + 1
12
13
This is because PIDs -1 and 0 are reserved in GDB and cannot be used by
14
processes.
15
16
A default process is created to handle CPUs that are not in a cluster.
17
This process gets the PID of the last process PID + 1.
18
19
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
20
Acked-by: Alistair Francis <alistair.francis@wdc.com>
21
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
22
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
23
Message-id: 20181207090135.7651-3-luc.michel@greensocs.com
24
[PMM: fixed checkpatch nit about block comment style]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
26
---
14
target/arm/helper.h | 18 ++---
27
gdbstub.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
15
target/arm/crypto_helper.c | 184 +++++++++++++++++----------------------------
28
1 file changed, 97 insertions(+)
16
target/arm/translate-a64.c | 75 ++++++++++--------
17
target/arm/translate.c | 68 +++++++++--------
18
4 files changed, 161 insertions(+), 184 deletions(-)
19
29
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
30
diff --git a/gdbstub.c b/gdbstub.c
21
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
32
--- a/gdbstub.c
23
+++ b/target/arm/helper.h
33
+++ b/gdbstub.c
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(neon_qzip8, void, env, i32, i32)
34
@@ -XXX,XX +XXX,XX @@
25
DEF_HELPER_3(neon_qzip16, void, env, i32, i32)
35
#include "chardev/char-fe.h"
26
DEF_HELPER_3(neon_qzip32, void, env, i32, i32)
36
#include "sysemu/sysemu.h"
27
37
#include "exec/gdbstub.h"
28
-DEF_HELPER_4(crypto_aese, void, env, i32, i32, i32)
38
+#include "hw/cpu/cluster.h"
29
-DEF_HELPER_4(crypto_aesmc, void, env, i32, i32, i32)
30
+DEF_HELPER_FLAGS_3(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
31
+DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
32
33
-DEF_HELPER_5(crypto_sha1_3reg, void, env, i32, i32, i32, i32)
34
-DEF_HELPER_3(crypto_sha1h, void, env, i32, i32)
35
-DEF_HELPER_3(crypto_sha1su1, void, env, i32, i32)
36
+DEF_HELPER_FLAGS_4(crypto_sha1_3reg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
37
+DEF_HELPER_FLAGS_2(crypto_sha1h, TCG_CALL_NO_RWG, void, ptr, ptr)
38
+DEF_HELPER_FLAGS_2(crypto_sha1su1, TCG_CALL_NO_RWG, void, ptr, ptr)
39
40
-DEF_HELPER_4(crypto_sha256h, void, env, i32, i32, i32)
41
-DEF_HELPER_4(crypto_sha256h2, void, env, i32, i32, i32)
42
-DEF_HELPER_3(crypto_sha256su0, void, env, i32, i32)
43
-DEF_HELPER_4(crypto_sha256su1, void, env, i32, i32, i32)
44
+DEF_HELPER_FLAGS_3(crypto_sha256h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
45
+DEF_HELPER_FLAGS_3(crypto_sha256h2, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
46
+DEF_HELPER_FLAGS_2(crypto_sha256su0, TCG_CALL_NO_RWG, void, ptr, ptr)
47
+DEF_HELPER_FLAGS_3(crypto_sha256su1, TCG_CALL_NO_RWG, void, ptr, ptr, ptr)
48
49
DEF_HELPER_FLAGS_3(crc32, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
50
DEF_HELPER_FLAGS_3(crc32c, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32)
51
diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/arm/crypto_helper.c
54
+++ b/target/arm/crypto_helper.c
55
@@ -XXX,XX +XXX,XX @@ union CRYPTO_STATE {
56
#define CR_ST_WORD(state, i) (state.words[i])
57
#endif
39
#endif
58
40
59
-void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm,
41
#define MAX_PACKET_LENGTH 4096
60
- uint32_t decrypt)
42
@@ -XXX,XX +XXX,XX @@ typedef struct GDBRegisterState {
61
+void HELPER(crypto_aese)(void *vd, void *vm, uint32_t decrypt)
43
struct GDBRegisterState *next;
62
{
44
} GDBRegisterState;
63
static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox };
45
64
static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts };
46
+typedef struct GDBProcess {
65
-
47
+ uint32_t pid;
66
- union CRYPTO_STATE rk = { .l = {
48
+ bool attached;
67
- float64_val(env->vfp.regs[rm]),
49
+} GDBProcess;
68
- float64_val(env->vfp.regs[rm + 1])
50
+
69
- } };
51
enum RSState {
70
- union CRYPTO_STATE st = { .l = {
52
RS_INACTIVE,
71
- float64_val(env->vfp.regs[rd]),
53
RS_IDLE,
72
- float64_val(env->vfp.regs[rd + 1])
54
@@ -XXX,XX +XXX,XX @@ typedef struct GDBState {
73
- } };
55
CharBackend chr;
74
+ uint64_t *rd = vd;
56
Chardev *mon_chr;
75
+ uint64_t *rm = vm;
57
#endif
76
+ union CRYPTO_STATE rk = { .l = { rm[0], rm[1] } };
58
+ bool multiprocess;
77
+ union CRYPTO_STATE st = { .l = { rd[0], rd[1] } };
59
+ GDBProcess *processes;
78
int i;
60
+ int process_num;
79
61
char syscall_buf[256];
80
assert(decrypt < 2);
62
gdb_syscall_complete_cb current_syscall_cb;
81
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm,
63
} GDBState;
82
CR_ST_BYTE(st, i) = sbox[decrypt][CR_ST_BYTE(rk, shift[decrypt][i])];
64
@@ -XXX,XX +XXX,XX @@ void gdb_exit(CPUArchState *env, int code)
83
}
65
#endif
84
85
- env->vfp.regs[rd] = make_float64(st.l[0]);
86
- env->vfp.regs[rd + 1] = make_float64(st.l[1]);
87
+ rd[0] = st.l[0];
88
+ rd[1] = st.l[1];
89
}
66
}
90
67
91
-void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm,
68
+/*
92
- uint32_t decrypt)
69
+ * Create the process that will contain all the "orphan" CPUs (that are not
93
+void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt)
70
+ * part of a CPU cluster). Note that if this process contains no CPUs, it won't
94
{
71
+ * be attachable and thus will be invisible to the user.
95
static uint32_t const mc[][256] = { {
72
+ */
96
/* MixColumns lookup table */
73
+static void create_default_process(GDBState *s)
97
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm,
74
+{
98
0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5,
75
+ GDBProcess *process;
99
0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d,
76
+ int max_pid = 0;
100
} };
101
- union CRYPTO_STATE st = { .l = {
102
- float64_val(env->vfp.regs[rm]),
103
- float64_val(env->vfp.regs[rm + 1])
104
- } };
105
+
77
+
106
+ uint64_t *rd = vd;
78
+ if (s->process_num) {
107
+ uint64_t *rm = vm;
79
+ max_pid = s->processes[s->process_num - 1].pid;
108
+ union CRYPTO_STATE st = { .l = { rm[0], rm[1] } };
80
+ }
109
int i;
81
+
110
82
+ s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
111
assert(decrypt < 2);
83
+ process = &s->processes[s->process_num - 1];
112
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm,
84
+
113
rol32(mc[decrypt][CR_ST_BYTE(st, i + 3)], 24);
85
+ /* We need an available PID slot for this process */
114
}
86
+ assert(max_pid < UINT32_MAX);
115
87
+
116
- env->vfp.regs[rd] = make_float64(st.l[0]);
88
+ process->pid = max_pid + 1;
117
- env->vfp.regs[rd + 1] = make_float64(st.l[1]);
89
+ process->attached = false;
118
+ rd[0] = st.l[0];
119
+ rd[1] = st.l[1];
120
}
121
122
/*
123
@@ -XXX,XX +XXX,XX @@ static uint32_t maj(uint32_t x, uint32_t y, uint32_t z)
124
return (x & y) | ((x | y) & z);
125
}
126
127
-void HELPER(crypto_sha1_3reg)(CPUARMState *env, uint32_t rd, uint32_t rn,
128
- uint32_t rm, uint32_t op)
129
+void HELPER(crypto_sha1_3reg)(void *vd, void *vn, void *vm, uint32_t op)
130
{
131
- union CRYPTO_STATE d = { .l = {
132
- float64_val(env->vfp.regs[rd]),
133
- float64_val(env->vfp.regs[rd + 1])
134
- } };
135
- union CRYPTO_STATE n = { .l = {
136
- float64_val(env->vfp.regs[rn]),
137
- float64_val(env->vfp.regs[rn + 1])
138
- } };
139
- union CRYPTO_STATE m = { .l = {
140
- float64_val(env->vfp.regs[rm]),
141
- float64_val(env->vfp.regs[rm + 1])
142
- } };
143
+ uint64_t *rd = vd;
144
+ uint64_t *rn = vn;
145
+ uint64_t *rm = vm;
146
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
147
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
148
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
149
150
if (op == 3) { /* sha1su0 */
151
d.l[0] ^= d.l[1] ^ m.l[0];
152
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha1_3reg)(CPUARMState *env, uint32_t rd, uint32_t rn,
153
CR_ST_WORD(d, 0) = t;
154
}
155
}
156
- env->vfp.regs[rd] = make_float64(d.l[0]);
157
- env->vfp.regs[rd + 1] = make_float64(d.l[1]);
158
+ rd[0] = d.l[0];
159
+ rd[1] = d.l[1];
160
}
161
162
-void HELPER(crypto_sha1h)(CPUARMState *env, uint32_t rd, uint32_t rm)
163
+void HELPER(crypto_sha1h)(void *vd, void *vm)
164
{
165
- union CRYPTO_STATE m = { .l = {
166
- float64_val(env->vfp.regs[rm]),
167
- float64_val(env->vfp.regs[rm + 1])
168
- } };
169
+ uint64_t *rd = vd;
170
+ uint64_t *rm = vm;
171
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
172
173
CR_ST_WORD(m, 0) = ror32(CR_ST_WORD(m, 0), 2);
174
CR_ST_WORD(m, 1) = CR_ST_WORD(m, 2) = CR_ST_WORD(m, 3) = 0;
175
176
- env->vfp.regs[rd] = make_float64(m.l[0]);
177
- env->vfp.regs[rd + 1] = make_float64(m.l[1]);
178
+ rd[0] = m.l[0];
179
+ rd[1] = m.l[1];
180
}
181
182
-void HELPER(crypto_sha1su1)(CPUARMState *env, uint32_t rd, uint32_t rm)
183
+void HELPER(crypto_sha1su1)(void *vd, void *vm)
184
{
185
- union CRYPTO_STATE d = { .l = {
186
- float64_val(env->vfp.regs[rd]),
187
- float64_val(env->vfp.regs[rd + 1])
188
- } };
189
- union CRYPTO_STATE m = { .l = {
190
- float64_val(env->vfp.regs[rm]),
191
- float64_val(env->vfp.regs[rm + 1])
192
- } };
193
+ uint64_t *rd = vd;
194
+ uint64_t *rm = vm;
195
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
196
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
197
198
CR_ST_WORD(d, 0) = rol32(CR_ST_WORD(d, 0) ^ CR_ST_WORD(m, 1), 1);
199
CR_ST_WORD(d, 1) = rol32(CR_ST_WORD(d, 1) ^ CR_ST_WORD(m, 2), 1);
200
CR_ST_WORD(d, 2) = rol32(CR_ST_WORD(d, 2) ^ CR_ST_WORD(m, 3), 1);
201
CR_ST_WORD(d, 3) = rol32(CR_ST_WORD(d, 3) ^ CR_ST_WORD(d, 0), 1);
202
203
- env->vfp.regs[rd] = make_float64(d.l[0]);
204
- env->vfp.regs[rd + 1] = make_float64(d.l[1]);
205
+ rd[0] = d.l[0];
206
+ rd[1] = d.l[1];
207
}
208
209
/*
210
@@ -XXX,XX +XXX,XX @@ static uint32_t s1(uint32_t x)
211
return ror32(x, 17) ^ ror32(x, 19) ^ (x >> 10);
212
}
213
214
-void HELPER(crypto_sha256h)(CPUARMState *env, uint32_t rd, uint32_t rn,
215
- uint32_t rm)
216
+void HELPER(crypto_sha256h)(void *vd, void *vn, void *vm)
217
{
218
- union CRYPTO_STATE d = { .l = {
219
- float64_val(env->vfp.regs[rd]),
220
- float64_val(env->vfp.regs[rd + 1])
221
- } };
222
- union CRYPTO_STATE n = { .l = {
223
- float64_val(env->vfp.regs[rn]),
224
- float64_val(env->vfp.regs[rn + 1])
225
- } };
226
- union CRYPTO_STATE m = { .l = {
227
- float64_val(env->vfp.regs[rm]),
228
- float64_val(env->vfp.regs[rm + 1])
229
- } };
230
+ uint64_t *rd = vd;
231
+ uint64_t *rn = vn;
232
+ uint64_t *rm = vm;
233
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
234
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
235
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
236
int i;
237
238
for (i = 0; i < 4; i++) {
239
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha256h)(CPUARMState *env, uint32_t rd, uint32_t rn,
240
CR_ST_WORD(d, 0) = t;
241
}
242
243
- env->vfp.regs[rd] = make_float64(d.l[0]);
244
- env->vfp.regs[rd + 1] = make_float64(d.l[1]);
245
+ rd[0] = d.l[0];
246
+ rd[1] = d.l[1];
247
}
248
249
-void HELPER(crypto_sha256h2)(CPUARMState *env, uint32_t rd, uint32_t rn,
250
- uint32_t rm)
251
+void HELPER(crypto_sha256h2)(void *vd, void *vn, void *vm)
252
{
253
- union CRYPTO_STATE d = { .l = {
254
- float64_val(env->vfp.regs[rd]),
255
- float64_val(env->vfp.regs[rd + 1])
256
- } };
257
- union CRYPTO_STATE n = { .l = {
258
- float64_val(env->vfp.regs[rn]),
259
- float64_val(env->vfp.regs[rn + 1])
260
- } };
261
- union CRYPTO_STATE m = { .l = {
262
- float64_val(env->vfp.regs[rm]),
263
- float64_val(env->vfp.regs[rm + 1])
264
- } };
265
+ uint64_t *rd = vd;
266
+ uint64_t *rn = vn;
267
+ uint64_t *rm = vm;
268
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
269
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
270
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
271
int i;
272
273
for (i = 0; i < 4; i++) {
274
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_sha256h2)(CPUARMState *env, uint32_t rd, uint32_t rn,
275
CR_ST_WORD(d, 0) = CR_ST_WORD(n, 3 - i) + t;
276
}
277
278
- env->vfp.regs[rd] = make_float64(d.l[0]);
279
- env->vfp.regs[rd + 1] = make_float64(d.l[1]);
280
+ rd[0] = d.l[0];
281
+ rd[1] = d.l[1];
282
}
283
284
-void HELPER(crypto_sha256su0)(CPUARMState *env, uint32_t rd, uint32_t rm)
285
+void HELPER(crypto_sha256su0)(void *vd, void *vm)
286
{
287
- union CRYPTO_STATE d = { .l = {
288
- float64_val(env->vfp.regs[rd]),
289
- float64_val(env->vfp.regs[rd + 1])
290
- } };
291
- union CRYPTO_STATE m = { .l = {
292
- float64_val(env->vfp.regs[rm]),
293
- float64_val(env->vfp.regs[rm + 1])
294
- } };
295
+ uint64_t *rd = vd;
296
+ uint64_t *rm = vm;
297
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
298
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
299
300
CR_ST_WORD(d, 0) += s0(CR_ST_WORD(d, 1));
301
CR_ST_WORD(d, 1) += s0(CR_ST_WORD(d, 2));
302
CR_ST_WORD(d, 2) += s0(CR_ST_WORD(d, 3));
303
CR_ST_WORD(d, 3) += s0(CR_ST_WORD(m, 0));
304
305
- env->vfp.regs[rd] = make_float64(d.l[0]);
306
- env->vfp.regs[rd + 1] = make_float64(d.l[1]);
307
+ rd[0] = d.l[0];
308
+ rd[1] = d.l[1];
309
}
310
311
-void HELPER(crypto_sha256su1)(CPUARMState *env, uint32_t rd, uint32_t rn,
312
- uint32_t rm)
313
+void HELPER(crypto_sha256su1)(void *vd, void *vn, void *vm)
314
{
315
- union CRYPTO_STATE d = { .l = {
316
- float64_val(env->vfp.regs[rd]),
317
- float64_val(env->vfp.regs[rd + 1])
318
- } };
319
- union CRYPTO_STATE n = { .l = {
320
- float64_val(env->vfp.regs[rn]),
321
- float64_val(env->vfp.regs[rn + 1])
322
- } };
323
- union CRYPTO_STATE m = { .l = {
324
- float64_val(env->vfp.regs[rm]),
325
- float64_val(env->vfp.regs[rm + 1])
326
- } };
327
+ uint64_t *rd = vd;
328
+ uint64_t *rn = vn;
329
+ uint64_t *rm = vm;
330
+ union CRYPTO_STATE d = { .l = { rd[0], rd[1] } };
331
+ union CRYPTO_STATE n = { .l = { rn[0], rn[1] } };
332
+ union CRYPTO_STATE m = { .l = { rm[0], rm[1] } };
333
334
CR_ST_WORD(d, 0) += s1(CR_ST_WORD(m, 2)) + CR_ST_WORD(n, 1);
335
CR_ST_WORD(d, 1) += s1(CR_ST_WORD(m, 3)) + CR_ST_WORD(n, 2);
336
CR_ST_WORD(d, 2) += s1(CR_ST_WORD(d, 0)) + CR_ST_WORD(n, 3);
337
CR_ST_WORD(d, 3) += s1(CR_ST_WORD(d, 1)) + CR_ST_WORD(m, 0);
338
339
- env->vfp.regs[rd] = make_float64(d.l[0]);
340
- env->vfp.regs[rd + 1] = make_float64(d.l[1]);
341
+ rd[0] = d.l[0];
342
+ rd[1] = d.l[1];
343
}
344
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
345
index XXXXXXX..XXXXXXX 100644
346
--- a/target/arm/translate-a64.c
347
+++ b/target/arm/translate-a64.c
348
@@ -XXX,XX +XXX,XX @@ typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
349
typedef void NeonGenTwoSingleOPFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
350
typedef void NeonGenTwoDoubleOPFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
351
typedef void NeonGenOneOpFn(TCGv_i64, TCGv_i64);
352
-typedef void CryptoTwoOpEnvFn(TCGv_ptr, TCGv_i32, TCGv_i32);
353
-typedef void CryptoThreeOpEnvFn(TCGv_ptr, TCGv_i32, TCGv_i32, TCGv_i32);
354
+typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
355
+typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
356
+typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
357
358
/* initialize TCG globals. */
359
void a64_translate_init(void)
360
@@ -XXX,XX +XXX,XX @@ static inline int vec_reg_offset(DisasContext *s, int regno,
361
return offs;
362
}
363
364
+/* Return the offset info CPUARMState of the "whole" vector register Qn. */
365
+static inline int vec_full_reg_offset(DisasContext *s, int regno)
366
+{
367
+ assert_fp_access_checked(s);
368
+ return offsetof(CPUARMState, vfp.regs[regno * 2]);
369
+}
90
+}
370
+
91
+
371
+/* Return a newly allocated pointer to the vector register. */
92
#ifdef CONFIG_USER_ONLY
372
+static TCGv_ptr vec_full_reg_ptr(DisasContext *s, int regno)
93
int
94
gdb_handlesig(CPUState *cpu, int sig)
95
@@ -XXX,XX +XXX,XX @@ static bool gdb_accept(void)
96
s = g_malloc0(sizeof(GDBState));
97
s->c_cpu = first_cpu;
98
s->g_cpu = first_cpu;
99
+ create_default_process(s);
100
s->fd = fd;
101
gdb_has_xml = false;
102
103
@@ -XXX,XX +XXX,XX @@ static const TypeInfo char_gdb_type_info = {
104
.class_init = char_gdb_class_init,
105
};
106
107
+static int find_cpu_clusters(Object *child, void *opaque)
373
+{
108
+{
374
+ TCGv_ptr ret = tcg_temp_new_ptr();
109
+ if (object_dynamic_cast(child, TYPE_CPU_CLUSTER)) {
375
+ tcg_gen_addi_ptr(ret, cpu_env, vec_full_reg_offset(s, regno));
110
+ GDBState *s = (GDBState *) opaque;
376
+ return ret;
111
+ CPUClusterState *cluster = CPU_CLUSTER(child);
112
+ GDBProcess *process;
113
+
114
+ s->processes = g_renew(GDBProcess, s->processes, ++s->process_num);
115
+
116
+ process = &s->processes[s->process_num - 1];
117
+
118
+ /*
119
+ * GDB process IDs -1 and 0 are reserved. To avoid subtle errors at
120
+ * runtime, we enforce here that the machine does not use a cluster ID
121
+ * that would lead to PID 0.
122
+ */
123
+ assert(cluster->cluster_id != UINT32_MAX);
124
+ process->pid = cluster->cluster_id + 1;
125
+ process->attached = false;
126
+
127
+ return 0;
128
+ }
129
+
130
+ return object_child_foreach(child, find_cpu_clusters, opaque);
377
+}
131
+}
378
+
132
+
379
/* Return the offset into CPUARMState of a slice (from
133
+static int pid_order(const void *a, const void *b)
380
* the least significant end) of FP register Qn (ie
381
* Dn, Sn, Hn or Bn).
382
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn)
383
int rn = extract32(insn, 5, 5);
384
int rd = extract32(insn, 0, 5);
385
int decrypt;
386
- TCGv_i32 tcg_rd_regno, tcg_rn_regno, tcg_decrypt;
387
- CryptoThreeOpEnvFn *genfn;
388
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
389
+ TCGv_i32 tcg_decrypt;
390
+ CryptoThreeOpIntFn *genfn;
391
392
if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
393
|| size != 0) {
394
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_aes(DisasContext *s, uint32_t insn)
395
return;
396
}
397
398
- /* Note that we convert the Vx register indexes into the
399
- * index within the vfp.regs[] array, so we can share the
400
- * helper with the AArch32 instructions.
401
- */
402
- tcg_rd_regno = tcg_const_i32(rd << 1);
403
- tcg_rn_regno = tcg_const_i32(rn << 1);
404
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
405
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
406
tcg_decrypt = tcg_const_i32(decrypt);
407
408
- genfn(cpu_env, tcg_rd_regno, tcg_rn_regno, tcg_decrypt);
409
+ genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_decrypt);
410
411
- tcg_temp_free_i32(tcg_rd_regno);
412
- tcg_temp_free_i32(tcg_rn_regno);
413
+ tcg_temp_free_ptr(tcg_rd_ptr);
414
+ tcg_temp_free_ptr(tcg_rn_ptr);
415
tcg_temp_free_i32(tcg_decrypt);
416
}
417
418
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
419
int rm = extract32(insn, 16, 5);
420
int rn = extract32(insn, 5, 5);
421
int rd = extract32(insn, 0, 5);
422
- CryptoThreeOpEnvFn *genfn;
423
- TCGv_i32 tcg_rd_regno, tcg_rn_regno, tcg_rm_regno;
424
+ CryptoThreeOpFn *genfn;
425
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr;
426
int feature = ARM_FEATURE_V8_SHA256;
427
428
if (size != 0) {
429
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_three_reg_sha(DisasContext *s, uint32_t insn)
430
return;
431
}
432
433
- tcg_rd_regno = tcg_const_i32(rd << 1);
434
- tcg_rn_regno = tcg_const_i32(rn << 1);
435
- tcg_rm_regno = tcg_const_i32(rm << 1);
436
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
437
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
438
+ tcg_rm_ptr = vec_full_reg_ptr(s, rm);
439
440
if (genfn) {
441
- genfn(cpu_env, tcg_rd_regno, tcg_rn_regno, tcg_rm_regno);
442
+ genfn(tcg_rd_ptr, tcg_rn_ptr, tcg_rm_ptr);
443
} else {
444
TCGv_i32 tcg_opcode = tcg_const_i32(opcode);
445
446
- gen_helper_crypto_sha1_3reg(cpu_env, tcg_rd_regno,
447
- tcg_rn_regno, tcg_rm_regno, tcg_opcode);
448
+ gen_helper_crypto_sha1_3reg(tcg_rd_ptr, tcg_rn_ptr,
449
+ tcg_rm_ptr, tcg_opcode);
450
tcg_temp_free_i32(tcg_opcode);
451
}
452
453
- tcg_temp_free_i32(tcg_rd_regno);
454
- tcg_temp_free_i32(tcg_rn_regno);
455
- tcg_temp_free_i32(tcg_rm_regno);
456
+ tcg_temp_free_ptr(tcg_rd_ptr);
457
+ tcg_temp_free_ptr(tcg_rn_ptr);
458
+ tcg_temp_free_ptr(tcg_rm_ptr);
459
}
460
461
/* Crypto two-reg SHA
462
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
463
int opcode = extract32(insn, 12, 5);
464
int rn = extract32(insn, 5, 5);
465
int rd = extract32(insn, 0, 5);
466
- CryptoTwoOpEnvFn *genfn;
467
+ CryptoTwoOpFn *genfn;
468
int feature;
469
- TCGv_i32 tcg_rd_regno, tcg_rn_regno;
470
+ TCGv_ptr tcg_rd_ptr, tcg_rn_ptr;
471
472
if (size != 0) {
473
unallocated_encoding(s);
474
@@ -XXX,XX +XXX,XX @@ static void disas_crypto_two_reg_sha(DisasContext *s, uint32_t insn)
475
return;
476
}
477
478
- tcg_rd_regno = tcg_const_i32(rd << 1);
479
- tcg_rn_regno = tcg_const_i32(rn << 1);
480
+ tcg_rd_ptr = vec_full_reg_ptr(s, rd);
481
+ tcg_rn_ptr = vec_full_reg_ptr(s, rn);
482
483
- genfn(cpu_env, tcg_rd_regno, tcg_rn_regno);
484
+ genfn(tcg_rd_ptr, tcg_rn_ptr);
485
486
- tcg_temp_free_i32(tcg_rd_regno);
487
- tcg_temp_free_i32(tcg_rn_regno);
488
+ tcg_temp_free_ptr(tcg_rd_ptr);
489
+ tcg_temp_free_ptr(tcg_rn_ptr);
490
}
491
492
/* C3.6 Data processing - SIMD, inc Crypto
493
diff --git a/target/arm/translate.c b/target/arm/translate.c
494
index XXXXXXX..XXXXXXX 100644
495
--- a/target/arm/translate.c
496
+++ b/target/arm/translate.c
497
@@ -XXX,XX +XXX,XX @@ static inline void neon_store_reg64(TCGv_i64 var, int reg)
498
tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
499
}
500
501
+static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
502
+{
134
+{
503
+ TCGv_ptr ret = tcg_temp_new_ptr();
135
+ GDBProcess *pa = (GDBProcess *) a;
504
+ tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
136
+ GDBProcess *pb = (GDBProcess *) b;
505
+ return ret;
137
+
138
+ if (pa->pid < pb->pid) {
139
+ return -1;
140
+ } else if (pa->pid > pb->pid) {
141
+ return 1;
142
+ } else {
143
+ return 0;
144
+ }
506
+}
145
+}
507
+
146
+
508
#define tcg_gen_ld_f32 tcg_gen_ld_i32
147
+static void create_processes(GDBState *s)
509
#define tcg_gen_ld_f64 tcg_gen_ld_i64
148
+{
510
#define tcg_gen_st_f32 tcg_gen_st_i32
149
+ object_child_foreach(object_get_root(), find_cpu_clusters, s);
511
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
150
+
512
int u;
151
+ if (s->processes) {
513
uint32_t imm, mask;
152
+ /* Sort by PID */
514
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
153
+ qsort(s->processes, s->process_num, sizeof(s->processes[0]), pid_order);
515
+ TCGv_ptr ptr1, ptr2, ptr3;
154
+ }
516
TCGv_i64 tmp64;
155
+
517
156
+ create_default_process(s);
518
/* FIXME: this access check should not take precedence over UNDEF
157
+}
519
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
158
+
520
if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
159
+static void cleanup_processes(GDBState *s)
521
return 1;
160
+{
522
}
161
+ g_free(s->processes);
523
- tmp = tcg_const_i32(rd);
162
+ s->process_num = 0;
524
- tmp2 = tcg_const_i32(rn);
163
+ s->processes = NULL;
525
- tmp3 = tcg_const_i32(rm);
164
+}
526
+ ptr1 = vfp_reg_ptr(true, rd);
165
+
527
+ ptr2 = vfp_reg_ptr(true, rn);
166
int gdbserver_start(const char *device)
528
+ ptr3 = vfp_reg_ptr(true, rm);
167
{
529
tmp4 = tcg_const_i32(size);
168
trace_gdbstub_op_start(device);
530
- gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
169
@@ -XXX,XX +XXX,XX @@ int gdbserver_start(const char *device)
531
+ gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
170
} else {
532
tcg_temp_free_i32(tmp4);
171
qemu_chr_fe_deinit(&s->chr, true);
533
} else { /* SHA-256 */
172
mon_chr = s->mon_chr;
534
if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
173
+ cleanup_processes(s);
535
return 1;
174
memset(s, 0, sizeof(GDBState));
536
}
175
s->mon_chr = mon_chr;
537
- tmp = tcg_const_i32(rd);
176
}
538
- tmp2 = tcg_const_i32(rn);
177
s->c_cpu = first_cpu;
539
- tmp3 = tcg_const_i32(rm);
178
s->g_cpu = first_cpu;
540
+ ptr1 = vfp_reg_ptr(true, rd);
179
+
541
+ ptr2 = vfp_reg_ptr(true, rn);
180
+ create_processes(s);
542
+ ptr3 = vfp_reg_ptr(true, rm);
181
+
543
switch (size) {
182
if (chr) {
544
case 0:
183
qemu_chr_fe_init(&s->chr, chr, &error_abort);
545
- gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
184
qemu_chr_fe_set_handlers(&s->chr, gdb_chr_can_receive, gdb_chr_receive,
546
+ gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
547
break;
548
case 1:
549
- gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
550
+ gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
551
break;
552
case 2:
553
- gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
554
+ gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
555
break;
556
}
557
}
558
- tcg_temp_free_i32(tmp);
559
- tcg_temp_free_i32(tmp2);
560
- tcg_temp_free_i32(tmp3);
561
+ tcg_temp_free_ptr(ptr1);
562
+ tcg_temp_free_ptr(ptr2);
563
+ tcg_temp_free_ptr(ptr3);
564
return 0;
565
}
566
if (size == 3 && op != NEON_3R_LOGIC) {
567
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
568
|| ((rm | rd) & 1)) {
569
return 1;
570
}
571
- tmp = tcg_const_i32(rd);
572
- tmp2 = tcg_const_i32(rm);
573
+ ptr1 = vfp_reg_ptr(true, rd);
574
+ ptr2 = vfp_reg_ptr(true, rm);
575
576
/* Bit 6 is the lowest opcode bit; it distinguishes between
577
* encryption (AESE/AESMC) and decryption (AESD/AESIMC)
578
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
579
tmp3 = tcg_const_i32(extract32(insn, 6, 1));
580
581
if (op == NEON_2RM_AESE) {
582
- gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
583
+ gen_helper_crypto_aese(ptr1, ptr2, tmp3);
584
} else {
585
- gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
586
+ gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
587
}
588
- tcg_temp_free_i32(tmp);
589
- tcg_temp_free_i32(tmp2);
590
+ tcg_temp_free_ptr(ptr1);
591
+ tcg_temp_free_ptr(ptr2);
592
tcg_temp_free_i32(tmp3);
593
break;
594
case NEON_2RM_SHA1H:
595
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
596
|| ((rm | rd) & 1)) {
597
return 1;
598
}
599
- tmp = tcg_const_i32(rd);
600
- tmp2 = tcg_const_i32(rm);
601
+ ptr1 = vfp_reg_ptr(true, rd);
602
+ ptr2 = vfp_reg_ptr(true, rm);
603
604
- gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
605
+ gen_helper_crypto_sha1h(ptr1, ptr2);
606
607
- tcg_temp_free_i32(tmp);
608
- tcg_temp_free_i32(tmp2);
609
+ tcg_temp_free_ptr(ptr1);
610
+ tcg_temp_free_ptr(ptr2);
611
break;
612
case NEON_2RM_SHA1SU1:
613
if ((rm | rd) & 1) {
614
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
615
} else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
616
return 1;
617
}
618
- tmp = tcg_const_i32(rd);
619
- tmp2 = tcg_const_i32(rm);
620
+ ptr1 = vfp_reg_ptr(true, rd);
621
+ ptr2 = vfp_reg_ptr(true, rm);
622
if (q) {
623
- gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
624
+ gen_helper_crypto_sha256su0(ptr1, ptr2);
625
} else {
626
- gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
627
+ gen_helper_crypto_sha1su1(ptr1, ptr2);
628
}
629
- tcg_temp_free_i32(tmp);
630
- tcg_temp_free_i32(tmp2);
631
+ tcg_temp_free_ptr(ptr1);
632
+ tcg_temp_free_ptr(ptr2);
633
break;
634
default:
635
elementwise:
636
--
185
--
637
2.7.4
186
2.19.2
638
187
639
188
diff view generated by jsdifflib
New patch
1
From: Luc Michel <luc.michel@greensocs.com>
1
2
3
The gdb_get_cpu_pid() function does the PID lookup for the given CPU. It
4
checks if the CPU is a direct child of a CPU cluster. If it is, the
5
returned PID is the cluster ID plus one (cluster IDs start at 0, GDB
6
PIDs at 1). When the CPU is not a child of such a container, the PID of
7
the default process is returned.
8
9
The gdb_fmt_thread_id() function generates the string to be used to identify
10
a given thread, in a response packet for the peer. This function
11
supports generating thread IDs when multiprocess mode is enabled (in the
12
form `p<pid>.<tid>').
13
14
Use them in the reply to a '?' request.
15
16
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
17
Acked-by: Alistair Francis <alistair.francis@wdc.com>
18
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
19
Message-id: 20181207090135.7651-4-luc.michel@greensocs.com
20
[PMM: fixed checkpatch blockquote style nit]
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
gdbstub.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
24
1 file changed, 64 insertions(+), 2 deletions(-)
25
26
diff --git a/gdbstub.c b/gdbstub.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/gdbstub.c
29
+++ b/gdbstub.c
30
@@ -XXX,XX +XXX,XX @@ static int memtox(char *buf, const char *mem, int len)
31
return p - buf;
32
}
33
34
+static uint32_t gdb_get_cpu_pid(const GDBState *s, CPUState *cpu)
35
+{
36
+#ifndef CONFIG_USER_ONLY
37
+ gchar *path, *name = NULL;
38
+ Object *obj;
39
+ CPUClusterState *cluster;
40
+ uint32_t ret;
41
+
42
+ path = object_get_canonical_path(OBJECT(cpu));
43
+
44
+ if (path == NULL) {
45
+ /* Return the default process' PID */
46
+ ret = s->processes[s->process_num - 1].pid;
47
+ goto out;
48
+ }
49
+
50
+ name = object_get_canonical_path_component(OBJECT(cpu));
51
+ assert(name != NULL);
52
+
53
+ /*
54
+ * Retrieve the CPU parent path by removing the last '/' and the CPU name
55
+ * from the CPU canonical path.
56
+ */
57
+ path[strlen(path) - strlen(name) - 1] = '\0';
58
+
59
+ obj = object_resolve_path_type(path, TYPE_CPU_CLUSTER, NULL);
60
+
61
+ if (obj == NULL) {
62
+ /* Return the default process' PID */
63
+ ret = s->processes[s->process_num - 1].pid;
64
+ goto out;
65
+ }
66
+
67
+ cluster = CPU_CLUSTER(obj);
68
+ ret = cluster->cluster_id + 1;
69
+
70
+out:
71
+ g_free(name);
72
+ g_free(path);
73
+
74
+ return ret;
75
+
76
+#else
77
+ /* TODO: In user mode, we should use the task state PID */
78
+ return s->processes[s->process_num - 1].pid;
79
+#endif
80
+}
81
+
82
static const char *get_feature_xml(const char *p, const char **newp,
83
CPUClass *cc)
84
{
85
@@ -XXX,XX +XXX,XX @@ static CPUState *find_cpu(uint32_t thread_id)
86
return NULL;
87
}
88
89
+static char *gdb_fmt_thread_id(const GDBState *s, CPUState *cpu,
90
+ char *buf, size_t buf_size)
91
+{
92
+ if (s->multiprocess) {
93
+ snprintf(buf, buf_size, "p%02x.%02x",
94
+ gdb_get_cpu_pid(s, cpu), cpu_gdb_index(cpu));
95
+ } else {
96
+ snprintf(buf, buf_size, "%02x", cpu_gdb_index(cpu));
97
+ }
98
+
99
+ return buf;
100
+}
101
+
102
static int is_query_packet(const char *p, const char *query, char separator)
103
{
104
unsigned int query_len = strlen(query);
105
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
106
int ch, reg_size, type, res;
107
uint8_t mem_buf[MAX_PACKET_LENGTH];
108
char buf[sizeof(mem_buf) + 1 /* trailing NUL */];
109
+ char thread_id[16];
110
uint8_t *registers;
111
target_ulong addr, len;
112
113
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
114
switch(ch) {
115
case '?':
116
/* TODO: Make this return the correct value for user-mode. */
117
- snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
118
- cpu_gdb_index(s->c_cpu));
119
+ snprintf(buf, sizeof(buf), "T%02xthread:%s;", GDB_SIGNAL_TRAP,
120
+ gdb_fmt_thread_id(s, s->c_cpu, thread_id, sizeof(thread_id)));
121
put_packet(s, buf);
122
/* Remove all the breakpoints when this query is issued,
123
* because gdb is doing and initial connect and the state
124
--
125
2.19.2
126
127
diff view generated by jsdifflib
New patch
1
1
From: Luc Michel <luc.michel@greensocs.com>
2
3
Add a couple of helper functions to cope with GDB threads and processes.
4
5
The gdb_get_process() function looks for a process given a pid.
6
7
The gdb_get_cpu() function returns the CPU corresponding to the (pid,
8
tid) pair given as parameters.
9
10
The read_thread_id() function parses the thread-id sent by the peer.
11
This function supports the multiprocess extension thread-id syntax. The
12
return value specifies if the parsing failed, or if a special case was
13
encountered (all processes or all threads).
14
15
Use them in 'H' and 'T' packets handling to support the multiprocess
16
extension.
17
18
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
19
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
20
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
21
Acked-by: Alistair Francis <alistair.francis@wdc.com>
22
Message-id: 20181207090135.7651-5-luc.michel@greensocs.com
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
25
gdbstub.c | 154 +++++++++++++++++++++++++++++++++++++++++++++++-------
26
1 file changed, 136 insertions(+), 18 deletions(-)
27
28
diff --git a/gdbstub.c b/gdbstub.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/gdbstub.c
31
+++ b/gdbstub.c
32
@@ -XXX,XX +XXX,XX @@ out:
33
#endif
34
}
35
36
+static GDBProcess *gdb_get_process(const GDBState *s, uint32_t pid)
37
+{
38
+ int i;
39
+
40
+ if (!pid) {
41
+ /* 0 means any process, we take the first one */
42
+ return &s->processes[0];
43
+ }
44
+
45
+ for (i = 0; i < s->process_num; i++) {
46
+ if (s->processes[i].pid == pid) {
47
+ return &s->processes[i];
48
+ }
49
+ }
50
+
51
+ return NULL;
52
+}
53
+
54
+static GDBProcess *gdb_get_cpu_process(const GDBState *s, CPUState *cpu)
55
+{
56
+ return gdb_get_process(s, gdb_get_cpu_pid(s, cpu));
57
+}
58
+
59
+static CPUState *find_cpu(uint32_t thread_id)
60
+{
61
+ CPUState *cpu;
62
+
63
+ CPU_FOREACH(cpu) {
64
+ if (cpu_gdb_index(cpu) == thread_id) {
65
+ return cpu;
66
+ }
67
+ }
68
+
69
+ return NULL;
70
+}
71
+
72
+static CPUState *gdb_get_cpu(const GDBState *s, uint32_t pid, uint32_t tid)
73
+{
74
+ GDBProcess *process;
75
+ CPUState *cpu;
76
+
77
+ if (!tid) {
78
+ /* 0 means any thread, we take the first one */
79
+ tid = 1;
80
+ }
81
+
82
+ cpu = find_cpu(tid);
83
+
84
+ if (cpu == NULL) {
85
+ return NULL;
86
+ }
87
+
88
+ process = gdb_get_cpu_process(s, cpu);
89
+
90
+ if (process->pid != pid) {
91
+ return NULL;
92
+ }
93
+
94
+ if (!process->attached) {
95
+ return NULL;
96
+ }
97
+
98
+ return cpu;
99
+}
100
+
101
static const char *get_feature_xml(const char *p, const char **newp,
102
CPUClass *cc)
103
{
104
@@ -XXX,XX +XXX,XX @@ static void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
105
cpu_set_pc(cpu, pc);
106
}
107
108
-static CPUState *find_cpu(uint32_t thread_id)
109
-{
110
- CPUState *cpu;
111
-
112
- CPU_FOREACH(cpu) {
113
- if (cpu_gdb_index(cpu) == thread_id) {
114
- return cpu;
115
- }
116
- }
117
-
118
- return NULL;
119
-}
120
-
121
static char *gdb_fmt_thread_id(const GDBState *s, CPUState *cpu,
122
char *buf, size_t buf_size)
123
{
124
@@ -XXX,XX +XXX,XX @@ static char *gdb_fmt_thread_id(const GDBState *s, CPUState *cpu,
125
return buf;
126
}
127
128
+typedef enum GDBThreadIdKind {
129
+ GDB_ONE_THREAD = 0,
130
+ GDB_ALL_THREADS, /* One process, all threads */
131
+ GDB_ALL_PROCESSES,
132
+ GDB_READ_THREAD_ERR
133
+} GDBThreadIdKind;
134
+
135
+static GDBThreadIdKind read_thread_id(const char *buf, const char **end_buf,
136
+ uint32_t *pid, uint32_t *tid)
137
+{
138
+ unsigned long p, t;
139
+ int ret;
140
+
141
+ if (*buf == 'p') {
142
+ buf++;
143
+ ret = qemu_strtoul(buf, &buf, 16, &p);
144
+
145
+ if (ret) {
146
+ return GDB_READ_THREAD_ERR;
147
+ }
148
+
149
+ /* Skip '.' */
150
+ buf++;
151
+ } else {
152
+ p = 1;
153
+ }
154
+
155
+ ret = qemu_strtoul(buf, &buf, 16, &t);
156
+
157
+ if (ret) {
158
+ return GDB_READ_THREAD_ERR;
159
+ }
160
+
161
+ *end_buf = buf;
162
+
163
+ if (p == -1) {
164
+ return GDB_ALL_PROCESSES;
165
+ }
166
+
167
+ if (pid) {
168
+ *pid = p;
169
+ }
170
+
171
+ if (t == -1) {
172
+ return GDB_ALL_THREADS;
173
+ }
174
+
175
+ if (tid) {
176
+ *tid = t;
177
+ }
178
+
179
+ return GDB_ONE_THREAD;
180
+}
181
+
182
static int is_query_packet(const char *p, const char *query, char separator)
183
{
184
unsigned int query_len = strlen(query);
185
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
186
CPUClass *cc;
187
const char *p;
188
uint32_t thread;
189
+ uint32_t pid, tid;
190
int ch, reg_size, type, res;
191
uint8_t mem_buf[MAX_PACKET_LENGTH];
192
char buf[sizeof(mem_buf) + 1 /* trailing NUL */];
193
char thread_id[16];
194
uint8_t *registers;
195
target_ulong addr, len;
196
+ GDBThreadIdKind thread_kind;
197
198
trace_gdbstub_io_command(line_buf);
199
200
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
201
break;
202
case 'H':
203
type = *p++;
204
- thread = strtoull(p, (char **)&p, 16);
205
- if (thread == -1 || thread == 0) {
206
+
207
+ thread_kind = read_thread_id(p, &p, &pid, &tid);
208
+ if (thread_kind == GDB_READ_THREAD_ERR) {
209
+ put_packet(s, "E22");
210
+ break;
211
+ }
212
+
213
+ if (thread_kind != GDB_ONE_THREAD) {
214
put_packet(s, "OK");
215
break;
216
}
217
- cpu = find_cpu(thread);
218
+ cpu = gdb_get_cpu(s, pid, tid);
219
if (cpu == NULL) {
220
put_packet(s, "E22");
221
break;
222
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
223
}
224
break;
225
case 'T':
226
- thread = strtoull(p, (char **)&p, 16);
227
- cpu = find_cpu(thread);
228
+ thread_kind = read_thread_id(p, &p, &pid, &tid);
229
+ if (thread_kind == GDB_READ_THREAD_ERR) {
230
+ put_packet(s, "E22");
231
+ break;
232
+ }
233
+ cpu = gdb_get_cpu(s, pid, tid);
234
235
if (cpu != NULL) {
236
put_packet(s, "OK");
237
--
238
2.19.2
239
240
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Luc Michel <luc.michel@greensocs.com>
2
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
3
Add the gdb_first_attached_cpu() and gdb_next_attached_cpu() to iterate
4
Message-id: 20180119045438.28582-14-richard.henderson@linaro.org
4
over all the CPUs in currently attached processes.
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
6
Add the gdb_first_cpu_in_process() and gdb_next_cpu_in_process() to
7
iterate over CPUs of a given process.
8
9
Use them to add multiprocess extension support to vCont packets.
10
11
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
14
Acked-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-id: 20181207090135.7651-6-luc.michel@greensocs.com
16
[PMM: corrected checkpatch comment style nit]
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
18
---
8
target/arm/cpu.h | 127 +---------------------------------------------------
19
gdbstub.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++-------
9
target/arm/helper.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++
20
1 file changed, 100 insertions(+), 15 deletions(-)
10
2 files changed, 128 insertions(+), 125 deletions(-)
11
21
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
22
diff --git a/gdbstub.c b/gdbstub.c
13
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
24
--- a/gdbstub.c
15
+++ b/target/arm/cpu.h
25
+++ b/gdbstub.c
16
@@ -XXX,XX +XXX,XX @@ static inline bool bswap_code(bool sctlr_b)
26
@@ -XXX,XX +XXX,XX @@ static CPUState *find_cpu(uint32_t thread_id)
17
#endif
27
return NULL;
18
}
28
}
19
29
20
-/* Return the exception level to which FP-disabled exceptions should
30
+static CPUState *get_first_cpu_in_process(const GDBState *s,
21
- * be taken, or 0 if FP is enabled.
31
+ GDBProcess *process)
22
- */
32
+{
23
-static inline int fp_exception_el(CPUARMState *env)
33
+ CPUState *cpu;
24
-{
25
- int fpen;
26
- int cur_el = arm_current_el(env);
27
-
28
- /* CPACR and the CPTR registers don't exist before v6, so FP is
29
- * always accessible
30
- */
31
- if (!arm_feature(env, ARM_FEATURE_V6)) {
32
- return 0;
33
- }
34
-
35
- /* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
36
- * 0, 2 : trap EL0 and EL1/PL1 accesses
37
- * 1 : trap only EL0 accesses
38
- * 3 : trap no accesses
39
- */
40
- fpen = extract32(env->cp15.cpacr_el1, 20, 2);
41
- switch (fpen) {
42
- case 0:
43
- case 2:
44
- if (cur_el == 0 || cur_el == 1) {
45
- /* Trap to PL1, which might be EL1 or EL3 */
46
- if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
47
- return 3;
48
- }
49
- return 1;
50
- }
51
- if (cur_el == 3 && !is_a64(env)) {
52
- /* Secure PL1 running at EL3 */
53
- return 3;
54
- }
55
- break;
56
- case 1:
57
- if (cur_el == 0) {
58
- return 1;
59
- }
60
- break;
61
- case 3:
62
- break;
63
- }
64
-
65
- /* For the CPTR registers we don't need to guard with an ARM_FEATURE
66
- * check because zero bits in the registers mean "don't trap".
67
- */
68
-
69
- /* CPTR_EL2 : present in v7VE or v8 */
70
- if (cur_el <= 2 && extract32(env->cp15.cptr_el[2], 10, 1)
71
- && !arm_is_secure_below_el3(env)) {
72
- /* Trap FP ops at EL2, NS-EL1 or NS-EL0 to EL2 */
73
- return 2;
74
- }
75
-
76
- /* CPTR_EL3 : present in v8 */
77
- if (extract32(env->cp15.cptr_el[3], 10, 1)) {
78
- /* Trap all FP ops to EL3 */
79
- return 3;
80
- }
81
-
82
- return 0;
83
-}
84
-
85
#ifdef CONFIG_USER_ONLY
86
static inline bool arm_cpu_bswap_data(CPUARMState *env)
87
{
88
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
89
}
90
#endif
91
92
-static inline void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
93
- target_ulong *cs_base, uint32_t *flags)
94
-{
95
- ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
96
- if (is_a64(env)) {
97
- *pc = env->pc;
98
- *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
99
- /* Get control bits for tagged addresses */
100
- *flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
101
- *flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
102
- } else {
103
- *pc = env->regs[15];
104
- *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
105
- | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
106
- | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
107
- | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
108
- | (arm_sctlr_b(env) << ARM_TBFLAG_SCTLR_B_SHIFT);
109
- if (!(access_secure_reg(env))) {
110
- *flags |= ARM_TBFLAG_NS_MASK;
111
- }
112
- if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
113
- || arm_el_is_aa64(env, 1)) {
114
- *flags |= ARM_TBFLAG_VFPEN_MASK;
115
- }
116
- *flags |= (extract32(env->cp15.c15_cpar, 0, 2)
117
- << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
118
- }
119
-
120
- *flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
121
-
122
- /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
123
- * states defined in the ARM ARM for software singlestep:
124
- * SS_ACTIVE PSTATE.SS State
125
- * 0 x Inactive (the TB flag for SS is always 0)
126
- * 1 0 Active-pending
127
- * 1 1 Active-not-pending
128
- */
129
- if (arm_singlestep_active(env)) {
130
- *flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
131
- if (is_a64(env)) {
132
- if (env->pstate & PSTATE_SS) {
133
- *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
134
- }
135
- } else {
136
- if (env->uncached_cpsr & PSTATE_SS) {
137
- *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
138
- }
139
- }
140
- }
141
- if (arm_cpu_data_is_big_endian(env)) {
142
- *flags |= ARM_TBFLAG_BE_DATA_MASK;
143
- }
144
- *flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
145
-
146
- if (arm_v7m_is_handler_mode(env)) {
147
- *flags |= ARM_TBFLAG_HANDLER_MASK;
148
- }
149
-
150
- *cs_base = 0;
151
-}
152
+void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
153
+ target_ulong *cs_base, uint32_t *flags);
154
155
enum {
156
QEMU_PSCI_CONDUIT_DISABLED = 0,
157
diff --git a/target/arm/helper.c b/target/arm/helper.c
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/arm/helper.c
160
+++ b/target/arm/helper.c
161
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
162
/* Linux crc32c converts the output to one's complement. */
163
return crc32c(acc, buf, bytes) ^ 0xffffffff;
164
}
165
+
34
+
166
+/* Return the exception level to which FP-disabled exceptions should
35
+ CPU_FOREACH(cpu) {
167
+ * be taken, or 0 if FP is enabled.
36
+ if (gdb_get_cpu_pid(s, cpu) == process->pid) {
168
+ */
37
+ return cpu;
169
+static inline int fp_exception_el(CPUARMState *env)
38
+ }
170
+{
171
+ int fpen;
172
+ int cur_el = arm_current_el(env);
173
+
174
+ /* CPACR and the CPTR registers don't exist before v6, so FP is
175
+ * always accessible
176
+ */
177
+ if (!arm_feature(env, ARM_FEATURE_V6)) {
178
+ return 0;
179
+ }
39
+ }
180
+
40
+
181
+ /* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
41
+ return NULL;
182
+ * 0, 2 : trap EL0 and EL1/PL1 accesses
42
+}
183
+ * 1 : trap only EL0 accesses
43
+
184
+ * 3 : trap no accesses
44
+static CPUState *gdb_next_cpu_in_process(const GDBState *s, CPUState *cpu)
185
+ */
45
+{
186
+ fpen = extract32(env->cp15.cpacr_el1, 20, 2);
46
+ uint32_t pid = gdb_get_cpu_pid(s, cpu);
187
+ switch (fpen) {
47
+ cpu = CPU_NEXT(cpu);
188
+ case 0:
48
+
189
+ case 2:
49
+ while (cpu) {
190
+ if (cur_el == 0 || cur_el == 1) {
50
+ if (gdb_get_cpu_pid(s, cpu) == pid) {
191
+ /* Trap to PL1, which might be EL1 or EL3 */
51
+ break;
192
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
193
+ return 3;
194
+ }
195
+ return 1;
196
+ }
52
+ }
197
+ if (cur_el == 3 && !is_a64(env)) {
53
+
198
+ /* Secure PL1 running at EL3 */
54
+ cpu = CPU_NEXT(cpu);
199
+ return 3;
200
+ }
201
+ break;
202
+ case 1:
203
+ if (cur_el == 0) {
204
+ return 1;
205
+ }
206
+ break;
207
+ case 3:
208
+ break;
209
+ }
55
+ }
210
+
56
+
211
+ /* For the CPTR registers we don't need to guard with an ARM_FEATURE
57
+ return cpu;
212
+ * check because zero bits in the registers mean "don't trap".
58
+}
213
+ */
214
+
59
+
215
+ /* CPTR_EL2 : present in v7VE or v8 */
60
static CPUState *gdb_get_cpu(const GDBState *s, uint32_t pid, uint32_t tid)
216
+ if (cur_el <= 2 && extract32(env->cp15.cptr_el[2], 10, 1)
61
{
217
+ && !arm_is_secure_below_el3(env)) {
62
GDBProcess *process;
218
+ /* Trap FP ops at EL2, NS-EL1 or NS-EL0 to EL2 */
63
@@ -XXX,XX +XXX,XX @@ static CPUState *gdb_get_cpu(const GDBState *s, uint32_t pid, uint32_t tid)
219
+ return 2;
64
return cpu;
65
}
66
67
+/* Return the cpu following @cpu, while ignoring unattached processes. */
68
+static CPUState *gdb_next_attached_cpu(const GDBState *s, CPUState *cpu)
69
+{
70
+ cpu = CPU_NEXT(cpu);
71
+
72
+ while (cpu) {
73
+ if (gdb_get_cpu_process(s, cpu)->attached) {
74
+ break;
75
+ }
76
+
77
+ cpu = CPU_NEXT(cpu);
220
+ }
78
+ }
221
+
79
+
222
+ /* CPTR_EL3 : present in v8 */
80
+ return cpu;
223
+ if (extract32(env->cp15.cptr_el[3], 10, 1)) {
81
+}
224
+ /* Trap all FP ops to EL3 */
82
+
225
+ return 3;
83
+/* Return the first attached cpu */
84
+static CPUState *gdb_first_attached_cpu(const GDBState *s)
85
+{
86
+ CPUState *cpu = first_cpu;
87
+ GDBProcess *process = gdb_get_cpu_process(s, cpu);
88
+
89
+ if (!process->attached) {
90
+ return gdb_next_attached_cpu(s, cpu);
226
+ }
91
+ }
227
+
92
+
228
+ return 0;
93
+ return cpu;
229
+}
94
+}
230
+
95
+
231
+void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
96
static const char *get_feature_xml(const char *p, const char **newp,
232
+ target_ulong *cs_base, uint32_t *flags)
97
CPUClass *cc)
233
+{
98
{
234
+ ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
99
@@ -XXX,XX +XXX,XX @@ static int is_query_packet(const char *p, const char *query, char separator)
235
+ if (is_a64(env)) {
100
*/
236
+ *pc = env->pc;
101
static int gdb_handle_vcont(GDBState *s, const char *p)
237
+ *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
102
{
238
+ /* Get control bits for tagged addresses */
103
- int res, idx, signal = 0;
239
+ *flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
104
+ int res, signal = 0;
240
+ *flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
105
char cur_action;
241
+ } else {
106
char *newstates;
242
+ *pc = env->regs[15];
107
unsigned long tmp;
243
+ *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
108
+ uint32_t pid, tid;
244
+ | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
109
+ GDBProcess *process;
245
+ | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
110
CPUState *cpu;
246
+ | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
111
#ifdef CONFIG_USER_ONLY
247
+ | (arm_sctlr_b(env) << ARM_TBFLAG_SCTLR_B_SHIFT);
112
int max_cpus = 1; /* global variable max_cpus exists only in system mode */
248
+ if (!(access_secure_reg(env))) {
113
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_vcont(GDBState *s, const char *p)
249
+ *flags |= ARM_TBFLAG_NS_MASK;
114
res = -ENOTSUP;
115
goto out;
116
}
117
- /* thread specification. special values: (none), -1 = all; 0 = any */
118
- if ((p[0] == ':' && p[1] == '-' && p[2] == '1') || (p[0] != ':')) {
119
- if (*p == ':') {
120
- p += 3;
121
- }
122
- for (idx = 0; idx < max_cpus; idx++) {
123
- if (newstates[idx] == 1) {
124
- newstates[idx] = cur_action;
125
+
126
+ if (*p++ != ':') {
127
+ res = -ENOTSUP;
128
+ goto out;
250
+ }
129
+ }
251
+ if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
252
+ || arm_el_is_aa64(env, 1)) {
253
+ *flags |= ARM_TBFLAG_VFPEN_MASK;
254
+ }
255
+ *flags |= (extract32(env->cp15.c15_cpar, 0, 2)
256
+ << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
257
+ }
258
+
130
+
259
+ *flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
131
+ switch (read_thread_id(p, &p, &pid, &tid)) {
132
+ case GDB_READ_THREAD_ERR:
133
+ res = -EINVAL;
134
+ goto out;
260
+
135
+
261
+ /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
136
+ case GDB_ALL_PROCESSES:
262
+ * states defined in the ARM ARM for software singlestep:
137
+ cpu = gdb_first_attached_cpu(s);
263
+ * SS_ACTIVE PSTATE.SS State
138
+ while (cpu) {
264
+ * 0 x Inactive (the TB flag for SS is always 0)
139
+ if (newstates[cpu->cpu_index] == 1) {
265
+ * 1 0 Active-pending
140
+ newstates[cpu->cpu_index] = cur_action;
266
+ * 1 1 Active-not-pending
141
}
267
+ */
142
+
268
+ if (arm_singlestep_active(env)) {
143
+ cpu = gdb_next_attached_cpu(s, cpu);
269
+ *flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
144
}
270
+ if (is_a64(env)) {
145
- } else if (*p == ':') {
271
+ if (env->pstate & PSTATE_SS) {
146
- p++;
272
+ *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
147
- res = qemu_strtoul(p, &p, 16, &tmp);
148
- if (res) {
149
+ break;
150
+
151
+ case GDB_ALL_THREADS:
152
+ process = gdb_get_process(s, pid);
153
+
154
+ if (!process->attached) {
155
+ res = -EINVAL;
156
goto out;
157
}
158
159
- /* 0 means any thread, so we pick the first valid CPU */
160
- cpu = tmp ? find_cpu(tmp) : first_cpu;
161
+ cpu = get_first_cpu_in_process(s, process);
162
+ while (cpu) {
163
+ if (newstates[cpu->cpu_index] == 1) {
164
+ newstates[cpu->cpu_index] = cur_action;
165
+ }
166
+
167
+ cpu = gdb_next_cpu_in_process(s, cpu);
273
+ }
168
+ }
274
+ } else {
169
+ break;
275
+ if (env->uncached_cpsr & PSTATE_SS) {
276
+ *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
277
+ }
278
+ }
279
+ }
280
+ if (arm_cpu_data_is_big_endian(env)) {
281
+ *flags |= ARM_TBFLAG_BE_DATA_MASK;
282
+ }
283
+ *flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
284
+
170
+
285
+ if (arm_v7m_is_handler_mode(env)) {
171
+ case GDB_ONE_THREAD:
286
+ *flags |= ARM_TBFLAG_HANDLER_MASK;
172
+ cpu = gdb_get_cpu(s, pid, tid);
287
+ }
173
288
+
174
/* invalid CPU/thread specified */
289
+ *cs_base = 0;
175
if (!cpu) {
290
+}
176
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_vcont(GDBState *s, const char *p)
177
if (newstates[cpu->cpu_index] == 1) {
178
newstates[cpu->cpu_index] = cur_action;
179
}
180
+ break;
181
}
182
}
183
s->signal = signal;
291
--
184
--
292
2.7.4
185
2.19.2
293
186
294
187
diff view generated by jsdifflib
New patch
1
From: Luc Michel <luc.michel@greensocs.com>
1
2
3
Change the sC packet handling to support the multiprocess extension.
4
Instead of returning the first thread, we return the first thread of the
5
current process.
6
7
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Message-id: 20181207090135.7651-7-luc.michel@greensocs.com
12
[PMM: corrected checkpatch comment style nit]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
gdbstub.c | 12 +++++++++---
16
1 file changed, 9 insertions(+), 3 deletions(-)
17
18
diff --git a/gdbstub.c b/gdbstub.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/gdbstub.c
21
+++ b/gdbstub.c
22
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
23
put_packet(s, "OK");
24
break;
25
} else if (strcmp(p,"C") == 0) {
26
- /* "Current thread" remains vague in the spec, so always return
27
- * the first CPU (gdb returns the first thread). */
28
- put_packet(s, "QC1");
29
+ /*
30
+ * "Current thread" remains vague in the spec, so always return
31
+ * the first thread of the current process (gdb returns the
32
+ * first thread).
33
+ */
34
+ cpu = get_first_cpu_in_process(s, gdb_get_cpu_process(s, s->g_cpu));
35
+ snprintf(buf, sizeof(buf), "QC%s",
36
+ gdb_fmt_thread_id(s, cpu, thread_id, sizeof(thread_id)));
37
+ put_packet(s, buf);
38
break;
39
} else if (strcmp(p,"fThreadInfo") == 0) {
40
s->query_cpu = first_cpu;
41
--
42
2.19.2
43
44
diff view generated by jsdifflib
New patch
1
From: Luc Michel <luc.michel@greensocs.com>
1
2
3
Change the thread info related packets handling to support multiprocess
4
extension.
5
6
Add the CPUs class name in the extra info to help differentiate
7
them in multiprocess mode.
8
9
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-id: 20181207090135.7651-8-luc.michel@greensocs.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
gdbstub.c | 37 +++++++++++++++++++++++++++----------
17
1 file changed, 27 insertions(+), 10 deletions(-)
18
19
diff --git a/gdbstub.c b/gdbstub.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/gdbstub.c
22
+++ b/gdbstub.c
23
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
24
CPUState *cpu;
25
CPUClass *cc;
26
const char *p;
27
- uint32_t thread;
28
uint32_t pid, tid;
29
int ch, reg_size, type, res;
30
uint8_t mem_buf[MAX_PACKET_LENGTH];
31
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
32
put_packet(s, buf);
33
break;
34
} else if (strcmp(p,"fThreadInfo") == 0) {
35
- s->query_cpu = first_cpu;
36
+ s->query_cpu = gdb_first_attached_cpu(s);
37
goto report_cpuinfo;
38
} else if (strcmp(p,"sThreadInfo") == 0) {
39
report_cpuinfo:
40
if (s->query_cpu) {
41
- snprintf(buf, sizeof(buf), "m%x", cpu_gdb_index(s->query_cpu));
42
+ snprintf(buf, sizeof(buf), "m%s",
43
+ gdb_fmt_thread_id(s, s->query_cpu,
44
+ thread_id, sizeof(thread_id)));
45
put_packet(s, buf);
46
- s->query_cpu = CPU_NEXT(s->query_cpu);
47
+ s->query_cpu = gdb_next_attached_cpu(s, s->query_cpu);
48
} else
49
put_packet(s, "l");
50
break;
51
} else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
52
- thread = strtoull(p+16, (char **)&p, 16);
53
- cpu = find_cpu(thread);
54
+ if (read_thread_id(p + 16, &p, &pid, &tid) == GDB_READ_THREAD_ERR) {
55
+ put_packet(s, "E22");
56
+ break;
57
+ }
58
+ cpu = gdb_get_cpu(s, pid, tid);
59
if (cpu != NULL) {
60
cpu_synchronize_state(cpu);
61
- /* memtohex() doubles the required space */
62
- len = snprintf((char *)mem_buf, sizeof(buf) / 2,
63
- "CPU#%d [%s]", cpu->cpu_index,
64
- cpu->halted ? "halted " : "running");
65
+
66
+ if (s->multiprocess && (s->process_num > 1)) {
67
+ /* Print the CPU model and name in multiprocess mode */
68
+ ObjectClass *oc = object_get_class(OBJECT(cpu));
69
+ const char *cpu_model = object_class_get_name(oc);
70
+ char *cpu_name =
71
+ object_get_canonical_path_component(OBJECT(cpu));
72
+ len = snprintf((char *)mem_buf, sizeof(buf) / 2,
73
+ "%s %s [%s]", cpu_model, cpu_name,
74
+ cpu->halted ? "halted " : "running");
75
+ g_free(cpu_name);
76
+ } else {
77
+ /* memtohex() doubles the required space */
78
+ len = snprintf((char *)mem_buf, sizeof(buf) / 2,
79
+ "CPU#%d [%s]", cpu->cpu_index,
80
+ cpu->halted ? "halted " : "running");
81
+ }
82
trace_gdbstub_op_extra_info((char *)mem_buf);
83
memtohex(buf, mem_buf, len);
84
put_packet(s, buf);
85
--
86
2.19.2
87
88
diff view generated by jsdifflib
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
1
From: Luc Michel <luc.michel@greensocs.com>
2
2
3
When determining the group priority of a group 1 IRQ, if C_CTRL.CBPR is
3
Change the Xfer:features:read: packet handling to support the
4
0, the non-secure BPR value is used. However, this value must be
4
multiprocess extension. This packet is used to request the XML
5
incremented by one so that it matches the secure world number of
5
description of the CPU. In multiprocess mode, different descriptions can
6
implemented priority bits (NS world has one less priority bit compared
6
be sent for different processes.
7
to the Secure world).
8
7
9
Signed-off-by: Luc MICHEL <luc.michel@git.antfield.fr>
8
This function now takes the process to send the description for as a
10
Message-id: 20180119145756.7629-5-luc.michel@greensocs.com
9
parameter, and use a buffer in the process structure to store the
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
generated description.
12
[PMM: add assert, as the gicv3 code has]
11
12
It takes the first CPU of the process to generate the description.
13
14
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
15
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
16
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-id: 20181207090135.7651-9-luc.michel@greensocs.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
20
---
15
hw/intc/arm_gic.c | 3 ++-
21
gdbstub.c | 52 ++++++++++++++++++++++++++++++----------------------
16
1 file changed, 2 insertions(+), 1 deletion(-)
22
1 file changed, 30 insertions(+), 22 deletions(-)
17
23
18
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
24
diff --git a/gdbstub.c b/gdbstub.c
19
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/arm_gic.c
26
--- a/gdbstub.c
21
+++ b/hw/intc/arm_gic.c
27
+++ b/gdbstub.c
22
@@ -XXX,XX +XXX,XX @@ static int gic_get_group_priority(GICState *s, int cpu, int irq)
28
@@ -XXX,XX +XXX,XX @@ typedef struct GDBRegisterState {
23
if (gic_has_groups(s) &&
29
typedef struct GDBProcess {
24
!(s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) &&
30
uint32_t pid;
25
GIC_TEST_GROUP(irq, (1 << cpu))) {
31
bool attached;
26
- bpr = s->abpr[cpu];
32
+
27
+ bpr = s->abpr[cpu] - 1;
33
+ char target_xml[1024];
28
+ assert(bpr >= 0);
34
} GDBProcess;
29
} else {
35
30
bpr = s->bpr[cpu];
36
enum RSState {
37
@@ -XXX,XX +XXX,XX @@ static CPUState *gdb_first_attached_cpu(const GDBState *s)
38
return cpu;
39
}
40
41
-static const char *get_feature_xml(const char *p, const char **newp,
42
- CPUClass *cc)
43
+static const char *get_feature_xml(const GDBState *s, const char *p,
44
+ const char **newp, GDBProcess *process)
45
{
46
size_t len;
47
int i;
48
const char *name;
49
- static char target_xml[1024];
50
+ CPUState *cpu = get_first_cpu_in_process(s, process);
51
+ CPUClass *cc = CPU_GET_CLASS(cpu);
52
53
len = 0;
54
while (p[len] && p[len] != ':')
55
@@ -XXX,XX +XXX,XX @@ static const char *get_feature_xml(const char *p, const char **newp,
56
57
name = NULL;
58
if (strncmp(p, "target.xml", len) == 0) {
59
- /* Generate the XML description for this CPU. */
60
- if (!target_xml[0]) {
61
- GDBRegisterState *r;
62
- CPUState *cpu = first_cpu;
63
+ char *buf = process->target_xml;
64
+ const size_t buf_sz = sizeof(process->target_xml);
65
66
- pstrcat(target_xml, sizeof(target_xml),
67
+ /* Generate the XML description for this CPU. */
68
+ if (!buf[0]) {
69
+ GDBRegisterState *r;
70
+
71
+ pstrcat(buf, buf_sz,
72
"<?xml version=\"1.0\"?>"
73
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
74
"<target>");
75
if (cc->gdb_arch_name) {
76
gchar *arch = cc->gdb_arch_name(cpu);
77
- pstrcat(target_xml, sizeof(target_xml), "<architecture>");
78
- pstrcat(target_xml, sizeof(target_xml), arch);
79
- pstrcat(target_xml, sizeof(target_xml), "</architecture>");
80
+ pstrcat(buf, buf_sz, "<architecture>");
81
+ pstrcat(buf, buf_sz, arch);
82
+ pstrcat(buf, buf_sz, "</architecture>");
83
g_free(arch);
84
}
85
- pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
86
- pstrcat(target_xml, sizeof(target_xml), cc->gdb_core_xml_file);
87
- pstrcat(target_xml, sizeof(target_xml), "\"/>");
88
+ pstrcat(buf, buf_sz, "<xi:include href=\"");
89
+ pstrcat(buf, buf_sz, cc->gdb_core_xml_file);
90
+ pstrcat(buf, buf_sz, "\"/>");
91
for (r = cpu->gdb_regs; r; r = r->next) {
92
- pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
93
- pstrcat(target_xml, sizeof(target_xml), r->xml);
94
- pstrcat(target_xml, sizeof(target_xml), "\"/>");
95
+ pstrcat(buf, buf_sz, "<xi:include href=\"");
96
+ pstrcat(buf, buf_sz, r->xml);
97
+ pstrcat(buf, buf_sz, "\"/>");
98
}
99
- pstrcat(target_xml, sizeof(target_xml), "</target>");
100
+ pstrcat(buf, buf_sz, "</target>");
101
}
102
- return target_xml;
103
+ return buf;
104
}
105
if (cc->gdb_get_dynamic_xml) {
106
- CPUState *cpu = first_cpu;
107
char *xmlname = g_strndup(p, len);
108
const char *xml = cc->gdb_get_dynamic_xml(cpu, xmlname);
109
110
@@ -XXX,XX +XXX,XX @@ out:
111
static int gdb_handle_packet(GDBState *s, const char *line_buf)
112
{
113
CPUState *cpu;
114
+ GDBProcess *process;
115
CPUClass *cc;
116
const char *p;
117
uint32_t pid, tid;
118
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
119
const char *xml;
120
target_ulong total_len;
121
122
- cc = CPU_GET_CLASS(first_cpu);
123
+ process = gdb_get_cpu_process(s, s->g_cpu);
124
+ cc = CPU_GET_CLASS(s->g_cpu);
125
if (cc->gdb_core_xml_file == NULL) {
126
goto unknown_command;
127
}
128
129
gdb_has_xml = true;
130
p += 19;
131
- xml = get_feature_xml(p, &p, cc);
132
+ xml = get_feature_xml(s, p, &p, process);
133
if (!xml) {
134
snprintf(buf, sizeof(buf), "E00");
135
put_packet(s, buf);
136
@@ -XXX,XX +XXX,XX @@ static void create_default_process(GDBState *s)
137
138
process->pid = max_pid + 1;
139
process->attached = false;
140
+ process->target_xml[0] = '\0';
141
}
142
143
#ifdef CONFIG_USER_ONLY
144
@@ -XXX,XX +XXX,XX @@ static int find_cpu_clusters(Object *child, void *opaque)
145
assert(cluster->cluster_id != UINT32_MAX);
146
process->pid = cluster->cluster_id + 1;
147
process->attached = false;
148
+ process->target_xml[0] = '\0';
149
150
return 0;
31
}
151
}
32
--
152
--
33
2.7.4
153
2.19.2
34
154
35
155
diff view generated by jsdifflib
New patch
1
From: Luc Michel <luc.michel@greensocs.com>
1
2
3
Add support for multiprocess extension in gdb_vm_state_change()
4
function.
5
6
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20181207090135.7651-10-luc.michel@greensocs.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
gdbstub.c | 15 ++++++++++++---
14
1 file changed, 12 insertions(+), 3 deletions(-)
15
16
diff --git a/gdbstub.c b/gdbstub.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/gdbstub.c
19
+++ b/gdbstub.c
20
@@ -XXX,XX +XXX,XX @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
21
GDBState *s = gdbserver_state;
22
CPUState *cpu = s->c_cpu;
23
char buf[256];
24
+ char thread_id[16];
25
const char *type;
26
int ret;
27
28
@@ -XXX,XX +XXX,XX @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
29
put_packet(s, s->syscall_buf);
30
return;
31
}
32
+
33
+ if (cpu == NULL) {
34
+ /* No process attached */
35
+ return;
36
+ }
37
+
38
+ gdb_fmt_thread_id(s, cpu, thread_id, sizeof(thread_id));
39
+
40
switch (state) {
41
case RUN_STATE_DEBUG:
42
if (cpu->watchpoint_hit) {
43
@@ -XXX,XX +XXX,XX @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
44
trace_gdbstub_hit_watchpoint(type, cpu_gdb_index(cpu),
45
(target_ulong)cpu->watchpoint_hit->vaddr);
46
snprintf(buf, sizeof(buf),
47
- "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
48
- GDB_SIGNAL_TRAP, cpu_gdb_index(cpu), type,
49
+ "T%02xthread:%s;%swatch:" TARGET_FMT_lx ";",
50
+ GDB_SIGNAL_TRAP, thread_id, type,
51
(target_ulong)cpu->watchpoint_hit->vaddr);
52
cpu->watchpoint_hit = NULL;
53
goto send_packet;
54
@@ -XXX,XX +XXX,XX @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
55
break;
56
}
57
gdb_set_stop_cpu(cpu);
58
- snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, cpu_gdb_index(cpu));
59
+ snprintf(buf, sizeof(buf), "T%02xthread:%s;", ret, thread_id);
60
61
send_packet:
62
put_packet(s, buf);
63
--
64
2.19.2
65
66
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Luc Michel <luc.michel@greensocs.com>
2
2
3
Helpers that return a pointer into env->vfp.regs so that we isolate
3
'D' packets are used by GDB to detach from a process. In multiprocess
4
the logic of how to index the regs array for different cpu modes.
4
mode, the PID to detach from is sent in the request.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
7
Message-id: 20180119045438.28582-7-richard.henderson@linaro.org
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20181207090135.7651-11-luc.michel@greensocs.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/cpu.h | 27 +++++++++++++++++++++++++++
13
gdbstub.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++-------
12
linux-user/signal.c | 22 ++++++++++++----------
14
1 file changed, 53 insertions(+), 7 deletions(-)
13
target/arm/arch_dump.c | 8 +++++---
14
target/arm/helper-a64.c | 5 +++--
15
target/arm/helper.c | 32 ++++++++++++++++++++------------
16
target/arm/kvm32.c | 4 ++--
17
target/arm/kvm64.c | 31 ++++++++++---------------------
18
target/arm/translate-a64.c | 25 ++++++++-----------------
19
target/arm/translate.c | 16 +++++++++-------
20
9 files changed, 96 insertions(+), 74 deletions(-)
21
15
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
diff --git a/gdbstub.c b/gdbstub.c
23
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
18
--- a/gdbstub.c
25
+++ b/target/arm/cpu.h
19
+++ b/gdbstub.c
26
@@ -XXX,XX +XXX,XX @@ static inline void *arm_get_el_change_hook_opaque(ARMCPU *cpu)
20
@@ -XXX,XX +XXX,XX @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
27
return cpu->el_change_hook_opaque;
21
}
28
}
22
}
29
23
30
+/**
24
+static inline void gdb_cpu_breakpoint_remove_all(CPUState *cpu)
31
+ * aa32_vfp_dreg:
32
+ * Return a pointer to the Dn register within env in 32-bit mode.
33
+ */
34
+static inline uint64_t *aa32_vfp_dreg(CPUARMState *env, unsigned regno)
35
+{
25
+{
36
+ return &env->vfp.regs[regno];
26
+ cpu_breakpoint_remove_all(cpu, BP_GDB);
27
+#ifndef CONFIG_USER_ONLY
28
+ cpu_watchpoint_remove_all(cpu, BP_GDB);
29
+#endif
37
+}
30
+}
38
+
31
+
39
+/**
32
+static void gdb_process_breakpoint_remove_all(const GDBState *s, GDBProcess *p)
40
+ * aa32_vfp_qreg:
41
+ * Return a pointer to the Qn register within env in 32-bit mode.
42
+ */
43
+static inline uint64_t *aa32_vfp_qreg(CPUARMState *env, unsigned regno)
44
+{
33
+{
45
+ return &env->vfp.regs[2 * regno];
34
+ CPUState *cpu = get_first_cpu_in_process(s, p);
35
+
36
+ while (cpu) {
37
+ gdb_cpu_breakpoint_remove_all(cpu);
38
+ cpu = gdb_next_cpu_in_process(s, cpu);
39
+ }
46
+}
40
+}
47
+
41
+
48
+/**
42
static void gdb_breakpoint_remove_all(void)
49
+ * aa64_vfp_qreg:
43
{
50
+ * Return a pointer to the Qn register within env in 64-bit mode.
44
CPUState *cpu;
51
+ */
45
@@ -XXX,XX +XXX,XX @@ static void gdb_breakpoint_remove_all(void)
52
+static inline uint64_t *aa64_vfp_qreg(CPUARMState *env, unsigned regno)
53
+{
54
+ return &env->vfp.regs[2 * regno];
55
+}
56
+
57
#endif
58
diff --git a/linux-user/signal.c b/linux-user/signal.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/linux-user/signal.c
61
+++ b/linux-user/signal.c
62
@@ -XXX,XX +XXX,XX @@ static int target_setup_sigframe(struct target_rt_sigframe *sf,
63
}
46
}
64
47
65
for (i = 0; i < 32; i++) {
48
CPU_FOREACH(cpu) {
66
+ uint64_t *q = aa64_vfp_qreg(env, i);
49
- cpu_breakpoint_remove_all(cpu, BP_GDB);
67
#ifdef TARGET_WORDS_BIGENDIAN
50
-#ifndef CONFIG_USER_ONLY
68
- __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
51
- cpu_watchpoint_remove_all(cpu, BP_GDB);
69
- __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
70
+ __put_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
71
+ __put_user(q[1], &aux->fpsimd.vregs[i * 2]);
72
#else
73
- __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
74
- __put_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
75
+ __put_user(q[0], &aux->fpsimd.vregs[i * 2]);
76
+ __put_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
77
#endif
78
}
79
__put_user(vfp_get_fpsr(env), &aux->fpsimd.fpsr);
80
@@ -XXX,XX +XXX,XX @@ static int target_restore_sigframe(CPUARMState *env,
81
}
82
83
for (i = 0; i < 32; i++) {
84
+ uint64_t *q = aa64_vfp_qreg(env, i);
85
#ifdef TARGET_WORDS_BIGENDIAN
86
- __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
87
- __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2]);
88
+ __get_user(q[0], &aux->fpsimd.vregs[i * 2 + 1]);
89
+ __get_user(q[1], &aux->fpsimd.vregs[i * 2]);
90
#else
91
- __get_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2]);
92
- __get_user(env->vfp.regs[i * 2 + 1], &aux->fpsimd.vregs[i * 2 + 1]);
93
+ __get_user(q[0], &aux->fpsimd.vregs[i * 2]);
94
+ __get_user(q[1], &aux->fpsimd.vregs[i * 2 + 1]);
95
#endif
96
}
97
__get_user(fpsr, &aux->fpsimd.fpsr);
98
@@ -XXX,XX +XXX,XX @@ static abi_ulong *setup_sigframe_v2_vfp(abi_ulong *regspace, CPUARMState *env)
99
__put_user(TARGET_VFP_MAGIC, &vfpframe->magic);
100
__put_user(sizeof(*vfpframe), &vfpframe->size);
101
for (i = 0; i < 32; i++) {
102
- __put_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
103
+ __put_user(*aa32_vfp_dreg(env, i), &vfpframe->ufp.fpregs[i]);
104
}
105
__put_user(vfp_get_fpscr(env), &vfpframe->ufp.fpscr);
106
__put_user(env->vfp.xregs[ARM_VFP_FPEXC], &vfpframe->ufp_exc.fpexc);
107
@@ -XXX,XX +XXX,XX @@ static abi_ulong *restore_sigframe_v2_vfp(CPUARMState *env, abi_ulong *regspace)
108
return 0;
109
}
110
for (i = 0; i < 32; i++) {
111
- __get_user(float64_val(env->vfp.regs[i]), &vfpframe->ufp.fpregs[i]);
112
+ __get_user(*aa32_vfp_dreg(env, i), &vfpframe->ufp.fpregs[i]);
113
}
114
__get_user(fpscr, &vfpframe->ufp.fpscr);
115
vfp_set_fpscr(env, fpscr);
116
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
117
index XXXXXXX..XXXXXXX 100644
118
--- a/target/arm/arch_dump.c
119
+++ b/target/arm/arch_dump.c
120
@@ -XXX,XX +XXX,XX @@ static int aarch64_write_elf64_prfpreg(WriteCoreDumpFunction f,
121
122
aarch64_note_init(&note, s, "CORE", 5, NT_PRFPREG, sizeof(note.vfp));
123
124
- for (i = 0; i < 64; ++i) {
125
- note.vfp.vregs[i] = cpu_to_dump64(s, env->vfp.regs[i]);
126
+ for (i = 0; i < 32; ++i) {
127
+ uint64_t *q = aa64_vfp_qreg(env, i);
128
+ note.vfp.vregs[2*i + 0] = cpu_to_dump64(s, q[0]);
129
+ note.vfp.vregs[2*i + 1] = cpu_to_dump64(s, q[1]);
130
}
131
132
if (s->dump_info.d_endian == ELFDATA2MSB) {
133
@@ -XXX,XX +XXX,XX @@ static int arm_write_elf32_vfp(WriteCoreDumpFunction f, CPUARMState *env,
134
arm_note_init(&note, s, "LINUX", 6, NT_ARM_VFP, sizeof(note.vfp));
135
136
for (i = 0; i < 32; ++i) {
137
- note.vfp.vregs[i] = cpu_to_dump64(s, env->vfp.regs[i]);
138
+ note.vfp.vregs[i] = cpu_to_dump64(s, *aa32_vfp_dreg(env, i));
139
}
140
141
note.vfp.fpscr = cpu_to_dump32(s, vfp_get_fpscr(env));
142
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
143
index XXXXXXX..XXXXXXX 100644
144
--- a/target/arm/helper-a64.c
145
+++ b/target/arm/helper-a64.c
146
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices,
147
if (index < 16 * numregs) {
148
/* Convert index (a byte offset into the virtual table
149
* which is a series of 128-bit vectors concatenated)
150
- * into the correct vfp.regs[] element plus a bit offset
151
+ * into the correct register element plus a bit offset
152
* into that element, bearing in mind that the table
153
* can wrap around from V31 to V0.
154
*/
155
int elt = (rn * 2 + (index >> 3)) % 64;
156
int bitidx = (index & 7) * 8;
157
- uint64_t val = extract64(env->vfp.regs[elt], bitidx, 8);
158
+ uint64_t *q = aa64_vfp_qreg(env, elt >> 1);
159
+ uint64_t val = extract64(q[elt & 1], bitidx, 8);
160
161
result = deposit64(result, shift, 8, val);
162
}
163
diff --git a/target/arm/helper.c b/target/arm/helper.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/target/arm/helper.c
166
+++ b/target/arm/helper.c
167
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
168
/* VFP data registers are always little-endian. */
169
nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
170
if (reg < nregs) {
171
- stq_le_p(buf, env->vfp.regs[reg]);
172
+ stq_le_p(buf, *aa32_vfp_dreg(env, reg));
173
return 8;
174
}
175
if (arm_feature(env, ARM_FEATURE_NEON)) {
176
/* Aliases for Q regs. */
177
nregs += 16;
178
if (reg < nregs) {
179
- stq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
180
- stq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
181
+ uint64_t *q = aa32_vfp_qreg(env, reg - 32);
182
+ stq_le_p(buf, q[0]);
183
+ stq_le_p(buf + 8, q[1]);
184
return 16;
185
}
186
}
187
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
188
189
nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
190
if (reg < nregs) {
191
- env->vfp.regs[reg] = ldq_le_p(buf);
192
+ *aa32_vfp_dreg(env, reg) = ldq_le_p(buf);
193
return 8;
194
}
195
if (arm_feature(env, ARM_FEATURE_NEON)) {
196
nregs += 16;
197
if (reg < nregs) {
198
- env->vfp.regs[(reg - 32) * 2] = ldq_le_p(buf);
199
- env->vfp.regs[(reg - 32) * 2 + 1] = ldq_le_p(buf + 8);
200
+ uint64_t *q = aa32_vfp_qreg(env, reg - 32);
201
+ q[0] = ldq_le_p(buf);
202
+ q[1] = ldq_le_p(buf + 8);
203
return 16;
204
}
205
}
206
@@ -XXX,XX +XXX,XX @@ static int aarch64_fpu_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
207
switch (reg) {
208
case 0 ... 31:
209
/* 128 bit FP register */
210
- stq_le_p(buf, env->vfp.regs[reg * 2]);
211
- stq_le_p(buf + 8, env->vfp.regs[reg * 2 + 1]);
212
- return 16;
213
+ {
214
+ uint64_t *q = aa64_vfp_qreg(env, reg);
215
+ stq_le_p(buf, q[0]);
216
+ stq_le_p(buf + 8, q[1]);
217
+ return 16;
218
+ }
219
case 32:
220
/* FPSR */
221
stl_p(buf, vfp_get_fpsr(env));
222
@@ -XXX,XX +XXX,XX @@ static int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
223
switch (reg) {
224
case 0 ... 31:
225
/* 128 bit FP register */
226
- env->vfp.regs[reg * 2] = ldq_le_p(buf);
227
- env->vfp.regs[reg * 2 + 1] = ldq_le_p(buf + 8);
228
- return 16;
229
+ {
230
+ uint64_t *q = aa64_vfp_qreg(env, reg);
231
+ q[0] = ldq_le_p(buf);
232
+ q[1] = ldq_le_p(buf + 8);
233
+ return 16;
234
+ }
235
case 32:
236
/* FPSR */
237
vfp_set_fpsr(env, ldl_p(buf));
238
diff --git a/target/arm/kvm32.c b/target/arm/kvm32.c
239
index XXXXXXX..XXXXXXX 100644
240
--- a/target/arm/kvm32.c
241
+++ b/target/arm/kvm32.c
242
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
243
/* VFP registers */
244
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
245
for (i = 0; i < 32; i++) {
246
- r.addr = (uintptr_t)(&env->vfp.regs[i]);
247
+ r.addr = (uintptr_t)aa32_vfp_dreg(env, i);
248
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &r);
249
if (ret) {
250
return ret;
251
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
252
/* VFP registers */
253
r.id = KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP;
254
for (i = 0; i < 32; i++) {
255
- r.addr = (uintptr_t)(&env->vfp.regs[i]);
256
+ r.addr = (uintptr_t)aa32_vfp_dreg(env, i);
257
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &r);
258
if (ret) {
259
return ret;
260
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
261
index XXXXXXX..XXXXXXX 100644
262
--- a/target/arm/kvm64.c
263
+++ b/target/arm/kvm64.c
264
@@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level)
265
}
266
}
267
268
- /* Advanced SIMD and FP registers
269
- * We map Qn = regs[2n+1]:regs[2n]
270
- */
271
+ /* Advanced SIMD and FP registers. */
272
for (i = 0; i < 32; i++) {
273
- int rd = i << 1;
274
- uint64_t fp_val[2];
275
+ uint64_t *q = aa64_vfp_qreg(env, i);
276
#ifdef HOST_WORDS_BIGENDIAN
277
- fp_val[0] = env->vfp.regs[rd + 1];
278
- fp_val[1] = env->vfp.regs[rd];
279
+ uint64_t fp_val[2] = { q[1], q[0] };
280
+ reg.addr = (uintptr_t)fp_val;
281
#else
282
- fp_val[1] = env->vfp.regs[rd + 1];
283
- fp_val[0] = env->vfp.regs[rd];
284
+ reg.addr = (uintptr_t)q;
285
#endif
286
reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
287
- reg.addr = (uintptr_t)(&fp_val);
288
ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &reg);
289
if (ret) {
290
return ret;
291
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
292
env->spsr = env->banked_spsr[i];
293
}
294
295
- /* Advanced SIMD and FP registers
296
- * We map Qn = regs[2n+1]:regs[2n]
297
- */
298
+ /* Advanced SIMD and FP registers */
299
for (i = 0; i < 32; i++) {
300
- uint64_t fp_val[2];
301
+ uint64_t *q = aa64_vfp_qreg(env, i);
302
reg.id = AARCH64_SIMD_CORE_REG(fp_regs.vregs[i]);
303
- reg.addr = (uintptr_t)(&fp_val);
304
+ reg.addr = (uintptr_t)q;
305
ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &reg);
306
if (ret) {
307
return ret;
308
} else {
309
- int rd = i << 1;
310
#ifdef HOST_WORDS_BIGENDIAN
311
- env->vfp.regs[rd + 1] = fp_val[0];
312
- env->vfp.regs[rd] = fp_val[1];
313
-#else
314
- env->vfp.regs[rd + 1] = fp_val[1];
315
- env->vfp.regs[rd] = fp_val[0];
316
+ uint64_t t;
317
+ t = q[0], q[0] = q[1], q[1] = t;
318
#endif
319
}
320
}
321
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
322
index XXXXXXX..XXXXXXX 100644
323
--- a/target/arm/translate-a64.c
324
+++ b/target/arm/translate-a64.c
325
@@ -XXX,XX +XXX,XX @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
326
327
if (flags & CPU_DUMP_FPU) {
328
int numvfpregs = 32;
329
- for (i = 0; i < numvfpregs; i += 2) {
330
- uint64_t vlo = env->vfp.regs[i * 2];
331
- uint64_t vhi = env->vfp.regs[(i * 2) + 1];
332
- cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 " ",
333
- i, vhi, vlo);
334
- vlo = env->vfp.regs[(i + 1) * 2];
335
- vhi = env->vfp.regs[((i + 1) * 2) + 1];
336
- cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "\n",
337
- i + 1, vhi, vlo);
338
+ for (i = 0; i < numvfpregs; i++) {
339
+ uint64_t *q = aa64_vfp_qreg(env, i);
340
+ uint64_t vlo = q[0];
341
+ uint64_t vhi = q[1];
342
+ cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "%c",
343
+ i, vhi, vlo, (i & 1 ? '\n' : ' '));
344
}
345
cpu_fprintf(f, "FPCR: %08x FPSR: %08x\n",
346
vfp_get_fpcr(env), vfp_get_fpsr(env));
347
@@ -XXX,XX +XXX,XX @@ static TCGv_ptr vec_full_reg_ptr(DisasContext *s, int regno)
348
*/
349
static inline int fp_reg_offset(DisasContext *s, int regno, TCGMemOp size)
350
{
351
- int offs = offsetof(CPUARMState, vfp.regs[regno * 2]);
352
-#ifdef HOST_WORDS_BIGENDIAN
353
- offs += (8 - (1 << size));
354
-#endif
52
-#endif
355
- assert_fp_access_checked(s);
53
+ gdb_cpu_breakpoint_remove_all(cpu);
356
- return offs;
357
+ return vec_reg_offset(s, regno, 0, size);
358
}
359
360
/* Offset of the high half of the 128 bit vector Qn */
361
static inline int fp_reg_hi_offset(DisasContext *s, int regno)
362
{
363
- assert_fp_access_checked(s);
364
- return offsetof(CPUARMState, vfp.regs[regno * 2 + 1]);
365
+ return vec_reg_offset(s, regno, 1, MO_64);
366
}
367
368
/* Convenience accessors for reading and writing single and double
369
diff --git a/target/arm/translate.c b/target/arm/translate.c
370
index XXXXXXX..XXXXXXX 100644
371
--- a/target/arm/translate.c
372
+++ b/target/arm/translate.c
373
@@ -XXX,XX +XXX,XX @@ static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
374
static inline long
375
vfp_reg_offset (int dp, int reg)
376
{
377
- if (dp)
378
+ if (dp) {
379
return offsetof(CPUARMState, vfp.regs[reg]);
380
- else if (reg & 1) {
381
- return offsetof(CPUARMState, vfp.regs[reg >> 1])
382
- + offsetof(CPU_DoubleU, l.upper);
383
} else {
384
- return offsetof(CPUARMState, vfp.regs[reg >> 1])
385
- + offsetof(CPU_DoubleU, l.lower);
386
+ long ofs = offsetof(CPUARMState, vfp.regs[reg >> 1]);
387
+ if (reg & 1) {
388
+ ofs += offsetof(CPU_DoubleU, l.upper);
389
+ } else {
390
+ ofs += offsetof(CPU_DoubleU, l.lower);
391
+ }
392
+ return ofs;
393
}
54
}
394
}
55
}
395
56
396
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
57
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
397
numvfpregs += 16;
58
exit(0);
398
}
59
case 'D':
399
for (i = 0; i < numvfpregs; i++) {
60
/* Detach packet */
400
- uint64_t v = env->vfp.regs[i];
61
- gdb_breakpoint_remove_all();
401
+ uint64_t v = *aa32_vfp_dreg(env, i);
62
- gdb_syscall_mode = GDB_SYS_DISABLED;
402
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
63
- gdb_continue(s);
403
i * 2, (uint32_t)v,
64
+ pid = 1;
404
i * 2 + 1, (uint32_t)(v >> 32),
65
+
66
+ if (s->multiprocess) {
67
+ unsigned long lpid;
68
+ if (*p != ';') {
69
+ put_packet(s, "E22");
70
+ break;
71
+ }
72
+
73
+ if (qemu_strtoul(p + 1, &p, 16, &lpid)) {
74
+ put_packet(s, "E22");
75
+ break;
76
+ }
77
+
78
+ pid = lpid;
79
+ }
80
+
81
+ process = gdb_get_process(s, pid);
82
+ gdb_process_breakpoint_remove_all(s, process);
83
+ process->attached = false;
84
+
85
+ if (pid == gdb_get_cpu_pid(s, s->c_cpu)) {
86
+ s->c_cpu = gdb_first_attached_cpu(s);
87
+ }
88
+
89
+ if (pid == gdb_get_cpu_pid(s, s->g_cpu)) {
90
+ s->g_cpu = gdb_first_attached_cpu(s);
91
+ }
92
+
93
+ if (s->c_cpu == NULL) {
94
+ /* No more process attached */
95
+ gdb_syscall_mode = GDB_SYS_DISABLED;
96
+ gdb_continue(s);
97
+ }
98
put_packet(s, "OK");
99
break;
100
case 's':
405
--
101
--
406
2.7.4
102
2.19.2
407
103
408
104
diff view generated by jsdifflib
New patch
1
From: Luc Michel <luc.michel@greensocs.com>
1
2
3
Add support for the '!' extended mode packet. This is required for the
4
multiprocess extension.
5
6
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20181207090135.7651-12-luc.michel@greensocs.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
gdbstub.c | 3 +++
13
1 file changed, 3 insertions(+)
14
15
diff --git a/gdbstub.c b/gdbstub.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/gdbstub.c
18
+++ b/gdbstub.c
19
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
20
p = line_buf;
21
ch = *p++;
22
switch(ch) {
23
+ case '!':
24
+ put_packet(s, "OK");
25
+ break;
26
case '?':
27
/* TODO: Make this return the correct value for user-mode. */
28
snprintf(buf, sizeof(buf), "T%02xthread:%s;", GDB_SIGNAL_TRAP,
29
--
30
2.19.2
31
32
diff view generated by jsdifflib
New patch
1
From: Luc Michel <luc.michel@greensocs.com>
1
2
3
Add support for the vAttach packets. In multiprocess mode, GDB sends
4
them to attach to additional processes.
5
6
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20181207090135.7651-13-luc.michel@greensocs.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
gdbstub.c | 35 +++++++++++++++++++++++++++++++++++
14
1 file changed, 35 insertions(+)
15
16
diff --git a/gdbstub.c b/gdbstub.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/gdbstub.c
19
+++ b/gdbstub.c
20
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
21
goto unknown_command;
22
}
23
break;
24
+ } else if (strncmp(p, "Attach;", 7) == 0) {
25
+ unsigned long pid;
26
+
27
+ p += 7;
28
+
29
+ if (qemu_strtoul(p, &p, 16, &pid)) {
30
+ put_packet(s, "E22");
31
+ break;
32
+ }
33
+
34
+ process = gdb_get_process(s, pid);
35
+
36
+ if (process == NULL) {
37
+ put_packet(s, "E22");
38
+ break;
39
+ }
40
+
41
+ cpu = get_first_cpu_in_process(s, process);
42
+
43
+ if (cpu == NULL) {
44
+ /* Refuse to attach an empty process */
45
+ put_packet(s, "E22");
46
+ break;
47
+ }
48
+
49
+ process->attached = true;
50
+
51
+ s->g_cpu = cpu;
52
+ s->c_cpu = cpu;
53
+
54
+ snprintf(buf, sizeof(buf), "T%02xthread:%s;", GDB_SIGNAL_TRAP,
55
+ gdb_fmt_thread_id(s, cpu, thread_id, sizeof(thread_id)));
56
+
57
+ put_packet(s, buf);
58
+ break;
59
} else {
60
goto unknown_command;
61
}
62
--
63
2.19.2
64
65
diff view generated by jsdifflib
New patch
1
From: Luc Michel <luc.michel@greensocs.com>
1
2
3
When a new connection is established, we set the first process to be
4
attached, and the others detached. The first CPU of the first process
5
is selected as the current CPU.
6
7
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
11
Message-id: 20181207090135.7651-14-luc.michel@greensocs.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
gdbstub.c | 20 +++++++++++++++-----
15
1 file changed, 15 insertions(+), 5 deletions(-)
16
17
diff --git a/gdbstub.c b/gdbstub.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/gdbstub.c
20
+++ b/gdbstub.c
21
@@ -XXX,XX +XXX,XX @@ static bool gdb_accept(void)
22
}
23
24
s = g_malloc0(sizeof(GDBState));
25
- s->c_cpu = first_cpu;
26
- s->g_cpu = first_cpu;
27
create_default_process(s);
28
+ s->processes[0].attached = true;
29
+ s->c_cpu = gdb_first_attached_cpu(s);
30
+ s->g_cpu = s->c_cpu;
31
s->fd = fd;
32
gdb_has_xml = false;
33
34
@@ -XXX,XX +XXX,XX @@ static void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
35
36
static void gdb_chr_event(void *opaque, int event)
37
{
38
+ int i;
39
+ GDBState *s = (GDBState *) opaque;
40
+
41
switch (event) {
42
case CHR_EVENT_OPENED:
43
+ /* Start with first process attached, others detached */
44
+ for (i = 0; i < s->process_num; i++) {
45
+ s->processes[i].attached = !i;
46
+ }
47
+
48
+ s->c_cpu = gdb_first_attached_cpu(s);
49
+ s->g_cpu = s->c_cpu;
50
+
51
vm_stop(RUN_STATE_PAUSED);
52
gdb_has_xml = false;
53
break;
54
@@ -XXX,XX +XXX,XX @@ int gdbserver_start(const char *device)
55
memset(s, 0, sizeof(GDBState));
56
s->mon_chr = mon_chr;
57
}
58
- s->c_cpu = first_cpu;
59
- s->g_cpu = first_cpu;
60
61
create_processes(s);
62
63
if (chr) {
64
qemu_chr_fe_init(&s->chr, chr, &error_abort);
65
qemu_chr_fe_set_handlers(&s->chr, gdb_chr_can_receive, gdb_chr_receive,
66
- gdb_chr_event, NULL, NULL, NULL, true);
67
+ gdb_chr_event, NULL, s, NULL, true);
68
}
69
s->state = chr ? RS_IDLE : RS_INACTIVE;
70
s->mon_chr = mon_chr;
71
--
72
2.19.2
73
74
diff view generated by jsdifflib
New patch
1
From: Luc Michel <luc.michel@greensocs.com>
1
2
3
When gdb_set_stop_cpu() is called with a CPU associated to a process
4
currently not attached by the GDB client, return without modifying the
5
stop CPU. Otherwise, GDB gets confused if it receives packets with a
6
thread-id it does not know about.
7
8
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Message-id: 20181207090135.7651-15-luc.michel@greensocs.com
12
[PMM: fix checkpatch comment style nit]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
gdbstub.c | 10 ++++++++++
16
1 file changed, 10 insertions(+)
17
18
diff --git a/gdbstub.c b/gdbstub.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/gdbstub.c
21
+++ b/gdbstub.c
22
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
23
24
void gdb_set_stop_cpu(CPUState *cpu)
25
{
26
+ GDBProcess *p = gdb_get_cpu_process(gdbserver_state, cpu);
27
+
28
+ if (!p->attached) {
29
+ /*
30
+ * Having a stop CPU corresponding to a process that is not attached
31
+ * confuses GDB. So we ignore the request.
32
+ */
33
+ return;
34
+ }
35
+
36
gdbserver_state->c_cpu = cpu;
37
gdbserver_state->g_cpu = cpu;
38
}
39
--
40
2.19.2
41
42
diff view generated by jsdifflib
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
1
From: Luc Michel <luc.michel@greensocs.com>
2
2
3
When C_CTRL.CBPR is 1, the Non-Secure view of C_BPR is altered:
3
Add multiprocess extension support by enabling multiprocess mode when
4
- A Non-Secure read of C_BPR should return the BPR value plus 1,
4
the peer requests it, and by replying that we actually support it in the
5
saturated to 7,
5
qSupported reply packet.
6
- A Non-Secure write should be ignored.
7
6
8
Signed-off-by: Luc MICHEL <luc.michel@git.antfield.fr>
7
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20180119145756.7629-6-luc.michel@greensocs.com
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
[PMM: fixed comment typo]
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Message-id: 20181207090135.7651-16-luc.michel@greensocs.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
hw/intc/arm_gic.c | 16 +++++++++++++---
14
gdbstub.c | 6 ++++++
15
1 file changed, 13 insertions(+), 3 deletions(-)
15
1 file changed, 6 insertions(+)
16
16
17
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
17
diff --git a/gdbstub.c b/gdbstub.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/arm_gic.c
19
--- a/gdbstub.c
20
+++ b/hw/intc/arm_gic.c
20
+++ b/gdbstub.c
21
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
21
@@ -XXX,XX +XXX,XX @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
22
break;
22
if (cc->gdb_core_xml_file != NULL) {
23
case 0x08: /* Binary Point */
23
pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
24
if (s->security_extn && !attrs.secure) {
24
}
25
- /* BPR is banked. Non-secure copy stored in ABPR. */
25
+
26
- *data = s->abpr[cpu];
26
+ if (strstr(p, "multiprocess+")) {
27
+ if (s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) {
27
+ s->multiprocess = true;
28
+ /* NS view of BPR when CBPR is 1 */
29
+ *data = MIN(s->bpr[cpu] + 1, 7);
30
+ } else {
31
+ /* BPR is banked. Non-secure copy stored in ABPR. */
32
+ *data = s->abpr[cpu];
33
+ }
28
+ }
34
} else {
29
+ pstrcat(buf, sizeof(buf), ";multiprocess+");
35
*data = s->bpr[cpu];
30
+
36
}
31
put_packet(s, buf);
37
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
32
break;
38
break;
39
case 0x08: /* Binary Point */
40
if (s->security_extn && !attrs.secure) {
41
- s->abpr[cpu] = MAX(value & 0x7, GIC_MIN_ABPR);
42
+ if (s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) {
43
+ /* WI when CBPR is 1 */
44
+ return MEMTX_OK;
45
+ } else {
46
+ s->abpr[cpu] = MAX(value & 0x7, GIC_MIN_ABPR);
47
+ }
48
} else {
49
s->bpr[cpu] = MAX(value & 0x7, GIC_MIN_BPR);
50
}
33
}
51
--
34
--
52
2.7.4
35
2.19.2
53
36
54
37
diff view generated by jsdifflib
New patch
1
From: Luc Michel <luc.michel@greensocs.com>
1
2
3
Create two separate CPU clusters for APUs and RPUs.
4
5
Signed-off-by: Luc Michel <luc.michel@greensocs.com>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20181207090135.7651-17-luc.michel@greensocs.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
include/hw/arm/xlnx-zynqmp.h | 3 +++
13
hw/arm/xlnx-zynqmp.c | 23 +++++++++++++++++++----
14
2 files changed, 22 insertions(+), 4 deletions(-)
15
16
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/xlnx-zynqmp.h
19
+++ b/include/hw/arm/xlnx-zynqmp.h
20
@@ -XXX,XX +XXX,XX @@
21
#include "hw/display/xlnx_dp.h"
22
#include "hw/intc/xlnx-zynqmp-ipi.h"
23
#include "hw/timer/xlnx-zynqmp-rtc.h"
24
+#include "hw/cpu/cluster.h"
25
26
#define TYPE_XLNX_ZYNQMP "xlnx,zynqmp"
27
#define XLNX_ZYNQMP(obj) OBJECT_CHECK(XlnxZynqMPState, (obj), \
28
@@ -XXX,XX +XXX,XX @@ typedef struct XlnxZynqMPState {
29
DeviceState parent_obj;
30
31
/*< public >*/
32
+ CPUClusterState apu_cluster;
33
+ CPUClusterState rpu_cluster;
34
ARMCPU apu_cpu[XLNX_ZYNQMP_NUM_APU_CPUS];
35
ARMCPU rpu_cpu[XLNX_ZYNQMP_NUM_RPU_CPUS];
36
GICState gic;
37
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/arm/xlnx-zynqmp.c
40
+++ b/hw/arm/xlnx-zynqmp.c
41
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_create_rpu(XlnxZynqMPState *s, const char *boot_cpu,
42
int i;
43
int num_rpus = MIN(smp_cpus - XLNX_ZYNQMP_NUM_APU_CPUS, XLNX_ZYNQMP_NUM_RPU_CPUS);
44
45
+ object_initialize_child(OBJECT(s), "rpu-cluster", &s->rpu_cluster,
46
+ sizeof(s->rpu_cluster), TYPE_CPU_CLUSTER,
47
+ &error_abort, NULL);
48
+ qdev_prop_set_uint32(DEVICE(&s->rpu_cluster), "cluster-id", 1);
49
+
50
+ qdev_init_nofail(DEVICE(&s->rpu_cluster));
51
+
52
for (i = 0; i < num_rpus; i++) {
53
char *name;
54
55
object_initialize(&s->rpu_cpu[i], sizeof(s->rpu_cpu[i]),
56
"cortex-r5f-" TYPE_ARM_CPU);
57
- object_property_add_child(OBJECT(s), "rpu-cpu[*]",
58
+ object_property_add_child(OBJECT(&s->rpu_cluster), "rpu-cpu[*]",
59
OBJECT(&s->rpu_cpu[i]), &error_abort);
60
61
name = object_get_canonical_path_component(OBJECT(&s->rpu_cpu[i]));
62
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_init(Object *obj)
63
int i;
64
int num_apus = MIN(smp_cpus, XLNX_ZYNQMP_NUM_APU_CPUS);
65
66
+ object_initialize_child(obj, "apu-cluster", &s->apu_cluster,
67
+ sizeof(s->apu_cluster), TYPE_CPU_CLUSTER,
68
+ &error_abort, NULL);
69
+ qdev_prop_set_uint32(DEVICE(&s->apu_cluster), "cluster-id", 0);
70
+
71
for (i = 0; i < num_apus; i++) {
72
- object_initialize_child(obj, "apu-cpu[*]", &s->apu_cpu[i],
73
- sizeof(s->apu_cpu[i]),
74
- "cortex-a53-" TYPE_ARM_CPU, &error_abort, NULL);
75
+ object_initialize_child(OBJECT(&s->apu_cluster), "apu-cpu[*]",
76
+ &s->apu_cpu[i], sizeof(s->apu_cpu[i]),
77
+ "cortex-a53-" TYPE_ARM_CPU, &error_abort,
78
+ NULL);
79
}
80
81
sysbus_init_child_obj(obj, "gic", &s->gic, sizeof(s->gic),
82
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
83
qdev_prop_set_bit(DEVICE(&s->gic),
84
"has-virtualization-extensions", s->virt);
85
86
+ qdev_init_nofail(DEVICE(&s->apu_cluster));
87
+
88
/* Realize APUs before realizing the GIC. KVM requires this. */
89
for (i = 0; i < num_apus; i++) {
90
char *name;
91
--
92
2.19.2
93
94
diff view generated by jsdifflib
New patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
2
3
This reverts commit 01fd41ab3fb69971c24a69ed49cde96086d81278.
4
5
The generic loader device (-device loader,file=kernel.bin) can be used
6
to load a kernel instead of the -kernel option. Some boards have flash
7
memory (pflash) that is set via the -pflash or -drive options.
8
9
Allow starting QEMU without the -kernel option to accommodate these
10
scenarios.
11
12
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Message-id: 20190103144124.18917-1-stefanha@redhat.com
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
hw/arm/armv7m.c | 5 -----
19
1 file changed, 5 deletions(-)
20
21
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/armv7m.c
24
+++ b/hw/arm/armv7m.c
25
@@ -XXX,XX +XXX,XX @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
26
big_endian = 0;
27
#endif
28
29
- if (!kernel_filename && !qtest_enabled()) {
30
- error_report("Guest image must be specified (using -kernel)");
31
- exit(1);
32
- }
33
-
34
if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
35
asidx = ARMASIdx_S;
36
} else {
37
--
38
2.19.2
39
40
diff view generated by jsdifflib
New patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
2
3
Plug a couple of "board creation time" memory leaks.
4
5
Fixes: 6f16da53ffe4567 ("hw/arm: versal: Add a virtual Xilinx Versal board")
6
Reported-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190104104749.5314-2-edgar.iglesias@gmail.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/xlnx-versal-virt.c | 2 ++
14
1 file changed, 2 insertions(+)
15
16
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/xlnx-versal-virt.c
19
+++ b/hw/arm/xlnx-versal-virt.c
20
@@ -XXX,XX +XXX,XX @@ static void fdt_add_gic_nodes(VersalVirt *s)
21
2, MM_GIC_APU_REDIST_0_SIZE);
22
qemu_fdt_setprop_cell(s->fdt, nodename, "#interrupt-cells", 3);
23
qemu_fdt_setprop_string(s->fdt, nodename, "compatible", "arm,gic-v3");
24
+ g_free(nodename);
25
}
26
27
static void fdt_add_timer_nodes(VersalVirt *s)
28
@@ -XXX,XX +XXX,XX @@ static void create_virtio_regions(VersalVirt *s)
29
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic_irq);
30
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
31
memory_region_add_subregion(&s->soc.mr_ps, base, mr);
32
+ g_free(name);
33
}
34
35
for (i = 0; i < NUM_VIRTIO_TRANSPORT; i++) {
36
--
37
2.19.2
38
39
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Rather than passing regnos to the helpers, pass pointers to the
3
Some of the files in hw/input/, hw/misc/ and hw/timer/ are only
4
vector registers directly. This eliminates the need to pass in
4
used by one of the ARM machines, so we can assign these files to
5
the environment pointer and reduces the number of places that
5
the corresponding boards.
6
directly access env->vfp.regs[].
7
6
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Thomas Huth <thuth@redhat.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 1546433583-18397-1-git-send-email-thuth@redhat.com
11
Message-id: 20180119045438.28582-4-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
target/arm/helper.h | 20 +++---
12
MAINTAINERS | 16 ++++++++++++++--
15
target/arm/neon_helper.c | 162 +++++++++++++++++++++++++----------------------
13
1 file changed, 14 insertions(+), 2 deletions(-)
16
target/arm/translate.c | 42 ++++++------
17
3 files changed, 120 insertions(+), 104 deletions(-)
18
14
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
15
diff --git a/MAINTAINERS b/MAINTAINERS
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.h
17
--- a/MAINTAINERS
22
+++ b/target/arm/helper.h
18
+++ b/MAINTAINERS
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(iwmmxt_muladdsl, i64, i64, i32, i32)
19
@@ -XXX,XX +XXX,XX @@ F: hw/intc/arm*
24
DEF_HELPER_3(iwmmxt_muladdsw, i64, i64, i32, i32)
20
F: hw/intc/gic_internal.h
25
DEF_HELPER_3(iwmmxt_muladdswl, i64, i64, i32, i32)
21
F: hw/misc/a9scu.c
26
22
F: hw/misc/arm11scu.c
27
-DEF_HELPER_3(neon_unzip8, void, env, i32, i32)
23
+F: hw/misc/arm_l2x0.c
28
-DEF_HELPER_3(neon_unzip16, void, env, i32, i32)
24
F: hw/timer/a9gtimer*
29
-DEF_HELPER_3(neon_qunzip8, void, env, i32, i32)
25
F: hw/timer/arm*
30
-DEF_HELPER_3(neon_qunzip16, void, env, i32, i32)
26
F: include/hw/arm/arm*.h
31
-DEF_HELPER_3(neon_qunzip32, void, env, i32, i32)
27
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
32
-DEF_HELPER_3(neon_zip8, void, env, i32, i32)
28
S: Maintained
33
-DEF_HELPER_3(neon_zip16, void, env, i32, i32)
29
F: hw/arm/integratorcp.c
34
-DEF_HELPER_3(neon_qzip8, void, env, i32, i32)
30
F: hw/misc/arm_integrator_debug.c
35
-DEF_HELPER_3(neon_qzip16, void, env, i32, i32)
31
+F: include/hw/misc/arm_integrator_debug.h
36
-DEF_HELPER_3(neon_qzip32, void, env, i32, i32)
32
37
+DEF_HELPER_FLAGS_2(neon_unzip8, TCG_CALL_NO_RWG, void, ptr, ptr)
33
MCIMX6UL EVK / i.MX6ul
38
+DEF_HELPER_FLAGS_2(neon_unzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
34
M: Peter Maydell <peter.maydell@linaro.org>
39
+DEF_HELPER_FLAGS_2(neon_qunzip8, TCG_CALL_NO_RWG, void, ptr, ptr)
35
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
40
+DEF_HELPER_FLAGS_2(neon_qunzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
36
S: Odd Fixes
41
+DEF_HELPER_FLAGS_2(neon_qunzip32, TCG_CALL_NO_RWG, void, ptr, ptr)
37
F: hw/arm/mcimx7d-sabre.c
42
+DEF_HELPER_FLAGS_2(neon_zip8, TCG_CALL_NO_RWG, void, ptr, ptr)
38
F: hw/arm/fsl-imx7.c
43
+DEF_HELPER_FLAGS_2(neon_zip16, TCG_CALL_NO_RWG, void, ptr, ptr)
39
+F: hw/misc/imx7_*.c
44
+DEF_HELPER_FLAGS_2(neon_qzip8, TCG_CALL_NO_RWG, void, ptr, ptr)
40
F: include/hw/arm/fsl-imx7.h
45
+DEF_HELPER_FLAGS_2(neon_qzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
41
+F: include/hw/misc/imx7_*.h
46
+DEF_HELPER_FLAGS_2(neon_qzip32, TCG_CALL_NO_RWG, void, ptr, ptr)
42
F: hw/pci-host/designware.c
47
43
F: include/hw/pci-host/designware.h
48
DEF_HELPER_FLAGS_3(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
44
49
DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
45
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
50
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
46
L: qemu-arm@nongnu.org
51
index XXXXXXX..XXXXXXX 100644
47
S: Odd Fixes
52
--- a/target/arm/neon_helper.c
48
F: hw/arm/nseries.c
53
+++ b/target/arm/neon_helper.c
49
+F: hw/input/lm832x.c
54
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_acgt_f64)(uint64_t a, uint64_t b, void *fpstp)
50
+F: hw/input/tsc2005.c
55
51
+F: hw/misc/cbus.c
56
#define ELEM(V, N, SIZE) (((V) >> ((N) * (SIZE))) & ((1ull << (SIZE)) - 1))
52
+F: hw/timer/twl92230.c
57
53
58
-void HELPER(neon_qunzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
54
Palm
59
+void HELPER(neon_qunzip8)(void *vd, void *vm)
55
M: Andrzej Zaborowski <balrogg@gmail.com>
60
{
56
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
61
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
57
L: qemu-arm@nongnu.org
62
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
58
S: Odd Fixes
63
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
59
F: hw/arm/palm.c
64
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
60
+F: hw/input/tsc210x.c
65
+ uint64_t *rd = vd, *rm = vm;
61
66
+ uint64_t zd0 = rd[0], zd1 = rd[1];
62
Raspberry Pi
67
+ uint64_t zm0 = rm[0], zm1 = rm[1];
63
M: Peter Maydell <peter.maydell@linaro.org>
68
+
64
@@ -XXX,XX +XXX,XX @@ F: hw/display/tc6393xb.c
69
uint64_t d0 = ELEM(zd0, 0, 8) | (ELEM(zd0, 2, 8) << 8)
65
F: hw/gpio/max7310.c
70
| (ELEM(zd0, 4, 8) << 16) | (ELEM(zd0, 6, 8) << 24)
66
F: hw/gpio/zaurus.c
71
| (ELEM(zd1, 0, 8) << 32) | (ELEM(zd1, 2, 8) << 40)
67
F: hw/misc/mst_fpga.c
72
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_qunzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
68
+F: hw/misc/max111x.c
73
| (ELEM(zm0, 5, 8) << 16) | (ELEM(zm0, 7, 8) << 24)
69
F: include/hw/arm/pxa.h
74
| (ELEM(zm1, 1, 8) << 32) | (ELEM(zm1, 3, 8) << 40)
70
F: include/hw/arm/sharpsl.h
75
| (ELEM(zm1, 5, 8) << 48) | (ELEM(zm1, 7, 8) << 56);
71
76
- env->vfp.regs[rm] = make_float64(m0);
72
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
77
- env->vfp.regs[rm + 1] = make_float64(m1);
73
S: Odd Fixes
78
- env->vfp.regs[rd] = make_float64(d0);
74
F: hw/arm/sabrelite.c
79
- env->vfp.regs[rd + 1] = make_float64(d1);
75
F: hw/arm/fsl-imx6.c
80
+
76
-F: hw/misc/imx6_src.c
81
+ rm[0] = m0;
77
+F: hw/misc/imx6_*.c
82
+ rm[1] = m1;
78
F: hw/ssi/imx_spi.c
83
+ rd[0] = d0;
79
F: include/hw/arm/fsl-imx6.h
84
+ rd[1] = d1;
80
-F: include/hw/misc/imx6_src.h
85
}
81
+F: include/hw/misc/imx6_*.h
86
82
F: include/hw/ssi/imx_spi.h
87
-void HELPER(neon_qunzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
83
88
+void HELPER(neon_qunzip16)(void *vd, void *vm)
84
Sharp SL-5500 (Collie) PDA
89
{
85
@@ -XXX,XX +XXX,XX @@ R: Joel Stanley <joel@jms.id.au>
90
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
86
L: qemu-arm@nongnu.org
91
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
87
S: Maintained
92
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
88
F: hw/*/*aspeed*
93
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
89
+F: hw/misc/pca9552.c
94
+ uint64_t *rd = vd, *rm = vm;
90
F: include/hw/*/*aspeed*
95
+ uint64_t zd0 = rd[0], zd1 = rd[1];
91
+F: include/hw/misc/pca9552*.h
96
+ uint64_t zm0 = rm[0], zm1 = rm[1];
92
F: hw/net/ftgmac100.c
97
+
93
F: include/hw/net/ftgmac100.h
98
uint64_t d0 = ELEM(zd0, 0, 16) | (ELEM(zd0, 2, 16) << 16)
99
| (ELEM(zd1, 0, 16) << 32) | (ELEM(zd1, 2, 16) << 48);
100
uint64_t d1 = ELEM(zm0, 0, 16) | (ELEM(zm0, 2, 16) << 16)
101
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_qunzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
102
| (ELEM(zd1, 1, 16) << 32) | (ELEM(zd1, 3, 16) << 48);
103
uint64_t m1 = ELEM(zm0, 1, 16) | (ELEM(zm0, 3, 16) << 16)
104
| (ELEM(zm1, 1, 16) << 32) | (ELEM(zm1, 3, 16) << 48);
105
- env->vfp.regs[rm] = make_float64(m0);
106
- env->vfp.regs[rm + 1] = make_float64(m1);
107
- env->vfp.regs[rd] = make_float64(d0);
108
- env->vfp.regs[rd + 1] = make_float64(d1);
109
+
110
+ rm[0] = m0;
111
+ rm[1] = m1;
112
+ rd[0] = d0;
113
+ rd[1] = d1;
114
}
115
116
-void HELPER(neon_qunzip32)(CPUARMState *env, uint32_t rd, uint32_t rm)
117
+void HELPER(neon_qunzip32)(void *vd, void *vm)
118
{
119
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
120
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
121
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
122
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
123
+ uint64_t *rd = vd, *rm = vm;
124
+ uint64_t zd0 = rd[0], zd1 = rd[1];
125
+ uint64_t zm0 = rm[0], zm1 = rm[1];
126
+
127
uint64_t d0 = ELEM(zd0, 0, 32) | (ELEM(zd1, 0, 32) << 32);
128
uint64_t d1 = ELEM(zm0, 0, 32) | (ELEM(zm1, 0, 32) << 32);
129
uint64_t m0 = ELEM(zd0, 1, 32) | (ELEM(zd1, 1, 32) << 32);
130
uint64_t m1 = ELEM(zm0, 1, 32) | (ELEM(zm1, 1, 32) << 32);
131
- env->vfp.regs[rm] = make_float64(m0);
132
- env->vfp.regs[rm + 1] = make_float64(m1);
133
- env->vfp.regs[rd] = make_float64(d0);
134
- env->vfp.regs[rd + 1] = make_float64(d1);
135
+
136
+ rm[0] = m0;
137
+ rm[1] = m1;
138
+ rd[0] = d0;
139
+ rd[1] = d1;
140
}
141
142
-void HELPER(neon_unzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
143
+void HELPER(neon_unzip8)(void *vd, void *vm)
144
{
145
- uint64_t zm = float64_val(env->vfp.regs[rm]);
146
- uint64_t zd = float64_val(env->vfp.regs[rd]);
147
+ uint64_t *rd = vd, *rm = vm;
148
+ uint64_t zd = rd[0], zm = rm[0];
149
+
150
uint64_t d0 = ELEM(zd, 0, 8) | (ELEM(zd, 2, 8) << 8)
151
| (ELEM(zd, 4, 8) << 16) | (ELEM(zd, 6, 8) << 24)
152
| (ELEM(zm, 0, 8) << 32) | (ELEM(zm, 2, 8) << 40)
153
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_unzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
154
| (ELEM(zd, 5, 8) << 16) | (ELEM(zd, 7, 8) << 24)
155
| (ELEM(zm, 1, 8) << 32) | (ELEM(zm, 3, 8) << 40)
156
| (ELEM(zm, 5, 8) << 48) | (ELEM(zm, 7, 8) << 56);
157
- env->vfp.regs[rm] = make_float64(m0);
158
- env->vfp.regs[rd] = make_float64(d0);
159
+
160
+ rm[0] = m0;
161
+ rd[0] = d0;
162
}
163
164
-void HELPER(neon_unzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
165
+void HELPER(neon_unzip16)(void *vd, void *vm)
166
{
167
- uint64_t zm = float64_val(env->vfp.regs[rm]);
168
- uint64_t zd = float64_val(env->vfp.regs[rd]);
169
+ uint64_t *rd = vd, *rm = vm;
170
+ uint64_t zd = rd[0], zm = rm[0];
171
+
172
uint64_t d0 = ELEM(zd, 0, 16) | (ELEM(zd, 2, 16) << 16)
173
| (ELEM(zm, 0, 16) << 32) | (ELEM(zm, 2, 16) << 48);
174
uint64_t m0 = ELEM(zd, 1, 16) | (ELEM(zd, 3, 16) << 16)
175
| (ELEM(zm, 1, 16) << 32) | (ELEM(zm, 3, 16) << 48);
176
- env->vfp.regs[rm] = make_float64(m0);
177
- env->vfp.regs[rd] = make_float64(d0);
178
+
179
+ rm[0] = m0;
180
+ rd[0] = d0;
181
}
182
183
-void HELPER(neon_qzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
184
+void HELPER(neon_qzip8)(void *vd, void *vm)
185
{
186
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
187
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
188
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
189
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
190
+ uint64_t *rd = vd, *rm = vm;
191
+ uint64_t zd0 = rd[0], zd1 = rd[1];
192
+ uint64_t zm0 = rm[0], zm1 = rm[1];
193
+
194
uint64_t d0 = ELEM(zd0, 0, 8) | (ELEM(zm0, 0, 8) << 8)
195
| (ELEM(zd0, 1, 8) << 16) | (ELEM(zm0, 1, 8) << 24)
196
| (ELEM(zd0, 2, 8) << 32) | (ELEM(zm0, 2, 8) << 40)
197
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_qzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
198
| (ELEM(zd1, 5, 8) << 16) | (ELEM(zm1, 5, 8) << 24)
199
| (ELEM(zd1, 6, 8) << 32) | (ELEM(zm1, 6, 8) << 40)
200
| (ELEM(zd1, 7, 8) << 48) | (ELEM(zm1, 7, 8) << 56);
201
- env->vfp.regs[rm] = make_float64(m0);
202
- env->vfp.regs[rm + 1] = make_float64(m1);
203
- env->vfp.regs[rd] = make_float64(d0);
204
- env->vfp.regs[rd + 1] = make_float64(d1);
205
+
206
+ rm[0] = m0;
207
+ rm[1] = m1;
208
+ rd[0] = d0;
209
+ rd[1] = d1;
210
}
211
212
-void HELPER(neon_qzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
213
+void HELPER(neon_qzip16)(void *vd, void *vm)
214
{
215
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
216
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
217
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
218
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
219
+ uint64_t *rd = vd, *rm = vm;
220
+ uint64_t zd0 = rd[0], zd1 = rd[1];
221
+ uint64_t zm0 = rm[0], zm1 = rm[1];
222
+
223
uint64_t d0 = ELEM(zd0, 0, 16) | (ELEM(zm0, 0, 16) << 16)
224
| (ELEM(zd0, 1, 16) << 32) | (ELEM(zm0, 1, 16) << 48);
225
uint64_t d1 = ELEM(zd0, 2, 16) | (ELEM(zm0, 2, 16) << 16)
226
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_qzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
227
| (ELEM(zd1, 1, 16) << 32) | (ELEM(zm1, 1, 16) << 48);
228
uint64_t m1 = ELEM(zd1, 2, 16) | (ELEM(zm1, 2, 16) << 16)
229
| (ELEM(zd1, 3, 16) << 32) | (ELEM(zm1, 3, 16) << 48);
230
- env->vfp.regs[rm] = make_float64(m0);
231
- env->vfp.regs[rm + 1] = make_float64(m1);
232
- env->vfp.regs[rd] = make_float64(d0);
233
- env->vfp.regs[rd + 1] = make_float64(d1);
234
+
235
+ rm[0] = m0;
236
+ rm[1] = m1;
237
+ rd[0] = d0;
238
+ rd[1] = d1;
239
}
240
241
-void HELPER(neon_qzip32)(CPUARMState *env, uint32_t rd, uint32_t rm)
242
+void HELPER(neon_qzip32)(void *vd, void *vm)
243
{
244
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
245
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
246
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
247
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
248
+ uint64_t *rd = vd, *rm = vm;
249
+ uint64_t zd0 = rd[0], zd1 = rd[1];
250
+ uint64_t zm0 = rm[0], zm1 = rm[1];
251
+
252
uint64_t d0 = ELEM(zd0, 0, 32) | (ELEM(zm0, 0, 32) << 32);
253
uint64_t d1 = ELEM(zd0, 1, 32) | (ELEM(zm0, 1, 32) << 32);
254
uint64_t m0 = ELEM(zd1, 0, 32) | (ELEM(zm1, 0, 32) << 32);
255
uint64_t m1 = ELEM(zd1, 1, 32) | (ELEM(zm1, 1, 32) << 32);
256
- env->vfp.regs[rm] = make_float64(m0);
257
- env->vfp.regs[rm + 1] = make_float64(m1);
258
- env->vfp.regs[rd] = make_float64(d0);
259
- env->vfp.regs[rd + 1] = make_float64(d1);
260
+
261
+ rm[0] = m0;
262
+ rm[1] = m1;
263
+ rd[0] = d0;
264
+ rd[1] = d1;
265
}
266
267
-void HELPER(neon_zip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
268
+void HELPER(neon_zip8)(void *vd, void *vm)
269
{
270
- uint64_t zm = float64_val(env->vfp.regs[rm]);
271
- uint64_t zd = float64_val(env->vfp.regs[rd]);
272
+ uint64_t *rd = vd, *rm = vm;
273
+ uint64_t zd = rd[0], zm = rm[0];
274
+
275
uint64_t d0 = ELEM(zd, 0, 8) | (ELEM(zm, 0, 8) << 8)
276
| (ELEM(zd, 1, 8) << 16) | (ELEM(zm, 1, 8) << 24)
277
| (ELEM(zd, 2, 8) << 32) | (ELEM(zm, 2, 8) << 40)
278
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_zip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
279
| (ELEM(zd, 5, 8) << 16) | (ELEM(zm, 5, 8) << 24)
280
| (ELEM(zd, 6, 8) << 32) | (ELEM(zm, 6, 8) << 40)
281
| (ELEM(zd, 7, 8) << 48) | (ELEM(zm, 7, 8) << 56);
282
- env->vfp.regs[rm] = make_float64(m0);
283
- env->vfp.regs[rd] = make_float64(d0);
284
+
285
+ rm[0] = m0;
286
+ rd[0] = d0;
287
}
288
289
-void HELPER(neon_zip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
290
+void HELPER(neon_zip16)(void *vd, void *vm)
291
{
292
- uint64_t zm = float64_val(env->vfp.regs[rm]);
293
- uint64_t zd = float64_val(env->vfp.regs[rd]);
294
+ uint64_t *rd = vd, *rm = vm;
295
+ uint64_t zd = rd[0], zm = rm[0];
296
+
297
uint64_t d0 = ELEM(zd, 0, 16) | (ELEM(zm, 0, 16) << 16)
298
| (ELEM(zd, 1, 16) << 32) | (ELEM(zm, 1, 16) << 48);
299
uint64_t m0 = ELEM(zd, 2, 16) | (ELEM(zm, 2, 16) << 16)
300
| (ELEM(zd, 3, 16) << 32) | (ELEM(zm, 3, 16) << 48);
301
- env->vfp.regs[rm] = make_float64(m0);
302
- env->vfp.regs[rd] = make_float64(d0);
303
+
304
+ rm[0] = m0;
305
+ rd[0] = d0;
306
}
307
308
/* Helper function for 64 bit polynomial multiply case:
309
diff --git a/target/arm/translate.c b/target/arm/translate.c
310
index XXXXXXX..XXXXXXX 100644
311
--- a/target/arm/translate.c
312
+++ b/target/arm/translate.c
313
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 neon_get_scalar(int size, int reg)
314
315
static int gen_neon_unzip(int rd, int rm, int size, int q)
316
{
317
- TCGv_i32 tmp, tmp2;
318
+ TCGv_ptr pd, pm;
319
+
320
if (!q && size == 2) {
321
return 1;
322
}
323
- tmp = tcg_const_i32(rd);
324
- tmp2 = tcg_const_i32(rm);
325
+ pd = vfp_reg_ptr(true, rd);
326
+ pm = vfp_reg_ptr(true, rm);
327
if (q) {
328
switch (size) {
329
case 0:
330
- gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
331
+ gen_helper_neon_qunzip8(pd, pm);
332
break;
333
case 1:
334
- gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
335
+ gen_helper_neon_qunzip16(pd, pm);
336
break;
337
case 2:
338
- gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
339
+ gen_helper_neon_qunzip32(pd, pm);
340
break;
341
default:
342
abort();
343
@@ -XXX,XX +XXX,XX @@ static int gen_neon_unzip(int rd, int rm, int size, int q)
344
} else {
345
switch (size) {
346
case 0:
347
- gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
348
+ gen_helper_neon_unzip8(pd, pm);
349
break;
350
case 1:
351
- gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
352
+ gen_helper_neon_unzip16(pd, pm);
353
break;
354
default:
355
abort();
356
}
357
}
358
- tcg_temp_free_i32(tmp);
359
- tcg_temp_free_i32(tmp2);
360
+ tcg_temp_free_ptr(pd);
361
+ tcg_temp_free_ptr(pm);
362
return 0;
363
}
364
365
static int gen_neon_zip(int rd, int rm, int size, int q)
366
{
367
- TCGv_i32 tmp, tmp2;
368
+ TCGv_ptr pd, pm;
369
+
370
if (!q && size == 2) {
371
return 1;
372
}
373
- tmp = tcg_const_i32(rd);
374
- tmp2 = tcg_const_i32(rm);
375
+ pd = vfp_reg_ptr(true, rd);
376
+ pm = vfp_reg_ptr(true, rm);
377
if (q) {
378
switch (size) {
379
case 0:
380
- gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
381
+ gen_helper_neon_qzip8(pd, pm);
382
break;
383
case 1:
384
- gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
385
+ gen_helper_neon_qzip16(pd, pm);
386
break;
387
case 2:
388
- gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
389
+ gen_helper_neon_qzip32(pd, pm);
390
break;
391
default:
392
abort();
393
@@ -XXX,XX +XXX,XX @@ static int gen_neon_zip(int rd, int rm, int size, int q)
394
} else {
395
switch (size) {
396
case 0:
397
- gen_helper_neon_zip8(cpu_env, tmp, tmp2);
398
+ gen_helper_neon_zip8(pd, pm);
399
break;
400
case 1:
401
- gen_helper_neon_zip16(cpu_env, tmp, tmp2);
402
+ gen_helper_neon_zip16(pd, pm);
403
break;
404
default:
405
abort();
406
}
407
}
408
- tcg_temp_free_i32(tmp);
409
- tcg_temp_free_i32(tmp2);
410
+ tcg_temp_free_ptr(pd);
411
+ tcg_temp_free_ptr(pm);
412
return 0;
413
}
414
94
415
--
95
--
416
2.7.4
96
2.19.2
417
97
418
98
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
We use cpu_stop_current() to ensure the current CPU has stopped
2
from places like qemu_system_reset_request(). Unfortunately its
3
current implementation has a race. It calls qemu_cpu_stop(),
4
which sets cpu->stopped to true even though the CPU hasn't
5
actually stopped yet. The main thread will look at the flags
6
set by qemu_system_reset_request() and call pause_all_vcpus().
7
pause_all_vcpus() waits for every cpu to have cpu->stopped true,
8
so it can continue (and we will start the system reset operation)
9
before the vcpu thread has got back to its top level loop.
2
10
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Instead, just set cpu->stop and call cpu_exit(). This will
4
Message-id: 20180119045438.28582-16-richard.henderson@linaro.org
12
cause the vcpu to exit back to the top level loop, and there
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
(as part of the wait_io_event code) it will call qemu_cpu_stop().
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
14
15
This fixes bugs where the reset request appeared to be ignored
16
or the CPU misbehaved because the reset operation started
17
to change vcpu state while the vcpu thread was still using it.
18
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Emilio G. Cota <cota@braap.org>
21
Tested-by: Jaap Crezee <jaap@jcz.nl>
22
Message-id: 20181207155911.12710-1-peter.maydell@linaro.org
8
---
23
---
9
target/arm/helper.c | 3 ++-
24
cpus.c | 3 ++-
10
1 file changed, 2 insertions(+), 1 deletion(-)
25
1 file changed, 2 insertions(+), 1 deletion(-)
11
26
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
27
diff --git a/cpus.c b/cpus.c
13
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
29
--- a/cpus.c
15
+++ b/target/arm/helper.c
30
+++ b/cpus.c
16
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
31
@@ -XXX,XX +XXX,XX @@ void qemu_init_vcpu(CPUState *cpu)
17
*/
32
void cpu_stop_current(void)
18
static inline int fp_exception_el(CPUARMState *env)
19
{
33
{
20
+#ifndef CONFIG_USER_ONLY
34
if (current_cpu) {
21
int fpen;
35
- qemu_cpu_stop(current_cpu, true);
22
int cur_el = arm_current_el(env);
36
+ current_cpu->stop = true;
23
37
+ cpu_exit(current_cpu);
24
@@ -XXX,XX +XXX,XX @@ static inline int fp_exception_el(CPUARMState *env)
25
/* Trap all FP ops to EL3 */
26
return 3;
27
}
38
}
28
-
29
+#endif
30
return 0;
31
}
39
}
32
40
33
--
41
--
34
2.7.4
42
2.19.2
35
43
36
44
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
2
3
missed in 60765b6ceeb4.
3
From the "A10 User Manual V1.20" p.29: "3.2. Memory Mapping" and:
4
4
5
Thread 1 "qemu-system-aarch64" received signal SIGSEGV, Segmentation fault.
5
7. System Control
6
address_space_init (as=0x0, root=0x55555726e410, name=name@entry=0x555555e3f0a7 "sdhci-dma") at memory.c:3050
6
7.1. Overview
7
3050     as->root = root;
8
(gdb) bt
9
#0 address_space_init (as=0x0, root=0x55555726e410, name=name@entry=0x555555e3f0a7 "sdhci-dma") at memory.c:3050
10
#1 0x0000555555af62c3 in sdhci_sysbus_realize (dev=<optimized out>, errp=0x7fff7f931150) at hw/sd/sdhci.c:1564
11
#2 0x00005555558b25e5 in zynqmp_sdhci_realize (dev=0x555557051520, errp=0x7fff7f931150) at hw/sd/zynqmp-sdhci.c:151
12
#3 0x0000555555a2e7f3 in device_set_realized (obj=0x555557051520, value=<optimized out>, errp=0x7fff7f931270) at hw/core/qdev.c:966
13
#4 0x0000555555ba3f74 in property_set_bool (obj=0x555557051520, v=<optimized out>, name=<optimized out>, opaque=0x555556e04a20,
14
errp=0x7fff7f931270) at qom/object.c:1906
15
#5 0x0000555555ba51f4 in object_property_set (obj=obj@entry=0x555557051520, v=v@entry=0x5555576dbd60,
16
name=name@entry=0x555555dd6306 "realized", errp=errp@entry=0x7fff7f931270) at qom/object.c:1102
17
7
18
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
8
A10 embeds a high-speed SRAM which has been split into five segments.
9
See detailed memory mapping in following table:
10
11
Area Address Size (Bytes)
12
A1 0x00000000-0x00003FFF 16K
13
A2 0x00004000-0x00007FFF 16K
14
A3 0x00008000-0x0000B3FF 13K
15
A4 0x0000B400-0x0000BFFF 3K
16
17
Since for emulation purpose we don't need the segmentations, we simply define
18
the 'A' area as a single 48KB SRAM.
19
20
We don't implement the following others areas:
21
- 'B': 'Secure RAM' (64K),
22
- 'C': Debug/ISP SRAM
23
- 'D': USB SRAM
24
25
(qemu) info mtree
26
address-space: memory
27
0000000000000000-ffffffffffffffff (prio 0, i/o): system
28
0000000000000000-000000000000bfff (prio 0, ram): sram A
29
0000000001c00000-0000000001c00fff (prio -1000, i/o): a10-sram-ctrl
30
0000000001c0b000-0000000001c0bfff (prio 0, i/o): aw_emac
31
0000000001c18000-0000000001c18fff (prio 0, i/o): ahci
32
0000000001c18080-0000000001c180ff (prio 0, i/o): allwinner-ahci
33
0000000001c20400-0000000001c207ff (prio 0, i/o): allwinner-a10-pic
34
0000000001c20c00-0000000001c20fff (prio 0, i/o): allwinner-A10-timer
35
0000000001c28000-0000000001c2801f (prio 0, i/o): serial
36
0000000040000000-0000000047ffffff (prio 0, ram): cubieboard.ram
37
38
Reported-by: Charlie Smurthwaite <charlie@atech.media>
39
Tested-by: Charlie Smurthwaite <charlie@atech.media>
19
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
40
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Message-id: 20180123132051.24448-1-f4bug@amsat.org
41
Message-id: 20190104142921.878-1-f4bug@amsat.org
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
42
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
44
---
24
include/hw/sd/sdhci.h | 1 +
45
include/hw/arm/allwinner-a10.h | 1 +
25
hw/sd/sdhci.c | 1 +
46
hw/arm/allwinner-a10.c | 6 ++++++
26
2 files changed, 2 insertions(+)
47
2 files changed, 7 insertions(+)
27
48
28
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
49
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
29
index XXXXXXX..XXXXXXX 100644
50
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/sd/sdhci.h
51
--- a/include/hw/arm/allwinner-a10.h
31
+++ b/include/hw/sd/sdhci.h
52
+++ b/include/hw/arm/allwinner-a10.h
32
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
53
@@ -XXX,XX +XXX,XX @@ typedef struct AwA10State {
33
/*< public >*/
54
AwA10PICState intc;
34
SDBus sdbus;
55
AwEmacState emac;
35
MemoryRegion iomem;
56
AllwinnerAHCIState sata;
36
+ AddressSpace sysbus_dma_as;
57
+ MemoryRegion sram_a;
37
AddressSpace *dma_as;
58
} AwA10State;
38
MemoryRegion *dma_mr;
59
39
60
#define ALLWINNER_H_
40
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
61
diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c
41
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/sd/sdhci.c
63
--- a/hw/arm/allwinner-a10.c
43
+++ b/hw/sd/sdhci.c
64
+++ b/hw/arm/allwinner-a10.c
44
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
65
@@ -XXX,XX +XXX,XX @@
45
}
66
#include "hw/sysbus.h"
46
67
#include "hw/devices.h"
47
if (s->dma_mr) {
68
#include "hw/arm/allwinner-a10.h"
48
+ s->dma_as = &s->sysbus_dma_as;
69
+#include "hw/misc/unimp.h"
49
address_space_init(s->dma_as, s->dma_mr, "sdhci-dma");
70
50
} else {
71
static void aw_a10_init(Object *obj)
51
/* use system_memory() if property "dma" not set */
72
{
73
@@ -XXX,XX +XXX,XX @@ static void aw_a10_realize(DeviceState *dev, Error **errp)
74
sysbus_connect_irq(sysbusdev, 4, s->irq[67]);
75
sysbus_connect_irq(sysbusdev, 5, s->irq[68]);
76
77
+ memory_region_init_ram(&s->sram_a, OBJECT(dev), "sram A", 48 * KiB,
78
+ &error_fatal);
79
+ memory_region_add_subregion(get_system_memory(), 0x00000000, &s->sram_a);
80
+ create_unimplemented_device("a10-sram-ctrl", 0x01c00000, 4 * KiB);
81
+
82
/* FIXME use qdev NIC properties instead of nd_table[] */
83
if (nd_table[0].used) {
84
qemu_check_nic_model(&nd_table[0], TYPE_AW_EMAC);
52
--
85
--
53
2.7.4
86
2.19.2
54
87
55
88
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
2
3
Rather than passing a regno to the helper, pass pointers to the
3
Adds a new qtest command "set_irq_in" which allows
4
vector register directly. This eliminates the need to pass in
4
to set qemu gpio lines to a given level.
5
the environment pointer and reduces the number of places that
6
directly access env->vfp.regs[].
7
5
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Based on https://lists.gnu.org/archive/html/qemu-devel/2012-12/msg02363.html
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
which never got merged.
10
Message-id: 20180119045438.28582-5-richard.henderson@linaro.org
8
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Reviewed-by: Thomas Huth <thuth@redhat.com>
12
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Message-id: 20190103091119.9367-2-stefanha@redhat.com
15
Originally-by: Matthew Ogilvie <mmogilvi_qemu@miniinfo.net>
16
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Reviewed-by: Thomas Huth <thuth@redhat.com>
18
Reviewed-by: Laurent Vivier <lvivier@redhat.com>
19
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
21
---
14
target/arm/helper.h | 2 +-
22
tests/libqtest.h | 13 +++++++++++++
15
target/arm/op_helper.c | 17 +++++++----------
23
qtest.c | 43 +++++++++++++++++++++++++++++++++++++++++++
16
target/arm/translate.c | 8 ++++----
24
tests/libqtest.c | 10 ++++++++++
17
3 files changed, 12 insertions(+), 15 deletions(-)
25
3 files changed, 66 insertions(+)
18
26
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
27
diff --git a/tests/libqtest.h b/tests/libqtest.h
20
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.h
29
--- a/tests/libqtest.h
22
+++ b/target/arm/helper.h
30
+++ b/tests/libqtest.h
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
31
@@ -XXX,XX +XXX,XX @@ void qtest_irq_intercept_in(QTestState *s, const char *string);
24
DEF_HELPER_FLAGS_2(rsqrte_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
32
*/
25
DEF_HELPER_2(recpe_u32, i32, i32, ptr)
33
void qtest_irq_intercept_out(QTestState *s, const char *string);
26
DEF_HELPER_FLAGS_2(rsqrte_u32, TCG_CALL_NO_RWG, i32, i32, ptr)
34
27
-DEF_HELPER_5(neon_tbl, i32, env, i32, i32, i32, i32)
35
+/**
28
+DEF_HELPER_FLAGS_4(neon_tbl, TCG_CALL_NO_RWG, i32, i32, i32, ptr, i32)
36
+ * qtest_set_irq_in:
29
37
+ * @s: QTestState instance to operate on.
30
DEF_HELPER_3(shl_cc, i32, env, i32, i32)
38
+ * @string: QOM path of a device
31
DEF_HELPER_3(shr_cc, i32, env, i32, i32)
39
+ * @name: IRQ name
32
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
40
+ * @irq: IRQ number
41
+ * @level: IRQ level
42
+ *
43
+ * Force given device/irq GPIO-in pin to the given level.
44
+ */
45
+void qtest_set_irq_in(QTestState *s, const char *string, const char *name,
46
+ int irq, int level);
47
+
48
/**
49
* qtest_outb:
50
* @s: #QTestState instance to operate on.
51
diff --git a/qtest.c b/qtest.c
33
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/op_helper.c
53
--- a/qtest.c
35
+++ b/target/arm/op_helper.c
54
+++ b/qtest.c
36
@@ -XXX,XX +XXX,XX @@ static int exception_target_el(CPUARMState *env)
55
@@ -XXX,XX +XXX,XX @@ static bool qtest_opened;
37
return target_el;
56
* where NUM is an IRQ number. For the PC, interrupts can be intercepted
57
* simply with "irq_intercept_in ioapic" (note that IRQ0 comes out with
58
* NUM=0 even though it is remapped to GSI 2).
59
+ *
60
+ * Setting interrupt level:
61
+ *
62
+ * > set_irq_in QOM-PATH NAME NUM LEVEL
63
+ * < OK
64
+ *
65
+ * where NAME is the name of the irq/gpio list, NUM is an IRQ number and
66
+ * LEVEL is an signed integer IRQ level.
67
+ *
68
+ * Forcibly set the given interrupt pin to the given level.
69
+ *
70
*/
71
72
static int hex2nib(char ch)
73
@@ -XXX,XX +XXX,XX @@ static void qtest_process_command(CharBackend *chr, gchar **words)
74
irq_intercept_dev = dev;
75
qtest_send_prefix(chr);
76
qtest_send(chr, "OK\n");
77
+ } else if (strcmp(words[0], "set_irq_in") == 0) {
78
+ DeviceState *dev;
79
+ qemu_irq irq;
80
+ char *name;
81
+ int ret;
82
+ int num;
83
+ int level;
84
85
+ g_assert(words[1] && words[2] && words[3] && words[4]);
86
+
87
+ dev = DEVICE(object_resolve_path(words[1], NULL));
88
+ if (!dev) {
89
+ qtest_send_prefix(chr);
90
+ qtest_send(chr, "FAIL Unknown device\n");
91
+ return;
92
+ }
93
+
94
+ if (strcmp(words[2], "unnamed-gpio-in") == 0) {
95
+ name = NULL;
96
+ } else {
97
+ name = words[2];
98
+ }
99
+
100
+ ret = qemu_strtoi(words[3], NULL, 0, &num);
101
+ g_assert(!ret);
102
+ ret = qemu_strtoi(words[4], NULL, 0, &level);
103
+ g_assert(!ret);
104
+
105
+ irq = qdev_get_gpio_in_named(dev, name, num);
106
+
107
+ qemu_set_irq(irq, level);
108
+ qtest_send_prefix(chr);
109
+ qtest_send(chr, "OK\n");
110
} else if (strcmp(words[0], "outb") == 0 ||
111
strcmp(words[0], "outw") == 0 ||
112
strcmp(words[0], "outl") == 0) {
113
diff --git a/tests/libqtest.c b/tests/libqtest.c
114
index XXXXXXX..XXXXXXX 100644
115
--- a/tests/libqtest.c
116
+++ b/tests/libqtest.c
117
@@ -XXX,XX +XXX,XX @@ void qtest_irq_intercept_in(QTestState *s, const char *qom_path)
118
qtest_rsp(s, 0);
38
}
119
}
39
120
40
-uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
121
+void qtest_set_irq_in(QTestState *s, const char *qom_path, const char *name,
41
- uint32_t rn, uint32_t maxindex)
122
+ int num, int level)
42
+uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, void *vn,
123
+{
43
+ uint32_t maxindex)
124
+ if (!name) {
125
+ name = "unnamed-gpio-in";
126
+ }
127
+ qtest_sendf(s, "set_irq_in %s %s %d %d\n", qom_path, name, num, level);
128
+ qtest_rsp(s, 0);
129
+}
130
+
131
static void qtest_out(QTestState *s, const char *cmd, uint16_t addr, uint32_t value)
44
{
132
{
45
- uint32_t val;
133
qtest_sendf(s, "%s 0x%x 0x%x\n", cmd, addr, value);
46
- uint32_t tmp;
47
- int index;
48
- int shift;
49
- uint64_t *table;
50
- table = (uint64_t *)&env->vfp.regs[rn];
51
+ uint32_t val, shift;
52
+ uint64_t *table = vn;
53
+
54
val = 0;
55
for (shift = 0; shift < 32; shift += 8) {
56
- index = (ireg >> shift) & 0xff;
57
+ uint32_t index = (ireg >> shift) & 0xff;
58
if (index < maxindex) {
59
- tmp = (table[index >> 3] >> ((index & 7) << 3)) & 0xff;
60
+ uint32_t tmp = (table[index >> 3] >> ((index & 7) << 3)) & 0xff;
61
val |= tmp << shift;
62
} else {
63
val |= def & (0xff << shift);
64
diff --git a/target/arm/translate.c b/target/arm/translate.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/translate.c
67
+++ b/target/arm/translate.c
68
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
69
tcg_gen_movi_i32(tmp, 0);
70
}
71
tmp2 = neon_load_reg(rm, 0);
72
- tmp4 = tcg_const_i32(rn);
73
+ ptr1 = vfp_reg_ptr(true, rn);
74
tmp5 = tcg_const_i32(n);
75
- gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
76
+ gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
77
tcg_temp_free_i32(tmp);
78
if (insn & (1 << 6)) {
79
tmp = neon_load_reg(rd, 1);
80
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
81
tcg_gen_movi_i32(tmp, 0);
82
}
83
tmp3 = neon_load_reg(rm, 1);
84
- gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
85
+ gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
86
tcg_temp_free_i32(tmp5);
87
- tcg_temp_free_i32(tmp4);
88
+ tcg_temp_free_ptr(ptr1);
89
neon_store_reg(rd, 0, tmp2);
90
neon_store_reg(rd, 1, tmp3);
91
tcg_temp_free_i32(tmp);
92
--
134
--
93
2.7.4
135
2.19.2
94
136
95
137
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
2
3
If it isn't used when translate.h is included,
3
Adds a header that provides definitions that are used
4
we'll get a compiler Werror.
4
across nRF51 peripherals
5
5
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20190103091119.9367-3-stefanha@redhat.com
10
Message-id: 20180119045438.28582-2-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
target/arm/translate.h | 2 +-
13
include/hw/arm/nrf51.h | 45 ++++++++++++++++++++++++++++++++++++
14
1 file changed, 1 insertion(+), 1 deletion(-)
14
include/hw/char/nrf51_uart.h | 1 -
15
hw/arm/nrf51_soc.c | 33 ++++++++++----------------
16
3 files changed, 57 insertions(+), 22 deletions(-)
17
create mode 100644 include/hw/arm/nrf51.h
15
18
16
diff --git a/target/arm/translate.h b/target/arm/translate.h
19
diff --git a/include/hw/arm/nrf51.h b/include/hw/arm/nrf51.h
20
new file mode 100644
21
index XXXXXXX..XXXXXXX
22
--- /dev/null
23
+++ b/include/hw/arm/nrf51.h
24
@@ -XXX,XX +XXX,XX @@
25
+/*
26
+ * Nordic Semiconductor nRF51 Series SOC Common Defines
27
+ *
28
+ * This file hosts generic defines used in various nRF51 peripheral devices.
29
+ *
30
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
31
+ * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf
32
+ *
33
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
34
+ *
35
+ * This code is licensed under the GPL version 2 or later. See
36
+ * the COPYING file in the top-level directory.
37
+ */
38
+
39
+#ifndef NRF51_H
40
+#define NRF51_H
41
+
42
+#define NRF51_FLASH_BASE 0x00000000
43
+#define NRF51_FICR_BASE 0x10000000
44
+#define NRF51_FICR_SIZE 0x00000100
45
+#define NRF51_UICR_BASE 0x10001000
46
+#define NRF51_SRAM_BASE 0x20000000
47
+
48
+#define NRF51_IOMEM_BASE 0x40000000
49
+#define NRF51_IOMEM_SIZE 0x20000000
50
+
51
+#define NRF51_UART_BASE 0x40002000
52
+#define NRF51_TIMER_BASE 0x40008000
53
+#define NRF51_TIMER_SIZE 0x00001000
54
+#define NRF51_RNG_BASE 0x4000D000
55
+#define NRF51_NVMC_BASE 0x4001E000
56
+#define NRF51_GPIO_BASE 0x50000000
57
+
58
+#define NRF51_PRIVATE_BASE 0xF0000000
59
+#define NRF51_PRIVATE_SIZE 0x10000000
60
+
61
+#define NRF51_PAGE_SIZE 1024
62
+
63
+/* Trigger */
64
+#define NRF51_TRIGGER_TASK 0x01
65
+
66
+/* Events */
67
+#define NRF51_EVENT_CLEAR 0x00
68
+
69
+#endif
70
diff --git a/include/hw/char/nrf51_uart.h b/include/hw/char/nrf51_uart.h
17
index XXXXXXX..XXXXXXX 100644
71
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.h
72
--- a/include/hw/char/nrf51_uart.h
19
+++ b/target/arm/translate.h
73
+++ b/include/hw/char/nrf51_uart.h
20
@@ -XXX,XX +XXX,XX @@ static inline int default_exception_el(DisasContext *s)
74
@@ -XXX,XX +XXX,XX @@
21
? 3 : MAX(1, s->current_el);
75
#include "hw/registerfields.h"
76
77
#define UART_FIFO_LENGTH 6
78
-#define UART_BASE 0x40002000
79
#define UART_SIZE 0x1000
80
81
#define TYPE_NRF51_UART "nrf51_soc.uart"
82
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/arm/nrf51_soc.c
85
+++ b/hw/arm/nrf51_soc.c
86
@@ -XXX,XX +XXX,XX @@
87
#include "qemu/log.h"
88
#include "cpu.h"
89
90
+#include "hw/arm/nrf51.h"
91
#include "hw/arm/nrf51_soc.h"
92
93
-#define IOMEM_BASE 0x40000000
94
-#define IOMEM_SIZE 0x20000000
95
-
96
-#define FICR_BASE 0x10000000
97
-#define FICR_SIZE 0x000000fc
98
-
99
-#define FLASH_BASE 0x00000000
100
-#define SRAM_BASE 0x20000000
101
-
102
-#define PRIVATE_BASE 0xF0000000
103
-#define PRIVATE_SIZE 0x10000000
104
-
105
/*
106
* The size and base is for the NRF51822 part. If other parts
107
* are supported in the future, add a sub-class of NRF51SoC for
108
* the specific variants
109
*/
110
-#define NRF51822_FLASH_SIZE (256 * 1024)
111
-#define NRF51822_SRAM_SIZE (16 * 1024)
112
+#define NRF51822_FLASH_SIZE (256 * NRF51_PAGE_SIZE)
113
+#define NRF51822_SRAM_SIZE (16 * NRF51_PAGE_SIZE)
114
115
#define BASE_TO_IRQ(base) ((base >> 12) & 0x1F)
116
117
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
118
error_propagate(errp, err);
119
return;
120
}
121
- memory_region_add_subregion(&s->container, FLASH_BASE, &s->flash);
122
+ memory_region_add_subregion(&s->container, NRF51_FLASH_BASE, &s->flash);
123
124
memory_region_init_ram(&s->sram, NULL, "nrf51.sram", s->sram_size, &err);
125
if (err) {
126
error_propagate(errp, err);
127
return;
128
}
129
- memory_region_add_subregion(&s->container, SRAM_BASE, &s->sram);
130
+ memory_region_add_subregion(&s->container, NRF51_SRAM_BASE, &s->sram);
131
132
/* UART */
133
object_property_set_bool(OBJECT(&s->uart), true, "realized", &err);
134
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
135
return;
136
}
137
mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->uart), 0);
138
- memory_region_add_subregion_overlap(&s->container, UART_BASE, mr, 0);
139
+ memory_region_add_subregion_overlap(&s->container, NRF51_UART_BASE, mr, 0);
140
sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart), 0,
141
qdev_get_gpio_in(DEVICE(&s->cpu),
142
- BASE_TO_IRQ(UART_BASE)));
143
+ BASE_TO_IRQ(NRF51_UART_BASE)));
144
145
- create_unimplemented_device("nrf51_soc.io", IOMEM_BASE, IOMEM_SIZE);
146
- create_unimplemented_device("nrf51_soc.ficr", FICR_BASE, FICR_SIZE);
147
+ create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
148
+ NRF51_IOMEM_SIZE);
149
+ create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
150
+ NRF51_FICR_SIZE);
151
create_unimplemented_device("nrf51_soc.private",
152
- PRIVATE_BASE, PRIVATE_SIZE);
153
+ NRF51_PRIVATE_BASE, NRF51_PRIVATE_SIZE);
22
}
154
}
23
155
24
-static void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
156
static void nrf51_soc_init(Object *obj)
25
+static inline void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
26
{
27
/* We don't need to save all of the syndrome so we mask and shift
28
* out unneeded bits to help the sleb128 encoder do a better job.
29
--
157
--
30
2.7.4
158
2.19.2
31
159
32
160
diff view generated by jsdifflib
New patch
1
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
3
Add a model of the NRF51 random number generator peripheral.
4
This is a simple random generator that continuously generates
5
new random values after startup.
6
7
Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
8
9
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
10
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
Message-id: 20190103091119.9367-4-stefanha@redhat.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/misc/Makefile.objs | 1 +
17
include/hw/misc/nrf51_rng.h | 83 ++++++++++++
18
hw/misc/nrf51_rng.c | 262 ++++++++++++++++++++++++++++++++++++
19
3 files changed, 346 insertions(+)
20
create mode 100644 include/hw/misc/nrf51_rng.h
21
create mode 100644 hw/misc/nrf51_rng.c
22
23
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/misc/Makefile.objs
26
+++ b/hw/misc/Makefile.objs
27
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
28
obj-$(CONFIG_AUX) += auxbus.o
29
obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
30
obj-$(CONFIG_MSF2) += msf2-sysreg.o
31
+obj-$(CONFIG_NRF51_SOC) += nrf51_rng.o
32
diff --git a/include/hw/misc/nrf51_rng.h b/include/hw/misc/nrf51_rng.h
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/include/hw/misc/nrf51_rng.h
37
@@ -XXX,XX +XXX,XX @@
38
+/*
39
+ * nRF51 Random Number Generator
40
+ *
41
+ * QEMU interface:
42
+ * + Property "period_unfiltered_us": Time between two biased values in
43
+ * microseconds.
44
+ * + Property "period_filtered_us": Time between two unbiased values in
45
+ * microseconds.
46
+ * + sysbus MMIO regions 0: Memory Region with tasks, events and registers
47
+ * to be mapped to the peripherals instance address by the SOC.
48
+ * + Named GPIO output "irq": Interrupt line of the peripheral. Must be
49
+ * connected to the associated peripheral interrupt line of the NVIC.
50
+ * + Named GPIO output "eep_valrdy": Event set when new random value is ready
51
+ * to be read.
52
+ * + Named GPIO input "tep_start": Task that triggers start of continuous
53
+ * generation of random values.
54
+ * + Named GPIO input "tep_stop": Task that ends continuous generation of
55
+ * random values.
56
+ *
57
+ * Accuracy of the peripheral model:
58
+ * + Stochastic properties of different configurations of the random source
59
+ * are not modeled.
60
+ * + Generation of unfiltered and filtered random values take at least the
61
+ * average generation time stated in the production specification;
62
+ * non-deterministic generation times are not modeled.
63
+ *
64
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
65
+ *
66
+ * This code is licensed under the GPL version 2 or later. See
67
+ * the COPYING file in the top-level directory.
68
+ *
69
+ */
70
+#ifndef NRF51_RNG_H
71
+#define NRF51_RNG_H
72
+
73
+#include "hw/sysbus.h"
74
+#include "qemu/timer.h"
75
+#define TYPE_NRF51_RNG "nrf51_soc.rng"
76
+#define NRF51_RNG(obj) OBJECT_CHECK(NRF51RNGState, (obj), TYPE_NRF51_RNG)
77
+
78
+#define NRF51_RNG_SIZE 0x1000
79
+
80
+#define NRF51_RNG_TASK_START 0x000
81
+#define NRF51_RNG_TASK_STOP 0x004
82
+#define NRF51_RNG_EVENT_VALRDY 0x100
83
+#define NRF51_RNG_REG_SHORTS 0x200
84
+#define NRF51_RNG_REG_SHORTS_VALRDY_STOP 0
85
+#define NRF51_RNG_REG_INTEN 0x300
86
+#define NRF51_RNG_REG_INTEN_VALRDY 0
87
+#define NRF51_RNG_REG_INTENSET 0x304
88
+#define NRF51_RNG_REG_INTENCLR 0x308
89
+#define NRF51_RNG_REG_CONFIG 0x504
90
+#define NRF51_RNG_REG_CONFIG_DECEN 0
91
+#define NRF51_RNG_REG_VALUE 0x508
92
+
93
+typedef struct {
94
+ SysBusDevice parent_obj;
95
+
96
+ MemoryRegion mmio;
97
+ qemu_irq irq;
98
+
99
+ /* Event End Points */
100
+ qemu_irq eep_valrdy;
101
+
102
+ QEMUTimer timer;
103
+
104
+ /* Time between generation of successive unfiltered values in us */
105
+ uint16_t period_unfiltered_us;
106
+ /* Time between generation of successive filtered values in us */
107
+ uint16_t period_filtered_us;
108
+
109
+ uint8_t value;
110
+
111
+ uint32_t active;
112
+ uint32_t event_valrdy;
113
+ uint32_t shortcut_stop_on_valrdy;
114
+ uint32_t interrupt_enabled;
115
+ uint32_t filter_enabled;
116
+
117
+} NRF51RNGState;
118
+
119
+
120
+#endif /* NRF51_RNG_H_ */
121
diff --git a/hw/misc/nrf51_rng.c b/hw/misc/nrf51_rng.c
122
new file mode 100644
123
index XXXXXXX..XXXXXXX
124
--- /dev/null
125
+++ b/hw/misc/nrf51_rng.c
126
@@ -XXX,XX +XXX,XX @@
127
+/*
128
+ * nRF51 Random Number Generator
129
+ *
130
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.1.pdf
131
+ *
132
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
133
+ *
134
+ * This code is licensed under the GPL version 2 or later. See
135
+ * the COPYING file in the top-level directory.
136
+ */
137
+
138
+#include "qemu/osdep.h"
139
+#include "qemu/log.h"
140
+#include "qapi/error.h"
141
+#include "hw/arm/nrf51.h"
142
+#include "hw/misc/nrf51_rng.h"
143
+#include "crypto/random.h"
144
+
145
+static void update_irq(NRF51RNGState *s)
146
+{
147
+ bool irq = s->interrupt_enabled && s->event_valrdy;
148
+ qemu_set_irq(s->irq, irq);
149
+}
150
+
151
+static uint64_t rng_read(void *opaque, hwaddr offset, unsigned int size)
152
+{
153
+ NRF51RNGState *s = NRF51_RNG(opaque);
154
+ uint64_t r = 0;
155
+
156
+ switch (offset) {
157
+ case NRF51_RNG_EVENT_VALRDY:
158
+ r = s->event_valrdy;
159
+ break;
160
+ case NRF51_RNG_REG_SHORTS:
161
+ r = s->shortcut_stop_on_valrdy;
162
+ break;
163
+ case NRF51_RNG_REG_INTEN:
164
+ case NRF51_RNG_REG_INTENSET:
165
+ case NRF51_RNG_REG_INTENCLR:
166
+ r = s->interrupt_enabled;
167
+ break;
168
+ case NRF51_RNG_REG_CONFIG:
169
+ r = s->filter_enabled;
170
+ break;
171
+ case NRF51_RNG_REG_VALUE:
172
+ r = s->value;
173
+ break;
174
+
175
+ default:
176
+ qemu_log_mask(LOG_GUEST_ERROR,
177
+ "%s: bad read offset 0x%" HWADDR_PRIx "\n",
178
+ __func__, offset);
179
+ }
180
+
181
+ return r;
182
+}
183
+
184
+static int64_t calc_next_timeout(NRF51RNGState *s)
185
+{
186
+ int64_t timeout = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL);
187
+ if (s->filter_enabled) {
188
+ timeout += s->period_filtered_us;
189
+ } else {
190
+ timeout += s->period_unfiltered_us;
191
+ }
192
+
193
+ return timeout;
194
+}
195
+
196
+
197
+static void rng_update_timer(NRF51RNGState *s)
198
+{
199
+ if (s->active) {
200
+ timer_mod(&s->timer, calc_next_timeout(s));
201
+ } else {
202
+ timer_del(&s->timer);
203
+ }
204
+}
205
+
206
+
207
+static void rng_write(void *opaque, hwaddr offset,
208
+ uint64_t value, unsigned int size)
209
+{
210
+ NRF51RNGState *s = NRF51_RNG(opaque);
211
+
212
+ switch (offset) {
213
+ case NRF51_RNG_TASK_START:
214
+ if (value == NRF51_TRIGGER_TASK) {
215
+ s->active = 1;
216
+ rng_update_timer(s);
217
+ }
218
+ break;
219
+ case NRF51_RNG_TASK_STOP:
220
+ if (value == NRF51_TRIGGER_TASK) {
221
+ s->active = 0;
222
+ rng_update_timer(s);
223
+ }
224
+ break;
225
+ case NRF51_RNG_EVENT_VALRDY:
226
+ if (value == NRF51_EVENT_CLEAR) {
227
+ s->event_valrdy = 0;
228
+ }
229
+ break;
230
+ case NRF51_RNG_REG_SHORTS:
231
+ s->shortcut_stop_on_valrdy =
232
+ (value & BIT_MASK(NRF51_RNG_REG_SHORTS_VALRDY_STOP)) ? 1 : 0;
233
+ break;
234
+ case NRF51_RNG_REG_INTEN:
235
+ s->interrupt_enabled =
236
+ (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) ? 1 : 0;
237
+ break;
238
+ case NRF51_RNG_REG_INTENSET:
239
+ if (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) {
240
+ s->interrupt_enabled = 1;
241
+ }
242
+ break;
243
+ case NRF51_RNG_REG_INTENCLR:
244
+ if (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) {
245
+ s->interrupt_enabled = 0;
246
+ }
247
+ break;
248
+ case NRF51_RNG_REG_CONFIG:
249
+ s->filter_enabled =
250
+ (value & BIT_MASK(NRF51_RNG_REG_CONFIG_DECEN)) ? 1 : 0;
251
+ break;
252
+
253
+ default:
254
+ qemu_log_mask(LOG_GUEST_ERROR,
255
+ "%s: bad write offset 0x%" HWADDR_PRIx "\n",
256
+ __func__, offset);
257
+ }
258
+
259
+ update_irq(s);
260
+}
261
+
262
+static const MemoryRegionOps rng_ops = {
263
+ .read = rng_read,
264
+ .write = rng_write,
265
+ .endianness = DEVICE_LITTLE_ENDIAN,
266
+ .impl.min_access_size = 4,
267
+ .impl.max_access_size = 4
268
+};
269
+
270
+static void nrf51_rng_timer_expire(void *opaque)
271
+{
272
+ NRF51RNGState *s = NRF51_RNG(opaque);
273
+
274
+ qcrypto_random_bytes(&s->value, 1, &error_abort);
275
+
276
+ s->event_valrdy = 1;
277
+ qemu_set_irq(s->eep_valrdy, 1);
278
+
279
+ if (s->shortcut_stop_on_valrdy) {
280
+ s->active = 0;
281
+ }
282
+
283
+ rng_update_timer(s);
284
+ update_irq(s);
285
+}
286
+
287
+static void nrf51_rng_tep_start(void *opaque, int n, int level)
288
+{
289
+ NRF51RNGState *s = NRF51_RNG(opaque);
290
+
291
+ if (level) {
292
+ s->active = 1;
293
+ rng_update_timer(s);
294
+ }
295
+}
296
+
297
+static void nrf51_rng_tep_stop(void *opaque, int n, int level)
298
+{
299
+ NRF51RNGState *s = NRF51_RNG(opaque);
300
+
301
+ if (level) {
302
+ s->active = 0;
303
+ rng_update_timer(s);
304
+ }
305
+}
306
+
307
+
308
+static void nrf51_rng_init(Object *obj)
309
+{
310
+ NRF51RNGState *s = NRF51_RNG(obj);
311
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
312
+
313
+ memory_region_init_io(&s->mmio, obj, &rng_ops, s,
314
+ TYPE_NRF51_RNG, NRF51_RNG_SIZE);
315
+ sysbus_init_mmio(sbd, &s->mmio);
316
+
317
+ timer_init_us(&s->timer, QEMU_CLOCK_VIRTUAL, nrf51_rng_timer_expire, s);
318
+
319
+ sysbus_init_irq(sbd, &s->irq);
320
+
321
+ /* Tasks */
322
+ qdev_init_gpio_in_named(DEVICE(s), nrf51_rng_tep_start, "tep_start", 1);
323
+ qdev_init_gpio_in_named(DEVICE(s), nrf51_rng_tep_stop, "tep_stop", 1);
324
+
325
+ /* Events */
326
+ qdev_init_gpio_out_named(DEVICE(s), &s->eep_valrdy, "eep_valrdy", 1);
327
+}
328
+
329
+static void nrf51_rng_reset(DeviceState *dev)
330
+{
331
+ NRF51RNGState *s = NRF51_RNG(dev);
332
+
333
+ s->value = 0;
334
+ s->active = 0;
335
+ s->event_valrdy = 0;
336
+ s->shortcut_stop_on_valrdy = 0;
337
+ s->interrupt_enabled = 0;
338
+ s->filter_enabled = 0;
339
+
340
+ rng_update_timer(s);
341
+}
342
+
343
+
344
+static Property nrf51_rng_properties[] = {
345
+ DEFINE_PROP_UINT16("period_unfiltered_us", NRF51RNGState,
346
+ period_unfiltered_us, 167),
347
+ DEFINE_PROP_UINT16("period_filtered_us", NRF51RNGState,
348
+ period_filtered_us, 660),
349
+ DEFINE_PROP_END_OF_LIST(),
350
+};
351
+
352
+static const VMStateDescription vmstate_rng = {
353
+ .name = "nrf51_soc.rng",
354
+ .version_id = 1,
355
+ .minimum_version_id = 1,
356
+ .fields = (VMStateField[]) {
357
+ VMSTATE_UINT32(active, NRF51RNGState),
358
+ VMSTATE_UINT32(event_valrdy, NRF51RNGState),
359
+ VMSTATE_UINT32(shortcut_stop_on_valrdy, NRF51RNGState),
360
+ VMSTATE_UINT32(interrupt_enabled, NRF51RNGState),
361
+ VMSTATE_UINT32(filter_enabled, NRF51RNGState),
362
+ VMSTATE_END_OF_LIST()
363
+ }
364
+};
365
+
366
+static void nrf51_rng_class_init(ObjectClass *klass, void *data)
367
+{
368
+ DeviceClass *dc = DEVICE_CLASS(klass);
369
+
370
+ dc->props = nrf51_rng_properties;
371
+ dc->vmsd = &vmstate_rng;
372
+ dc->reset = nrf51_rng_reset;
373
+}
374
+
375
+static const TypeInfo nrf51_rng_info = {
376
+ .name = TYPE_NRF51_RNG,
377
+ .parent = TYPE_SYS_BUS_DEVICE,
378
+ .instance_size = sizeof(NRF51RNGState),
379
+ .instance_init = nrf51_rng_init,
380
+ .class_init = nrf51_rng_class_init
381
+};
382
+
383
+static void nrf51_rng_register_types(void)
384
+{
385
+ type_register_static(&nrf51_rng_info);
386
+}
387
+
388
+type_init(nrf51_rng_register_types)
389
--
390
2.19.2
391
392
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
2
3
Coverity found that the variable tx_rx in the function
3
Use RNG in SOC.
4
xilinx_spips_flush_txfifo was being used uninitialized (CID 1383841). This
5
patch corrects this by always initializing tx_rx to zeros.
6
4
7
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
5
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
8
Message-id: 20180124215708.30400-1-frasse.iglesias@gmail.com
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190103091119.9367-5-stefanha@redhat.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/ssi/xilinx_spips.c | 18 +++++++++++++++++-
12
include/hw/arm/nrf51_soc.h | 2 ++
13
1 file changed, 17 insertions(+), 1 deletion(-)
13
hw/arm/nrf51_soc.c | 16 ++++++++++++++++
14
2 files changed, 18 insertions(+)
14
15
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
16
diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
18
--- a/include/hw/arm/nrf51_soc.h
18
+++ b/hw/ssi/xilinx_spips.c
19
+++ b/include/hw/arm/nrf51_soc.h
19
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@
20
#define SNOOP_NONE 0xEE
21
#include "hw/sysbus.h"
21
#define SNOOP_STRIPING 0
22
#include "hw/arm/armv7m.h"
22
23
#include "hw/char/nrf51_uart.h"
23
+#define MIN_NUM_BUSSES 1
24
+#include "hw/misc/nrf51_rng.h"
24
+#define MAX_NUM_BUSSES 2
25
25
+
26
#define TYPE_NRF51_SOC "nrf51-soc"
26
static inline int num_effective_busses(XilinxSPIPS *s)
27
#define NRF51_SOC(obj) \
27
{
28
@@ -XXX,XX +XXX,XX @@ typedef struct NRF51State {
28
return (s->regs[R_LQSPI_CFG] & LQSPI_CFG_SEP_BUS &&
29
ARMv7MState cpu;
29
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
30
30
for (;;) {
31
NRF51UARTState uart;
31
int i;
32
+ NRF51RNGState rng;
32
uint8_t tx = 0;
33
33
- uint8_t tx_rx[num_effective_busses(s)];
34
MemoryRegion iomem;
34
+ uint8_t tx_rx[MAX_NUM_BUSSES] = { 0 };
35
MemoryRegion sram;
35
uint8_t dummy_cycles = 0;
36
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
36
uint8_t addr_length;
37
index XXXXXXX..XXXXXXX 100644
37
38
--- a/hw/arm/nrf51_soc.c
38
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
39
+++ b/hw/arm/nrf51_soc.c
39
40
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
40
DB_PRINT_L(0, "realized spips\n");
41
qdev_get_gpio_in(DEVICE(&s->cpu),
41
42
BASE_TO_IRQ(NRF51_UART_BASE)));
42
+ if (s->num_busses > MAX_NUM_BUSSES) {
43
43
+ error_setg(errp,
44
+ /* RNG */
44
+ "requested number of SPI busses %u exceeds maximum %d",
45
+ object_property_set_bool(OBJECT(&s->rng), true, "realized", &err);
45
+ s->num_busses, MAX_NUM_BUSSES);
46
+ if (err) {
46
+ return;
47
+ error_propagate(errp, err);
47
+ }
48
+ if (s->num_busses < MIN_NUM_BUSSES) {
49
+ error_setg(errp,
50
+ "requested number of SPI busses %u is below minimum %d",
51
+ s->num_busses, MIN_NUM_BUSSES);
52
+ return;
48
+ return;
53
+ }
49
+ }
54
+
50
+
55
s->spi = g_new(SSIBus *, s->num_busses);
51
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->rng), 0);
56
for (i = 0; i < s->num_busses; ++i) {
52
+ memory_region_add_subregion_overlap(&s->container, NRF51_RNG_BASE, mr, 0);
57
char bus_name[16];
53
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->rng), 0,
54
+ qdev_get_gpio_in(DEVICE(&s->cpu),
55
+ BASE_TO_IRQ(NRF51_RNG_BASE)));
56
+
57
create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
58
NRF51_IOMEM_SIZE);
59
create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
60
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_init(Object *obj)
61
TYPE_NRF51_UART);
62
object_property_add_alias(obj, "serial0", OBJECT(&s->uart), "chardev",
63
&error_abort);
64
+
65
+ sysbus_init_child_obj(obj, "rng", &s->rng, sizeof(s->rng),
66
+ TYPE_NRF51_RNG);
67
}
68
69
static Property nrf51_soc_properties[] = {
58
--
70
--
59
2.7.4
71
2.19.2
60
72
61
73
diff view generated by jsdifflib
New patch
1
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
3
This adds a model of the nRF51 GPIO peripheral.
4
5
Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
6
7
The nRF51 series microcontrollers support up to 32 GPIO pins in various configurations.
8
The pins can be used as input pins with pull-ups or pull-down.
9
Furthermore, three different output driver modes per level are
10
available (disconnected, standard, high-current).
11
12
The GPIO-Peripheral has a mechanism for detecting level changes which is
13
not featured in this model.
14
15
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
16
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
19
Message-id: 20190103091119.9367-6-stefanha@redhat.com
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
Makefile.objs | 1 +
23
hw/gpio/Makefile.objs | 1 +
24
include/hw/gpio/nrf51_gpio.h | 69 ++++++++
25
hw/gpio/nrf51_gpio.c | 300 +++++++++++++++++++++++++++++++++++
26
hw/gpio/trace-events | 7 +
27
5 files changed, 378 insertions(+)
28
create mode 100644 include/hw/gpio/nrf51_gpio.h
29
create mode 100644 hw/gpio/nrf51_gpio.c
30
create mode 100644 hw/gpio/trace-events
31
32
diff --git a/Makefile.objs b/Makefile.objs
33
index XXXXXXX..XXXXXXX 100644
34
--- a/Makefile.objs
35
+++ b/Makefile.objs
36
@@ -XXX,XX +XXX,XX @@ trace-events-subdirs += hw/vfio
37
trace-events-subdirs += hw/virtio
38
trace-events-subdirs += hw/watchdog
39
trace-events-subdirs += hw/xen
40
+trace-events-subdirs += hw/gpio
41
trace-events-subdirs += io
42
trace-events-subdirs += linux-user
43
trace-events-subdirs += migration
44
diff --git a/hw/gpio/Makefile.objs b/hw/gpio/Makefile.objs
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/gpio/Makefile.objs
47
+++ b/hw/gpio/Makefile.objs
48
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_GPIO_KEY) += gpio_key.o
49
obj-$(CONFIG_OMAP) += omap_gpio.o
50
obj-$(CONFIG_IMX) += imx_gpio.o
51
obj-$(CONFIG_RASPI) += bcm2835_gpio.o
52
+obj-$(CONFIG_NRF51_SOC) += nrf51_gpio.o
53
diff --git a/include/hw/gpio/nrf51_gpio.h b/include/hw/gpio/nrf51_gpio.h
54
new file mode 100644
55
index XXXXXXX..XXXXXXX
56
--- /dev/null
57
+++ b/include/hw/gpio/nrf51_gpio.h
58
@@ -XXX,XX +XXX,XX @@
59
+/*
60
+ * nRF51 System-on-Chip general purpose input/output register definition
61
+ *
62
+ * QEMU interface:
63
+ * + sysbus MMIO regions 0: GPIO registers
64
+ * + Unnamed GPIO inputs 0-31: Set tri-state input level for GPIO pin.
65
+ * Level -1: Externally Disconnected/Floating; Pull-up/down will be regarded
66
+ * Level 0: Input externally driven LOW
67
+ * Level 1: Input externally driven HIGH
68
+ * + Unnamed GPIO outputs 0-31:
69
+ * Level -1: Disconnected/Floating
70
+ * Level 0: Driven LOW
71
+ * Level 1: Driven HIGH
72
+ *
73
+ * Accuracy of the peripheral model:
74
+ * + The nRF51 GPIO output driver supports two modes, standard and high-current
75
+ * mode. These different drive modes are not modeled and handled the same.
76
+ * + Pin SENSEing is not modeled/implemented.
77
+ *
78
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
79
+ *
80
+ * This code is licensed under the GPL version 2 or later. See
81
+ * the COPYING file in the top-level directory.
82
+ *
83
+ */
84
+#ifndef NRF51_GPIO_H
85
+#define NRF51_GPIO_H
86
+
87
+#include "hw/sysbus.h"
88
+#define TYPE_NRF51_GPIO "nrf51_soc.gpio"
89
+#define NRF51_GPIO(obj) OBJECT_CHECK(NRF51GPIOState, (obj), TYPE_NRF51_GPIO)
90
+
91
+#define NRF51_GPIO_PINS 32
92
+
93
+#define NRF51_GPIO_SIZE 0x1000
94
+
95
+#define NRF51_GPIO_REG_OUT 0x504
96
+#define NRF51_GPIO_REG_OUTSET 0x508
97
+#define NRF51_GPIO_REG_OUTCLR 0x50C
98
+#define NRF51_GPIO_REG_IN 0x510
99
+#define NRF51_GPIO_REG_DIR 0x514
100
+#define NRF51_GPIO_REG_DIRSET 0x518
101
+#define NRF51_GPIO_REG_DIRCLR 0x51C
102
+#define NRF51_GPIO_REG_CNF_START 0x700
103
+#define NRF51_GPIO_REG_CNF_END 0x77F
104
+
105
+#define NRF51_GPIO_PULLDOWN 1
106
+#define NRF51_GPIO_PULLUP 3
107
+
108
+typedef struct NRF51GPIOState {
109
+ SysBusDevice parent_obj;
110
+
111
+ MemoryRegion mmio;
112
+ qemu_irq irq;
113
+
114
+ uint32_t out;
115
+ uint32_t in;
116
+ uint32_t in_mask;
117
+ uint32_t dir;
118
+ uint32_t cnf[NRF51_GPIO_PINS];
119
+
120
+ uint32_t old_out;
121
+ uint32_t old_out_connected;
122
+
123
+ qemu_irq output[NRF51_GPIO_PINS];
124
+} NRF51GPIOState;
125
+
126
+
127
+#endif
128
diff --git a/hw/gpio/nrf51_gpio.c b/hw/gpio/nrf51_gpio.c
129
new file mode 100644
130
index XXXXXXX..XXXXXXX
131
--- /dev/null
132
+++ b/hw/gpio/nrf51_gpio.c
133
@@ -XXX,XX +XXX,XX @@
134
+/*
135
+ * nRF51 System-on-Chip general purpose input/output register definition
136
+ *
137
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
138
+ * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf
139
+ *
140
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
141
+ *
142
+ * This code is licensed under the GPL version 2 or later. See
143
+ * the COPYING file in the top-level directory.
144
+ */
145
+
146
+#include "qemu/osdep.h"
147
+#include "qemu/log.h"
148
+#include "hw/gpio/nrf51_gpio.h"
149
+#include "trace.h"
150
+
151
+/*
152
+ * Check if the output driver is connected to the direction switch
153
+ * given the current configuration and logic level.
154
+ * It is not differentiated between standard and "high"(-power) drive modes.
155
+ */
156
+static bool is_connected(uint32_t config, uint32_t level)
157
+{
158
+ bool state;
159
+ uint32_t drive_config = extract32(config, 8, 3);
160
+
161
+ switch (drive_config) {
162
+ case 0 ... 3:
163
+ state = true;
164
+ break;
165
+ case 4 ... 5:
166
+ state = level != 0;
167
+ break;
168
+ case 6 ... 7:
169
+ state = level == 0;
170
+ break;
171
+ default:
172
+ g_assert_not_reached();
173
+ break;
174
+ }
175
+
176
+ return state;
177
+}
178
+
179
+static void update_output_irq(NRF51GPIOState *s, size_t i,
180
+ bool connected, bool level)
181
+{
182
+ int64_t irq_level = connected ? level : -1;
183
+ bool old_connected = extract32(s->old_out_connected, i, 1);
184
+ bool old_level = extract32(s->old_out, i, 1);
185
+
186
+ if ((old_connected != connected) || (old_level != level)) {
187
+ qemu_set_irq(s->output[i], irq_level);
188
+ trace_nrf51_gpio_update_output_irq(i, irq_level);
189
+ }
190
+
191
+ s->old_out = deposit32(s->old_out, i, 1, level);
192
+ s->old_out_connected = deposit32(s->old_out_connected, i, 1, connected);
193
+}
194
+
195
+static void update_state(NRF51GPIOState *s)
196
+{
197
+ uint32_t pull;
198
+ size_t i;
199
+ bool connected_out, dir, connected_in, out, input;
200
+
201
+ for (i = 0; i < NRF51_GPIO_PINS; i++) {
202
+ pull = extract32(s->cnf[i], 2, 2);
203
+ dir = extract32(s->cnf[i], 0, 1);
204
+ connected_in = extract32(s->in_mask, i, 1);
205
+ out = extract32(s->out, i, 1);
206
+ input = !extract32(s->cnf[i], 1, 1);
207
+ connected_out = is_connected(s->cnf[i], out) && dir;
208
+
209
+ update_output_irq(s, i, connected_out, out);
210
+
211
+ /* Pin both driven externally and internally */
212
+ if (connected_out && connected_in) {
213
+ qemu_log_mask(LOG_GUEST_ERROR, "GPIO pin %zu short circuited\n", i);
214
+ }
215
+
216
+ /*
217
+ * Input buffer disconnected from internal/external drives, so
218
+ * pull-up/pull-down becomes relevant
219
+ */
220
+ if (!input || (input && !connected_in && !connected_out)) {
221
+ if (pull == NRF51_GPIO_PULLDOWN) {
222
+ s->in = deposit32(s->in, i, 1, 0);
223
+ } else if (pull == NRF51_GPIO_PULLUP) {
224
+ s->in = deposit32(s->in, i, 1, 1);
225
+ }
226
+ }
227
+
228
+ /* Self stimulation through internal output driver */
229
+ if (connected_out && !connected_in && input) {
230
+ s->in = deposit32(s->in, i, 1, out);
231
+ }
232
+ }
233
+
234
+}
235
+
236
+/*
237
+ * Direction is exposed in both the DIR register and the DIR bit
238
+ * of each PINs CNF configuration register. Reflect bits for pins in DIR
239
+ * to individual pin configuration registers.
240
+ */
241
+static void reflect_dir_bit_in_cnf(NRF51GPIOState *s)
242
+{
243
+ size_t i;
244
+
245
+ uint32_t value = s->dir;
246
+
247
+ for (i = 0; i < NRF51_GPIO_PINS; i++) {
248
+ s->cnf[i] = (s->cnf[i] & ~(1UL)) | ((value >> i) & 0x01);
249
+ }
250
+}
251
+
252
+static uint64_t nrf51_gpio_read(void *opaque, hwaddr offset, unsigned int size)
253
+{
254
+ NRF51GPIOState *s = NRF51_GPIO(opaque);
255
+ uint64_t r = 0;
256
+ size_t idx;
257
+
258
+ switch (offset) {
259
+ case NRF51_GPIO_REG_OUT ... NRF51_GPIO_REG_OUTCLR:
260
+ r = s->out;
261
+ break;
262
+
263
+ case NRF51_GPIO_REG_IN:
264
+ r = s->in;
265
+ break;
266
+
267
+ case NRF51_GPIO_REG_DIR ... NRF51_GPIO_REG_DIRCLR:
268
+ r = s->dir;
269
+ break;
270
+
271
+ case NRF51_GPIO_REG_CNF_START ... NRF51_GPIO_REG_CNF_END:
272
+ idx = (offset - NRF51_GPIO_REG_CNF_START) / 4;
273
+ r = s->cnf[idx];
274
+ break;
275
+
276
+ default:
277
+ qemu_log_mask(LOG_GUEST_ERROR,
278
+ "%s: bad read offset 0x%" HWADDR_PRIx "\n",
279
+ __func__, offset);
280
+ }
281
+
282
+ trace_nrf51_gpio_read(offset, r);
283
+
284
+ return r;
285
+}
286
+
287
+static void nrf51_gpio_write(void *opaque, hwaddr offset,
288
+ uint64_t value, unsigned int size)
289
+{
290
+ NRF51GPIOState *s = NRF51_GPIO(opaque);
291
+ size_t idx;
292
+
293
+ trace_nrf51_gpio_write(offset, value);
294
+
295
+ switch (offset) {
296
+ case NRF51_GPIO_REG_OUT:
297
+ s->out = value;
298
+ break;
299
+
300
+ case NRF51_GPIO_REG_OUTSET:
301
+ s->out |= value;
302
+ break;
303
+
304
+ case NRF51_GPIO_REG_OUTCLR:
305
+ s->out &= ~value;
306
+ break;
307
+
308
+ case NRF51_GPIO_REG_DIR:
309
+ s->dir = value;
310
+ reflect_dir_bit_in_cnf(s);
311
+ break;
312
+
313
+ case NRF51_GPIO_REG_DIRSET:
314
+ s->dir |= value;
315
+ reflect_dir_bit_in_cnf(s);
316
+ break;
317
+
318
+ case NRF51_GPIO_REG_DIRCLR:
319
+ s->dir &= ~value;
320
+ reflect_dir_bit_in_cnf(s);
321
+ break;
322
+
323
+ case NRF51_GPIO_REG_CNF_START ... NRF51_GPIO_REG_CNF_END:
324
+ idx = (offset - NRF51_GPIO_REG_CNF_START) / 4;
325
+ s->cnf[idx] = value;
326
+ /*
327
+ * direction is exposed in both the DIR register and the DIR bit
328
+ * of each PINs CNF configuration register.
329
+ */
330
+ s->dir = (s->dir & ~(1UL << idx)) | ((value & 0x01) << idx);
331
+ break;
332
+
333
+ default:
334
+ qemu_log_mask(LOG_GUEST_ERROR,
335
+ "%s: bad write offset 0x%" HWADDR_PRIx "\n",
336
+ __func__, offset);
337
+ }
338
+
339
+ update_state(s);
340
+}
341
+
342
+static const MemoryRegionOps gpio_ops = {
343
+ .read = nrf51_gpio_read,
344
+ .write = nrf51_gpio_write,
345
+ .endianness = DEVICE_LITTLE_ENDIAN,
346
+ .impl.min_access_size = 4,
347
+ .impl.max_access_size = 4,
348
+};
349
+
350
+static void nrf51_gpio_set(void *opaque, int line, int value)
351
+{
352
+ NRF51GPIOState *s = NRF51_GPIO(opaque);
353
+
354
+ trace_nrf51_gpio_set(line, value);
355
+
356
+ assert(line >= 0 && line < NRF51_GPIO_PINS);
357
+
358
+ s->in_mask = deposit32(s->in_mask, line, 1, value >= 0);
359
+ if (value >= 0) {
360
+ s->in = deposit32(s->in, line, 1, value != 0);
361
+ }
362
+
363
+ update_state(s);
364
+}
365
+
366
+static void nrf51_gpio_reset(DeviceState *dev)
367
+{
368
+ NRF51GPIOState *s = NRF51_GPIO(dev);
369
+ size_t i;
370
+
371
+ s->out = 0;
372
+ s->old_out = 0;
373
+ s->old_out_connected = 0;
374
+ s->in = 0;
375
+ s->in_mask = 0;
376
+ s->dir = 0;
377
+
378
+ for (i = 0; i < NRF51_GPIO_PINS; i++) {
379
+ s->cnf[i] = 0x00000002;
380
+ }
381
+}
382
+
383
+static const VMStateDescription vmstate_nrf51_gpio = {
384
+ .name = TYPE_NRF51_GPIO,
385
+ .version_id = 1,
386
+ .minimum_version_id = 1,
387
+ .fields = (VMStateField[]) {
388
+ VMSTATE_UINT32(out, NRF51GPIOState),
389
+ VMSTATE_UINT32(in, NRF51GPIOState),
390
+ VMSTATE_UINT32(in_mask, NRF51GPIOState),
391
+ VMSTATE_UINT32(dir, NRF51GPIOState),
392
+ VMSTATE_UINT32_ARRAY(cnf, NRF51GPIOState, NRF51_GPIO_PINS),
393
+ VMSTATE_UINT32(old_out, NRF51GPIOState),
394
+ VMSTATE_UINT32(old_out_connected, NRF51GPIOState),
395
+ VMSTATE_END_OF_LIST()
396
+ }
397
+};
398
+
399
+static void nrf51_gpio_init(Object *obj)
400
+{
401
+ NRF51GPIOState *s = NRF51_GPIO(obj);
402
+
403
+ memory_region_init_io(&s->mmio, obj, &gpio_ops, s,
404
+ TYPE_NRF51_GPIO, NRF51_GPIO_SIZE);
405
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
406
+
407
+ qdev_init_gpio_in(DEVICE(s), nrf51_gpio_set, NRF51_GPIO_PINS);
408
+ qdev_init_gpio_out(DEVICE(s), s->output, NRF51_GPIO_PINS);
409
+}
410
+
411
+static void nrf51_gpio_class_init(ObjectClass *klass, void *data)
412
+{
413
+ DeviceClass *dc = DEVICE_CLASS(klass);
414
+
415
+ dc->vmsd = &vmstate_nrf51_gpio;
416
+ dc->reset = nrf51_gpio_reset;
417
+ dc->desc = "nRF51 GPIO";
418
+}
419
+
420
+static const TypeInfo nrf51_gpio_info = {
421
+ .name = TYPE_NRF51_GPIO,
422
+ .parent = TYPE_SYS_BUS_DEVICE,
423
+ .instance_size = sizeof(NRF51GPIOState),
424
+ .instance_init = nrf51_gpio_init,
425
+ .class_init = nrf51_gpio_class_init
426
+};
427
+
428
+static void nrf51_gpio_register_types(void)
429
+{
430
+ type_register_static(&nrf51_gpio_info);
431
+}
432
+
433
+type_init(nrf51_gpio_register_types)
434
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events
435
new file mode 100644
436
index XXXXXXX..XXXXXXX
437
--- /dev/null
438
+++ b/hw/gpio/trace-events
439
@@ -XXX,XX +XXX,XX @@
440
+# See docs/devel/tracing.txt for syntax documentation.
441
+
442
+# hw/gpio/nrf51_gpio.c
443
+nrf51_gpio_read(uint64_t offset, uint64_t r) "offset 0x%" PRIx64 " value 0x%" PRIx64
444
+nrf51_gpio_write(uint64_t offset, uint64_t value) "offset 0x%" PRIx64 " value 0x%" PRIx64
445
+nrf51_gpio_set(int64_t line, int64_t value) "line %" PRIi64 " value %" PRIi64
446
+nrf51_gpio_update_output_irq(int64_t line, int64_t value) "line %" PRIi64 " value %" PRIi64
447
\ No newline at end of file
448
--
449
2.19.2
450
451
diff view generated by jsdifflib
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
2
3
When there is no active interrupts in the GIC, a read to the C_RPR
3
Instantiates GPIO peripheral model
4
register should return the value of the "Idle priority", which is either
5
the maximum value an IRQ priority field can be set to, or 0xff.
6
4
7
Since the QEMU GIC model implements all the 8 priority bits, the Idle
5
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
8
priority is 0xff.
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
10
Internally, when there is no active interrupt, the running priority
11
value is 0x100. The gic_get_running_priority function returns an uint8_t
12
and thus, truncate this value to 0x00 when returning it. This is wrong since
13
a value of 0x00 correspond to the maximum possible priority.
14
15
This commit fixes the returned value when the internal value is 0x100.
16
17
Note that it is correct for the Non-Secure view to return 0xff even
18
though from the NS world point of view, only 7 priority bits are
19
implemented. The specification states that the Idle priority can be 0xff
20
even when not all the 8 priority bits are implemented. This has been
21
verified against a real GICv2 hardware on a Xilinx ZynqMP based board.
22
23
Regarding the ARM11MPCore version of the GIC, the specification is not
24
clear on that point, so this commit does not alter its behavior.
25
26
Signed-off-by: Luc MICHEL <luc.michel@git.antfield.fr>
27
Message-id: 20180119145756.7629-4-luc.michel@greensocs.com
28
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20190103091119.9367-7-stefanha@redhat.com
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
---
11
---
31
hw/intc/arm_gic.c | 5 +++++
12
include/hw/arm/nrf51_soc.h | 2 ++
32
1 file changed, 5 insertions(+)
13
hw/arm/nrf51_soc.c | 16 ++++++++++++++++
14
2 files changed, 18 insertions(+)
33
15
34
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
16
diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h
35
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/intc/arm_gic.c
18
--- a/include/hw/arm/nrf51_soc.h
37
+++ b/hw/intc/arm_gic.c
19
+++ b/include/hw/arm/nrf51_soc.h
38
@@ -XXX,XX +XXX,XX @@ static void gic_set_cpu_control(GICState *s, int cpu, uint32_t value,
20
@@ -XXX,XX +XXX,XX @@
39
21
#include "hw/arm/armv7m.h"
40
static uint8_t gic_get_running_priority(GICState *s, int cpu, MemTxAttrs attrs)
22
#include "hw/char/nrf51_uart.h"
41
{
23
#include "hw/misc/nrf51_rng.h"
42
+ if ((s->revision != REV_11MPCORE) && (s->running_priority[cpu] > 0xff)) {
24
+#include "hw/gpio/nrf51_gpio.h"
43
+ /* Idle priority */
25
44
+ return 0xff;
26
#define TYPE_NRF51_SOC "nrf51-soc"
27
#define NRF51_SOC(obj) \
28
@@ -XXX,XX +XXX,XX @@ typedef struct NRF51State {
29
30
NRF51UARTState uart;
31
NRF51RNGState rng;
32
+ NRF51GPIOState gpio;
33
34
MemoryRegion iomem;
35
MemoryRegion sram;
36
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/arm/nrf51_soc.c
39
+++ b/hw/arm/nrf51_soc.c
40
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
41
qdev_get_gpio_in(DEVICE(&s->cpu),
42
BASE_TO_IRQ(NRF51_RNG_BASE)));
43
44
+ /* GPIO */
45
+ object_property_set_bool(OBJECT(&s->gpio), true, "realized", &err);
46
+ if (err) {
47
+ error_propagate(errp, err);
48
+ return;
45
+ }
49
+ }
46
+
50
+
47
if (s->security_extn && !attrs.secure) {
51
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gpio), 0);
48
if (s->running_priority[cpu] & 0x80) {
52
+ memory_region_add_subregion_overlap(&s->container, NRF51_GPIO_BASE, mr, 0);
49
/* Running priority in upper half of range: return the Non-secure
53
+
54
+ /* Pass all GPIOs to the SOC layer so they are available to the board */
55
+ qdev_pass_gpios(DEVICE(&s->gpio), dev_soc, NULL);
56
+
57
create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
58
NRF51_IOMEM_SIZE);
59
create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
60
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_init(Object *obj)
61
62
sysbus_init_child_obj(obj, "rng", &s->rng, sizeof(s->rng),
63
TYPE_NRF51_RNG);
64
+
65
+ sysbus_init_child_obj(obj, "gpio", &s->gpio, sizeof(s->gpio),
66
+ TYPE_NRF51_GPIO);
67
}
68
69
static Property nrf51_soc_properties[] = {
50
--
70
--
51
2.7.4
71
2.19.2
52
72
53
73
diff view generated by jsdifflib
New patch
1
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
3
The test suite for the nRF51 GPIO peripheral for now
4
only tests initial state. Additionally a set of
5
tests testing an implementation detail of the model
6
are included.
7
8
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
11
Message-id: 20190103091119.9367-8-stefanha@redhat.com
12
[PMM: fixed stray space at start of file]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
tests/Makefile.include | 2 +
16
tests/microbit-test.c | 160 +++++++++++++++++++++++++++++++++++++++++
17
2 files changed, 162 insertions(+)
18
create mode 100644 tests/microbit-test.c
19
20
diff --git a/tests/Makefile.include b/tests/Makefile.include
21
index XXXXXXX..XXXXXXX 100644
22
--- a/tests/Makefile.include
23
+++ b/tests/Makefile.include
24
@@ -XXX,XX +XXX,XX @@ check-qtest-sparc64-y += tests/boot-serial-test$(EXESUF)
25
check-qtest-arm-y += tests/tmp105-test$(EXESUF)
26
check-qtest-arm-y += tests/pca9552-test$(EXESUF)
27
check-qtest-arm-y += tests/ds1338-test$(EXESUF)
28
+check-qtest-arm-y += tests/microbit-test$(EXESUF)
29
check-qtest-arm-y += tests/m25p80-test$(EXESUF)
30
check-qtest-arm-y += tests/virtio-blk-test$(EXESUF)
31
check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
32
@@ -XXX,XX +XXX,XX @@ tests/pxe-test$(EXESUF): tests/pxe-test.o tests/boot-sector.o $(libqos-obj-y)
33
tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
34
tests/pca9552-test$(EXESUF): tests/pca9552-test.o $(libqos-omap-obj-y)
35
tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y)
36
+tests/microbit-test$(EXESUF): tests/microbit-test.o
37
tests/m25p80-test$(EXESUF): tests/m25p80-test.o
38
tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
39
tests/q35-test$(EXESUF): tests/q35-test.o $(libqos-pc-obj-y)
40
diff --git a/tests/microbit-test.c b/tests/microbit-test.c
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/tests/microbit-test.c
45
@@ -XXX,XX +XXX,XX @@
46
+/*
47
+ * QTest testcase for Microbit board using the Nordic Semiconductor nRF51 SoC.
48
+ *
49
+ * nRF51:
50
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
51
+ * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf
52
+ *
53
+ * Microbit Board: http://microbit.org/
54
+ *
55
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
56
+ *
57
+ * This code is licensed under the GPL version 2 or later. See
58
+ * the COPYING file in the top-level directory.
59
+ */
60
+
61
+
62
+#include "qemu/osdep.h"
63
+#include "exec/hwaddr.h"
64
+#include "libqtest.h"
65
+
66
+#include "hw/arm/nrf51.h"
67
+#include "hw/gpio/nrf51_gpio.h"
68
+
69
+static void test_nrf51_gpio(void)
70
+{
71
+ size_t i;
72
+ uint32_t actual, expected;
73
+
74
+ struct {
75
+ hwaddr addr;
76
+ uint32_t expected;
77
+ } const reset_state[] = {
78
+ {NRF51_GPIO_REG_OUT, 0x00000000}, {NRF51_GPIO_REG_OUTSET, 0x00000000},
79
+ {NRF51_GPIO_REG_OUTCLR, 0x00000000}, {NRF51_GPIO_REG_IN, 0x00000000},
80
+ {NRF51_GPIO_REG_DIR, 0x00000000}, {NRF51_GPIO_REG_DIRSET, 0x00000000},
81
+ {NRF51_GPIO_REG_DIRCLR, 0x00000000}
82
+ };
83
+
84
+ /* Check reset state */
85
+ for (i = 0; i < ARRAY_SIZE(reset_state); i++) {
86
+ expected = reset_state[i].expected;
87
+ actual = readl(NRF51_GPIO_BASE + reset_state[i].addr);
88
+ g_assert_cmpuint(actual, ==, expected);
89
+ }
90
+
91
+ for (i = 0; i < NRF51_GPIO_PINS; i++) {
92
+ expected = 0x00000002;
93
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START + i * 4);
94
+ g_assert_cmpuint(actual, ==, expected);
95
+ }
96
+
97
+ /* Check dir bit consistency between dir and cnf */
98
+ /* Check set via DIRSET */
99
+ expected = 0x80000001;
100
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIRSET, expected);
101
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR);
102
+ g_assert_cmpuint(actual, ==, expected);
103
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START) & 0x01;
104
+ g_assert_cmpuint(actual, ==, 0x01);
105
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01;
106
+ g_assert_cmpuint(actual, ==, 0x01);
107
+
108
+ /* Check clear via DIRCLR */
109
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIRCLR, 0x80000001);
110
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR);
111
+ g_assert_cmpuint(actual, ==, 0x00000000);
112
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START) & 0x01;
113
+ g_assert_cmpuint(actual, ==, 0x00);
114
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01;
115
+ g_assert_cmpuint(actual, ==, 0x00);
116
+
117
+ /* Check set via DIR */
118
+ expected = 0x80000001;
119
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR, expected);
120
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR);
121
+ g_assert_cmpuint(actual, ==, expected);
122
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START) & 0x01;
123
+ g_assert_cmpuint(actual, ==, 0x01);
124
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_END) & 0x01;
125
+ g_assert_cmpuint(actual, ==, 0x01);
126
+
127
+ /* Reset DIR */
128
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_DIR, 0x00000000);
129
+
130
+ /* Check Input propagates */
131
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x00);
132
+ qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, 0);
133
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
134
+ g_assert_cmpuint(actual, ==, 0x00);
135
+ qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, 1);
136
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
137
+ g_assert_cmpuint(actual, ==, 0x01);
138
+ qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, -1);
139
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
140
+ g_assert_cmpuint(actual, ==, 0x01);
141
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02);
142
+
143
+ /* Check pull-up working */
144
+ qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, 0);
145
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0000);
146
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
147
+ g_assert_cmpuint(actual, ==, 0x00);
148
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b1110);
149
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
150
+ g_assert_cmpuint(actual, ==, 0x01);
151
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02);
152
+
153
+ /* Check pull-down working */
154
+ qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, 1);
155
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0000);
156
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
157
+ g_assert_cmpuint(actual, ==, 0x01);
158
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0110);
159
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
160
+ g_assert_cmpuint(actual, ==, 0x00);
161
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0x02);
162
+ qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, -1);
163
+
164
+ /* Check Output propagates */
165
+ irq_intercept_out("/machine/nrf51");
166
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b0011);
167
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTSET, 0x01);
168
+ g_assert_true(get_irq(0));
169
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTCLR, 0x01);
170
+ g_assert_false(get_irq(0));
171
+
172
+ /* Check self-stimulation */
173
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b01);
174
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTSET, 0x01);
175
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
176
+ g_assert_cmpuint(actual, ==, 0x01);
177
+
178
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTCLR, 0x01);
179
+ actual = readl(NRF51_GPIO_BASE + NRF51_GPIO_REG_IN) & 0x01;
180
+ g_assert_cmpuint(actual, ==, 0x00);
181
+
182
+ /*
183
+ * Check short-circuit - generates an guest_error which must be checked
184
+ * manually as long as qtest can not scan qemu_log messages
185
+ */
186
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_CNF_START, 0b01);
187
+ writel(NRF51_GPIO_BASE + NRF51_GPIO_REG_OUTSET, 0x01);
188
+ qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, 0);
189
+}
190
+
191
+int main(int argc, char **argv)
192
+{
193
+ int ret;
194
+
195
+ g_test_init(&argc, &argv, NULL);
196
+
197
+ global_qtest = qtest_initf("-machine microbit");
198
+
199
+ qtest_add_func("/microbit/nrf51/gpio", test_nrf51_gpio);
200
+
201
+ ret = g_test_run();
202
+
203
+ qtest_quit(global_qtest);
204
+ return ret;
205
+}
206
--
207
2.19.2
208
209
diff view generated by jsdifflib
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
2
3
In the GIC, when an IRQ is acknowledged, its state goes from "pending"
3
This patch adds the model for the nRF51 timer peripheral.
4
to:
4
Currently, only the TIMER mode is implemented.
5
- "active" if the corresponding IRQ pin has been de-asserted
6
- "active and pending" otherwise.
7
The GICv2 manual states that when a IRQ becomes active (or active and
8
pending), the GIC should either signal another (higher priority) IRQ to
9
the CPU if there is one, or de-assert the CPU IRQ pin.
10
5
11
The current implementation of the GIC in QEMU does not check if the
6
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
12
IRQ is already active when looking for pending interrupts with
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
sufficient priority in gic_update(). This can lead to signaling an
8
Message-id: 20190103091119.9367-9-stefanha@redhat.com
14
interrupt that is already active.
15
16
This usually happens when splitting priority drop and interrupt
17
deactivation. On priority drop, the IRQ stays active until deactivation.
18
If it becomes pending again, chances are that it will be incorrectly
19
selected as best_irq in gic_update().
20
21
This commit fixes this by checking if the IRQ is not already active when
22
looking for best_irq in gic_update().
23
24
Note that regarding the ARM11MPCore GIC version, the corresponding
25
manual is not clear on that point, but it has has no priority
26
drop/interrupt deactivation separation, so this case should not happen.
27
28
Signed-off-by: Luc MICHEL <luc.michel@git.antfield.fr>
29
Message-id: 20180119145756.7629-3-luc.michel@greensocs.com
30
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
---
11
---
33
hw/intc/arm_gic.c | 1 +
12
hw/timer/Makefile.objs | 1 +
34
1 file changed, 1 insertion(+)
13
include/hw/timer/nrf51_timer.h | 80 +++++++
14
hw/timer/nrf51_timer.c | 393 +++++++++++++++++++++++++++++++++
15
hw/timer/trace-events | 5 +
16
4 files changed, 479 insertions(+)
17
create mode 100644 include/hw/timer/nrf51_timer.h
18
create mode 100644 hw/timer/nrf51_timer.c
35
19
36
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
20
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
37
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/intc/arm_gic.c
22
--- a/hw/timer/Makefile.objs
39
+++ b/hw/intc/arm_gic.c
23
+++ b/hw/timer/Makefile.objs
40
@@ -XXX,XX +XXX,XX @@ void gic_update(GICState *s)
24
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_IMX) += imx_gpt.o
41
best_irq = 1023;
25
common-obj-$(CONFIG_LM32) += lm32_timer.o
42
for (irq = 0; irq < s->num_irq; irq++) {
26
common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
43
if (GIC_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm) &&
27
common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp-rtc.o
44
+ (!GIC_TEST_ACTIVE(irq, cm)) &&
28
+common-obj-$(CONFIG_NRF51_SOC) += nrf51_timer.o
45
(irq < GIC_INTERNAL || GIC_TARGET(irq) & cm)) {
29
46
if (GIC_GET_PRIORITY(irq, cpu) < best_prio) {
30
obj-$(CONFIG_ALTERA_TIMER) += altera_timer.o
47
best_prio = GIC_GET_PRIORITY(irq, cpu);
31
obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o
32
diff --git a/include/hw/timer/nrf51_timer.h b/include/hw/timer/nrf51_timer.h
33
new file mode 100644
34
index XXXXXXX..XXXXXXX
35
--- /dev/null
36
+++ b/include/hw/timer/nrf51_timer.h
37
@@ -XXX,XX +XXX,XX @@
38
+/*
39
+ * nRF51 System-on-Chip Timer peripheral
40
+ *
41
+ * QEMU interface:
42
+ * + sysbus MMIO regions 0: GPIO registers
43
+ * + sysbus irq
44
+ *
45
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
46
+ *
47
+ * This code is licensed under the GPL version 2 or later. See
48
+ * the COPYING file in the top-level directory.
49
+ */
50
+#ifndef NRF51_TIMER_H
51
+#define NRF51_TIMER_H
52
+
53
+#include "hw/sysbus.h"
54
+#include "qemu/timer.h"
55
+#define TYPE_NRF51_TIMER "nrf51_soc.timer"
56
+#define NRF51_TIMER(obj) OBJECT_CHECK(NRF51TimerState, (obj), TYPE_NRF51_TIMER)
57
+
58
+#define NRF51_TIMER_REG_COUNT 4
59
+
60
+#define NRF51_TIMER_TASK_START 0x000
61
+#define NRF51_TIMER_TASK_STOP 0x004
62
+#define NRF51_TIMER_TASK_COUNT 0x008
63
+#define NRF51_TIMER_TASK_CLEAR 0x00C
64
+#define NRF51_TIMER_TASK_SHUTDOWN 0x010
65
+#define NRF51_TIMER_TASK_CAPTURE_0 0x040
66
+#define NRF51_TIMER_TASK_CAPTURE_3 0x04C
67
+
68
+#define NRF51_TIMER_EVENT_COMPARE_0 0x140
69
+#define NRF51_TIMER_EVENT_COMPARE_1 0x144
70
+#define NRF51_TIMER_EVENT_COMPARE_2 0x148
71
+#define NRF51_TIMER_EVENT_COMPARE_3 0x14C
72
+
73
+#define NRF51_TIMER_REG_SHORTS 0x200
74
+#define NRF51_TIMER_REG_SHORTS_MASK 0xf0f
75
+#define NRF51_TIMER_REG_INTENSET 0x304
76
+#define NRF51_TIMER_REG_INTENCLR 0x308
77
+#define NRF51_TIMER_REG_INTEN_MASK 0xf0000
78
+#define NRF51_TIMER_REG_MODE 0x504
79
+#define NRF51_TIMER_REG_MODE_MASK 0x01
80
+#define NRF51_TIMER_TIMER 0
81
+#define NRF51_TIMER_COUNTER 1
82
+#define NRF51_TIMER_REG_BITMODE 0x508
83
+#define NRF51_TIMER_REG_BITMODE_MASK 0x03
84
+#define NRF51_TIMER_WIDTH_16 0
85
+#define NRF51_TIMER_WIDTH_8 1
86
+#define NRF51_TIMER_WIDTH_24 2
87
+#define NRF51_TIMER_WIDTH_32 3
88
+#define NRF51_TIMER_REG_PRESCALER 0x510
89
+#define NRF51_TIMER_REG_PRESCALER_MASK 0x0F
90
+#define NRF51_TIMER_REG_CC0 0x540
91
+#define NRF51_TIMER_REG_CC3 0x54C
92
+
93
+typedef struct NRF51TimerState {
94
+ SysBusDevice parent_obj;
95
+
96
+ MemoryRegion iomem;
97
+ qemu_irq irq;
98
+
99
+ QEMUTimer timer;
100
+ int64_t timer_start_ns;
101
+ int64_t update_counter_ns;
102
+ uint32_t counter;
103
+
104
+ bool running;
105
+
106
+ uint8_t events_compare[NRF51_TIMER_REG_COUNT];
107
+ uint32_t cc[NRF51_TIMER_REG_COUNT];
108
+ uint32_t shorts;
109
+ uint32_t inten;
110
+ uint32_t mode;
111
+ uint32_t bitmode;
112
+ uint32_t prescaler;
113
+
114
+} NRF51TimerState;
115
+
116
+
117
+#endif
118
diff --git a/hw/timer/nrf51_timer.c b/hw/timer/nrf51_timer.c
119
new file mode 100644
120
index XXXXXXX..XXXXXXX
121
--- /dev/null
122
+++ b/hw/timer/nrf51_timer.c
123
@@ -XXX,XX +XXX,XX @@
124
+/*
125
+ * nRF51 System-on-Chip Timer peripheral
126
+ *
127
+ * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf
128
+ * Product Spec: http://infocenter.nordicsemi.com/pdf/nRF51822_PS_v3.1.pdf
129
+ *
130
+ * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de>
131
+ * Copyright (c) 2019 Red Hat, Inc.
132
+ *
133
+ * This code is licensed under the GPL version 2 or later. See
134
+ * the COPYING file in the top-level directory.
135
+ */
136
+
137
+#include "qemu/osdep.h"
138
+#include "qemu/log.h"
139
+#include "hw/arm/nrf51.h"
140
+#include "hw/timer/nrf51_timer.h"
141
+#include "trace.h"
142
+
143
+#define TIMER_CLK_FREQ 16000000UL
144
+
145
+static uint32_t const bitwidths[] = {16, 8, 24, 32};
146
+
147
+static uint32_t ns_to_ticks(NRF51TimerState *s, int64_t ns)
148
+{
149
+ uint32_t freq = TIMER_CLK_FREQ >> s->prescaler;
150
+
151
+ return muldiv64(ns, freq, NANOSECONDS_PER_SECOND);
152
+}
153
+
154
+static int64_t ticks_to_ns(NRF51TimerState *s, uint32_t ticks)
155
+{
156
+ uint32_t freq = TIMER_CLK_FREQ >> s->prescaler;
157
+
158
+ return muldiv64(ticks, NANOSECONDS_PER_SECOND, freq);
159
+}
160
+
161
+/* Returns number of ticks since last call */
162
+static uint32_t update_counter(NRF51TimerState *s, int64_t now)
163
+{
164
+ uint32_t ticks = ns_to_ticks(s, now - s->update_counter_ns);
165
+
166
+ s->counter = (s->counter + ticks) % BIT(bitwidths[s->bitmode]);
167
+ s->update_counter_ns = now;
168
+ return ticks;
169
+}
170
+
171
+/* Assumes s->counter is up-to-date */
172
+static void rearm_timer(NRF51TimerState *s, int64_t now)
173
+{
174
+ int64_t min_ns = INT64_MAX;
175
+ size_t i;
176
+
177
+ for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
178
+ int64_t delta_ns;
179
+
180
+ if (s->events_compare[i]) {
181
+ continue; /* already expired, ignore it for now */
182
+ }
183
+
184
+ if (s->cc[i] <= s->counter) {
185
+ delta_ns = ticks_to_ns(s, BIT(bitwidths[s->bitmode]) -
186
+ s->counter + s->cc[i]);
187
+ } else {
188
+ delta_ns = ticks_to_ns(s, s->cc[i] - s->counter);
189
+ }
190
+
191
+ if (delta_ns < min_ns) {
192
+ min_ns = delta_ns;
193
+ }
194
+ }
195
+
196
+ if (min_ns != INT64_MAX) {
197
+ timer_mod_ns(&s->timer, now + min_ns);
198
+ }
199
+}
200
+
201
+static void update_irq(NRF51TimerState *s)
202
+{
203
+ bool flag = false;
204
+ size_t i;
205
+
206
+ for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
207
+ flag |= s->events_compare[i] && extract32(s->inten, 16 + i, 1);
208
+ }
209
+ qemu_set_irq(s->irq, flag);
210
+}
211
+
212
+static void timer_expire(void *opaque)
213
+{
214
+ NRF51TimerState *s = NRF51_TIMER(opaque);
215
+ int64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
216
+ uint32_t cc_remaining[NRF51_TIMER_REG_COUNT];
217
+ bool should_stop = false;
218
+ uint32_t ticks;
219
+ size_t i;
220
+
221
+ for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
222
+ if (s->cc[i] > s->counter) {
223
+ cc_remaining[i] = s->cc[i] - s->counter;
224
+ } else {
225
+ cc_remaining[i] = BIT(bitwidths[s->bitmode]) -
226
+ s->counter + s->cc[i];
227
+ }
228
+ }
229
+
230
+ ticks = update_counter(s, now);
231
+
232
+ for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
233
+ if (cc_remaining[i] <= ticks) {
234
+ s->events_compare[i] = 1;
235
+
236
+ if (s->shorts & BIT(i)) {
237
+ s->timer_start_ns = now;
238
+ s->update_counter_ns = s->timer_start_ns;
239
+ s->counter = 0;
240
+ }
241
+
242
+ should_stop |= s->shorts & BIT(i + 8);
243
+ }
244
+ }
245
+
246
+ update_irq(s);
247
+
248
+ if (should_stop) {
249
+ s->running = false;
250
+ timer_del(&s->timer);
251
+ } else {
252
+ rearm_timer(s, now);
253
+ }
254
+}
255
+
256
+static void counter_compare(NRF51TimerState *s)
257
+{
258
+ uint32_t counter = s->counter;
259
+ size_t i;
260
+
261
+ for (i = 0; i < NRF51_TIMER_REG_COUNT; i++) {
262
+ if (counter == s->cc[i]) {
263
+ s->events_compare[i] = 1;
264
+
265
+ if (s->shorts & BIT(i)) {
266
+ s->counter = 0;
267
+ }
268
+ }
269
+ }
270
+}
271
+
272
+static uint64_t nrf51_timer_read(void *opaque, hwaddr offset, unsigned int size)
273
+{
274
+ NRF51TimerState *s = NRF51_TIMER(opaque);
275
+ uint64_t r = 0;
276
+
277
+ switch (offset) {
278
+ case NRF51_TIMER_EVENT_COMPARE_0 ... NRF51_TIMER_EVENT_COMPARE_3:
279
+ r = s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4];
280
+ break;
281
+ case NRF51_TIMER_REG_SHORTS:
282
+ r = s->shorts;
283
+ break;
284
+ case NRF51_TIMER_REG_INTENSET:
285
+ r = s->inten;
286
+ break;
287
+ case NRF51_TIMER_REG_INTENCLR:
288
+ r = s->inten;
289
+ break;
290
+ case NRF51_TIMER_REG_MODE:
291
+ r = s->mode;
292
+ break;
293
+ case NRF51_TIMER_REG_BITMODE:
294
+ r = s->bitmode;
295
+ break;
296
+ case NRF51_TIMER_REG_PRESCALER:
297
+ r = s->prescaler;
298
+ break;
299
+ case NRF51_TIMER_REG_CC0 ... NRF51_TIMER_REG_CC3:
300
+ r = s->cc[(offset - NRF51_TIMER_REG_CC0) / 4];
301
+ break;
302
+ default:
303
+ qemu_log_mask(LOG_GUEST_ERROR,
304
+ "%s: bad read offset 0x%" HWADDR_PRIx "\n",
305
+ __func__, offset);
306
+ }
307
+
308
+ trace_nrf51_timer_read(offset, r, size);
309
+
310
+ return r;
311
+}
312
+
313
+static void nrf51_timer_write(void *opaque, hwaddr offset,
314
+ uint64_t value, unsigned int size)
315
+{
316
+ NRF51TimerState *s = NRF51_TIMER(opaque);
317
+ uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
318
+ size_t idx;
319
+
320
+ trace_nrf51_timer_write(offset, value, size);
321
+
322
+ switch (offset) {
323
+ case NRF51_TIMER_TASK_START:
324
+ if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_TIMER) {
325
+ s->running = true;
326
+ s->timer_start_ns = now - ticks_to_ns(s, s->counter);
327
+ s->update_counter_ns = s->timer_start_ns;
328
+ rearm_timer(s, now);
329
+ }
330
+ break;
331
+ case NRF51_TIMER_TASK_STOP:
332
+ case NRF51_TIMER_TASK_SHUTDOWN:
333
+ if (value == NRF51_TRIGGER_TASK) {
334
+ s->running = false;
335
+ timer_del(&s->timer);
336
+ }
337
+ break;
338
+ case NRF51_TIMER_TASK_COUNT:
339
+ if (value == NRF51_TRIGGER_TASK && s->mode == NRF51_TIMER_COUNTER) {
340
+ s->counter = (s->counter + 1) % BIT(bitwidths[s->bitmode]);
341
+ counter_compare(s);
342
+ }
343
+ break;
344
+ case NRF51_TIMER_TASK_CLEAR:
345
+ if (value == NRF51_TRIGGER_TASK) {
346
+ s->timer_start_ns = now;
347
+ s->update_counter_ns = s->timer_start_ns;
348
+ s->counter = 0;
349
+ if (s->running) {
350
+ rearm_timer(s, now);
351
+ }
352
+ }
353
+ break;
354
+ case NRF51_TIMER_TASK_CAPTURE_0 ... NRF51_TIMER_TASK_CAPTURE_3:
355
+ if (value == NRF51_TRIGGER_TASK) {
356
+ if (s->running) {
357
+ timer_expire(s); /* update counter and all state */
358
+ }
359
+
360
+ idx = (offset - NRF51_TIMER_TASK_CAPTURE_0) / 4;
361
+ s->cc[idx] = s->counter;
362
+ }
363
+ break;
364
+ case NRF51_TIMER_EVENT_COMPARE_0 ... NRF51_TIMER_EVENT_COMPARE_3:
365
+ if (value == NRF51_EVENT_CLEAR) {
366
+ s->events_compare[(offset - NRF51_TIMER_EVENT_COMPARE_0) / 4] = 0;
367
+
368
+ if (s->running) {
369
+ timer_expire(s); /* update counter and all state */
370
+ }
371
+ }
372
+ break;
373
+ case NRF51_TIMER_REG_SHORTS:
374
+ s->shorts = value & NRF51_TIMER_REG_SHORTS_MASK;
375
+ break;
376
+ case NRF51_TIMER_REG_INTENSET:
377
+ s->inten |= value & NRF51_TIMER_REG_INTEN_MASK;
378
+ break;
379
+ case NRF51_TIMER_REG_INTENCLR:
380
+ s->inten &= ~(value & NRF51_TIMER_REG_INTEN_MASK);
381
+ break;
382
+ case NRF51_TIMER_REG_MODE:
383
+ s->mode = value;
384
+ break;
385
+ case NRF51_TIMER_REG_BITMODE:
386
+ if (s->mode == NRF51_TIMER_TIMER && s->running) {
387
+ qemu_log_mask(LOG_GUEST_ERROR,
388
+ "%s: erroneous change of BITMODE while timer is running\n",
389
+ __func__);
390
+ }
391
+ s->bitmode = value & NRF51_TIMER_REG_BITMODE_MASK;
392
+ break;
393
+ case NRF51_TIMER_REG_PRESCALER:
394
+ if (s->mode == NRF51_TIMER_TIMER && s->running) {
395
+ qemu_log_mask(LOG_GUEST_ERROR,
396
+ "%s: erroneous change of PRESCALER while timer is running\n",
397
+ __func__);
398
+ }
399
+ s->prescaler = value & NRF51_TIMER_REG_PRESCALER_MASK;
400
+ break;
401
+ case NRF51_TIMER_REG_CC0 ... NRF51_TIMER_REG_CC3:
402
+ if (s->running) {
403
+ timer_expire(s); /* update counter */
404
+ }
405
+
406
+ idx = (offset - NRF51_TIMER_REG_CC0) / 4;
407
+ s->cc[idx] = value % BIT(bitwidths[s->bitmode]);
408
+
409
+ if (s->running) {
410
+ rearm_timer(s, now);
411
+ }
412
+ break;
413
+ default:
414
+ qemu_log_mask(LOG_GUEST_ERROR,
415
+ "%s: bad write offset 0x%" HWADDR_PRIx "\n",
416
+ __func__, offset);
417
+ }
418
+
419
+ update_irq(s);
420
+}
421
+
422
+static const MemoryRegionOps rng_ops = {
423
+ .read = nrf51_timer_read,
424
+ .write = nrf51_timer_write,
425
+ .endianness = DEVICE_LITTLE_ENDIAN,
426
+ .impl.min_access_size = 4,
427
+ .impl.max_access_size = 4,
428
+};
429
+
430
+static void nrf51_timer_init(Object *obj)
431
+{
432
+ NRF51TimerState *s = NRF51_TIMER(obj);
433
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
434
+
435
+ memory_region_init_io(&s->iomem, obj, &rng_ops, s,
436
+ TYPE_NRF51_TIMER, NRF51_TIMER_SIZE);
437
+ sysbus_init_mmio(sbd, &s->iomem);
438
+ sysbus_init_irq(sbd, &s->irq);
439
+
440
+ timer_init_ns(&s->timer, QEMU_CLOCK_VIRTUAL, timer_expire, s);
441
+}
442
+
443
+static void nrf51_timer_reset(DeviceState *dev)
444
+{
445
+ NRF51TimerState *s = NRF51_TIMER(dev);
446
+
447
+ timer_del(&s->timer);
448
+ s->timer_start_ns = 0x00;
449
+ s->update_counter_ns = 0x00;
450
+ s->counter = 0x00;
451
+ s->running = false;
452
+
453
+ memset(s->events_compare, 0x00, sizeof(s->events_compare));
454
+ memset(s->cc, 0x00, sizeof(s->cc));
455
+
456
+ s->shorts = 0x00;
457
+ s->inten = 0x00;
458
+ s->mode = 0x00;
459
+ s->bitmode = 0x00;
460
+ s->prescaler = 0x00;
461
+}
462
+
463
+static int nrf51_timer_post_load(void *opaque, int version_id)
464
+{
465
+ NRF51TimerState *s = NRF51_TIMER(opaque);
466
+
467
+ if (s->running && s->mode == NRF51_TIMER_TIMER) {
468
+ timer_expire(s);
469
+ }
470
+ return 0;
471
+}
472
+
473
+static const VMStateDescription vmstate_nrf51_timer = {
474
+ .name = TYPE_NRF51_TIMER,
475
+ .version_id = 1,
476
+ .post_load = nrf51_timer_post_load,
477
+ .fields = (VMStateField[]) {
478
+ VMSTATE_TIMER(timer, NRF51TimerState),
479
+ VMSTATE_INT64(timer_start_ns, NRF51TimerState),
480
+ VMSTATE_INT64(update_counter_ns, NRF51TimerState),
481
+ VMSTATE_UINT32(counter, NRF51TimerState),
482
+ VMSTATE_BOOL(running, NRF51TimerState),
483
+ VMSTATE_UINT8_ARRAY(events_compare, NRF51TimerState,
484
+ NRF51_TIMER_REG_COUNT),
485
+ VMSTATE_UINT32_ARRAY(cc, NRF51TimerState, NRF51_TIMER_REG_COUNT),
486
+ VMSTATE_UINT32(shorts, NRF51TimerState),
487
+ VMSTATE_UINT32(inten, NRF51TimerState),
488
+ VMSTATE_UINT32(mode, NRF51TimerState),
489
+ VMSTATE_UINT32(bitmode, NRF51TimerState),
490
+ VMSTATE_UINT32(prescaler, NRF51TimerState),
491
+ VMSTATE_END_OF_LIST()
492
+ }
493
+};
494
+
495
+static void nrf51_timer_class_init(ObjectClass *klass, void *data)
496
+{
497
+ DeviceClass *dc = DEVICE_CLASS(klass);
498
+
499
+ dc->reset = nrf51_timer_reset;
500
+ dc->vmsd = &vmstate_nrf51_timer;
501
+}
502
+
503
+static const TypeInfo nrf51_timer_info = {
504
+ .name = TYPE_NRF51_TIMER,
505
+ .parent = TYPE_SYS_BUS_DEVICE,
506
+ .instance_size = sizeof(NRF51TimerState),
507
+ .instance_init = nrf51_timer_init,
508
+ .class_init = nrf51_timer_class_init
509
+};
510
+
511
+static void nrf51_timer_register_types(void)
512
+{
513
+ type_register_static(&nrf51_timer_info);
514
+}
515
+
516
+type_init(nrf51_timer_register_types)
517
diff --git a/hw/timer/trace-events b/hw/timer/trace-events
518
index XXXXXXX..XXXXXXX 100644
519
--- a/hw/timer/trace-events
520
+++ b/hw/timer/trace-events
521
@@ -XXX,XX +XXX,XX @@ sun4v_rtc_write(uint64_t addr, uint64_t value) "write: addr 0x%" PRIx64 " value
522
523
# hw/timer/xlnx-zynqmp-rtc.c
524
xlnx_zynqmp_rtc_gettime(int year, int month, int day, int hour, int min, int sec) "Get time from host: %d-%d-%d %2d:%02d:%02d"
525
+
526
+# hw/timer/nrf51_timer.c
527
+nrf51_timer_read(uint64_t addr, uint32_t value, unsigned size) "read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
528
+nrf51_timer_write(uint64_t addr, uint32_t value, unsigned size) "write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
529
+
48
--
530
--
49
2.7.4
531
2.19.2
50
532
51
533
diff view generated by jsdifflib
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
2
3
The actual imx_eth_enable_rx() function is buggy.
3
Instantiates TIMER0 - TIMER2
4
4
5
It updates s->regs[ENET_RDAR] after calling qemu_flush_queued_packets().
5
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
6
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
qemu_flush_queued_packets() is going to call imx_XXX_receive() which itself
8
is going to call imx_eth_enable_rx().
9
10
By updating s->regs[ENET_RDAR] after calling qemu_flush_queued_packets()
11
we end up updating the register with an outdated value which might
12
lead to disabling the receive function in the i.MX FEC/ENET device.
13
14
This patch change the place where the register update is done so that the
15
register value stays up to date and the receive function can keep
16
running.
17
18
Reported-by: Fyleo <fyleo45@gmail.com>
19
Tested-by: Fyleo <fyleo45@gmail.com>
20
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
21
Message-id: 20180113113445.2705-1-jcd@tribudubois.net
22
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Andrey Smirnov <andrew.smirnov@gmail.com>
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
24
Tested-by: Andrey Smirnov <andrew.smirnov@gmail.com>
9
Message-id: 20190103091119.9367-10-stefanha@redhat.com
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
11
---
27
hw/net/imx_fec.c | 8 ++------
12
include/hw/arm/nrf51_soc.h | 4 ++++
28
1 file changed, 2 insertions(+), 6 deletions(-)
13
hw/arm/nrf51_soc.c | 26 ++++++++++++++++++++++++++
14
2 files changed, 30 insertions(+)
29
15
30
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
16
diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h
31
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/net/imx_fec.c
18
--- a/include/hw/arm/nrf51_soc.h
33
+++ b/hw/net/imx_fec.c
19
+++ b/include/hw/arm/nrf51_soc.h
34
@@ -XXX,XX +XXX,XX @@ static void imx_eth_do_tx(IMXFECState *s, uint32_t index)
20
@@ -XXX,XX +XXX,XX @@
35
static void imx_eth_enable_rx(IMXFECState *s, bool flush)
21
#include "hw/char/nrf51_uart.h"
22
#include "hw/misc/nrf51_rng.h"
23
#include "hw/gpio/nrf51_gpio.h"
24
+#include "hw/timer/nrf51_timer.h"
25
26
#define TYPE_NRF51_SOC "nrf51-soc"
27
#define NRF51_SOC(obj) \
28
OBJECT_CHECK(NRF51State, (obj), TYPE_NRF51_SOC)
29
30
+#define NRF51_NUM_TIMERS 3
31
+
32
typedef struct NRF51State {
33
/*< private >*/
34
SysBusDevice parent_obj;
35
@@ -XXX,XX +XXX,XX @@ typedef struct NRF51State {
36
NRF51UARTState uart;
37
NRF51RNGState rng;
38
NRF51GPIOState gpio;
39
+ NRF51TimerState timer[NRF51_NUM_TIMERS];
40
41
MemoryRegion iomem;
42
MemoryRegion sram;
43
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/arm/nrf51_soc.c
46
+++ b/hw/arm/nrf51_soc.c
47
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
48
NRF51State *s = NRF51_SOC(dev_soc);
49
MemoryRegion *mr;
50
Error *err = NULL;
51
+ uint8_t i = 0;
52
+ hwaddr base_addr = 0;
53
54
if (!s->board_memory) {
55
error_setg(errp, "memory property was not set");
56
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
57
/* Pass all GPIOs to the SOC layer so they are available to the board */
58
qdev_pass_gpios(DEVICE(&s->gpio), dev_soc, NULL);
59
60
+ /* TIMER */
61
+ for (i = 0; i < NRF51_NUM_TIMERS; i++) {
62
+ object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
63
+ if (err) {
64
+ error_propagate(errp, err);
65
+ return;
66
+ }
67
+
68
+ base_addr = NRF51_TIMER_BASE + i * NRF51_TIMER_SIZE;
69
+
70
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->timer[i]), 0, base_addr);
71
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer[i]), 0,
72
+ qdev_get_gpio_in(DEVICE(&s->cpu),
73
+ BASE_TO_IRQ(base_addr)));
74
+ }
75
+
76
create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
77
NRF51_IOMEM_SIZE);
78
create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
79
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
80
81
static void nrf51_soc_init(Object *obj)
36
{
82
{
37
IMXFECBufDesc bd;
83
+ uint8_t i = 0;
38
- bool rx_ring_full;
84
+
39
85
NRF51State *s = NRF51_SOC(obj);
40
imx_fec_read_bd(&bd, s->rx_descriptor);
86
41
87
memory_region_init(&s->container, obj, "nrf51-container", UINT64_MAX);
42
- rx_ring_full = !(bd.flags & ENET_BD_E);
88
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_init(Object *obj)
43
+ s->regs[ENET_RDAR] = (bd.flags & ENET_BD_E) ? ENET_RDAR_RDAR : 0;
89
44
90
sysbus_init_child_obj(obj, "gpio", &s->gpio, sizeof(s->gpio),
45
- if (rx_ring_full) {
91
TYPE_NRF51_GPIO);
46
+ if (!s->regs[ENET_RDAR]) {
92
+
47
FEC_PRINTF("RX buffer full\n");
93
+ for (i = 0; i < NRF51_NUM_TIMERS; i++) {
48
} else if (flush) {
94
+ sysbus_init_child_obj(obj, "timer[*]", &s->timer[i],
49
qemu_flush_queued_packets(qemu_get_queue(s->nic));
95
+ sizeof(s->timer[i]), TYPE_NRF51_TIMER);
50
}
96
+
51
-
97
+ }
52
- s->regs[ENET_RDAR] = rx_ring_full ? 0 : ENET_RDAR_RDAR;
53
}
98
}
54
99
55
static void imx_eth_reset(DeviceState *d)
100
static Property nrf51_soc_properties[] = {
56
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
57
case ENET_RDAR:
58
if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
59
if (!s->regs[index]) {
60
- s->regs[index] = ENET_RDAR_RDAR;
61
imx_eth_enable_rx(s, true);
62
}
63
} else {
64
--
101
--
65
2.7.4
102
2.19.2
66
103
67
104
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
2
3
At the same time, move VMSTATE_UINT32_SUB_ARRAY
3
Basic tests for nRF51 Timer Peripheral.
4
beside the other UINT32 definitions.
5
4
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Message-id: 20180119045438.28582-8-richard.henderson@linaro.org
8
Message-id: 20190103091119.9367-11-stefanha@redhat.com
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
include/migration/vmstate.h | 9 ++++++---
11
tests/microbit-test.c | 95 +++++++++++++++++++++++++++++++++++++++++++
14
1 file changed, 6 insertions(+), 3 deletions(-)
12
1 file changed, 95 insertions(+)
15
13
16
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
14
diff --git a/tests/microbit-test.c b/tests/microbit-test.c
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/include/migration/vmstate.h
16
--- a/tests/microbit-test.c
19
+++ b/include/migration/vmstate.h
17
+++ b/tests/microbit-test.c
20
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
18
@@ -XXX,XX +XXX,XX @@
21
#define VMSTATE_UINT32_ARRAY(_f, _s, _n) \
19
22
VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0)
20
#include "hw/arm/nrf51.h"
23
21
#include "hw/gpio/nrf51_gpio.h"
24
+#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \
22
+#include "hw/timer/nrf51_timer.h"
25
+ VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t)
23
24
static void test_nrf51_gpio(void)
25
{
26
@@ -XXX,XX +XXX,XX @@ static void test_nrf51_gpio(void)
27
qtest_set_irq_in(global_qtest, "/machine/nrf51", "unnamed-gpio-in", 0, 0);
28
}
29
30
+static void timer_task(hwaddr task)
31
+{
32
+ writel(NRF51_TIMER_BASE + task, NRF51_TRIGGER_TASK);
33
+}
26
+
34
+
27
#define VMSTATE_UINT32_2DARRAY(_f, _s, _n1, _n2) \
35
+static void timer_clear_event(hwaddr event)
28
VMSTATE_UINT32_2DARRAY_V(_f, _s, _n1, _n2, 0)
36
+{
29
37
+ writel(NRF51_TIMER_BASE + event, NRF51_EVENT_CLEAR);
30
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
38
+}
31
#define VMSTATE_UINT64_ARRAY(_f, _s, _n) \
32
VMSTATE_UINT64_ARRAY_V(_f, _s, _n, 0)
33
34
+#define VMSTATE_UINT64_SUB_ARRAY(_f, _s, _start, _num) \
35
+ VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint64, uint64_t)
36
+
39
+
37
#define VMSTATE_UINT64_2DARRAY(_f, _s, _n1, _n2) \
40
+static void timer_set_bitmode(uint8_t mode)
38
VMSTATE_UINT64_2DARRAY_V(_f, _s, _n1, _n2, 0)
41
+{
39
42
+ writel(NRF51_TIMER_BASE + NRF51_TIMER_REG_BITMODE, mode);
40
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
43
+}
41
#define VMSTATE_INT32_ARRAY(_f, _s, _n) \
44
+
42
VMSTATE_INT32_ARRAY_V(_f, _s, _n, 0)
45
+static void timer_set_prescaler(uint8_t prescaler)
43
46
+{
44
-#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \
47
+ writel(NRF51_TIMER_BASE + NRF51_TIMER_REG_PRESCALER, prescaler);
45
- VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t)
48
+}
46
-
49
+
47
#define VMSTATE_INT64_ARRAY_V(_f, _s, _n, _v) \
50
+static void timer_set_cc(size_t idx, uint32_t value)
48
VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int64, int64_t)
51
+{
52
+ writel(NRF51_TIMER_BASE + NRF51_TIMER_REG_CC0 + idx * 4, value);
53
+}
54
+
55
+static void timer_assert_events(uint32_t ev0, uint32_t ev1, uint32_t ev2,
56
+ uint32_t ev3)
57
+{
58
+ g_assert(readl(NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_0) == ev0);
59
+ g_assert(readl(NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_1) == ev1);
60
+ g_assert(readl(NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_2) == ev2);
61
+ g_assert(readl(NRF51_TIMER_BASE + NRF51_TIMER_EVENT_COMPARE_3) == ev3);
62
+}
63
+
64
+static void test_nrf51_timer(void)
65
+{
66
+ uint32_t steps_to_overflow = 408;
67
+
68
+ /* Compare Match */
69
+ timer_task(NRF51_TIMER_TASK_STOP);
70
+ timer_task(NRF51_TIMER_TASK_CLEAR);
71
+
72
+ timer_clear_event(NRF51_TIMER_EVENT_COMPARE_0);
73
+ timer_clear_event(NRF51_TIMER_EVENT_COMPARE_1);
74
+ timer_clear_event(NRF51_TIMER_EVENT_COMPARE_2);
75
+ timer_clear_event(NRF51_TIMER_EVENT_COMPARE_3);
76
+
77
+ timer_set_bitmode(NRF51_TIMER_WIDTH_16); /* 16 MHz Timer */
78
+ timer_set_prescaler(0);
79
+ /* Swept over in first step */
80
+ timer_set_cc(0, 2);
81
+ /* Barely miss on first step */
82
+ timer_set_cc(1, 162);
83
+ /* Spot on on third step */
84
+ timer_set_cc(2, 480);
85
+
86
+ timer_assert_events(0, 0, 0, 0);
87
+
88
+ timer_task(NRF51_TIMER_TASK_START);
89
+ clock_step(10000);
90
+ timer_assert_events(1, 0, 0, 0);
91
+
92
+ /* Swept over on first overflow */
93
+ timer_set_cc(3, 114);
94
+
95
+ clock_step(10000);
96
+ timer_assert_events(1, 1, 0, 0);
97
+
98
+ clock_step(10000);
99
+ timer_assert_events(1, 1, 1, 0);
100
+
101
+ /* Wrap time until internal counter overflows */
102
+ while (steps_to_overflow--) {
103
+ timer_assert_events(1, 1, 1, 0);
104
+ clock_step(10000);
105
+ }
106
+
107
+ timer_assert_events(1, 1, 1, 1);
108
+
109
+ timer_clear_event(NRF51_TIMER_EVENT_COMPARE_0);
110
+ timer_clear_event(NRF51_TIMER_EVENT_COMPARE_1);
111
+ timer_clear_event(NRF51_TIMER_EVENT_COMPARE_2);
112
+ timer_clear_event(NRF51_TIMER_EVENT_COMPARE_3);
113
+ timer_assert_events(0, 0, 0, 0);
114
+
115
+ timer_task(NRF51_TIMER_TASK_STOP);
116
+
117
+ /* Test Proposal: Stop/Shutdown */
118
+ /* Test Proposal: Shortcut Compare -> Clear */
119
+ /* Test Proposal: Shortcut Compare -> Stop */
120
+ /* Test Proposal: Counter Mode */
121
+}
122
+
123
int main(int argc, char **argv)
124
{
125
int ret;
126
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv)
127
global_qtest = qtest_initf("-machine microbit");
128
129
qtest_add_func("/microbit/nrf51/gpio", test_nrf51_gpio);
130
+ qtest_add_func("/microbit/nrf51/timer", test_nrf51_timer);
131
132
ret = g_test_run();
49
133
50
--
134
--
51
2.7.4
135
2.19.2
52
136
53
137
diff view generated by jsdifflib
1
From: Linus Walleij <linus.walleij@linaro.org>
1
From: Steffen Görtz <contrib@steffen-goertz.de>
2
2
3
This implements rudimentary support for interrupt generation on the
3
This stubs enables the microbit-micropython firmware to run
4
PL110. I am working on a new DRI/KMS driver for Linux and since that
4
on the microbit machine.
5
uses the blanking interrupt, we need something to fire here. Without
6
any interrupt support Linux waits for a while and then gives ugly
7
messages about the vblank not working in the console (it does not
8
hang perpetually or anything though, DRI is pretty forgiving).
9
5
10
I solved it for now by setting up a timer to fire at 60Hz and pull
6
Signed-off-by: Steffen Görtz <contrib@steffen-goertz.de>
11
the interrupts for "vertical compare" and "next memory base"
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
at this interval. This works fine and fires roughly the same number
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
13
of IRQs on QEMU as on the hardware and leaves the console clean
9
Message-id: 20190103091119.9367-12-stefanha@redhat.com
14
and nice.
15
16
People who want to create more accurate emulation can probably work
17
on top of this if need be. It is certainly closer to the hardware
18
behaviour than what we have today anyway.
19
20
Cc: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
22
Message-id: 20180123225654.5764-1-linus.walleij@linaro.org
23
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
24
[PMM: folded long lines]
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
11
---
27
hw/display/pl110.c | 30 +++++++++++++++++++++++++++++-
12
include/hw/arm/nrf51_soc.h | 1 +
28
1 file changed, 29 insertions(+), 1 deletion(-)
13
hw/arm/nrf51_soc.c | 26 ++++++++++++++++++++++++++
14
2 files changed, 27 insertions(+)
29
15
30
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
16
diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h
31
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/display/pl110.c
18
--- a/include/hw/arm/nrf51_soc.h
33
+++ b/hw/display/pl110.c
19
+++ b/include/hw/arm/nrf51_soc.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct NRF51State {
21
MemoryRegion iomem;
22
MemoryRegion sram;
23
MemoryRegion flash;
24
+ MemoryRegion clock;
25
26
uint32_t sram_size;
27
uint32_t flash_size;
28
diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/arm/nrf51_soc.c
31
+++ b/hw/arm/nrf51_soc.c
34
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@
35
#include "ui/console.h"
33
36
#include "framebuffer.h"
34
#define BASE_TO_IRQ(base) ((base >> 12) & 0x1F)
37
#include "ui/pixel_ops.h"
35
38
+#include "qemu/timer.h"
36
+static uint64_t clock_read(void *opaque, hwaddr addr, unsigned int size)
39
#include "qemu/log.h"
37
+{
40
38
+ qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " [%u]\n",
41
#define PL110_CR_EN 0x001
39
+ __func__, addr, size);
42
@@ -XXX,XX +XXX,XX @@
40
+ return 1;
43
#define PL110_CR_BEBO 0x200
44
#define PL110_CR_BEPO 0x400
45
#define PL110_CR_PWR 0x800
46
+#define PL110_IE_NB 0x004
47
+#define PL110_IE_VC 0x008
48
49
enum pl110_bppmode
50
{
51
@@ -XXX,XX +XXX,XX @@ typedef struct PL110State {
52
MemoryRegion iomem;
53
MemoryRegionSection fbsection;
54
QemuConsole *con;
55
+ QEMUTimer *vblank_timer;
56
57
int version;
58
uint32_t timing[4];
59
@@ -XXX,XX +XXX,XX @@ static void pl110_resize(PL110State *s, int width, int height)
60
/* Update interrupts. */
61
static void pl110_update(PL110State *s)
62
{
63
- /* TODO: Implement interrupts. */
64
+ /* Raise IRQ if enabled and any status bit is 1 */
65
+ if (s->int_status & s->int_mask) {
66
+ qemu_irq_raise(s->irq);
67
+ } else {
68
+ qemu_irq_lower(s->irq);
69
+ }
70
+}
41
+}
71
+
42
+
72
+static void pl110_vblank_interrupt(void *opaque)
43
+static void clock_write(void *opaque, hwaddr addr, uint64_t data,
44
+ unsigned int size)
73
+{
45
+{
74
+ PL110State *s = opaque;
46
+ qemu_log_mask(LOG_UNIMP, "%s: 0x%" HWADDR_PRIx " <- 0x%" PRIx64 " [%u]\n",
47
+ __func__, addr, data, size);
48
+}
75
+
49
+
76
+ /* Fire the vertical compare and next base IRQs and re-arm */
50
+static const MemoryRegionOps clock_ops = {
77
+ s->int_status |= (PL110_IE_NB | PL110_IE_VC);
51
+ .read = clock_read,
78
+ timer_mod(s->vblank_timer,
52
+ .write = clock_write
79
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
53
+};
80
+ NANOSECONDS_PER_SECOND / 60);
54
+
81
+ pl110_update(s);
55
+
82
}
56
static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
83
57
{
84
static uint64_t pl110_read(void *opaque, hwaddr offset,
58
NRF51State *s = NRF51_SOC(dev_soc);
85
@@ -XXX,XX +XXX,XX @@ static void pl110_write(void *opaque, hwaddr offset,
59
@@ -XXX,XX +XXX,XX @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp)
86
s->bpp = (val >> 1) & 7;
60
BASE_TO_IRQ(base_addr)));
87
if (pl110_enabled(s)) {
61
}
88
qemu_console_resize(s->con, s->cols, s->rows);
62
89
+ timer_mod(s->vblank_timer,
63
+ /* STUB Peripherals */
90
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
64
+ memory_region_init_io(&s->clock, NULL, &clock_ops, NULL,
91
+ NANOSECONDS_PER_SECOND / 60);
65
+ "nrf51_soc.clock", 0x1000);
92
+ } else {
66
+ memory_region_add_subregion_overlap(&s->container,
93
+ timer_del(s->vblank_timer);
67
+ NRF51_IOMEM_BASE, &s->clock, -1);
94
}
68
+
95
break;
69
create_unimplemented_device("nrf51_soc.io", NRF51_IOMEM_BASE,
96
case 10: /* LCDICR */
70
NRF51_IOMEM_SIZE);
97
@@ -XXX,XX +XXX,XX @@ static void pl110_realize(DeviceState *dev, Error **errp)
71
create_unimplemented_device("nrf51_soc.ficr", NRF51_FICR_BASE,
98
memory_region_init_io(&s->iomem, OBJECT(s), &pl110_ops, s, "pl110", 0x1000);
99
sysbus_init_mmio(sbd, &s->iomem);
100
sysbus_init_irq(sbd, &s->irq);
101
+ s->vblank_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
102
+ pl110_vblank_interrupt, s);
103
qdev_init_gpio_in(dev, pl110_mux_ctrl_set, 1);
104
s->con = graphic_console_init(dev, 0, &pl110_gfx_ops, s);
105
}
106
--
72
--
107
2.7.4
73
2.19.2
108
74
109
75
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
Now that MTTCG is here, the comment in the 32-bit Arm decoder that
2
"Since the emulation does not have barriers, the acquire/release
3
semantics need no special handling" is no longer true. Emit the
4
correct barriers for the load-acquire/store-release insns, as
5
we already do in the A64 decoder.
2
6
3
All direct users of this field want an integral value. Drop all
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
of the extra casting between uint64_t and float64.
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
---
11
target/arm/translate.c | 33 ++++++++++++++++++++++++++-------
12
1 file changed, 26 insertions(+), 7 deletions(-)
5
13
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180119045438.28582-6-richard.henderson@linaro.org
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/cpu.h | 2 +-
12
target/arm/arch_dump.c | 4 ++--
13
target/arm/helper.c | 20 ++++++++++----------
14
target/arm/machine.c | 2 +-
15
target/arm/translate-a64.c | 8 ++++----
16
target/arm/translate.c | 2 +-
17
6 files changed, 19 insertions(+), 19 deletions(-)
18
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
24
* the two execution states, and means we do not need to explicitly
25
* map these registers when changing states.
26
*/
27
- float64 regs[64];
28
+ uint64_t regs[64];
29
30
uint32_t xregs[16];
31
/* We store these fpcsr fields separately for convenience. */
32
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/arch_dump.c
35
+++ b/target/arm/arch_dump.c
36
@@ -XXX,XX +XXX,XX @@ static int aarch64_write_elf64_prfpreg(WriteCoreDumpFunction f,
37
aarch64_note_init(&note, s, "CORE", 5, NT_PRFPREG, sizeof(note.vfp));
38
39
for (i = 0; i < 64; ++i) {
40
- note.vfp.vregs[i] = cpu_to_dump64(s, float64_val(env->vfp.regs[i]));
41
+ note.vfp.vregs[i] = cpu_to_dump64(s, env->vfp.regs[i]);
42
}
43
44
if (s->dump_info.d_endian == ELFDATA2MSB) {
45
@@ -XXX,XX +XXX,XX @@ static int arm_write_elf32_vfp(WriteCoreDumpFunction f, CPUARMState *env,
46
arm_note_init(&note, s, "LINUX", 6, NT_ARM_VFP, sizeof(note.vfp));
47
48
for (i = 0; i < 32; ++i) {
49
- note.vfp.vregs[i] = cpu_to_dump64(s, float64_val(env->vfp.regs[i]));
50
+ note.vfp.vregs[i] = cpu_to_dump64(s, env->vfp.regs[i]);
51
}
52
53
note.vfp.fpscr = cpu_to_dump32(s, vfp_get_fpscr(env));
54
diff --git a/target/arm/helper.c b/target/arm/helper.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/helper.c
57
+++ b/target/arm/helper.c
58
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
59
/* VFP data registers are always little-endian. */
60
nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
61
if (reg < nregs) {
62
- stfq_le_p(buf, env->vfp.regs[reg]);
63
+ stq_le_p(buf, env->vfp.regs[reg]);
64
return 8;
65
}
66
if (arm_feature(env, ARM_FEATURE_NEON)) {
67
/* Aliases for Q regs. */
68
nregs += 16;
69
if (reg < nregs) {
70
- stfq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
71
- stfq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
72
+ stq_le_p(buf, env->vfp.regs[(reg - 32) * 2]);
73
+ stq_le_p(buf + 8, env->vfp.regs[(reg - 32) * 2 + 1]);
74
return 16;
75
}
76
}
77
@@ -XXX,XX +XXX,XX @@ static int vfp_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
78
79
nregs = arm_feature(env, ARM_FEATURE_VFP3) ? 32 : 16;
80
if (reg < nregs) {
81
- env->vfp.regs[reg] = ldfq_le_p(buf);
82
+ env->vfp.regs[reg] = ldq_le_p(buf);
83
return 8;
84
}
85
if (arm_feature(env, ARM_FEATURE_NEON)) {
86
nregs += 16;
87
if (reg < nregs) {
88
- env->vfp.regs[(reg - 32) * 2] = ldfq_le_p(buf);
89
- env->vfp.regs[(reg - 32) * 2 + 1] = ldfq_le_p(buf + 8);
90
+ env->vfp.regs[(reg - 32) * 2] = ldq_le_p(buf);
91
+ env->vfp.regs[(reg - 32) * 2 + 1] = ldq_le_p(buf + 8);
92
return 16;
93
}
94
}
95
@@ -XXX,XX +XXX,XX @@ static int aarch64_fpu_gdb_get_reg(CPUARMState *env, uint8_t *buf, int reg)
96
switch (reg) {
97
case 0 ... 31:
98
/* 128 bit FP register */
99
- stfq_le_p(buf, env->vfp.regs[reg * 2]);
100
- stfq_le_p(buf + 8, env->vfp.regs[reg * 2 + 1]);
101
+ stq_le_p(buf, env->vfp.regs[reg * 2]);
102
+ stq_le_p(buf + 8, env->vfp.regs[reg * 2 + 1]);
103
return 16;
104
case 32:
105
/* FPSR */
106
@@ -XXX,XX +XXX,XX @@ static int aarch64_fpu_gdb_set_reg(CPUARMState *env, uint8_t *buf, int reg)
107
switch (reg) {
108
case 0 ... 31:
109
/* 128 bit FP register */
110
- env->vfp.regs[reg * 2] = ldfq_le_p(buf);
111
- env->vfp.regs[reg * 2 + 1] = ldfq_le_p(buf + 8);
112
+ env->vfp.regs[reg * 2] = ldq_le_p(buf);
113
+ env->vfp.regs[reg * 2 + 1] = ldq_le_p(buf + 8);
114
return 16;
115
case 32:
116
/* FPSR */
117
diff --git a/target/arm/machine.c b/target/arm/machine.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/target/arm/machine.c
120
+++ b/target/arm/machine.c
121
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_vfp = {
122
.minimum_version_id = 3,
123
.needed = vfp_needed,
124
.fields = (VMStateField[]) {
125
- VMSTATE_FLOAT64_ARRAY(env.vfp.regs, ARMCPU, 64),
126
+ VMSTATE_UINT64_ARRAY(env.vfp.regs, ARMCPU, 64),
127
/* The xregs array is a little awkward because element 1 (FPSCR)
128
* requires a specific accessor, so we have to split it up in
129
* the vmstate:
130
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/target/arm/translate-a64.c
133
+++ b/target/arm/translate-a64.c
134
@@ -XXX,XX +XXX,XX @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
135
if (flags & CPU_DUMP_FPU) {
136
int numvfpregs = 32;
137
for (i = 0; i < numvfpregs; i += 2) {
138
- uint64_t vlo = float64_val(env->vfp.regs[i * 2]);
139
- uint64_t vhi = float64_val(env->vfp.regs[(i * 2) + 1]);
140
+ uint64_t vlo = env->vfp.regs[i * 2];
141
+ uint64_t vhi = env->vfp.regs[(i * 2) + 1];
142
cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 " ",
143
i, vhi, vlo);
144
- vlo = float64_val(env->vfp.regs[(i + 1) * 2]);
145
- vhi = float64_val(env->vfp.regs[((i + 1) * 2) + 1]);
146
+ vlo = env->vfp.regs[(i + 1) * 2];
147
+ vhi = env->vfp.regs[((i + 1) * 2) + 1];
148
cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "\n",
149
i + 1, vhi, vlo);
150
}
151
diff --git a/target/arm/translate.c b/target/arm/translate.c
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
152
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
153
--- a/target/arm/translate.c
16
--- a/target/arm/translate.c
154
+++ b/target/arm/translate.c
17
+++ b/target/arm/translate.c
155
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
18
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
156
numvfpregs += 16;
19
rd = (insn >> 12) & 0xf;
157
}
20
if (insn & (1 << 23)) {
158
for (i = 0; i < numvfpregs; i++) {
21
/* load/store exclusive */
159
- uint64_t v = float64_val(env->vfp.regs[i]);
22
+ bool is_ld = extract32(insn, 20, 1);
160
+ uint64_t v = env->vfp.regs[i];
23
+ bool is_lasr = !extract32(insn, 8, 1);
161
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
24
int op2 = (insn >> 8) & 3;
162
i * 2, (uint32_t)v,
25
op1 = (insn >> 21) & 0x3;
163
i * 2 + 1, (uint32_t)(v >> 32),
26
27
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
28
addr = tcg_temp_local_new_i32();
29
load_reg_var(s, addr, rn);
30
31
- /* Since the emulation does not have barriers,
32
- the acquire/release semantics need no special
33
- handling */
34
+ if (is_lasr && !is_ld) {
35
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
36
+ }
37
+
38
if (op2 == 0) {
39
- if (insn & (1 << 20)) {
40
+ if (is_ld) {
41
tmp = tcg_temp_new_i32();
42
switch (op1) {
43
case 0: /* lda */
44
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
45
}
46
tcg_temp_free_i32(tmp);
47
}
48
- } else if (insn & (1 << 20)) {
49
+ } else if (is_ld) {
50
switch (op1) {
51
case 0: /* ldrex */
52
gen_load_exclusive(s, rd, 15, addr, 2);
53
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
54
}
55
}
56
tcg_temp_free_i32(addr);
57
+
58
+ if (is_lasr && is_ld) {
59
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
60
+ }
61
} else if ((insn & 0x00300f00) == 0) {
62
/* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
63
* - SWP, SWPB
64
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
65
tcg_gen_addi_i32(tmp, tmp, s->pc);
66
store_reg(s, 15, tmp);
67
} else {
68
+ bool is_lasr = false;
69
+ bool is_ld = extract32(insn, 20, 1);
70
int op2 = (insn >> 6) & 0x3;
71
op = (insn >> 4) & 0x3;
72
switch (op2) {
73
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
74
case 3:
75
/* Load-acquire/store-release exclusive */
76
ARCH(8);
77
+ is_lasr = true;
78
break;
79
}
80
+
81
+ if (is_lasr && !is_ld) {
82
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
83
+ }
84
+
85
addr = tcg_temp_local_new_i32();
86
load_reg_var(s, addr, rn);
87
if (!(op2 & 1)) {
88
- if (insn & (1 << 20)) {
89
+ if (is_ld) {
90
tmp = tcg_temp_new_i32();
91
switch (op) {
92
case 0: /* ldab */
93
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
94
}
95
tcg_temp_free_i32(tmp);
96
}
97
- } else if (insn & (1 << 20)) {
98
+ } else if (is_ld) {
99
gen_load_exclusive(s, rs, rd, addr, op);
100
} else {
101
gen_store_exclusive(s, rm, rs, rd, addr, op);
102
}
103
tcg_temp_free_i32(addr);
104
+
105
+ if (is_lasr && is_ld) {
106
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
107
+ }
108
}
109
} else {
110
/* Load/store multiple, RFE, SRS. */
164
--
111
--
165
2.7.4
112
2.19.2
166
113
167
114
diff view generated by jsdifflib
1
We were passing a NULL error pointer to the object_property_set_bool()
1
In the TZ Memory Protection Controller, the BLK_MAX register is supposed
2
call that realizes the CPU object. This meant that we wouldn't detect
2
to return the maximum permitted value of the BLK_IDX register. Our
3
failure, and would plough blindly on to crash later trying to use a
3
implementation incorrectly returned max+1 (ie the total number of
4
NULL CPU object pointer. Detect errors and fail instead.
4
valid index values, since BLK_IDX is zero-based).
5
5
6
In particular, this will be necessary to detect the user error
6
Correct this off-by-one error. Since we consistently initialize
7
of using "-cpu host" without "-enable-kvm" once we make the host
7
and use s->blk_max throughout the implementation as the 'size'
8
CPU type be registered unconditionally rather than only in
8
of the LUT, just adjust the value we return when the guest reads
9
kvm_arch_init().
9
the BLK_MAX register, rather than trying to change the semantics
10
of the s->blk_max internal struct field.
10
11
12
Fixes: https://bugs.launchpad.net/qemu/+bug/1806824
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20181213183249.3468-1-peter.maydell@linaro.org
12
---
16
---
13
hw/arm/virt.c | 2 +-
17
hw/misc/tz-mpc.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
18
1 file changed, 1 insertion(+), 1 deletion(-)
15
19
16
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
20
diff --git a/hw/misc/tz-mpc.c b/hw/misc/tz-mpc.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/virt.c
22
--- a/hw/misc/tz-mpc.c
19
+++ b/hw/arm/virt.c
23
+++ b/hw/misc/tz-mpc.c
20
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
24
@@ -XXX,XX +XXX,XX @@ static MemTxResult tz_mpc_reg_read(void *opaque, hwaddr addr,
21
"secure-memory", &error_abort);
25
r = s->ctrl;
22
}
26
break;
23
27
case A_BLK_MAX:
24
- object_property_set_bool(cpuobj, true, "realized", NULL);
28
- r = s->blk_max;
25
+ object_property_set_bool(cpuobj, true, "realized", &error_fatal);
29
+ r = s->blk_max - 1;
26
object_unref(cpuobj);
30
break;
27
}
31
case A_BLK_CFG:
28
fdt_add_timer_nodes(vms);
32
/* We are never in "init in progress state", so this just indicates
29
--
33
--
30
2.7.4
34
2.19.2
31
35
32
36
diff view generated by jsdifflib
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1
From: Nick Hudson <nick.hudson@gmx.co.uk>
2
2
3
Commit ("3b39d734141a target/arm: Handle page table walk load failures
3
noload kernels are loaded with the u-boot image header and as a result
4
correctly") modified both versions of the page table walking code (i.e.,
4
the header size needs adding to the entry point. Fake up a hdr so the
5
arm_ldl_ptw and arm_ldq_ptw) to record the result of the translation in
5
kernel image is loaded at the right address and the entry point is
6
a temporary 'data' variable so that it can be inspected before being
6
adjusted appropriately.
7
returned. However, arm_ldq_ptw() returns an uint64_t, and using a
8
temporary uint32_t variable truncates the upper bits, corrupting the
9
result. This causes problems when using more than 4 GB of memory in
10
a TCG guest. So use a uint64_t instead.
11
7
12
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
8
The default location for the uboot file is 32MiB above bottom of DRAM.
13
Message-id: 20180119194648.25501-1-ard.biesheuvel@linaro.org
9
This matches the recommendation in Documentation/arm/Booting.
10
11
Clarify the load_uimage API to state the passing of a load address when an
12
image doesn't specify one, or when loading a ramdisk is expected.
13
14
Adjust callers of load_uimage, etc.
15
16
Signed-off-by: Nick Hudson <skrll@netbsd.org>
17
Message-id: 11488a08-1fe0-a278-2210-deb64731107f@gmx.co.uk
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
20
---
17
target/arm/helper.c | 2 +-
21
hw/core/uboot_image.h | 1 +
18
1 file changed, 1 insertion(+), 1 deletion(-)
22
include/hw/loader.h | 7 ++++++-
23
hw/arm/boot.c | 8 +++++---
24
hw/core/loader.c | 19 ++++++++++++++++---
25
hw/microblaze/boot.c | 2 +-
26
hw/nios2/boot.c | 2 +-
27
hw/ppc/e500.c | 1 +
28
hw/ppc/ppc440_bamboo.c | 2 +-
29
hw/ppc/sam460ex.c | 2 +-
30
9 files changed, 33 insertions(+), 11 deletions(-)
19
31
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
diff --git a/hw/core/uboot_image.h b/hw/core/uboot_image.h
21
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
34
--- a/hw/core/uboot_image.h
23
+++ b/target/arm/helper.c
35
+++ b/hw/core/uboot_image.h
24
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
36
@@ -XXX,XX +XXX,XX @@
25
MemTxAttrs attrs = {};
37
#define IH_TYPE_SCRIPT        6    /* Script file            */
26
MemTxResult result = MEMTX_OK;
38
#define IH_TYPE_FILESYSTEM    7    /* Filesystem Image (any type)    */
27
AddressSpace *as;
39
#define IH_TYPE_FLATDT        8    /* Binary Flat Device Tree Blob    */
28
- uint32_t data;
40
+#define IH_TYPE_KERNEL_NOLOAD 14    /* OS Kernel Image (noload)    */
29
+ uint64_t data;
41
30
42
/*
31
attrs.secure = is_secure;
43
* Compression Types
32
as = arm_addressspace(cs, attrs);
44
diff --git a/include/hw/loader.h b/include/hw/loader.h
45
index XXXXXXX..XXXXXXX 100644
46
--- a/include/hw/loader.h
47
+++ b/include/hw/loader.h
48
@@ -XXX,XX +XXX,XX @@ void load_elf_hdr(const char *filename, void *hdr, bool *is64, Error **errp);
49
int load_aout(const char *filename, hwaddr addr, int max_sz,
50
int bswap_needed, hwaddr target_page_size);
51
52
+#define LOAD_UIMAGE_LOADADDR_INVALID (-1)
53
+
54
/** load_uimage_as:
55
* @filename: Path of uimage file
56
* @ep: Populated with program entry point. Ignored if NULL.
57
- * @loadaddr: Populated with the load address. Ignored if NULL.
58
+ * @loadaddr: load address if none specified in the image or when loading a
59
+ * ramdisk. Populated with the load address. Ignored if NULL or
60
+ * LOAD_UIMAGE_LOADADDR_INVALID (images which do not specify a load
61
+ * address will not be loadable).
62
* @is_linux: Is set to true if the image loaded is Linux. Ignored if NULL.
63
* @translate_fn: optional function to translate load addresses
64
* @translate_opaque: opaque data passed to @translate_fn
65
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/boot.c
68
+++ b/hw/arm/boot.c
69
@@ -XXX,XX +XXX,XX @@
70
* Documentation/arm/Booting and Documentation/arm64/booting.txt
71
* They have different preferred image load offsets from system RAM base.
72
*/
73
-#define KERNEL_ARGS_ADDR 0x100
74
-#define KERNEL_LOAD_ADDR 0x00010000
75
+#define KERNEL_ARGS_ADDR 0x100
76
+#define KERNEL_NOLOAD_ADDR 0x02000000
77
+#define KERNEL_LOAD_ADDR 0x00010000
78
#define KERNEL64_LOAD_ADDR 0x00080000
79
80
#define ARM64_TEXT_OFFSET_OFFSET 8
81
@@ -XXX,XX +XXX,XX @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
82
}
83
entry = elf_entry;
84
if (kernel_size < 0) {
85
- kernel_size = load_uimage_as(info->kernel_filename, &entry, NULL,
86
+ uint64_t loadaddr = info->loader_start + KERNEL_NOLOAD_ADDR;
87
+ kernel_size = load_uimage_as(info->kernel_filename, &entry, &loadaddr,
88
&is_linux, NULL, NULL, as);
89
}
90
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
91
diff --git a/hw/core/loader.c b/hw/core/loader.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/hw/core/loader.c
94
+++ b/hw/core/loader.c
95
@@ -XXX,XX +XXX,XX @@ static int load_uboot_image(const char *filename, hwaddr *ep, hwaddr *loadaddr,
96
goto out;
97
98
if (hdr->ih_type != image_type) {
99
- fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type,
100
- image_type);
101
- goto out;
102
+ if (!(image_type == IH_TYPE_KERNEL &&
103
+ hdr->ih_type == IH_TYPE_KERNEL_NOLOAD)) {
104
+ fprintf(stderr, "Wrong image type %d, expected %d\n", hdr->ih_type,
105
+ image_type);
106
+ goto out;
107
+ }
108
}
109
110
/* TODO: Implement other image types. */
111
switch (hdr->ih_type) {
112
+ case IH_TYPE_KERNEL_NOLOAD:
113
+ if (!loadaddr || *loadaddr == LOAD_UIMAGE_LOADADDR_INVALID) {
114
+ fprintf(stderr, "this image format (kernel_noload) cannot be "
115
+ "loaded on this machine type");
116
+ goto out;
117
+ }
118
+
119
+ hdr->ih_load = *loadaddr + sizeof(*hdr);
120
+ hdr->ih_ep += hdr->ih_load;
121
+ /* fall through */
122
case IH_TYPE_KERNEL:
123
address = hdr->ih_load;
124
if (translate_fn) {
125
diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c
126
index XXXXXXX..XXXXXXX 100644
127
--- a/hw/microblaze/boot.c
128
+++ b/hw/microblaze/boot.c
129
@@ -XXX,XX +XXX,XX @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
130
131
/* If it wasn't an ELF image, try an u-boot image. */
132
if (kernel_size < 0) {
133
- hwaddr uentry, loadaddr;
134
+ hwaddr uentry, loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
135
136
kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0,
137
NULL, NULL);
138
diff --git a/hw/nios2/boot.c b/hw/nios2/boot.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/hw/nios2/boot.c
141
+++ b/hw/nios2/boot.c
142
@@ -XXX,XX +XXX,XX @@ void nios2_load_kernel(Nios2CPU *cpu, hwaddr ddr_base,
143
144
/* If it wasn't an ELF image, try an u-boot image. */
145
if (kernel_size < 0) {
146
- hwaddr uentry, loadaddr;
147
+ hwaddr uentry, loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
148
149
kernel_size = load_uimage(kernel_filename, &uentry, &loadaddr, 0,
150
NULL, NULL);
151
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
152
index XXXXXXX..XXXXXXX 100644
153
--- a/hw/ppc/e500.c
154
+++ b/hw/ppc/e500.c
155
@@ -XXX,XX +XXX,XX @@ void ppce500_init(MachineState *machine)
156
* Hrm. No ELF image? Try a uImage, maybe someone is giving us an
157
* ePAPR compliant kernel
158
*/
159
+ loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
160
payload_size = load_uimage(filename, &bios_entry, &loadaddr, NULL,
161
NULL, NULL);
162
if (payload_size < 0) {
163
diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/hw/ppc/ppc440_bamboo.c
166
+++ b/hw/ppc/ppc440_bamboo.c
167
@@ -XXX,XX +XXX,XX @@ static void bamboo_init(MachineState *machine)
168
CPUPPCState *env;
169
uint64_t elf_entry;
170
uint64_t elf_lowaddr;
171
- hwaddr loadaddr = 0;
172
+ hwaddr loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
173
target_long initrd_size = 0;
174
DeviceState *dev;
175
int success;
176
diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c
177
index XXXXXXX..XXXXXXX 100644
178
--- a/hw/ppc/sam460ex.c
179
+++ b/hw/ppc/sam460ex.c
180
@@ -XXX,XX +XXX,XX @@ static void sam460ex_init(MachineState *machine)
181
CPUPPCState *env;
182
PPC4xxI2CState *i2c[2];
183
hwaddr entry = UBOOT_ENTRY;
184
- hwaddr loadaddr = 0;
185
+ hwaddr loadaddr = LOAD_UIMAGE_LOADADDR_INVALID;
186
target_long initrd_size = 0;
187
DeviceState *dev;
188
SysBusDevice *sbdev;
33
--
189
--
34
2.7.4
190
2.19.2
35
191
36
192
diff view generated by jsdifflib