1
A surprisingly short target-arm queue, but no point in holding
1
The following changes since commit ad1b4ec39caa5b3f17cbd8160283a03a3dcfe2ae:
2
onto these waiting for more code to arrive :-)
3
2
4
thanks
3
Merge remote-tracking branch 'remotes/kraxel/tags/input-20180515-pull-request' into staging (2018-05-15 12:50:06 +0100)
5
-- PMM
6
4
7
The following changes since commit 3d0bf8dfdfebd7f2ae41b6f220444b8047d6b1ee:
5
are available in the Git repository at:
8
6
9
Merge remote-tracking branch 'remotes/dgilbert/tags/pull-migration-20170710a' into staging (2017-07-10 18:13:03 +0100)
7
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180515
10
8
11
are available in the git repository at:
9
for you to fetch changes up to ae7651804748c6b479d5ae09aeac4edb9c44f76e:
12
10
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170711
11
tcg: Optionally log FPU state in TCG -d cpu logging (2018-05-15 14:58:44 +0100)
14
15
for you to fetch changes up to 792dac309c8660306557ba058b8b5a6a75ab3c1f:
16
17
target-arm: v7M: ignore writes to CONTROL.SPSEL from Thread mode (2017-07-11 11:21:26 +0100)
18
12
19
----------------------------------------------------------------
13
----------------------------------------------------------------
20
target-arm queue:
14
target-arm queue:
21
* v7M: ignore writes to CONTROL.SPSEL from Thread mode
15
* Fix coverity nit in int_to_float code
22
* KVM: Enable in-kernel timers with user space gic
16
* Don't set Invalid for float-to-int(MAXINT)
23
* aspeed: Register all watchdogs
17
* Fix fp_status_f16 tininess before rounding
24
* hw/misc: Add Exynos4210 Pseudo Random Number Generator
18
* Add various missing insns from the v8.2-FP16 extension
19
* Fix sqrt_f16 exception raising
20
* sdcard: Correct CRC16 offset in sd_function_switch()
21
* tcg: Optionally log FPU state in TCG -d cpu logging
25
22
26
----------------------------------------------------------------
23
----------------------------------------------------------------
27
Alexander Graf (1):
24
Alex Bennée (5):
28
ARM: KVM: Enable in-kernel timers with user space gic
25
fpu/softfloat: int_to_float ensure r fully initialised
26
target/arm: Implement FCMP for fp16
27
target/arm: Implement FCSEL for fp16
28
target/arm: Implement FMOV (immediate) for fp16
29
target/arm: Fix sqrt_f16 exception raising
29
30
30
Joel Stanley (1):
31
Peter Maydell (3):
31
aspeed: Register all watchdogs
32
fpu/softfloat: Don't set Invalid for float-to-int(MAXINT)
33
target/arm: Fix fp_status_f16 tininess before rounding
34
tcg: Optionally log FPU state in TCG -d cpu logging
32
35
33
Krzysztof Kozlowski (1):
36
Philippe Mathieu-Daudé (1):
34
hw/misc: Add Exynos4210 Pseudo Random Number Generator
37
sdcard: Correct CRC16 offset in sd_function_switch()
35
38
36
Peter Maydell (1):
39
Richard Henderson (7):
37
target-arm: v7M: ignore writes to CONTROL.SPSEL from Thread mode
40
target/arm: Implement FMOV (general) for fp16
41
target/arm: Early exit after unallocated_encoding in disas_fp_int_conv
42
target/arm: Implement FCVT (scalar, integer) for fp16
43
target/arm: Implement FCVT (scalar, fixed-point) for fp16
44
target/arm: Introduce and use read_fp_hreg
45
target/arm: Implement FP data-processing (2 source) for fp16
46
target/arm: Implement FP data-processing (3 source) for fp16
38
47
39
hw/misc/Makefile.objs | 2 +-
48
include/qemu/log.h | 1 +
40
include/hw/arm/aspeed_soc.h | 4 +-
49
target/arm/helper-a64.h | 2 +
41
include/sysemu/kvm.h | 11 ++
50
target/arm/helper.h | 6 +
42
target/arm/cpu.h | 3 +
51
accel/tcg/cpu-exec.c | 9 +-
43
accel/kvm/kvm-all.c | 5 +
52
fpu/softfloat.c | 6 +-
44
accel/stubs/kvm-stub.c | 5 +
53
hw/sd/sd.c | 2 +-
45
hw/arm/aspeed_soc.c | 25 ++--
54
target/arm/cpu.c | 2 +
46
hw/arm/exynos4210.c | 4 +
55
target/arm/helper-a64.c | 10 ++
47
hw/intc/arm_gic.c | 7 ++
56
target/arm/helper.c | 38 +++-
48
hw/misc/exynos4210_rng.c | 277 ++++++++++++++++++++++++++++++++++++++++++++
57
target/arm/translate-a64.c | 421 ++++++++++++++++++++++++++++++++++++++-------
49
target/arm/helper.c | 13 ++-
58
util/log.c | 2 +
50
target/arm/kvm.c | 51 ++++++++
59
11 files changed, 428 insertions(+), 71 deletions(-)
51
12 files changed, 394 insertions(+), 13 deletions(-)
52
create mode 100644 hw/misc/exynos4210_rng.c
53
60
diff view generated by jsdifflib
New patch
1
From: Alex Bennée <alex.bennee@linaro.org>
1
2
3
Reported by Coverity (CID1390635). We ensure this for uint_to_float
4
later on so we might as well mirror that.
5
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
fpu/softfloat.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/fpu/softfloat.c
17
+++ b/fpu/softfloat.c
18
@@ -XXX,XX +XXX,XX @@ FLOAT_TO_UINT(64, 64)
19
20
static FloatParts int_to_float(int64_t a, float_status *status)
21
{
22
- FloatParts r;
23
+ FloatParts r = {};
24
if (a == 0) {
25
r.cls = float_class_zero;
26
r.sign = false;
27
--
28
2.17.0
29
30
diff view generated by jsdifflib
New patch
1
In float-to-integer conversion, if the floating point input
2
converts exactly to the largest or smallest integer that
3
fits in to the result type, this is not an overflow.
4
In this situation we were producing the correct result value,
5
but were incorrectly setting the Invalid flag.
6
For example for Arm A64, "FCVTAS w0, d0" on an input of
7
0x41dfffffffc00000 should produce 0x7fffffff and set no flags.
1
8
9
Fix the boundary case to take the right half of the if()
10
statements.
11
12
This fixes a regression from 2.11 introduced by the softfloat
13
refactoring.
14
15
Cc: qemu-stable@nongnu.org
16
Fixes: ab52f973a50
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20180510140141.12120-1-peter.maydell@linaro.org
20
---
21
fpu/softfloat.c | 4 ++--
22
1 file changed, 2 insertions(+), 2 deletions(-)
23
24
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat.c
27
+++ b/fpu/softfloat.c
28
@@ -XXX,XX +XXX,XX @@ static int64_t round_to_int_and_pack(FloatParts in, int rmode,
29
r = UINT64_MAX;
30
}
31
if (p.sign) {
32
- if (r < -(uint64_t) min) {
33
+ if (r <= -(uint64_t) min) {
34
return -r;
35
} else {
36
s->float_exception_flags = orig_flags | float_flag_invalid;
37
return min;
38
}
39
} else {
40
- if (r < max) {
41
+ if (r <= max) {
42
return r;
43
} else {
44
s->float_exception_flags = orig_flags | float_flag_invalid;
45
--
46
2.17.0
47
48
diff view generated by jsdifflib
New patch
1
In commit d81ce0ef2c4f105 we added an extra float_status field
2
fp_status_fp16 for Arm, but forgot to initialize it correctly
3
by setting it to float_tininess_before_rounding. This currently
4
will only cause problems for the new V8_FP16 feature, since the
5
float-to-float conversion code doesn't use it yet. The effect
6
would be that we failed to set the Underflow IEEE exception flag
7
in all the cases where we should.
1
8
9
Add the missing initialization.
10
11
Fixes: d81ce0ef2c4f105
12
Cc: qemu-stable@nongnu.org
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Message-id: 20180512004311.9299-16-richard.henderson@linaro.org
17
---
18
target/arm/cpu.c | 2 ++
19
1 file changed, 2 insertions(+)
20
21
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.c
24
+++ b/target/arm/cpu.c
25
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
26
&env->vfp.fp_status);
27
set_float_detect_tininess(float_tininess_before_rounding,
28
&env->vfp.standard_fp_status);
29
+ set_float_detect_tininess(float_tininess_before_rounding,
30
+ &env->vfp.fp_status_f16);
31
#ifndef CONFIG_USER_ONLY
32
if (kvm_enabled()) {
33
kvm_arm_reset_vcpu(cpu);
34
--
35
2.17.0
36
37
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Adding the fp16 moves to/from general registers.
4
5
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Tested-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20180512003217.9105-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 21 +++++++++++++++++++++
13
1 file changed, 21 insertions(+)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
20
tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_hi_offset(s, rd));
21
clear_vec_high(s, true, rd);
22
break;
23
+ case 3:
24
+ /* 16 bit */
25
+ tmp = tcg_temp_new_i64();
26
+ tcg_gen_ext16u_i64(tmp, tcg_rn);
27
+ write_fp_dreg(s, rd, tmp);
28
+ tcg_temp_free_i64(tmp);
29
+ break;
30
+ default:
31
+ g_assert_not_reached();
32
}
33
} else {
34
TCGv_i64 tcg_rd = cpu_reg(s, rd);
35
@@ -XXX,XX +XXX,XX @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
36
/* 64 bits from top half */
37
tcg_gen_ld_i64(tcg_rd, cpu_env, fp_reg_hi_offset(s, rn));
38
break;
39
+ case 3:
40
+ /* 16 bit */
41
+ tcg_gen_ld16u_i64(tcg_rd, cpu_env, fp_reg_offset(s, rn, MO_16));
42
+ break;
43
+ default:
44
+ g_assert_not_reached();
45
}
46
}
47
}
48
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
49
case 0xa: /* 64 bit */
50
case 0xd: /* 64 bit to top half of quad */
51
break;
52
+ case 0x6: /* 16-bit float, 32-bit int */
53
+ case 0xe: /* 16-bit float, 64-bit int */
54
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
55
+ break;
56
+ }
57
+ /* fallthru */
58
default:
59
/* all other sf/type/rmode combinations are invalid */
60
unallocated_encoding(s);
61
--
62
2.17.0
63
64
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
No sense in emitting code after the exception.
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180512003217.9105-3-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-a64.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
19
default:
20
/* all other sf/type/rmode combinations are invalid */
21
unallocated_encoding(s);
22
- break;
23
+ return;
24
}
25
26
if (!fp_access_check(s)) {
27
--
28
2.17.0
29
30
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Cc: qemu-stable@nongnu.org
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180512003217.9105-4-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/helper.h | 6 +++
11
target/arm/helper.c | 38 ++++++++++++++-
12
target/arm/translate-a64.c | 96 +++++++++++++++++++++++++++++++-------
13
3 files changed, 122 insertions(+), 18 deletions(-)
14
15
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.h
18
+++ b/target/arm/helper.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, ptr)
20
DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr)
21
DEF_HELPER_3(vfp_touhh, i32, f16, i32, ptr)
22
DEF_HELPER_3(vfp_toshh, i32, f16, i32, ptr)
23
+DEF_HELPER_3(vfp_toulh, i32, f16, i32, ptr)
24
+DEF_HELPER_3(vfp_toslh, i32, f16, i32, ptr)
25
+DEF_HELPER_3(vfp_touqh, i64, f16, i32, ptr)
26
+DEF_HELPER_3(vfp_tosqh, i64, f16, i32, ptr)
27
DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr)
28
DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr)
29
DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr)
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr)
31
DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr)
32
DEF_HELPER_3(vfp_sltoh, f16, i32, i32, ptr)
33
DEF_HELPER_3(vfp_ultoh, f16, i32, i32, ptr)
34
+DEF_HELPER_3(vfp_sqtoh, f16, i64, i32, ptr)
35
+DEF_HELPER_3(vfp_uqtoh, f16, i64, i32, ptr)
36
37
DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr)
38
DEF_HELPER_FLAGS_2(set_neon_rmode, TCG_CALL_NO_RWG, i32, i32, env)
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
44
#undef VFP_CONV_FIX_A64
45
46
/* Conversion to/from f16 can overflow to infinity before/after scaling.
47
- * Therefore we convert to f64 (which does not round), scale,
48
- * and then convert f64 to f16 (which may round).
49
+ * Therefore we convert to f64, scale, and then convert f64 to f16; or
50
+ * vice versa for conversion to integer.
51
+ *
52
+ * For 16- and 32-bit integers, the conversion to f64 never rounds.
53
+ * For 64-bit integers, any integer that would cause rounding will also
54
+ * overflow to f16 infinity, so there is no double rounding problem.
55
*/
56
57
static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
58
@@ -XXX,XX +XXX,XX @@ float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
59
return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
60
}
61
62
+float16 HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
63
+{
64
+ return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst);
65
+}
66
+
67
+float16 HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
68
+{
69
+ return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst);
70
+}
71
+
72
static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
73
{
74
if (unlikely(float16_is_any_nan(f))) {
75
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst)
76
return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
77
}
78
79
+uint32_t HELPER(vfp_toslh)(float16 x, uint32_t shift, void *fpst)
80
+{
81
+ return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst);
82
+}
83
+
84
+uint32_t HELPER(vfp_toulh)(float16 x, uint32_t shift, void *fpst)
85
+{
86
+ return float64_to_uint32(do_prescale_fp16(x, shift, fpst), fpst);
87
+}
88
+
89
+uint64_t HELPER(vfp_tosqh)(float16 x, uint32_t shift, void *fpst)
90
+{
91
+ return float64_to_int64(do_prescale_fp16(x, shift, fpst), fpst);
92
+}
93
+
94
+uint64_t HELPER(vfp_touqh)(float16 x, uint32_t shift, void *fpst)
95
+{
96
+ return float64_to_uint64(do_prescale_fp16(x, shift, fpst), fpst);
97
+}
98
+
99
/* Set the current fp rounding mode and return the old one.
100
* The argument is a softfloat float_round_ value.
101
*/
102
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/translate-a64.c
105
+++ b/target/arm/translate-a64.c
106
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
107
bool itof, int rmode, int scale, int sf, int type)
108
{
109
bool is_signed = !(opcode & 1);
110
- bool is_double = type;
111
TCGv_ptr tcg_fpstatus;
112
- TCGv_i32 tcg_shift;
113
+ TCGv_i32 tcg_shift, tcg_single;
114
+ TCGv_i64 tcg_double;
115
116
- tcg_fpstatus = get_fpstatus_ptr(false);
117
+ tcg_fpstatus = get_fpstatus_ptr(type == 3);
118
119
tcg_shift = tcg_const_i32(64 - scale);
120
121
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
122
tcg_int = tcg_extend;
123
}
124
125
- if (is_double) {
126
- TCGv_i64 tcg_double = tcg_temp_new_i64();
127
+ switch (type) {
128
+ case 1: /* float64 */
129
+ tcg_double = tcg_temp_new_i64();
130
if (is_signed) {
131
gen_helper_vfp_sqtod(tcg_double, tcg_int,
132
tcg_shift, tcg_fpstatus);
133
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
134
}
135
write_fp_dreg(s, rd, tcg_double);
136
tcg_temp_free_i64(tcg_double);
137
- } else {
138
- TCGv_i32 tcg_single = tcg_temp_new_i32();
139
+ break;
140
+
141
+ case 0: /* float32 */
142
+ tcg_single = tcg_temp_new_i32();
143
if (is_signed) {
144
gen_helper_vfp_sqtos(tcg_single, tcg_int,
145
tcg_shift, tcg_fpstatus);
146
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
147
}
148
write_fp_sreg(s, rd, tcg_single);
149
tcg_temp_free_i32(tcg_single);
150
+ break;
151
+
152
+ case 3: /* float16 */
153
+ tcg_single = tcg_temp_new_i32();
154
+ if (is_signed) {
155
+ gen_helper_vfp_sqtoh(tcg_single, tcg_int,
156
+ tcg_shift, tcg_fpstatus);
157
+ } else {
158
+ gen_helper_vfp_uqtoh(tcg_single, tcg_int,
159
+ tcg_shift, tcg_fpstatus);
160
+ }
161
+ write_fp_sreg(s, rd, tcg_single);
162
+ tcg_temp_free_i32(tcg_single);
163
+ break;
164
+
165
+ default:
166
+ g_assert_not_reached();
167
}
168
} else {
169
TCGv_i64 tcg_int = cpu_reg(s, rd);
170
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
171
172
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
173
174
- if (is_double) {
175
- TCGv_i64 tcg_double = read_fp_dreg(s, rn);
176
+ switch (type) {
177
+ case 1: /* float64 */
178
+ tcg_double = read_fp_dreg(s, rn);
179
if (is_signed) {
180
if (!sf) {
181
gen_helper_vfp_tosld(tcg_int, tcg_double,
182
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
183
tcg_shift, tcg_fpstatus);
184
}
185
}
186
+ if (!sf) {
187
+ tcg_gen_ext32u_i64(tcg_int, tcg_int);
188
+ }
189
tcg_temp_free_i64(tcg_double);
190
- } else {
191
- TCGv_i32 tcg_single = read_fp_sreg(s, rn);
192
+ break;
193
+
194
+ case 0: /* float32 */
195
+ tcg_single = read_fp_sreg(s, rn);
196
if (sf) {
197
if (is_signed) {
198
gen_helper_vfp_tosqs(tcg_int, tcg_single,
199
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
200
tcg_temp_free_i32(tcg_dest);
201
}
202
tcg_temp_free_i32(tcg_single);
203
+ break;
204
+
205
+ case 3: /* float16 */
206
+ tcg_single = read_fp_sreg(s, rn);
207
+ if (sf) {
208
+ if (is_signed) {
209
+ gen_helper_vfp_tosqh(tcg_int, tcg_single,
210
+ tcg_shift, tcg_fpstatus);
211
+ } else {
212
+ gen_helper_vfp_touqh(tcg_int, tcg_single,
213
+ tcg_shift, tcg_fpstatus);
214
+ }
215
+ } else {
216
+ TCGv_i32 tcg_dest = tcg_temp_new_i32();
217
+ if (is_signed) {
218
+ gen_helper_vfp_toslh(tcg_dest, tcg_single,
219
+ tcg_shift, tcg_fpstatus);
220
+ } else {
221
+ gen_helper_vfp_toulh(tcg_dest, tcg_single,
222
+ tcg_shift, tcg_fpstatus);
223
+ }
224
+ tcg_gen_extu_i32_i64(tcg_int, tcg_dest);
225
+ tcg_temp_free_i32(tcg_dest);
226
+ }
227
+ tcg_temp_free_i32(tcg_single);
228
+ break;
229
+
230
+ default:
231
+ g_assert_not_reached();
232
}
233
234
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
235
tcg_temp_free_i32(tcg_rmode);
236
-
237
- if (!sf) {
238
- tcg_gen_ext32u_i64(tcg_int, tcg_int);
239
- }
240
}
241
242
tcg_temp_free_ptr(tcg_fpstatus);
243
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
244
/* actual FP conversions */
245
bool itof = extract32(opcode, 1, 1);
246
247
- if (type > 1 || (rmode != 0 && opcode > 1)) {
248
+ if (rmode != 0 && opcode > 1) {
249
+ unallocated_encoding(s);
250
+ return;
251
+ }
252
+ switch (type) {
253
+ case 0: /* float32 */
254
+ case 1: /* float64 */
255
+ break;
256
+ case 3: /* float16 */
257
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
258
+ break;
259
+ }
260
+ /* fallthru */
261
+ default:
262
unallocated_encoding(s);
263
return;
264
}
265
--
266
2.17.0
267
268
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Cc: qemu-stable@nongnu.org
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180512003217.9105-5-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 17 +++++++++++++++--
11
1 file changed, 15 insertions(+), 2 deletions(-)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
18
bool sf = extract32(insn, 31, 1);
19
bool itof;
20
21
- if (sbit || (type > 1)
22
- || (!sf && scale < 32)) {
23
+ if (sbit || (!sf && scale < 32)) {
24
+ unallocated_encoding(s);
25
+ return;
26
+ }
27
+
28
+ switch (type) {
29
+ case 0: /* float32 */
30
+ case 1: /* float64 */
31
+ break;
32
+ case 3: /* float16 */
33
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
34
+ break;
35
+ }
36
+ /* fallthru */
37
+ default:
38
unallocated_encoding(s);
39
return;
40
}
41
--
42
2.17.0
43
44
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Cc: qemu-stable@nongnu.org
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180512003217.9105-6-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/translate-a64.c | 30 ++++++++++++++----------------
11
1 file changed, 14 insertions(+), 16 deletions(-)
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 read_fp_sreg(DisasContext *s, int reg)
18
return v;
19
}
20
21
+static TCGv_i32 read_fp_hreg(DisasContext *s, int reg)
22
+{
23
+ TCGv_i32 v = tcg_temp_new_i32();
24
+
25
+ tcg_gen_ld16u_i32(v, cpu_env, fp_reg_offset(s, reg, MO_16));
26
+ return v;
27
+}
28
+
29
/* Clear the bits above an N-bit vector, for N = (is_q ? 128 : 64).
30
* If SVE is not enabled, then there are only 128 bits in the vector.
31
*/
32
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
33
static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
34
{
35
TCGv_ptr fpst = NULL;
36
- TCGv_i32 tcg_op = tcg_temp_new_i32();
37
+ TCGv_i32 tcg_op = read_fp_hreg(s, rn);
38
TCGv_i32 tcg_res = tcg_temp_new_i32();
39
40
- read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
41
-
42
switch (opcode) {
43
case 0x0: /* FMOV */
44
tcg_gen_mov_i32(tcg_res, tcg_op);
45
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
46
tcg_temp_free_i64(tcg_op2);
47
tcg_temp_free_i64(tcg_res);
48
} else {
49
- TCGv_i32 tcg_op1 = tcg_temp_new_i32();
50
- TCGv_i32 tcg_op2 = tcg_temp_new_i32();
51
+ TCGv_i32 tcg_op1 = read_fp_hreg(s, rn);
52
+ TCGv_i32 tcg_op2 = read_fp_hreg(s, rm);
53
TCGv_i64 tcg_res = tcg_temp_new_i64();
54
55
- read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
56
- read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
57
-
58
gen_helper_neon_mull_s16(tcg_res, tcg_op1, tcg_op2);
59
gen_helper_neon_addl_saturate_s32(tcg_res, cpu_env, tcg_res, tcg_res);
60
61
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s,
62
63
fpst = get_fpstatus_ptr(true);
64
65
- tcg_op1 = tcg_temp_new_i32();
66
- tcg_op2 = tcg_temp_new_i32();
67
+ tcg_op1 = read_fp_hreg(s, rn);
68
+ tcg_op2 = read_fp_hreg(s, rm);
69
tcg_res = tcg_temp_new_i32();
70
71
- read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
72
- read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
73
-
74
switch (fpopcode) {
75
case 0x03: /* FMULX */
76
gen_helper_advsimd_mulxh(tcg_res, tcg_op1, tcg_op2, fpst);
77
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
78
}
79
80
if (is_scalar) {
81
- TCGv_i32 tcg_op = tcg_temp_new_i32();
82
+ TCGv_i32 tcg_op = read_fp_hreg(s, rn);
83
TCGv_i32 tcg_res = tcg_temp_new_i32();
84
85
- read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
86
-
87
switch (fpop) {
88
case 0x1a: /* FCVTNS */
89
case 0x1b: /* FCVTMS */
90
--
91
2.17.0
92
93
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
We missed all of the scalar fp16 binary operations.
4
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180512003217.9105-7-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 65 ++++++++++++++++++++++++++++++++++++++
13
1 file changed, 65 insertions(+)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void handle_fp_2src_double(DisasContext *s, int opcode,
20
tcg_temp_free_i64(tcg_res);
21
}
22
23
+/* Floating-point data-processing (2 source) - half precision */
24
+static void handle_fp_2src_half(DisasContext *s, int opcode,
25
+ int rd, int rn, int rm)
26
+{
27
+ TCGv_i32 tcg_op1;
28
+ TCGv_i32 tcg_op2;
29
+ TCGv_i32 tcg_res;
30
+ TCGv_ptr fpst;
31
+
32
+ tcg_res = tcg_temp_new_i32();
33
+ fpst = get_fpstatus_ptr(true);
34
+ tcg_op1 = read_fp_hreg(s, rn);
35
+ tcg_op2 = read_fp_hreg(s, rm);
36
+
37
+ switch (opcode) {
38
+ case 0x0: /* FMUL */
39
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
40
+ break;
41
+ case 0x1: /* FDIV */
42
+ gen_helper_advsimd_divh(tcg_res, tcg_op1, tcg_op2, fpst);
43
+ break;
44
+ case 0x2: /* FADD */
45
+ gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
46
+ break;
47
+ case 0x3: /* FSUB */
48
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
49
+ break;
50
+ case 0x4: /* FMAX */
51
+ gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
52
+ break;
53
+ case 0x5: /* FMIN */
54
+ gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
55
+ break;
56
+ case 0x6: /* FMAXNM */
57
+ gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
58
+ break;
59
+ case 0x7: /* FMINNM */
60
+ gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
61
+ break;
62
+ case 0x8: /* FNMUL */
63
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
64
+ tcg_gen_xori_i32(tcg_res, tcg_res, 0x8000);
65
+ break;
66
+ default:
67
+ g_assert_not_reached();
68
+ }
69
+
70
+ write_fp_sreg(s, rd, tcg_res);
71
+
72
+ tcg_temp_free_ptr(fpst);
73
+ tcg_temp_free_i32(tcg_op1);
74
+ tcg_temp_free_i32(tcg_op2);
75
+ tcg_temp_free_i32(tcg_res);
76
+}
77
+
78
/* Floating point data-processing (2 source)
79
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
80
* +---+---+---+-----------+------+---+------+--------+-----+------+------+
81
@@ -XXX,XX +XXX,XX @@ static void disas_fp_2src(DisasContext *s, uint32_t insn)
82
}
83
handle_fp_2src_double(s, opcode, rd, rn, rm);
84
break;
85
+ case 3:
86
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
87
+ unallocated_encoding(s);
88
+ return;
89
+ }
90
+ if (!fp_access_check(s)) {
91
+ return;
92
+ }
93
+ handle_fp_2src_half(s, opcode, rd, rn, rm);
94
+ break;
95
default:
96
unallocated_encoding(s);
97
}
98
--
99
2.17.0
100
101
diff view generated by jsdifflib
1
From: Joel Stanley <joel@jms.id.au>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The ast2400 contains two and the ast2500 contains three watchdogs.
3
We missed all of the scalar fp16 fma operations.
4
Add this information to the AspeedSoCInfo and realise the correct number
5
of watchdogs for that each SoC type.
6
4
7
Signed-off-by: Joel Stanley <joel@jms.id.au>
5
Cc: qemu-stable@nongnu.org
8
Reviewed-by: Cédric Le Goater <clg@kaod.org>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Tested-by: Cédric Le Goater <clg@kaod.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180512003217.9105-8-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
include/hw/arm/aspeed_soc.h | 4 +++-
12
target/arm/translate-a64.c | 48 ++++++++++++++++++++++++++++++++++++++
13
hw/arm/aspeed_soc.c | 25 +++++++++++++++++--------
13
1 file changed, 48 insertions(+)
14
2 files changed, 20 insertions(+), 9 deletions(-)
15
14
16
diff --git a/include/hw/arm/aspeed_soc.h b/include/hw/arm/aspeed_soc.h
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/aspeed_soc.h
17
--- a/target/arm/translate-a64.c
19
+++ b/include/hw/arm/aspeed_soc.h
18
+++ b/target/arm/translate-a64.c
20
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
21
#include "hw/net/ftgmac100.h"
20
tcg_temp_free_i64(tcg_res);
22
21
}
23
#define ASPEED_SPIS_NUM 2
22
24
+#define ASPEED_WDTS_NUM 3
23
+/* Floating-point data-processing (3 source) - half precision */
25
24
+static void handle_fp_3src_half(DisasContext *s, bool o0, bool o1,
26
typedef struct AspeedSoCState {
25
+ int rd, int rn, int rm, int ra)
27
/*< private >*/
26
+{
28
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCState {
27
+ TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
29
AspeedSMCState fmc;
28
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
30
AspeedSMCState spi[ASPEED_SPIS_NUM];
29
+ TCGv_ptr fpst = get_fpstatus_ptr(true);
31
AspeedSDMCState sdmc;
30
+
32
- AspeedWDTState wdt;
31
+ tcg_op1 = read_fp_hreg(s, rn);
33
+ AspeedWDTState wdt[ASPEED_WDTS_NUM];
32
+ tcg_op2 = read_fp_hreg(s, rm);
34
FTGMAC100State ftgmac100;
33
+ tcg_op3 = read_fp_hreg(s, ra);
35
} AspeedSoCState;
34
+
36
35
+ /* These are fused multiply-add, and must be done as one
37
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSoCInfo {
36
+ * floating point operation with no rounding between the
38
const hwaddr *spi_bases;
37
+ * multiplication and addition steps.
39
const char *fmc_typename;
38
+ * NB that doing the negations here as separate steps is
40
const char **spi_typename;
39
+ * correct : an input NaN should come out with its sign bit
41
+ int wdts_num;
40
+ * flipped if it is a negated-input.
42
} AspeedSoCInfo;
41
+ */
43
42
+ if (o1 == true) {
44
typedef struct AspeedSoCClass {
43
+ tcg_gen_xori_i32(tcg_op3, tcg_op3, 0x8000);
45
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/arm/aspeed_soc.c
48
+++ b/hw/arm/aspeed_soc.c
49
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
50
.spi_bases = aspeed_soc_ast2400_spi_bases,
51
.fmc_typename = "aspeed.smc.fmc",
52
.spi_typename = aspeed_soc_ast2400_typenames,
53
+ .wdts_num = 2,
54
}, {
55
.name = "ast2400-a1",
56
.cpu_model = "arm926",
57
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
58
.spi_bases = aspeed_soc_ast2400_spi_bases,
59
.fmc_typename = "aspeed.smc.fmc",
60
.spi_typename = aspeed_soc_ast2400_typenames,
61
+ .wdts_num = 2,
62
}, {
63
.name = "ast2400",
64
.cpu_model = "arm926",
65
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
66
.spi_bases = aspeed_soc_ast2400_spi_bases,
67
.fmc_typename = "aspeed.smc.fmc",
68
.spi_typename = aspeed_soc_ast2400_typenames,
69
+ .wdts_num = 2,
70
}, {
71
.name = "ast2500-a1",
72
.cpu_model = "arm1176",
73
@@ -XXX,XX +XXX,XX @@ static const AspeedSoCInfo aspeed_socs[] = {
74
.spi_bases = aspeed_soc_ast2500_spi_bases,
75
.fmc_typename = "aspeed.smc.ast2500-fmc",
76
.spi_typename = aspeed_soc_ast2500_typenames,
77
+ .wdts_num = 3,
78
},
79
};
80
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
82
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
83
"ram-size", &error_abort);
84
85
- object_initialize(&s->wdt, sizeof(s->wdt), TYPE_ASPEED_WDT);
86
- object_property_add_child(obj, "wdt", OBJECT(&s->wdt), NULL);
87
- qdev_set_parent_bus(DEVICE(&s->wdt), sysbus_get_default());
88
+ for (i = 0; i < sc->info->wdts_num; i++) {
89
+ object_initialize(&s->wdt[i], sizeof(s->wdt[i]), TYPE_ASPEED_WDT);
90
+ object_property_add_child(obj, "wdt[*]", OBJECT(&s->wdt[i]), NULL);
91
+ qdev_set_parent_bus(DEVICE(&s->wdt[i]), sysbus_get_default());
92
+ }
44
+ }
93
45
+
94
object_initialize(&s->ftgmac100, sizeof(s->ftgmac100), TYPE_FTGMAC100);
46
+ if (o0 != o1) {
95
object_property_add_child(obj, "ftgmac100", OBJECT(&s->ftgmac100), NULL);
47
+ tcg_gen_xori_i32(tcg_op1, tcg_op1, 0x8000);
96
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_realize(DeviceState *dev, Error **errp)
48
+ }
97
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sdmc), 0, ASPEED_SOC_SDMC_BASE);
49
+
98
50
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);
99
/* Watch dog */
51
+
100
- object_property_set_bool(OBJECT(&s->wdt), true, "realized", &err);
52
+ write_fp_sreg(s, rd, tcg_res);
101
- if (err) {
53
+
102
- error_propagate(errp, err);
54
+ tcg_temp_free_ptr(fpst);
103
- return;
55
+ tcg_temp_free_i32(tcg_op1);
104
+ for (i = 0; i < sc->info->wdts_num; i++) {
56
+ tcg_temp_free_i32(tcg_op2);
105
+ object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized", &err);
57
+ tcg_temp_free_i32(tcg_op3);
106
+ if (err) {
58
+ tcg_temp_free_i32(tcg_res);
107
+ error_propagate(errp, err);
59
+}
60
+
61
/* Floating point data-processing (3 source)
62
* 31 30 29 28 24 23 22 21 20 16 15 14 10 9 5 4 0
63
* +---+---+---+-----------+------+----+------+----+------+------+------+
64
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
65
}
66
handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra);
67
break;
68
+ case 3:
69
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
70
+ unallocated_encoding(s);
108
+ return;
71
+ return;
109
+ }
72
+ }
110
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
73
+ if (!fp_access_check(s)) {
111
+ ASPEED_SOC_WDT_BASE + i * 0x20);
74
+ return;
75
+ }
76
+ handle_fp_3src_half(s, o0, o1, rd, rn, rm, ra);
77
+ break;
78
default:
79
unallocated_encoding(s);
112
}
80
}
113
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt), 0, ASPEED_SOC_WDT_BASE);
114
115
/* Net */
116
qdev_set_nic_properties(DEVICE(&s->ftgmac100), &nd_table[0]);
117
--
81
--
118
2.7.4
82
2.17.0
119
83
120
84
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@suse.de>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
When running with KVM enabled, you can choose between emulating the
3
These where missed out from the rest of the half-precision work.
4
gic in kernel or user space. If the kernel supports in-kernel virtualization
4
5
of the interrupt controller, it will default to that. If not, if will
5
Cc: qemu-stable@nongnu.org
6
default to user space emulation.
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Unfortunately when running in user mode gic emulation, we miss out on
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
interrupt events which are only available from kernel space, such as the timer.
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
This patch leverages the new kernel/user space pending line synchronization for
10
Message-id: 20180512003217.9105-9-richard.henderson@linaro.org
11
timer events. It does not handle PMU events yet.
11
[rth: Diagnose lack of FP16 before fp_access_check]
12
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Alexander Graf <agraf@suse.de>
14
Reviewed-by: Andrew Jones <drjones@redhat.com>
15
Message-id: 1498577737-130264-1-git-send-email-agraf@suse.de
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
14
---
18
include/sysemu/kvm.h | 11 +++++++++++
15
target/arm/helper-a64.h | 2 +
19
target/arm/cpu.h | 3 +++
16
target/arm/helper-a64.c | 10 +++++
20
accel/kvm/kvm-all.c | 5 +++++
17
target/arm/translate-a64.c | 88 ++++++++++++++++++++++++++++++--------
21
accel/stubs/kvm-stub.c | 5 +++++
18
3 files changed, 83 insertions(+), 17 deletions(-)
22
hw/intc/arm_gic.c | 7 +++++++
19
23
target/arm/kvm.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++
20
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
24
6 files changed, 82 insertions(+)
25
26
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
27
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
28
--- a/include/sysemu/kvm.h
22
--- a/target/arm/helper-a64.h
29
+++ b/include/sysemu/kvm.h
23
+++ b/target/arm/helper-a64.h
30
@@ -XXX,XX +XXX,XX @@ int kvm_init_vcpu(CPUState *cpu);
24
@@ -XXX,XX +XXX,XX @@
31
int kvm_cpu_exec(CPUState *cpu);
25
DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
32
int kvm_destroy_vcpu(CPUState *cpu);
26
DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
33
27
DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
34
+/**
28
+DEF_HELPER_3(vfp_cmph_a64, i64, f16, f16, ptr)
35
+ * kvm_arm_supports_user_irq
29
+DEF_HELPER_3(vfp_cmpeh_a64, i64, f16, f16, ptr)
36
+ *
30
DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
37
+ * Not all KVM implementations support notifications for kernel generated
31
DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr)
38
+ * interrupt events to user space. This function indicates whether the current
32
DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr)
39
+ * KVM implementation does support them.
33
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
40
+ *
41
+ * Returns: true if KVM supports using kernel generated IRQs from user space
42
+ */
43
+bool kvm_arm_supports_user_irq(void);
44
+
45
#ifdef NEED_CPU_H
46
#include "cpu.h"
47
48
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
49
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/cpu.h
35
--- a/target/arm/helper-a64.c
51
+++ b/target/arm/cpu.h
36
+++ b/target/arm/helper-a64.c
52
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
37
@@ -XXX,XX +XXX,XX @@ static inline uint32_t float_rel_to_flags(int res)
53
void *el_change_hook_opaque;
38
return flags;
54
39
}
55
int32_t node_id; /* NUMA node this CPU belongs to */
40
56
+
41
+uint64_t HELPER(vfp_cmph_a64)(float16 x, float16 y, void *fp_status)
57
+ /* Used to synchronize KVM and QEMU in-kernel device levels */
42
+{
58
+ uint8_t device_irq_level;
43
+ return float_rel_to_flags(float16_compare_quiet(x, y, fp_status));
59
};
44
+}
60
45
+
61
static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
46
+uint64_t HELPER(vfp_cmpeh_a64)(float16 x, float16 y, void *fp_status)
62
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
47
+{
48
+ return float_rel_to_flags(float16_compare(x, y, fp_status));
49
+}
50
+
51
uint64_t HELPER(vfp_cmps_a64)(float32 x, float32 y, void *fp_status)
52
{
53
return float_rel_to_flags(float32_compare_quiet(x, y, fp_status));
54
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
63
index XXXXXXX..XXXXXXX 100644
55
index XXXXXXX..XXXXXXX 100644
64
--- a/accel/kvm/kvm-all.c
56
--- a/target/arm/translate-a64.c
65
+++ b/accel/kvm/kvm-all.c
57
+++ b/target/arm/translate-a64.c
66
@@ -XXX,XX +XXX,XX @@ int kvm_has_intx_set_mask(void)
58
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
67
return kvm_state->intx_set_mask;
59
}
68
}
60
}
69
61
70
+bool kvm_arm_supports_user_irq(void)
62
-static void handle_fp_compare(DisasContext *s, bool is_double,
71
+{
63
+static void handle_fp_compare(DisasContext *s, int size,
72
+ return kvm_check_extension(kvm_state, KVM_CAP_ARM_USER_IRQ);
64
unsigned int rn, unsigned int rm,
73
+}
65
bool cmp_with_zero, bool signal_all_nans)
74
+
75
#ifdef KVM_CAP_SET_GUEST_DEBUG
76
struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *cpu,
77
target_ulong pc)
78
diff --git a/accel/stubs/kvm-stub.c b/accel/stubs/kvm-stub.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/accel/stubs/kvm-stub.c
81
+++ b/accel/stubs/kvm-stub.c
82
@@ -XXX,XX +XXX,XX @@ void kvm_init_cpu_signals(CPUState *cpu)
83
{
66
{
84
abort();
67
TCGv_i64 tcg_flags = tcg_temp_new_i64();
85
}
68
- TCGv_ptr fpst = get_fpstatus_ptr(false);
86
+
69
+ TCGv_ptr fpst = get_fpstatus_ptr(size == MO_16);
87
+bool kvm_arm_supports_user_irq(void)
70
88
+{
71
- if (is_double) {
89
+ return false;
72
+ if (size == MO_64) {
90
+}
73
TCGv_i64 tcg_vn, tcg_vm;
91
#endif
74
92
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
75
tcg_vn = read_fp_dreg(s, rn);
93
index XXXXXXX..XXXXXXX 100644
76
@@ -XXX,XX +XXX,XX @@ static void handle_fp_compare(DisasContext *s, bool is_double,
94
--- a/hw/intc/arm_gic.c
77
tcg_temp_free_i64(tcg_vn);
95
+++ b/hw/intc/arm_gic.c
78
tcg_temp_free_i64(tcg_vm);
96
@@ -XXX,XX +XXX,XX @@
79
} else {
97
#include "qom/cpu.h"
80
- TCGv_i32 tcg_vn, tcg_vm;
98
#include "qemu/log.h"
81
+ TCGv_i32 tcg_vn = tcg_temp_new_i32();
99
#include "trace.h"
82
+ TCGv_i32 tcg_vm = tcg_temp_new_i32();
100
+#include "sysemu/kvm.h"
83
101
84
- tcg_vn = read_fp_sreg(s, rn);
102
/* #define DEBUG_GIC */
85
+ read_vec_element_i32(s, tcg_vn, rn, 0, size);
103
86
if (cmp_with_zero) {
104
@@ -XXX,XX +XXX,XX @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
87
- tcg_vm = tcg_const_i32(0);
105
return;
88
+ tcg_gen_movi_i32(tcg_vm, 0);
106
}
89
} else {
107
90
- tcg_vm = read_fp_sreg(s, rm);
108
+ if (kvm_enabled() && !kvm_arm_supports_user_irq()) {
91
+ read_vec_element_i32(s, tcg_vm, rm, 0, size);
109
+ error_setg(errp, "KVM with user space irqchip only works when the "
92
}
110
+ "host kernel supports KVM_CAP_ARM_USER_IRQ");
93
- if (signal_all_nans) {
94
- gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
95
- } else {
96
- gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
97
+
98
+ switch (size) {
99
+ case MO_32:
100
+ if (signal_all_nans) {
101
+ gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
102
+ } else {
103
+ gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
104
+ }
105
+ break;
106
+ case MO_16:
107
+ if (signal_all_nans) {
108
+ gen_helper_vfp_cmpeh_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
109
+ } else {
110
+ gen_helper_vfp_cmph_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
111
+ }
112
+ break;
113
+ default:
114
+ g_assert_not_reached();
115
}
116
+
117
tcg_temp_free_i32(tcg_vn);
118
tcg_temp_free_i32(tcg_vm);
119
}
120
@@ -XXX,XX +XXX,XX @@ static void handle_fp_compare(DisasContext *s, bool is_double,
121
static void disas_fp_compare(DisasContext *s, uint32_t insn)
122
{
123
unsigned int mos, type, rm, op, rn, opc, op2r;
124
+ int size;
125
126
mos = extract32(insn, 29, 3);
127
- type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
128
+ type = extract32(insn, 22, 2);
129
rm = extract32(insn, 16, 5);
130
op = extract32(insn, 14, 2);
131
rn = extract32(insn, 5, 5);
132
opc = extract32(insn, 3, 2);
133
op2r = extract32(insn, 0, 3);
134
135
- if (mos || op || op2r || type > 1) {
136
+ if (mos || op || op2r) {
137
+ unallocated_encoding(s);
111
+ return;
138
+ return;
112
+ }
139
+ }
113
+
140
+
114
/* This creates distributor and main CPU interface (s->cpuiomem[0]) */
141
+ switch (type) {
115
gic_init_irqs_and_mmio(s, gic_set_irq, gic_ops);
142
+ case 0:
116
143
+ size = MO_32;
117
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
144
+ break;
118
index XXXXXXX..XXXXXXX 100644
145
+ case 1:
119
--- a/target/arm/kvm.c
146
+ size = MO_64;
120
+++ b/target/arm/kvm.c
147
+ break;
121
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
148
+ case 3:
122
*/
149
+ size = MO_16;
123
kvm_async_interrupts_allowed = true;
150
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
124
151
+ break;
125
+ /*
152
+ }
126
+ * PSCI wakes up secondary cores, so we always need to
153
+ /* fallthru */
127
+ * have vCPUs waiting in kernel space
154
+ default:
128
+ */
155
unallocated_encoding(s);
129
+ kvm_halt_in_kernel_allowed = true;
156
return;
130
+
157
}
131
cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
158
@@ -XXX,XX +XXX,XX @@ static void disas_fp_compare(DisasContext *s, uint32_t insn)
132
159
return;
133
type_register_static(&host_arm_cpu_type_info);
160
}
134
@@ -XXX,XX +XXX,XX @@ void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
161
135
162
- handle_fp_compare(s, type, rn, rm, opc & 1, opc & 2);
136
MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
163
+ handle_fp_compare(s, size, rn, rm, opc & 1, opc & 2);
137
{
164
}
138
+ ARMCPU *cpu;
165
139
+ uint32_t switched_level;
166
/* Floating point conditional compare
140
+
167
@@ -XXX,XX +XXX,XX @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
141
+ if (kvm_irqchip_in_kernel()) {
168
unsigned int mos, type, rm, cond, rn, op, nzcv;
142
+ /*
169
TCGv_i64 tcg_flags;
143
+ * We only need to sync timer states with user-space interrupt
170
TCGLabel *label_continue = NULL;
144
+ * controllers, so return early and save cycles if we don't.
171
+ int size;
145
+ */
172
146
+ return MEMTXATTRS_UNSPECIFIED;
173
mos = extract32(insn, 29, 3);
174
- type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
175
+ type = extract32(insn, 22, 2);
176
rm = extract32(insn, 16, 5);
177
cond = extract32(insn, 12, 4);
178
rn = extract32(insn, 5, 5);
179
op = extract32(insn, 4, 1);
180
nzcv = extract32(insn, 0, 4);
181
182
- if (mos || type > 1) {
183
+ if (mos) {
184
+ unallocated_encoding(s);
185
+ return;
147
+ }
186
+ }
148
+
187
+
149
+ cpu = ARM_CPU(cs);
188
+ switch (type) {
150
+
189
+ case 0:
151
+ /* Synchronize our shadowed in-kernel device irq lines with the kvm ones */
190
+ size = MO_32;
152
+ if (run->s.regs.device_irq_level != cpu->device_irq_level) {
191
+ break;
153
+ switched_level = cpu->device_irq_level ^ run->s.regs.device_irq_level;
192
+ case 1:
154
+
193
+ size = MO_64;
155
+ qemu_mutex_lock_iothread();
194
+ break;
156
+
195
+ case 3:
157
+ if (switched_level & KVM_ARM_DEV_EL1_VTIMER) {
196
+ size = MO_16;
158
+ qemu_set_irq(cpu->gt_timer_outputs[GTIMER_VIRT],
197
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
159
+ !!(run->s.regs.device_irq_level &
198
+ break;
160
+ KVM_ARM_DEV_EL1_VTIMER));
161
+ switched_level &= ~KVM_ARM_DEV_EL1_VTIMER;
162
+ }
199
+ }
163
+
200
+ /* fallthru */
164
+ if (switched_level & KVM_ARM_DEV_EL1_PTIMER) {
201
+ default:
165
+ qemu_set_irq(cpu->gt_timer_outputs[GTIMER_PHYS],
202
unallocated_encoding(s);
166
+ !!(run->s.regs.device_irq_level &
203
return;
167
+ KVM_ARM_DEV_EL1_PTIMER));
204
}
168
+ switched_level &= ~KVM_ARM_DEV_EL1_PTIMER;
205
@@ -XXX,XX +XXX,XX @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
169
+ }
206
gen_set_label(label_match);
170
+
207
}
171
+ /* XXX PMU IRQ is missing */
208
172
+
209
- handle_fp_compare(s, type, rn, rm, false, op);
173
+ if (switched_level) {
210
+ handle_fp_compare(s, size, rn, rm, false, op);
174
+ qemu_log_mask(LOG_UNIMP, "%s: unhandled in-kernel device IRQ %x\n",
211
175
+ __func__, switched_level);
212
if (cond < 0x0e) {
176
+ }
213
gen_set_label(label_continue);
177
+
178
+ /* We also mark unknown levels as processed to not waste cycles */
179
+ cpu->device_irq_level = run->s.regs.device_irq_level;
180
+ qemu_mutex_unlock_iothread();
181
+ }
182
+
183
return MEMTXATTRS_UNSPECIFIED;
184
}
185
186
--
214
--
187
2.7.4
215
2.17.0
188
216
189
217
diff view generated by jsdifflib
1
From: Krzysztof Kozlowski <krzk@kernel.org>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
Add emulation for Exynos4210 Pseudo Random Number Generator which could
3
These were missed out from the rest of the half-precision work.
4
work on fixed seeds or with seeds provided by True Random Number
5
Generator block inside the SoC.
6
4
7
Implement only the fixed seeds part of it in polling mode (no
5
Cc: qemu-stable@nongnu.org
8
interrupts).
9
10
Emulation tested with two independent Linux kernel exynos-rng drivers:
11
1. New kcapi-rng interface (targeting Linux v4.12),
12
2. Old hwrng inteface
13
# echo "exynos" > /sys/class/misc/hw_random/rng_current
14
# dd if=/dev/hwrng of=/dev/null bs=1 count=16
15
16
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
17
Message-id: 20170425180609.11004-1-krzk@kernel.org
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
[PMM: wrapped a few overlong lines; more efficient implementation
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
20
of exynos4210_rng_seed_ready()]
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180512003217.9105-10-richard.henderson@linaro.org
11
[rth: Fix erroneous check vs type]
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
14
---
23
hw/misc/Makefile.objs | 2 +-
15
target/arm/translate-a64.c | 31 +++++++++++++++++++++++++------
24
hw/arm/exynos4210.c | 4 +
16
1 file changed, 25 insertions(+), 6 deletions(-)
25
hw/misc/exynos4210_rng.c | 277 +++++++++++++++++++++++++++++++++++++++++++++++
26
3 files changed, 282 insertions(+), 1 deletion(-)
27
create mode 100644 hw/misc/exynos4210_rng.c
28
17
29
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
18
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
30
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/misc/Makefile.objs
20
--- a/target/arm/translate-a64.c
32
+++ b/hw/misc/Makefile.objs
21
+++ b/target/arm/translate-a64.c
33
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IVSHMEM) += ivshmem.o
22
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
34
obj-$(CONFIG_REALVIEW) += arm_sysctl.o
23
unsigned int mos, type, rm, cond, rn, rd;
35
obj-$(CONFIG_NSERIES) += cbus.o
24
TCGv_i64 t_true, t_false, t_zero;
36
obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
25
DisasCompare64 c;
37
-obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o exynos4210_clk.o
26
+ TCGMemOp sz;
38
+obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o exynos4210_clk.o exynos4210_rng.o
27
39
obj-$(CONFIG_IMX) += imx_ccm.o
28
mos = extract32(insn, 29, 3);
40
obj-$(CONFIG_IMX) += imx31_ccm.o
29
- type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
41
obj-$(CONFIG_IMX) += imx25_ccm.o
30
+ type = extract32(insn, 22, 2);
42
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
31
rm = extract32(insn, 16, 5);
43
index XXXXXXX..XXXXXXX 100644
32
cond = extract32(insn, 12, 4);
44
--- a/hw/arm/exynos4210.c
33
rn = extract32(insn, 5, 5);
45
+++ b/hw/arm/exynos4210.c
34
rd = extract32(insn, 0, 5);
46
@@ -XXX,XX +XXX,XX @@
35
47
/* Clock controller SFR base address */
36
- if (mos || type > 1) {
48
#define EXYNOS4210_CLK_BASE_ADDR 0x10030000
37
+ if (mos) {
49
38
+ unallocated_encoding(s);
50
+/* PRNG/HASH SFR base address */
39
+ return;
51
+#define EXYNOS4210_RNG_BASE_ADDR 0x10830400
52
+
53
/* Display controllers (FIMD) */
54
#define EXYNOS4210_FIMD0_BASE_ADDR 0x11C00000
55
56
@@ -XXX,XX +XXX,XX @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem)
57
sysbus_create_simple("exynos4210.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL);
58
59
sysbus_create_simple("exynos4210.clk", EXYNOS4210_CLK_BASE_ADDR, NULL);
60
+ sysbus_create_simple("exynos4210.rng", EXYNOS4210_RNG_BASE_ADDR, NULL);
61
62
/* PWM */
63
sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
64
diff --git a/hw/misc/exynos4210_rng.c b/hw/misc/exynos4210_rng.c
65
new file mode 100644
66
index XXXXXXX..XXXXXXX
67
--- /dev/null
68
+++ b/hw/misc/exynos4210_rng.c
69
@@ -XXX,XX +XXX,XX @@
70
+/*
71
+ * Exynos4210 Pseudo Random Nubmer Generator Emulation
72
+ *
73
+ * Copyright (c) 2017 Krzysztof Kozlowski <krzk@kernel.org>
74
+ *
75
+ * This program is free software; you can redistribute it and/or modify it
76
+ * under the terms of the GNU General Public License as published by the
77
+ * Free Software Foundation; either version 2 of the License, or
78
+ * (at your option) any later version.
79
+ *
80
+ * This program is distributed in the hope that it will be useful, but WITHOUT
81
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
82
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
83
+ * for more details.
84
+ *
85
+ * You should have received a copy of the GNU General Public License along
86
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
87
+ */
88
+
89
+#include "qemu/osdep.h"
90
+#include "crypto/random.h"
91
+#include "hw/sysbus.h"
92
+#include "qemu/log.h"
93
+
94
+#define DEBUG_EXYNOS_RNG 0
95
+
96
+#define DPRINTF(fmt, ...) \
97
+ do { \
98
+ if (DEBUG_EXYNOS_RNG) { \
99
+ printf("exynos4210_rng: " fmt, ## __VA_ARGS__); \
100
+ } \
101
+ } while (0)
102
+
103
+#define TYPE_EXYNOS4210_RNG "exynos4210.rng"
104
+#define EXYNOS4210_RNG(obj) \
105
+ OBJECT_CHECK(Exynos4210RngState, (obj), TYPE_EXYNOS4210_RNG)
106
+
107
+/*
108
+ * Exynos4220, PRNG, only polling mode is supported.
109
+ */
110
+
111
+/* RNG_CONTROL_1 register bitfields, reset value: 0x0 */
112
+#define EXYNOS4210_RNG_CONTROL_1_PRNG 0x8
113
+#define EXYNOS4210_RNG_CONTROL_1_START_INIT BIT(4)
114
+/* RNG_STATUS register bitfields, reset value: 0x1 */
115
+#define EXYNOS4210_RNG_STATUS_PRNG_ERROR BIT(7)
116
+#define EXYNOS4210_RNG_STATUS_PRNG_DONE BIT(5)
117
+#define EXYNOS4210_RNG_STATUS_MSG_DONE BIT(4)
118
+#define EXYNOS4210_RNG_STATUS_PARTIAL_DONE BIT(3)
119
+#define EXYNOS4210_RNG_STATUS_PRNG_BUSY BIT(2)
120
+#define EXYNOS4210_RNG_STATUS_SEED_SETTING_DONE BIT(1)
121
+#define EXYNOS4210_RNG_STATUS_BUFFER_READY BIT(0)
122
+#define EXYNOS4210_RNG_STATUS_WRITE_MASK (EXYNOS4210_RNG_STATUS_PRNG_DONE \
123
+ | EXYNOS4210_RNG_STATUS_MSG_DONE \
124
+ | EXYNOS4210_RNG_STATUS_PARTIAL_DONE)
125
+
126
+#define EXYNOS4210_RNG_CONTROL_1 0x0
127
+#define EXYNOS4210_RNG_STATUS 0x10
128
+#define EXYNOS4210_RNG_SEED_IN 0x140
129
+#define EXYNOS4210_RNG_SEED_IN_OFFSET(n) (EXYNOS4210_RNG_SEED_IN + (n * 0x4))
130
+#define EXYNOS4210_RNG_PRNG 0x160
131
+#define EXYNOS4210_RNG_PRNG_OFFSET(n) (EXYNOS4210_RNG_PRNG + (n * 0x4))
132
+
133
+#define EXYNOS4210_RNG_PRNG_NUM 5
134
+
135
+#define EXYNOS4210_RNG_REGS_MEM_SIZE 0x200
136
+
137
+typedef struct Exynos4210RngState {
138
+ SysBusDevice parent_obj;
139
+ MemoryRegion iomem;
140
+
141
+ int32_t randr_value[EXYNOS4210_RNG_PRNG_NUM];
142
+ /* bits from 0 to EXYNOS4210_RNG_PRNG_NUM if given seed register was set */
143
+ uint32_t seed_set;
144
+
145
+ /* Register values */
146
+ uint32_t reg_control;
147
+ uint32_t reg_status;
148
+} Exynos4210RngState;
149
+
150
+static bool exynos4210_rng_seed_ready(const Exynos4210RngState *s)
151
+{
152
+ uint32_t mask = MAKE_64BIT_MASK(0, EXYNOS4210_RNG_PRNG_NUM);
153
+
154
+ /* Return true if all the seed-set bits are set. */
155
+ return (s->seed_set & mask) == mask;
156
+}
157
+
158
+static void exynos4210_rng_set_seed(Exynos4210RngState *s, unsigned int i,
159
+ uint64_t val)
160
+{
161
+ /*
162
+ * We actually ignore the seed and always generate true random numbers.
163
+ * Theoretically this should not match the device as Exynos has
164
+ * a Pseudo Random Number Generator but testing shown that it always
165
+ * generates random numbers regardless of the seed value.
166
+ */
167
+ s->seed_set |= BIT(i);
168
+
169
+ /* If all seeds were written, update the status to reflect it */
170
+ if (exynos4210_rng_seed_ready(s)) {
171
+ s->reg_status |= EXYNOS4210_RNG_STATUS_SEED_SETTING_DONE;
172
+ } else {
173
+ s->reg_status &= ~EXYNOS4210_RNG_STATUS_SEED_SETTING_DONE;
174
+ }
175
+}
176
+
177
+static void exynos4210_rng_run_engine(Exynos4210RngState *s)
178
+{
179
+ Error *err = NULL;
180
+ int ret;
181
+
182
+ /* Seed set? */
183
+ if ((s->reg_status & EXYNOS4210_RNG_STATUS_SEED_SETTING_DONE) == 0) {
184
+ goto out;
185
+ }
40
+ }
186
+
41
+
187
+ /* PRNG engine chosen? */
42
+ switch (type) {
188
+ if ((s->reg_control & EXYNOS4210_RNG_CONTROL_1_PRNG) == 0) {
43
+ case 0:
189
+ goto out;
44
+ sz = MO_32;
190
+ }
191
+
192
+ /* PRNG engine started? */
193
+ if ((s->reg_control & EXYNOS4210_RNG_CONTROL_1_START_INIT) == 0) {
194
+ goto out;
195
+ }
196
+
197
+ /* Get randoms */
198
+ ret = qcrypto_random_bytes((uint8_t *)s->randr_value,
199
+ sizeof(s->randr_value), &err);
200
+ if (!ret) {
201
+ /* Notify that PRNG is ready */
202
+ s->reg_status |= EXYNOS4210_RNG_STATUS_PRNG_DONE;
203
+ } else {
204
+ error_report_err(err);
205
+ }
206
+
207
+out:
208
+ /* Always clear start engine bit */
209
+ s->reg_control &= ~EXYNOS4210_RNG_CONTROL_1_START_INIT;
210
+}
211
+
212
+static uint64_t exynos4210_rng_read(void *opaque, hwaddr offset,
213
+ unsigned size)
214
+{
215
+ Exynos4210RngState *s = (Exynos4210RngState *)opaque;
216
+ uint32_t val = 0;
217
+
218
+ assert(size == 4);
219
+
220
+ switch (offset) {
221
+ case EXYNOS4210_RNG_CONTROL_1:
222
+ val = s->reg_control;
223
+ break;
45
+ break;
224
+
46
+ case 1:
225
+ case EXYNOS4210_RNG_STATUS:
47
+ sz = MO_64;
226
+ val = s->reg_status;
227
+ break;
48
+ break;
228
+
49
+ case 3:
229
+ case EXYNOS4210_RNG_PRNG_OFFSET(0):
50
+ sz = MO_16;
230
+ case EXYNOS4210_RNG_PRNG_OFFSET(1):
51
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
231
+ case EXYNOS4210_RNG_PRNG_OFFSET(2):
52
+ break;
232
+ case EXYNOS4210_RNG_PRNG_OFFSET(3):
53
+ }
233
+ case EXYNOS4210_RNG_PRNG_OFFSET(4):
54
+ /* fallthru */
234
+ val = s->randr_value[(offset - EXYNOS4210_RNG_PRNG_OFFSET(0)) / 4];
235
+ DPRINTF("returning random @0x%" HWADDR_PRIx ": 0x%" PRIx32 "\n",
236
+ offset, val);
237
+ break;
238
+
239
+ default:
55
+ default:
240
+ qemu_log_mask(LOG_GUEST_ERROR,
56
unallocated_encoding(s);
241
+ "%s: bad read offset 0x%" HWADDR_PRIx "\n",
57
return;
242
+ __func__, offset);
58
}
243
+ }
59
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
244
+
60
return;
245
+ return val;
61
}
246
+}
62
247
+
63
- /* Zero extend sreg inputs to 64 bits now. */
248
+static void exynos4210_rng_write(void *opaque, hwaddr offset,
64
+ /* Zero extend sreg & hreg inputs to 64 bits now. */
249
+ uint64_t val, unsigned size)
65
t_true = tcg_temp_new_i64();
250
+{
66
t_false = tcg_temp_new_i64();
251
+ Exynos4210RngState *s = (Exynos4210RngState *)opaque;
67
- read_vec_element(s, t_true, rn, 0, type ? MO_64 : MO_32);
252
+
68
- read_vec_element(s, t_false, rm, 0, type ? MO_64 : MO_32);
253
+ assert(size == 4);
69
+ read_vec_element(s, t_true, rn, 0, sz);
254
+
70
+ read_vec_element(s, t_false, rm, 0, sz);
255
+ switch (offset) {
71
256
+ case EXYNOS4210_RNG_CONTROL_1:
72
a64_test_cc(&c, cond);
257
+ DPRINTF("RNG_CONTROL_1 = 0x%" PRIx64 "\n", val);
73
t_zero = tcg_const_i64(0);
258
+ s->reg_control = val;
74
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
259
+ exynos4210_rng_run_engine(s);
75
tcg_temp_free_i64(t_false);
260
+ break;
76
a64_free_cc(&c);
261
+
77
262
+ case EXYNOS4210_RNG_STATUS:
78
- /* Note that sregs write back zeros to the high bits,
263
+ /* For clearing status fields */
79
+ /* Note that sregs & hregs write back zeros to the high bits,
264
+ s->reg_status &= ~EXYNOS4210_RNG_STATUS_WRITE_MASK;
80
and we've already done the zero-extension. */
265
+ s->reg_status |= val & EXYNOS4210_RNG_STATUS_WRITE_MASK;
81
write_fp_dreg(s, rd, t_true);
266
+ break;
82
tcg_temp_free_i64(t_true);
267
+
268
+ case EXYNOS4210_RNG_SEED_IN_OFFSET(0):
269
+ case EXYNOS4210_RNG_SEED_IN_OFFSET(1):
270
+ case EXYNOS4210_RNG_SEED_IN_OFFSET(2):
271
+ case EXYNOS4210_RNG_SEED_IN_OFFSET(3):
272
+ case EXYNOS4210_RNG_SEED_IN_OFFSET(4):
273
+ exynos4210_rng_set_seed(s,
274
+ (offset - EXYNOS4210_RNG_SEED_IN_OFFSET(0)) / 4,
275
+ val);
276
+ break;
277
+
278
+ default:
279
+ qemu_log_mask(LOG_GUEST_ERROR,
280
+ "%s: bad write offset 0x%" HWADDR_PRIx "\n",
281
+ __func__, offset);
282
+ }
283
+}
284
+
285
+static const MemoryRegionOps exynos4210_rng_ops = {
286
+ .read = exynos4210_rng_read,
287
+ .write = exynos4210_rng_write,
288
+ .endianness = DEVICE_NATIVE_ENDIAN,
289
+};
290
+
291
+static void exynos4210_rng_reset(DeviceState *dev)
292
+{
293
+ Exynos4210RngState *s = EXYNOS4210_RNG(dev);
294
+
295
+ s->reg_control = 0;
296
+ s->reg_status = EXYNOS4210_RNG_STATUS_BUFFER_READY;
297
+ memset(s->randr_value, 0, sizeof(s->randr_value));
298
+ s->seed_set = 0;
299
+}
300
+
301
+static void exynos4210_rng_init(Object *obj)
302
+{
303
+ Exynos4210RngState *s = EXYNOS4210_RNG(obj);
304
+ SysBusDevice *dev = SYS_BUS_DEVICE(obj);
305
+
306
+ memory_region_init_io(&s->iomem, obj, &exynos4210_rng_ops, s,
307
+ TYPE_EXYNOS4210_RNG, EXYNOS4210_RNG_REGS_MEM_SIZE);
308
+ sysbus_init_mmio(dev, &s->iomem);
309
+}
310
+
311
+static const VMStateDescription exynos4210_rng_vmstate = {
312
+ .name = TYPE_EXYNOS4210_RNG,
313
+ .version_id = 1,
314
+ .minimum_version_id = 1,
315
+ .fields = (VMStateField[]) {
316
+ VMSTATE_INT32_ARRAY(randr_value, Exynos4210RngState,
317
+ EXYNOS4210_RNG_PRNG_NUM),
318
+ VMSTATE_UINT32(seed_set, Exynos4210RngState),
319
+ VMSTATE_UINT32(reg_status, Exynos4210RngState),
320
+ VMSTATE_UINT32(reg_control, Exynos4210RngState),
321
+ VMSTATE_END_OF_LIST()
322
+ }
323
+};
324
+
325
+static void exynos4210_rng_class_init(ObjectClass *klass, void *data)
326
+{
327
+ DeviceClass *dc = DEVICE_CLASS(klass);
328
+
329
+ dc->reset = exynos4210_rng_reset;
330
+ dc->vmsd = &exynos4210_rng_vmstate;
331
+}
332
+
333
+static const TypeInfo exynos4210_rng_info = {
334
+ .name = TYPE_EXYNOS4210_RNG,
335
+ .parent = TYPE_SYS_BUS_DEVICE,
336
+ .instance_size = sizeof(Exynos4210RngState),
337
+ .instance_init = exynos4210_rng_init,
338
+ .class_init = exynos4210_rng_class_init,
339
+};
340
+
341
+static void exynos4210_rng_register(void)
342
+{
343
+ type_register_static(&exynos4210_rng_info);
344
+}
345
+
346
+type_init(exynos4210_rng_register)
347
--
83
--
348
2.7.4
84
2.17.0
349
85
350
86
diff view generated by jsdifflib
New patch
1
From: Alex Bennée <alex.bennee@linaro.org>
1
2
3
All the hard work is already done by vfp_expand_imm, we just need to
4
make sure we pick up the correct size.
5
6
Cc: qemu-stable@nongnu.org
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
9
Tested-by: Alex Bennée <alex.bennee@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20180512003217.9105-11-richard.henderson@linaro.org
12
[rth: Merge unallocated_encoding check with TCGMemOp conversion.]
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
target/arm/translate-a64.c | 20 +++++++++++++++++---
17
1 file changed, 17 insertions(+), 3 deletions(-)
18
19
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-a64.c
22
+++ b/target/arm/translate-a64.c
23
@@ -XXX,XX +XXX,XX @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
24
{
25
int rd = extract32(insn, 0, 5);
26
int imm8 = extract32(insn, 13, 8);
27
- int is_double = extract32(insn, 22, 2);
28
+ int type = extract32(insn, 22, 2);
29
uint64_t imm;
30
TCGv_i64 tcg_res;
31
+ TCGMemOp sz;
32
33
- if (is_double > 1) {
34
+ switch (type) {
35
+ case 0:
36
+ sz = MO_32;
37
+ break;
38
+ case 1:
39
+ sz = MO_64;
40
+ break;
41
+ case 3:
42
+ sz = MO_16;
43
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
44
+ break;
45
+ }
46
+ /* fallthru */
47
+ default:
48
unallocated_encoding(s);
49
return;
50
}
51
@@ -XXX,XX +XXX,XX @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
52
return;
53
}
54
55
- imm = vfp_expand_imm(MO_32 + is_double, imm8);
56
+ imm = vfp_expand_imm(sz, imm8);
57
58
tcg_res = tcg_const_i64(imm);
59
write_fp_dreg(s, rd, tcg_res);
60
--
61
2.17.0
62
63
diff view generated by jsdifflib
New patch
1
From: Alex Bennée <alex.bennee@linaro.org>
1
2
3
We are meant to explicitly pass fpst, not cpu_env.
4
5
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20180512003217.9105-12-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/translate-a64.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
19
+++ b/target/arm/translate-a64.c
20
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
21
tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
22
break;
23
case 0x3: /* FSQRT */
24
- gen_helper_sqrt_f16(tcg_res, tcg_op, cpu_env);
25
+ fpst = get_fpstatus_ptr(true);
26
+ gen_helper_sqrt_f16(tcg_res, tcg_op, fpst);
27
break;
28
case 0x8: /* FRINTN */
29
case 0x9: /* FRINTP */
30
--
31
2.17.0
32
33
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
2
3
Per the Physical Layer Simplified Spec. "4.3.10.4 Switch Function Status":
4
5
The block length is predefined to 512 bits
6
7
and "4.10.2 SD Status":
8
9
The SD Status contains status bits that are related to the SD Memory Card
10
proprietary features and may be used for future application-specific usage.
11
The size of the SD Status is one data block of 512 bit. The content of this
12
register is transmitted to the Host over the DAT bus along with a 16-bit CRC.
13
14
Thus the 16-bit CRC goes at offset 64.
15
16
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20180509060104.4458-3-f4bug@amsat.org
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
21
hw/sd/sd.c | 2 +-
22
1 file changed, 1 insertion(+), 1 deletion(-)
23
24
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/sd/sd.c
27
+++ b/hw/sd/sd.c
28
@@ -XXX,XX +XXX,XX @@ static void sd_function_switch(SDState *sd, uint32_t arg)
29
sd->data[14 + (i >> 1)] = new_func << ((i * 4) & 4);
30
}
31
memset(&sd->data[17], 0, 47);
32
- stw_be_p(sd->data + 65, sd_crc16(sd->data, 64));
33
+ stw_be_p(sd->data + 64, sd_crc16(sd->data, 64));
34
}
35
36
static inline bool sd_wp_addr(SDState *sd, uint64_t addr)
37
--
38
2.17.0
39
40
diff view generated by jsdifflib
1
For v7M, writes to the CONTROL register are only permitted for
1
Usually the logging of the CPU state produced by -d cpu is sufficient
2
privileged code. However even if the code is privileged, the
2
to diagnose problems, but sometimes you want to see the state of
3
write must not affect the SPSEL bit in the CONTROL register
3
the floating point registers as well. We don't want to enable that
4
if the CPU is in Thread mode (as documented in the pseudocode
4
by default as it adds a lot of extra data to the log; instead,
5
for the MSR instruction). Implement this, instead of permitting
5
allow it to be optionally enabled via -d fpu.
6
SPSEL to be written in all cases.
7
8
This was causing mbed applications not to run, because the
9
RTX RTOS they use relies on this behaviour.
10
6
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 1498820791-8130-1-git-send-email-peter.maydell@linaro.org
9
Message-id: 20180510130024.31678-1-peter.maydell@linaro.org
14
---
10
---
15
target/arm/helper.c | 13 ++++++++++---
11
include/qemu/log.h | 1 +
16
1 file changed, 10 insertions(+), 3 deletions(-)
12
accel/tcg/cpu-exec.c | 9 ++++++---
13
util/log.c | 2 ++
14
3 files changed, 9 insertions(+), 3 deletions(-)
17
15
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/include/qemu/log.h b/include/qemu/log.h
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
18
--- a/include/qemu/log.h
21
+++ b/target/arm/helper.c
19
+++ b/include/qemu/log.h
22
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
20
@@ -XXX,XX +XXX,XX @@ static inline bool qemu_log_separate(void)
23
}
21
#define CPU_LOG_PAGE (1 << 14)
24
break;
22
/* LOG_TRACE (1 << 15) is defined in log-for-trace.h */
25
case 20: /* CONTROL */
23
#define CPU_LOG_TB_OP_IND (1 << 16)
26
- switch_v7m_sp(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
24
+#define CPU_LOG_TB_FPU (1 << 17)
27
- env->v7m.control = val & (R_V7M_CONTROL_SPSEL_MASK |
25
28
- R_V7M_CONTROL_NPRIV_MASK);
26
/* Lock output for a series of related logs. Since this is not needed
29
+ /* Writing to the SPSEL bit only has an effect if we are in
27
* for a single qemu_log / qemu_log_mask / qemu_log_mask_and_addr, we
30
+ * thread mode; other bits can be updated by any privileged code.
28
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
31
+ * switch_v7m_sp() deals with updating the SPSEL bit in
29
index XXXXXXX..XXXXXXX 100644
32
+ * env->v7m.control, so we only need update the others.
30
--- a/accel/tcg/cpu-exec.c
33
+ */
31
+++ b/accel/tcg/cpu-exec.c
34
+ if (env->v7m.exception == 0) {
32
@@ -XXX,XX +XXX,XX @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
35
+ switch_v7m_sp(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
33
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)
34
&& qemu_log_in_addr_range(itb->pc)) {
35
qemu_log_lock();
36
+ int flags = 0;
37
+ if (qemu_loglevel_mask(CPU_LOG_TB_FPU)) {
38
+ flags |= CPU_DUMP_FPU;
36
+ }
39
+ }
37
+ env->v7m.control &= ~R_V7M_CONTROL_NPRIV_MASK;
40
#if defined(TARGET_I386)
38
+ env->v7m.control |= val & R_V7M_CONTROL_NPRIV_MASK;
41
- log_cpu_state(cpu, CPU_DUMP_CCOP);
39
break;
42
-#else
40
default:
43
- log_cpu_state(cpu, 0);
41
qemu_log_mask(LOG_GUEST_ERROR, "Attempt to write unknown special"
44
+ flags |= CPU_DUMP_CCOP;
45
#endif
46
+ log_cpu_state(cpu, flags);
47
qemu_log_unlock();
48
}
49
#endif /* DEBUG_DISAS */
50
diff --git a/util/log.c b/util/log.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/util/log.c
53
+++ b/util/log.c
54
@@ -XXX,XX +XXX,XX @@ const QEMULogItem qemu_log_items[] = {
55
"show trace before each executed TB (lots of logs)" },
56
{ CPU_LOG_TB_CPU, "cpu",
57
"show CPU registers before entering a TB (lots of logs)" },
58
+ { CPU_LOG_TB_FPU, "fpu",
59
+ "include FPU registers in the 'cpu' logging" },
60
{ CPU_LOG_MMU, "mmu",
61
"log MMU-related activities" },
62
{ CPU_LOG_PCALL, "pcall",
42
--
63
--
43
2.7.4
64
2.17.0
44
65
45
66
diff view generated by jsdifflib