1
Arm queue built up to a point where it seems worth sending:
1
v2: minor tweak to fix format string issue on Windows hosts...
2
various bug fixes, plus RTH's refactoring in preparation for SVE.
3
2
4
thanks
5
-- PMM
6
7
8
The following changes since commit 0f79bfe38a2cf0f43c7ea4959da7f8ebd7858f3d:
9
3
10
Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-2.12-pull-request' into staging (2018-01-25 09:53:53 +0000)
4
The following changes since commit 6eeea6725a70e6fcb5abba0764496bdab07ddfb3:
11
5
12
are available in the git repository at:
6
Merge remote-tracking branch 'remotes/huth-gitlab/tags/pull-request-2020-10-06' into staging (2020-10-06 21:13:34 +0100)
13
7
14
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180125
8
are available in the Git repository at:
15
9
16
for you to fetch changes up to 24da047af0e99a83fcc0d50b86c0f2627f7418b3:
10
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20201008-1
17
11
18
pl110: Implement vertical compare/next base interrupts (2018-01-25 11:45:30 +0000)
12
for you to fetch changes up to d1b6b7017572e8d82f26eb827a1dba0e8cf3cae6:
13
14
target/arm: Make '-cpu max' have a 48-bit PA (2020-10-08 21:40:01 +0100)
19
15
20
----------------------------------------------------------------
16
----------------------------------------------------------------
21
target-arm queue:
17
target-arm queue:
22
* target/arm: Fix address truncation in 64-bit pagetable walks
18
* hw/ssi/npcm7xx_fiu: Fix handling of unsigned integer
23
* i.MX: Fix FEC/ENET receive functions
19
* hw/arm/fsl-imx25: Fix a typo
24
* target/arm: preparatory refactoring for SVE emulation
20
* hw/arm/sbsa-ref : Fix SMMUv3 Initialisation
25
* hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
21
* hw/arm/sbsa-ref : allocate IRQs for SMMUv3
26
* hw/intc/arm_gic: Fix C_RPR value on idle priority
22
* hw/char/bcm2835_aux: Allow less than 32-bit accesses
27
* hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
23
* hw/arm/virt: Implement kvm-steal-time
28
* hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1
24
* target/arm: Make '-cpu max' have a 48-bit PA
29
* hw/arm/virt: Check that the CPU realize method succeeded
30
* sdhci: fix a NULL pointer dereference due to uninitialized AddressSpace object
31
* xilinx_spips: Correct usage of an uninitialized local variable
32
* pl110: Implement vertical compare/next base interrupts
33
25
34
----------------------------------------------------------------
26
----------------------------------------------------------------
35
Ard Biesheuvel (1):
27
Andrew Jones (6):
36
target/arm: Fix 32-bit address truncation
28
linux headers: sync to 5.9-rc7
29
target/arm/kvm: Make uncalled stubs explicitly unreachable
30
hw/arm/virt: Move post cpu realize check into its own function
31
hw/arm/virt: Move kvm pmu setup to virt_cpu_post_init
32
tests/qtest: Restore aarch64 arm-cpu-features test
33
hw/arm/virt: Implement kvm-steal-time
37
34
38
Francisco Iglesias (1):
35
Graeme Gregory (2):
39
xilinx_spips: Correct usage of an uninitialized local variable
36
hw/arm/sbsa-ref : Fix SMMUv3 Initialisation
40
37
hw/arm/sbsa-ref : allocate IRQs for SMMUv3
41
Jean-Christophe Dubois (1):
42
i.MX: Fix FEC/ENET receive funtions
43
44
Linus Walleij (1):
45
pl110: Implement vertical compare/next base interrupts
46
47
Luc MICHEL (4):
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
38
53
Peter Maydell (1):
39
Peter Maydell (1):
54
hw/arm/virt: Check that the CPU realize method succeeded
40
target/arm: Make '-cpu max' have a 48-bit PA
55
41
56
Philippe Mathieu-Daudé (1):
42
Philippe Mathieu-Daudé (3):
57
sdhci: fix a NULL pointer dereference due to uninitialized AddresSpace object
43
hw/ssi/npcm7xx_fiu: Fix handling of unsigned integer
44
hw/arm/fsl-imx25: Fix a typo
45
hw/char/bcm2835_aux: Allow less than 32-bit accesses
58
46
59
Richard Henderson (11):
47
docs/system/arm/cpu-features.rst | 11 ++++
60
target/arm: Mark disas_set_insn_syndrome inline
48
include/hw/arm/fsl-imx25.h | 2 +-
61
target/arm: Use pointers in crypto helpers
49
include/hw/arm/virt.h | 5 ++
62
target/arm: Use pointers in neon zip/uzp helpers
50
linux-headers/linux/kvm.h | 6 ++-
63
target/arm: Use pointers in neon tbl helper
51
target/arm/cpu.h | 4 ++
64
target/arm: Change the type of vfp.regs
52
target/arm/kvm_arm.h | 94 ++++++++++++++++++++++++++-------
65
target/arm: Add aa{32, 64}_vfp_{dreg, qreg} helpers
53
hw/arm/sbsa-ref.c | 3 +-
66
vmstate: Add VMSTATE_UINT64_SUB_ARRAY
54
hw/arm/virt.c | 111 ++++++++++++++++++++++++++++-----------
67
target/arm: Add ARM_FEATURE_SVE
55
hw/char/bcm2835_aux.c | 4 +-
68
target/arm: Move cpu_get_tb_cpu_state out of line
56
hw/ssi/npcm7xx_fiu.c | 12 ++---
69
target/arm: Hoist store to flags output in cpu_get_tb_cpu_state
57
target/arm/cpu.c | 8 +++
70
target/arm: Simplify fp_exception_el for user-only
58
target/arm/cpu64.c | 4 ++
59
target/arm/kvm.c | 16 ++++++
60
target/arm/kvm64.c | 64 ++++++++++++++++++++--
61
target/arm/monitor.c | 2 +-
62
tests/qtest/arm-cpu-features.c | 25 +++++++--
63
hw/ssi/trace-events | 2 +-
64
tests/qtest/meson.build | 3 +-
65
18 files changed, 304 insertions(+), 72 deletions(-)
71
66
72
include/hw/sd/sdhci.h | 1 +
73
include/migration/vmstate.h | 9 ++-
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
diff view generated by jsdifflib
Deleted patch
1
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
2
1
3
Commit ("3b39d734141a target/arm: Handle page table walk load failures
4
correctly") modified both versions of the page table walking code (i.e.,
5
arm_ldl_ptw and arm_ldq_ptw) to record the result of the translation in
6
a temporary 'data' variable so that it can be inspected before being
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
12
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
13
Message-id: 20180119194648.25501-1-ard.biesheuvel@linaro.org
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/helper.c | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
19
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
23
+++ b/target/arm/helper.c
24
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
25
MemTxAttrs attrs = {};
26
MemTxResult result = MEMTX_OK;
27
AddressSpace *as;
28
- uint32_t data;
29
+ uint64_t data;
30
31
attrs.secure = is_secure;
32
as = arm_addressspace(cs, attrs);
33
--
34
2.7.4
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
1
3
The actual imx_eth_enable_rx() function is buggy.
4
5
It updates s->regs[ENET_RDAR] after calling qemu_flush_queued_packets().
6
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>
23
Reviewed-by: Andrey Smirnov <andrew.smirnov@gmail.com>
24
Tested-by: Andrey Smirnov <andrew.smirnov@gmail.com>
25
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
26
---
27
hw/net/imx_fec.c | 8 ++------
28
1 file changed, 2 insertions(+), 6 deletions(-)
29
30
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/net/imx_fec.c
33
+++ b/hw/net/imx_fec.c
34
@@ -XXX,XX +XXX,XX @@ static void imx_eth_do_tx(IMXFECState *s, uint32_t index)
35
static void imx_eth_enable_rx(IMXFECState *s, bool flush)
36
{
37
IMXFECBufDesc bd;
38
- bool rx_ring_full;
39
40
imx_fec_read_bd(&bd, s->rx_descriptor);
41
42
- rx_ring_full = !(bd.flags & ENET_BD_E);
43
+ s->regs[ENET_RDAR] = (bd.flags & ENET_BD_E) ? ENET_RDAR_RDAR : 0;
44
45
- if (rx_ring_full) {
46
+ if (!s->regs[ENET_RDAR]) {
47
FEC_PRINTF("RX buffer full\n");
48
} else if (flush) {
49
qemu_flush_queued_packets(qemu_get_queue(s->nic));
50
}
51
-
52
- s->regs[ENET_RDAR] = rx_ring_full ? 0 : ENET_RDAR_RDAR;
53
}
54
55
static void imx_eth_reset(DeviceState *d)
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
--
65
2.7.4
66
67
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
If it isn't used when translate.h is included,
4
we'll get a compiler Werror.
5
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20180119045438.28582-2-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/translate.h | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/target/arm/translate.h b/target/arm/translate.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate.h
19
+++ b/target/arm/translate.h
20
@@ -XXX,XX +XXX,XX @@ static inline int default_exception_el(DisasContext *s)
21
? 3 : MAX(1, s->current_el);
22
}
23
24
-static void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
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
--
30
2.7.4
31
32
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Rather than passing regnos to the helpers, pass pointers to the
4
vector registers directly. This eliminates the need to pass in
5
the environment pointer and reduces the number of places that
6
directly access env->vfp.regs[].
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Message-id: 20180119045438.28582-3-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/helper.h | 18 ++---
15
target/arm/crypto_helper.c | 184 +++++++++++++++++----------------------------
16
target/arm/translate-a64.c | 75 ++++++++++--------
17
target/arm/translate.c | 68 +++++++++--------
18
4 files changed, 161 insertions(+), 184 deletions(-)
19
20
diff --git a/target/arm/helper.h b/target/arm/helper.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.h
23
+++ b/target/arm/helper.h
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(neon_qzip8, void, env, i32, i32)
25
DEF_HELPER_3(neon_qzip16, void, env, i32, i32)
26
DEF_HELPER_3(neon_qzip32, void, env, i32, i32)
27
28
-DEF_HELPER_4(crypto_aese, void, env, i32, i32, i32)
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
58
59
-void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm,
60
- uint32_t decrypt)
61
+void HELPER(crypto_aese)(void *vd, void *vm, uint32_t decrypt)
62
{
63
static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox };
64
static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts };
65
-
66
- union CRYPTO_STATE rk = { .l = {
67
- float64_val(env->vfp.regs[rm]),
68
- float64_val(env->vfp.regs[rm + 1])
69
- } };
70
- union CRYPTO_STATE st = { .l = {
71
- float64_val(env->vfp.regs[rd]),
72
- float64_val(env->vfp.regs[rd + 1])
73
- } };
74
+ uint64_t *rd = vd;
75
+ uint64_t *rm = vm;
76
+ union CRYPTO_STATE rk = { .l = { rm[0], rm[1] } };
77
+ union CRYPTO_STATE st = { .l = { rd[0], rd[1] } };
78
int i;
79
80
assert(decrypt < 2);
81
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm,
82
CR_ST_BYTE(st, i) = sbox[decrypt][CR_ST_BYTE(rk, shift[decrypt][i])];
83
}
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
}
90
91
-void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm,
92
- uint32_t decrypt)
93
+void HELPER(crypto_aesmc)(void *vd, void *vm, uint32_t decrypt)
94
{
95
static uint32_t const mc[][256] = { {
96
/* MixColumns lookup table */
97
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm,
98
0x92b479a7, 0x99b970a9, 0x84ae6bbb, 0x8fa362b5,
99
0xbe805d9f, 0xb58d5491, 0xa89a4f83, 0xa397468d,
100
} };
101
- union CRYPTO_STATE st = { .l = {
102
- float64_val(env->vfp.regs[rm]),
103
- float64_val(env->vfp.regs[rm + 1])
104
- } };
105
+
106
+ uint64_t *rd = vd;
107
+ uint64_t *rm = vm;
108
+ union CRYPTO_STATE st = { .l = { rm[0], rm[1] } };
109
int i;
110
111
assert(decrypt < 2);
112
@@ -XXX,XX +XXX,XX @@ void HELPER(crypto_aesmc)(CPUARMState *env, uint32_t rd, uint32_t rm,
113
rol32(mc[decrypt][CR_ST_BYTE(st, i + 3)], 24);
114
}
115
116
- env->vfp.regs[rd] = make_float64(st.l[0]);
117
- env->vfp.regs[rd + 1] = make_float64(st.l[1]);
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
+}
370
+
371
+/* Return a newly allocated pointer to the vector register. */
372
+static TCGv_ptr vec_full_reg_ptr(DisasContext *s, int regno)
373
+{
374
+ TCGv_ptr ret = tcg_temp_new_ptr();
375
+ tcg_gen_addi_ptr(ret, cpu_env, vec_full_reg_offset(s, regno));
376
+ return ret;
377
+}
378
+
379
/* Return the offset into CPUARMState of a slice (from
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
+{
503
+ TCGv_ptr ret = tcg_temp_new_ptr();
504
+ tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
505
+ return ret;
506
+}
507
+
508
#define tcg_gen_ld_f32 tcg_gen_ld_i32
509
#define tcg_gen_ld_f64 tcg_gen_ld_i64
510
#define tcg_gen_st_f32 tcg_gen_st_i32
511
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
512
int u;
513
uint32_t imm, mask;
514
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
515
+ TCGv_ptr ptr1, ptr2, ptr3;
516
TCGv_i64 tmp64;
517
518
/* FIXME: this access check should not take precedence over UNDEF
519
@@ -XXX,XX +XXX,XX @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
520
if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
521
return 1;
522
}
523
- tmp = tcg_const_i32(rd);
524
- tmp2 = tcg_const_i32(rn);
525
- tmp3 = tcg_const_i32(rm);
526
+ ptr1 = vfp_reg_ptr(true, rd);
527
+ ptr2 = vfp_reg_ptr(true, rn);
528
+ ptr3 = vfp_reg_ptr(true, rm);
529
tmp4 = tcg_const_i32(size);
530
- gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
531
+ gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
532
tcg_temp_free_i32(tmp4);
533
} else { /* SHA-256 */
534
if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
535
return 1;
536
}
537
- tmp = tcg_const_i32(rd);
538
- tmp2 = tcg_const_i32(rn);
539
- tmp3 = tcg_const_i32(rm);
540
+ ptr1 = vfp_reg_ptr(true, rd);
541
+ ptr2 = vfp_reg_ptr(true, rn);
542
+ ptr3 = vfp_reg_ptr(true, rm);
543
switch (size) {
544
case 0:
545
- gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
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
--
637
2.7.4
638
639
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Rather than passing regnos to the helpers, pass pointers to the
4
vector registers directly. This eliminates the need to pass in
5
the environment pointer and reduces the number of places that
6
directly access env->vfp.regs[].
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Message-id: 20180119045438.28582-4-richard.henderson@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/helper.h | 20 +++---
15
target/arm/neon_helper.c | 162 +++++++++++++++++++++++++----------------------
16
target/arm/translate.c | 42 ++++++------
17
3 files changed, 120 insertions(+), 104 deletions(-)
18
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.h
22
+++ b/target/arm/helper.h
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(iwmmxt_muladdsl, i64, i64, i32, i32)
24
DEF_HELPER_3(iwmmxt_muladdsw, i64, i64, i32, i32)
25
DEF_HELPER_3(iwmmxt_muladdswl, i64, i64, i32, i32)
26
27
-DEF_HELPER_3(neon_unzip8, void, env, i32, i32)
28
-DEF_HELPER_3(neon_unzip16, void, env, i32, i32)
29
-DEF_HELPER_3(neon_qunzip8, void, env, i32, i32)
30
-DEF_HELPER_3(neon_qunzip16, void, env, i32, i32)
31
-DEF_HELPER_3(neon_qunzip32, void, env, i32, i32)
32
-DEF_HELPER_3(neon_zip8, void, env, i32, i32)
33
-DEF_HELPER_3(neon_zip16, void, env, i32, i32)
34
-DEF_HELPER_3(neon_qzip8, void, env, i32, i32)
35
-DEF_HELPER_3(neon_qzip16, void, env, i32, i32)
36
-DEF_HELPER_3(neon_qzip32, void, env, i32, i32)
37
+DEF_HELPER_FLAGS_2(neon_unzip8, TCG_CALL_NO_RWG, void, ptr, ptr)
38
+DEF_HELPER_FLAGS_2(neon_unzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
39
+DEF_HELPER_FLAGS_2(neon_qunzip8, TCG_CALL_NO_RWG, void, ptr, ptr)
40
+DEF_HELPER_FLAGS_2(neon_qunzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
41
+DEF_HELPER_FLAGS_2(neon_qunzip32, TCG_CALL_NO_RWG, void, ptr, ptr)
42
+DEF_HELPER_FLAGS_2(neon_zip8, TCG_CALL_NO_RWG, void, ptr, ptr)
43
+DEF_HELPER_FLAGS_2(neon_zip16, TCG_CALL_NO_RWG, void, ptr, ptr)
44
+DEF_HELPER_FLAGS_2(neon_qzip8, TCG_CALL_NO_RWG, void, ptr, ptr)
45
+DEF_HELPER_FLAGS_2(neon_qzip16, TCG_CALL_NO_RWG, void, ptr, ptr)
46
+DEF_HELPER_FLAGS_2(neon_qzip32, TCG_CALL_NO_RWG, void, ptr, ptr)
47
48
DEF_HELPER_FLAGS_3(crypto_aese, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
49
DEF_HELPER_FLAGS_3(crypto_aesmc, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
50
diff --git a/target/arm/neon_helper.c b/target/arm/neon_helper.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/neon_helper.c
53
+++ b/target/arm/neon_helper.c
54
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(neon_acgt_f64)(uint64_t a, uint64_t b, void *fpstp)
55
56
#define ELEM(V, N, SIZE) (((V) >> ((N) * (SIZE))) & ((1ull << (SIZE)) - 1))
57
58
-void HELPER(neon_qunzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
59
+void HELPER(neon_qunzip8)(void *vd, void *vm)
60
{
61
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
62
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
63
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
64
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
65
+ uint64_t *rd = vd, *rm = vm;
66
+ uint64_t zd0 = rd[0], zd1 = rd[1];
67
+ uint64_t zm0 = rm[0], zm1 = rm[1];
68
+
69
uint64_t d0 = ELEM(zd0, 0, 8) | (ELEM(zd0, 2, 8) << 8)
70
| (ELEM(zd0, 4, 8) << 16) | (ELEM(zd0, 6, 8) << 24)
71
| (ELEM(zd1, 0, 8) << 32) | (ELEM(zd1, 2, 8) << 40)
72
@@ -XXX,XX +XXX,XX @@ void HELPER(neon_qunzip8)(CPUARMState *env, uint32_t rd, uint32_t rm)
73
| (ELEM(zm0, 5, 8) << 16) | (ELEM(zm0, 7, 8) << 24)
74
| (ELEM(zm1, 1, 8) << 32) | (ELEM(zm1, 3, 8) << 40)
75
| (ELEM(zm1, 5, 8) << 48) | (ELEM(zm1, 7, 8) << 56);
76
- env->vfp.regs[rm] = make_float64(m0);
77
- env->vfp.regs[rm + 1] = make_float64(m1);
78
- env->vfp.regs[rd] = make_float64(d0);
79
- env->vfp.regs[rd + 1] = make_float64(d1);
80
+
81
+ rm[0] = m0;
82
+ rm[1] = m1;
83
+ rd[0] = d0;
84
+ rd[1] = d1;
85
}
86
87
-void HELPER(neon_qunzip16)(CPUARMState *env, uint32_t rd, uint32_t rm)
88
+void HELPER(neon_qunzip16)(void *vd, void *vm)
89
{
90
- uint64_t zm0 = float64_val(env->vfp.regs[rm]);
91
- uint64_t zm1 = float64_val(env->vfp.regs[rm + 1]);
92
- uint64_t zd0 = float64_val(env->vfp.regs[rd]);
93
- uint64_t zd1 = float64_val(env->vfp.regs[rd + 1]);
94
+ uint64_t *rd = vd, *rm = vm;
95
+ uint64_t zd0 = rd[0], zd1 = rd[1];
96
+ uint64_t zm0 = rm[0], zm1 = rm[1];
97
+
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
415
--
416
2.7.4
417
418
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Rather than passing a regno to the helper, pass pointers to the
4
vector register directly. This eliminates the need to pass in
5
the environment pointer and reduces the number of places that
6
directly access env->vfp.regs[].
7
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180119045438.28582-5-richard.henderson@linaro.org
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/helper.h | 2 +-
15
target/arm/op_helper.c | 17 +++++++----------
16
target/arm/translate.c | 8 ++++----
17
3 files changed, 12 insertions(+), 15 deletions(-)
18
19
diff --git a/target/arm/helper.h b/target/arm/helper.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.h
22
+++ b/target/arm/helper.h
23
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(rsqrte_f32, TCG_CALL_NO_RWG, f32, f32, ptr)
24
DEF_HELPER_FLAGS_2(rsqrte_f64, TCG_CALL_NO_RWG, f64, f64, ptr)
25
DEF_HELPER_2(recpe_u32, i32, i32, ptr)
26
DEF_HELPER_FLAGS_2(rsqrte_u32, TCG_CALL_NO_RWG, i32, i32, ptr)
27
-DEF_HELPER_5(neon_tbl, i32, env, i32, i32, i32, i32)
28
+DEF_HELPER_FLAGS_4(neon_tbl, TCG_CALL_NO_RWG, i32, i32, i32, ptr, i32)
29
30
DEF_HELPER_3(shl_cc, i32, env, i32, i32)
31
DEF_HELPER_3(shr_cc, i32, env, i32, i32)
32
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/op_helper.c
35
+++ b/target/arm/op_helper.c
36
@@ -XXX,XX +XXX,XX @@ static int exception_target_el(CPUARMState *env)
37
return target_el;
38
}
39
40
-uint32_t HELPER(neon_tbl)(CPUARMState *env, uint32_t ireg, uint32_t def,
41
- uint32_t rn, uint32_t maxindex)
42
+uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, void *vn,
43
+ uint32_t maxindex)
44
{
45
- uint32_t val;
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
--
93
2.7.4
94
95
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
All direct users of this field want an integral value. Drop all
4
of the extra casting between uint64_t and float64.
5
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
152
index XXXXXXX..XXXXXXX 100644
153
--- a/target/arm/translate.c
154
+++ b/target/arm/translate.c
155
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
156
numvfpregs += 16;
157
}
158
for (i = 0; i < numvfpregs; i++) {
159
- uint64_t v = float64_val(env->vfp.regs[i]);
160
+ uint64_t v = env->vfp.regs[i];
161
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
162
i * 2, (uint32_t)v,
163
i * 2 + 1, (uint32_t)(v >> 32),
164
--
165
2.7.4
166
167
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Helpers that return a pointer into env->vfp.regs so that we isolate
4
the logic of how to index the regs array for different cpu modes.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20180119045438.28582-7-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 | 27 +++++++++++++++++++++++++++
12
linux-user/signal.c | 22 ++++++++++++----------
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
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ static inline void *arm_get_el_change_hook_opaque(ARMCPU *cpu)
27
return cpu->el_change_hook_opaque;
28
}
29
30
+/**
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
+{
36
+ return &env->vfp.regs[regno];
37
+}
38
+
39
+/**
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
+{
45
+ return &env->vfp.regs[2 * regno];
46
+}
47
+
48
+/**
49
+ * aa64_vfp_qreg:
50
+ * Return a pointer to the Qn register within env in 64-bit mode.
51
+ */
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
}
64
65
for (i = 0; i < 32; i++) {
66
+ uint64_t *q = aa64_vfp_qreg(env, i);
67
#ifdef TARGET_WORDS_BIGENDIAN
68
- __put_user(env->vfp.regs[i * 2], &aux->fpsimd.vregs[i * 2 + 1]);
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
355
- assert_fp_access_checked(s);
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
}
394
}
395
396
@@ -XXX,XX +XXX,XX @@ void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
397
numvfpregs += 16;
398
}
399
for (i = 0; i < numvfpregs; i++) {
400
- uint64_t v = env->vfp.regs[i];
401
+ uint64_t v = *aa32_vfp_dreg(env, i);
402
cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
403
i * 2, (uint32_t)v,
404
i * 2 + 1, (uint32_t)(v >> 32),
405
--
406
2.7.4
407
408
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
At the same time, move VMSTATE_UINT32_SUB_ARRAY
4
beside the other UINT32 definitions.
5
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180119045438.28582-8-richard.henderson@linaro.org
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/migration/vmstate.h | 9 ++++++---
14
1 file changed, 6 insertions(+), 3 deletions(-)
15
16
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/migration/vmstate.h
19
+++ b/include/migration/vmstate.h
20
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
21
#define VMSTATE_UINT32_ARRAY(_f, _s, _n) \
22
VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0)
23
24
+#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \
25
+ VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t)
26
+
27
#define VMSTATE_UINT32_2DARRAY(_f, _s, _n1, _n2) \
28
VMSTATE_UINT32_2DARRAY_V(_f, _s, _n1, _n2, 0)
29
30
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
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
+
37
#define VMSTATE_UINT64_2DARRAY(_f, _s, _n1, _n2) \
38
VMSTATE_UINT64_2DARRAY_V(_f, _s, _n1, _n2, 0)
39
40
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
41
#define VMSTATE_INT32_ARRAY(_f, _s, _n) \
42
VMSTATE_INT32_ARRAY_V(_f, _s, _n, 0)
43
44
-#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \
45
- VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t)
46
-
47
#define VMSTATE_INT64_ARRAY_V(_f, _s, _n, _v) \
48
VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int64, int64_t)
49
50
--
51
2.7.4
52
53
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Not enabled anywhere so far.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20180119045438.28582-11-richard.henderson@linaro.org
7
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>
10
---
11
target/arm/cpu.h | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
17
+++ b/target/arm/cpu.h
18
@@ -XXX,XX +XXX,XX @@ enum arm_features {
19
ARM_FEATURE_VBAR, /* has cp15 VBAR */
20
ARM_FEATURE_M_SECURITY, /* M profile Security Extension */
21
ARM_FEATURE_JAZELLE, /* has (trivial) Jazelle implementation */
22
+ ARM_FEATURE_SVE, /* has Scalable Vector Extension */
23
};
24
25
static inline int arm_feature(CPUARMState *env, int feature)
26
--
27
2.7.4
28
29
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20180119045438.28582-14-richard.henderson@linaro.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/cpu.h | 127 +---------------------------------------------------
9
target/arm/helper.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++
10
2 files changed, 128 insertions(+), 125 deletions(-)
11
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
15
+++ b/target/arm/cpu.h
16
@@ -XXX,XX +XXX,XX @@ static inline bool bswap_code(bool sctlr_b)
17
#endif
18
}
19
20
-/* Return the exception level to which FP-disabled exceptions should
21
- * be taken, or 0 if FP is enabled.
22
- */
23
-static inline int fp_exception_el(CPUARMState *env)
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
+
166
+/* Return the exception level to which FP-disabled exceptions should
167
+ * be taken, or 0 if FP is enabled.
168
+ */
169
+static inline int fp_exception_el(CPUARMState *env)
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
+ }
180
+
181
+ /* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
182
+ * 0, 2 : trap EL0 and EL1/PL1 accesses
183
+ * 1 : trap only EL0 accesses
184
+ * 3 : trap no accesses
185
+ */
186
+ fpen = extract32(env->cp15.cpacr_el1, 20, 2);
187
+ switch (fpen) {
188
+ case 0:
189
+ case 2:
190
+ if (cur_el == 0 || cur_el == 1) {
191
+ /* Trap to PL1, which might be EL1 or EL3 */
192
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3)) {
193
+ return 3;
194
+ }
195
+ return 1;
196
+ }
197
+ if (cur_el == 3 && !is_a64(env)) {
198
+ /* Secure PL1 running at EL3 */
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
+ }
210
+
211
+ /* For the CPTR registers we don't need to guard with an ARM_FEATURE
212
+ * check because zero bits in the registers mean "don't trap".
213
+ */
214
+
215
+ /* CPTR_EL2 : present in v7VE or v8 */
216
+ if (cur_el <= 2 && extract32(env->cp15.cptr_el[2], 10, 1)
217
+ && !arm_is_secure_below_el3(env)) {
218
+ /* Trap FP ops at EL2, NS-EL1 or NS-EL0 to EL2 */
219
+ return 2;
220
+ }
221
+
222
+ /* CPTR_EL3 : present in v8 */
223
+ if (extract32(env->cp15.cptr_el[3], 10, 1)) {
224
+ /* Trap all FP ops to EL3 */
225
+ return 3;
226
+ }
227
+
228
+ return 0;
229
+}
230
+
231
+void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
232
+ target_ulong *cs_base, uint32_t *flags)
233
+{
234
+ ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
235
+ if (is_a64(env)) {
236
+ *pc = env->pc;
237
+ *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
238
+ /* Get control bits for tagged addresses */
239
+ *flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
240
+ *flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
241
+ } else {
242
+ *pc = env->regs[15];
243
+ *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
244
+ | (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
245
+ | (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
246
+ | (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
247
+ | (arm_sctlr_b(env) << ARM_TBFLAG_SCTLR_B_SHIFT);
248
+ if (!(access_secure_reg(env))) {
249
+ *flags |= ARM_TBFLAG_NS_MASK;
250
+ }
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
+
259
+ *flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
260
+
261
+ /* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
262
+ * states defined in the ARM ARM for software singlestep:
263
+ * SS_ACTIVE PSTATE.SS State
264
+ * 0 x Inactive (the TB flag for SS is always 0)
265
+ * 1 0 Active-pending
266
+ * 1 1 Active-not-pending
267
+ */
268
+ if (arm_singlestep_active(env)) {
269
+ *flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
270
+ if (is_a64(env)) {
271
+ if (env->pstate & PSTATE_SS) {
272
+ *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
273
+ }
274
+ } else {
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
+
285
+ if (arm_v7m_is_handler_mode(env)) {
286
+ *flags |= ARM_TBFLAG_HANDLER_MASK;
287
+ }
288
+
289
+ *cs_base = 0;
290
+}
291
--
292
2.7.4
293
294
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20180119045438.28582-15-richard.henderson@linaro.org
5
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>
8
---
9
target/arm/helper.c | 35 +++++++++++++++++++----------------
10
1 file changed, 19 insertions(+), 16 deletions(-)
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static inline int fp_exception_el(CPUARMState *env)
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));
24
+ uint32_t flags;
25
+
26
if (is_a64(env)) {
27
*pc = env->pc;
28
- *flags = ARM_TBFLAG_AARCH64_STATE_MASK;
29
+ flags = ARM_TBFLAG_AARCH64_STATE_MASK;
30
/* Get control bits for tagged addresses */
31
- *flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
32
- *flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
33
+ flags |= (arm_regime_tbi0(env, mmu_idx) << ARM_TBFLAG_TBI0_SHIFT);
34
+ flags |= (arm_regime_tbi1(env, mmu_idx) << ARM_TBFLAG_TBI1_SHIFT);
35
} else {
36
*pc = env->regs[15];
37
- *flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
38
+ flags = (env->thumb << ARM_TBFLAG_THUMB_SHIFT)
39
| (env->vfp.vec_len << ARM_TBFLAG_VECLEN_SHIFT)
40
| (env->vfp.vec_stride << ARM_TBFLAG_VECSTRIDE_SHIFT)
41
| (env->condexec_bits << ARM_TBFLAG_CONDEXEC_SHIFT)
42
| (arm_sctlr_b(env) << ARM_TBFLAG_SCTLR_B_SHIFT);
43
if (!(access_secure_reg(env))) {
44
- *flags |= ARM_TBFLAG_NS_MASK;
45
+ flags |= ARM_TBFLAG_NS_MASK;
46
}
47
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
48
|| arm_el_is_aa64(env, 1)) {
49
- *flags |= ARM_TBFLAG_VFPEN_MASK;
50
+ flags |= ARM_TBFLAG_VFPEN_MASK;
51
}
52
- *flags |= (extract32(env->cp15.c15_cpar, 0, 2)
53
- << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
54
+ flags |= (extract32(env->cp15.c15_cpar, 0, 2)
55
+ << ARM_TBFLAG_XSCALE_CPAR_SHIFT);
56
}
57
58
- *flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
59
+ flags |= (arm_to_core_mmu_idx(mmu_idx) << ARM_TBFLAG_MMUIDX_SHIFT);
60
61
/* The SS_ACTIVE and PSTATE_SS bits correspond to the state machine
62
* 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,
64
* 1 1 Active-not-pending
65
*/
66
if (arm_singlestep_active(env)) {
67
- *flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
68
+ flags |= ARM_TBFLAG_SS_ACTIVE_MASK;
69
if (is_a64(env)) {
70
if (env->pstate & PSTATE_SS) {
71
- *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
72
+ flags |= ARM_TBFLAG_PSTATE_SS_MASK;
73
}
74
} else {
75
if (env->uncached_cpsr & PSTATE_SS) {
76
- *flags |= ARM_TBFLAG_PSTATE_SS_MASK;
77
+ flags |= ARM_TBFLAG_PSTATE_SS_MASK;
78
}
79
}
80
}
81
if (arm_cpu_data_is_big_endian(env)) {
82
- *flags |= ARM_TBFLAG_BE_DATA_MASK;
83
+ flags |= ARM_TBFLAG_BE_DATA_MASK;
84
}
85
- *flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
86
+ flags |= fp_exception_el(env) << ARM_TBFLAG_FPEXC_EL_SHIFT;
87
88
if (arm_v7m_is_handler_mode(env)) {
89
- *flags |= ARM_TBFLAG_HANDLER_MASK;
90
+ flags |= ARM_TBFLAG_HANDLER_MASK;
91
}
92
93
+ *pflags = flags;
94
*cs_base = 0;
95
}
96
--
97
2.7.4
98
99
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20180119045438.28582-16-richard.henderson@linaro.org
5
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>
8
---
9
target/arm/helper.c | 3 ++-
10
1 file changed, 2 insertions(+), 1 deletion(-)
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
17
*/
18
static inline int fp_exception_el(CPUARMState *env)
19
{
20
+#ifndef CONFIG_USER_ONLY
21
int fpen;
22
int cur_el = arm_current_el(env);
23
24
@@ -XXX,XX +XXX,XX @@ static inline int fp_exception_el(CPUARMState *env)
25
/* Trap all FP ops to EL3 */
26
return 3;
27
}
28
-
29
+#endif
30
return 0;
31
}
32
33
--
34
2.7.4
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
2
1
3
In the GIC, when an IRQ is acknowledged, its state goes from "pending"
4
to:
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
11
The current implementation of the GIC in QEMU does not check if the
12
IRQ is already active when looking for pending interrupts with
13
sufficient priority in gic_update(). This can lead to signaling an
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>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
---
33
hw/intc/arm_gic.c | 1 +
34
1 file changed, 1 insertion(+)
35
36
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/intc/arm_gic.c
39
+++ b/hw/intc/arm_gic.c
40
@@ -XXX,XX +XXX,XX @@ void gic_update(GICState *s)
41
best_irq = 1023;
42
for (irq = 0; irq < s->num_irq; irq++) {
43
if (GIC_TEST_ENABLED(irq, cm) && gic_test_pending(s, irq, cm) &&
44
+ (!GIC_TEST_ACTIVE(irq, cm)) &&
45
(irq < GIC_INTERNAL || GIC_TARGET(irq) & cm)) {
46
if (GIC_GET_PRIORITY(irq, cpu) < best_prio) {
47
best_prio = GIC_GET_PRIORITY(irq, cpu);
48
--
49
2.7.4
50
51
diff view generated by jsdifflib
Deleted patch
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
2
1
3
When there is no active interrupts in the GIC, a read to the C_RPR
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
7
Since the QEMU GIC model implements all the 8 priority bits, the Idle
8
priority is 0xff.
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>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
30
---
31
hw/intc/arm_gic.c | 5 +++++
32
1 file changed, 5 insertions(+)
33
34
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/intc/arm_gic.c
37
+++ b/hw/intc/arm_gic.c
38
@@ -XXX,XX +XXX,XX @@ static void gic_set_cpu_control(GICState *s, int cpu, uint32_t value,
39
40
static uint8_t gic_get_running_priority(GICState *s, int cpu, MemTxAttrs attrs)
41
{
42
+ if ((s->revision != REV_11MPCORE) && (s->running_priority[cpu] > 0xff)) {
43
+ /* Idle priority */
44
+ return 0xff;
45
+ }
46
+
47
if (s->security_extn && !attrs.secure) {
48
if (s->running_priority[cpu] & 0x80) {
49
/* Running priority in upper half of range: return the Non-secure
50
--
51
2.7.4
52
53
diff view generated by jsdifflib
Deleted patch
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
2
1
3
When determining the group priority of a group 1 IRQ, if C_CTRL.CBPR is
4
0, the non-secure BPR value is used. However, this value must be
5
incremented by one so that it matches the secure world number of
6
implemented priority bits (NS world has one less priority bit compared
7
to the Secure world).
8
9
Signed-off-by: Luc MICHEL <luc.michel@git.antfield.fr>
10
Message-id: 20180119145756.7629-5-luc.michel@greensocs.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
[PMM: add assert, as the gicv3 code has]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/intc/arm_gic.c | 3 ++-
16
1 file changed, 2 insertions(+), 1 deletion(-)
17
18
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/arm_gic.c
21
+++ b/hw/intc/arm_gic.c
22
@@ -XXX,XX +XXX,XX @@ static int gic_get_group_priority(GICState *s, int cpu, int irq)
23
if (gic_has_groups(s) &&
24
!(s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) &&
25
GIC_TEST_GROUP(irq, (1 << cpu))) {
26
- bpr = s->abpr[cpu];
27
+ bpr = s->abpr[cpu] - 1;
28
+ assert(bpr >= 0);
29
} else {
30
bpr = s->bpr[cpu];
31
}
32
--
33
2.7.4
34
35
diff view generated by jsdifflib
Deleted patch
1
From: Luc MICHEL <luc.michel@git.antfield.fr>
2
1
3
When C_CTRL.CBPR is 1, the Non-Secure view of C_BPR is altered:
4
- A Non-Secure read of C_BPR should return the BPR value plus 1,
5
saturated to 7,
6
- A Non-Secure write should be ignored.
7
8
Signed-off-by: Luc MICHEL <luc.michel@git.antfield.fr>
9
Message-id: 20180119145756.7629-6-luc.michel@greensocs.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: fixed comment typo]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/intc/arm_gic.c | 16 +++++++++++++---
15
1 file changed, 13 insertions(+), 3 deletions(-)
16
17
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/arm_gic.c
20
+++ b/hw/intc/arm_gic.c
21
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
22
break;
23
case 0x08: /* Binary Point */
24
if (s->security_extn && !attrs.secure) {
25
- /* BPR is banked. Non-secure copy stored in ABPR. */
26
- *data = s->abpr[cpu];
27
+ if (s->cpu_ctlr[cpu] & GICC_CTLR_CBPR) {
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
+ }
34
} else {
35
*data = s->bpr[cpu];
36
}
37
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
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
}
51
--
52
2.7.4
53
54
diff view generated by jsdifflib
Deleted patch
1
We were passing a NULL error pointer to the object_property_set_bool()
2
call that realizes the CPU object. This meant that we wouldn't detect
3
failure, and would plough blindly on to crash later trying to use a
4
NULL CPU object pointer. Detect errors and fail instead.
5
1
6
In particular, this will be necessary to detect the user error
7
of using "-cpu host" without "-enable-kvm" once we make the host
8
CPU type be registered unconditionally rather than only in
9
kvm_arch_init().
10
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/arm/virt.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/virt.c
19
+++ b/hw/arm/virt.c
20
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
21
"secure-memory", &error_abort);
22
}
23
24
- object_property_set_bool(cpuobj, true, "realized", NULL);
25
+ object_property_set_bool(cpuobj, true, "realized", &error_fatal);
26
object_unref(cpuobj);
27
}
28
fdt_add_timer_nodes(vms);
29
--
30
2.7.4
31
32
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
missed in 60765b6ceeb4.
4
5
Thread 1 "qemu-system-aarch64" received signal SIGSEGV, Segmentation fault.
6
address_space_init (as=0x0, root=0x55555726e410, name=name@entry=0x555555e3f0a7 "sdhci-dma") at memory.c:3050
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
18
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Message-id: 20180123132051.24448-1-f4bug@amsat.org
21
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
24
include/hw/sd/sdhci.h | 1 +
25
hw/sd/sdhci.c | 1 +
26
2 files changed, 2 insertions(+)
27
28
diff --git a/include/hw/sd/sdhci.h b/include/hw/sd/sdhci.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/sd/sdhci.h
31
+++ b/include/hw/sd/sdhci.h
32
@@ -XXX,XX +XXX,XX @@ typedef struct SDHCIState {
33
/*< public >*/
34
SDBus sdbus;
35
MemoryRegion iomem;
36
+ AddressSpace sysbus_dma_as;
37
AddressSpace *dma_as;
38
MemoryRegion *dma_mr;
39
40
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/sd/sdhci.c
43
+++ b/hw/sd/sdhci.c
44
@@ -XXX,XX +XXX,XX @@ static void sdhci_sysbus_realize(DeviceState *dev, Error ** errp)
45
}
46
47
if (s->dma_mr) {
48
+ s->dma_as = &s->sysbus_dma_as;
49
address_space_init(s->dma_as, s->dma_mr, "sdhci-dma");
50
} else {
51
/* use system_memory() if property "dma" not set */
52
--
53
2.7.4
54
55
diff view generated by jsdifflib
Deleted patch
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
2
1
3
Coverity found that the variable tx_rx in the function
4
xilinx_spips_flush_txfifo was being used uninitialized (CID 1383841). This
5
patch corrects this by always initializing tx_rx to zeros.
6
7
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Message-id: 20180124215708.30400-1-frasse.iglesias@gmail.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/ssi/xilinx_spips.c | 18 +++++++++++++++++-
13
1 file changed, 17 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
18
+++ b/hw/ssi/xilinx_spips.c
19
@@ -XXX,XX +XXX,XX @@
20
#define SNOOP_NONE 0xEE
21
#define SNOOP_STRIPING 0
22
23
+#define MIN_NUM_BUSSES 1
24
+#define MAX_NUM_BUSSES 2
25
+
26
static inline int num_effective_busses(XilinxSPIPS *s)
27
{
28
return (s->regs[R_LQSPI_CFG] & LQSPI_CFG_SEP_BUS &&
29
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
30
for (;;) {
31
int i;
32
uint8_t tx = 0;
33
- uint8_t tx_rx[num_effective_busses(s)];
34
+ uint8_t tx_rx[MAX_NUM_BUSSES] = { 0 };
35
uint8_t dummy_cycles = 0;
36
uint8_t addr_length;
37
38
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
39
40
DB_PRINT_L(0, "realized spips\n");
41
42
+ if (s->num_busses > MAX_NUM_BUSSES) {
43
+ error_setg(errp,
44
+ "requested number of SPI busses %u exceeds maximum %d",
45
+ s->num_busses, MAX_NUM_BUSSES);
46
+ return;
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;
53
+ }
54
+
55
s->spi = g_new(SSIBus *, s->num_busses);
56
for (i = 0; i < s->num_busses; ++i) {
57
char bus_name[16];
58
--
59
2.7.4
60
61
diff view generated by jsdifflib
Deleted patch
1
From: Linus Walleij <linus.walleij@linaro.org>
2
1
3
This implements rudimentary support for interrupt generation on the
4
PL110. I am working on a new DRI/KMS driver for Linux and since that
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
10
I solved it for now by setting up a timer to fire at 60Hz and pull
11
the interrupts for "vertical compare" and "next memory base"
12
at this interval. This works fine and fires roughly the same number
13
of IRQs on QEMU as on the hardware and leaves the console clean
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>
26
---
27
hw/display/pl110.c | 30 +++++++++++++++++++++++++++++-
28
1 file changed, 29 insertions(+), 1 deletion(-)
29
30
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/display/pl110.c
33
+++ b/hw/display/pl110.c
34
@@ -XXX,XX +XXX,XX @@
35
#include "ui/console.h"
36
#include "framebuffer.h"
37
#include "ui/pixel_ops.h"
38
+#include "qemu/timer.h"
39
#include "qemu/log.h"
40
41
#define PL110_CR_EN 0x001
42
@@ -XXX,XX +XXX,XX @@
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
+}
71
+
72
+static void pl110_vblank_interrupt(void *opaque)
73
+{
74
+ PL110State *s = opaque;
75
+
76
+ /* Fire the vertical compare and next base IRQs and re-arm */
77
+ s->int_status |= (PL110_IE_NB | PL110_IE_VC);
78
+ timer_mod(s->vblank_timer,
79
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
80
+ NANOSECONDS_PER_SECOND / 60);
81
+ pl110_update(s);
82
}
83
84
static uint64_t pl110_read(void *opaque, hwaddr offset,
85
@@ -XXX,XX +XXX,XX @@ static void pl110_write(void *opaque, hwaddr offset,
86
s->bpp = (val >> 1) & 7;
87
if (pl110_enabled(s)) {
88
qemu_console_resize(s->con, s->cols, s->rows);
89
+ timer_mod(s->vblank_timer,
90
+ qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
91
+ NANOSECONDS_PER_SECOND / 60);
92
+ } else {
93
+ timer_del(s->vblank_timer);
94
}
95
break;
96
case 10: /* LCDICR */
97
@@ -XXX,XX +XXX,XX @@ static void pl110_realize(DeviceState *dev, Error **errp)
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
--
107
2.7.4
108
109
diff view generated by jsdifflib