1
Arm patch queue -- these are all bug fix patches but we might
1
target-arm queue for softfreeze:
2
as well put them in to rc0...
2
This has all the big stuff I want to get in for softfreeze;
3
there may be one or two smaller patches I pick up later in
4
the week.
3
5
4
thanks
6
thanks
5
-- PMM
7
-- PMM
6
8
7
The following changes since commit 2c8cfc0b52b5a4d123c26c0b5fdf941be24805be:
9
The following changes since commit 0984a157c1c053394adbf64ed7de97f1aebe6a2d:
8
10
9
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging (2018-03-19 11:44:26 +0000)
11
Merge remote-tracking branch 'remotes/jasowang/tags/net-pull-request' into staging (2019-03-05 09:33:20 +0000)
10
12
11
are available in the Git repository at:
13
are available in the Git repository at:
12
14
13
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180319
15
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190305
14
16
15
for you to fetch changes up to ff72cb6b46b95bb530787add5277c211af3d31c6:
17
for you to fetch changes up to 566528f823d1a2e9eb2d7b2ed839547cb31bfc34:
16
18
17
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs (2018-03-19 18:23:24 +0000)
19
hw/arm/stellaris: Implement watchdog timer (2019-03-05 15:55:09 +0000)
18
20
19
----------------------------------------------------------------
21
----------------------------------------------------------------
20
target-arm queue:
22
target-arm queue:
21
* fsl-imx6: Fix incorrect Ethernet interrupt defines
23
* Fix PC test for LDM (exception return)
22
* dump: Update correct kdump phys_base field for AArch64
24
* Implement ARMv8.0-SB
23
* char: i.MX: Add support for "TX complete" interrupt
25
* Implement ARMv8.0-PredInv
24
* bcm2836/raspi: Fix various bugs resulting in panics trying
26
* Implement ARMv8.4-CondM
25
to boot a Debian Linux kernel on raspi3
27
* Implement ARMv8.5-CondM
28
* Implement ARMv8.5-FRINT
29
* hw/arm/stellaris: Implement watchdog timer
30
* virt: support more than 255GB of RAM
26
31
27
----------------------------------------------------------------
32
----------------------------------------------------------------
28
Andrey Smirnov (2):
33
Eric Auger (9):
29
char: i.MX: Simplify imx_update()
34
hw/arm/virt: Rename highmem IO regions
30
char: i.MX: Add support for "TX complete" interrupt
35
hw/arm/virt: Split the memory map description
36
hw/boards: Add a MachineState parameter to kvm_type callback
37
kvm: add kvm_arm_get_max_vm_ipa_size
38
vl: Set machine ram_size, maxram_size and ram_slots earlier
39
hw/arm/virt: Dynamic memory map depending on RAM requirements
40
hw/arm/virt: Implement kvm_type function for 4.0 machine
41
hw/arm/virt: Check the VCPU PA range in TCG mode
42
hw/arm/virt: Bump the 255GB initial RAM limit
31
43
32
Guenter Roeck (1):
44
Michel Heily (1):
33
fsl-imx6: Swap Ethernet interrupt defines
45
hw/arm/stellaris: Implement watchdog timer
34
46
35
Peter Maydell (9):
47
Richard Henderson (11):
36
hw/arm/raspi: Don't do board-setup or secure-boot for raspi3
48
target/arm: Fix PC test for LDM (exception return)
37
hw/arm/boot: assert that secure_boot and secure_board_setup are false for AArch64
49
target/arm: Split out arm_sctlr
38
hw/arm/boot: If booting a kernel in EL2, set SCR_EL3.HCE
50
target/arm: Implement ARMv8.0-SB
39
hw/arm/bcm2386: Fix parent type of bcm2386
51
target/arm: Implement ARMv8.0-PredInv
40
hw/arm/bcm2836: Rename bcm2836 type/struct to bcm283x
52
target/arm: Split helper_msr_i_pstate into 3
41
hw/arm/bcm2836: Create proper bcm2837 device
53
target/arm: Add set/clear_pstate_bits, share gen_ss_advance
42
hw/arm/bcm2836: Use correct affinity values for BCM2837
54
target/arm: Rearrange disas_data_proc_reg
43
hw/arm/bcm2836: Hardcode correct CPU type
55
target/arm: Implement ARMv8.4-CondM
44
hw/arm/raspi: Provide spin-loop code for AArch64 CPUs
56
target/arm: Implement ARMv8.5-CondM
57
target/arm: Restructure handle_fp_1src_{single, double}
58
target/arm: Implement ARMv8.5-FRINT
45
59
46
Wei Huang (1):
60
Shameer Kolothum (1):
47
dump: Update correct kdump phys_base field for AArch64
61
hw/arm/boot: introduce fdt_add_memory_node helper
48
62
49
include/hw/arm/bcm2836.h | 31 +++++++++++++---
63
include/hw/arm/virt.h | 16 +-
50
include/hw/arm/fsl-imx6.h | 4 +-
64
include/hw/boards.h | 5 +-
51
include/hw/char/imx_serial.h | 3 ++
65
include/hw/watchdog/cmsdk-apb-watchdog.h | 8 +
52
dump.c | 14 +++++--
66
target/arm/cpu.h | 64 ++++-
53
hw/arm/bcm2836.c | 87 +++++++++++++++++++++++++++++++-------------
67
target/arm/helper-a64.h | 3 +
54
hw/arm/boot.c | 12 ++++++
68
target/arm/helper.h | 8 +-
55
hw/arm/raspi.c | 77 +++++++++++++++++++++++++++++++--------
69
target/arm/internals.h | 15 +
56
hw/char/imx_serial.c | 44 ++++++++++++++++------
70
target/arm/kvm_arm.h | 13 +
57
hw/net/imx_fec.c | 28 +++++++++++++-
71
target/arm/translate.h | 34 +++
58
9 files changed, 237 insertions(+), 63 deletions(-)
72
accel/kvm/kvm-all.c | 2 +-
73
hw/arm/boot.c | 54 ++--
74
hw/arm/stellaris.c | 22 +-
75
hw/arm/virt-acpi-build.c | 10 +-
76
hw/arm/virt.c | 196 ++++++++++---
77
hw/ppc/mac_newworld.c | 3 +-
78
hw/ppc/mac_oldworld.c | 2 +-
79
hw/ppc/spapr.c | 2 +-
80
hw/watchdog/cmsdk-apb-watchdog.c | 74 ++++-
81
linux-user/elfload.c | 2 +
82
target/arm/cpu.c | 2 +
83
target/arm/cpu64.c | 6 +
84
target/arm/helper-a64.c | 30 ++
85
target/arm/helper.c | 63 +++-
86
target/arm/kvm.c | 10 +
87
target/arm/op_helper.c | 47 ---
88
target/arm/translate-a64.c | 478 +++++++++++++++++++++++--------
89
target/arm/translate.c | 35 ++-
90
target/arm/vfp_helper.c | 96 +++++++
91
vl.c | 6 +-
92
29 files changed, 1032 insertions(+), 274 deletions(-)
59
93
diff view generated by jsdifflib
1
The TypeInfo and state struct for bcm2386 disagree about what the
1
From: Richard Henderson <richard.henderson@linaro.org>
2
parent class is -- the TypeInfo says it's TYPE_SYS_BUS_DEVICE,
3
but the BCM2386State struct only defines the parent_obj field
4
as DeviceState. This would have caused problems if anything
5
actually tried to treat the object as a TYPE_SYS_BUS_DEVICE.
6
Fix the TypeInfo to use TYPE_DEVICE as the parent, since we don't
7
need any of the additional functionality TYPE_SYS_BUS_DEVICE
8
provides.
9
2
3
Found by inspection: Rn is the base register against which the
4
load began; I is the register within the mask being processed.
5
The exception return should of course be processed from the loaded PC.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Message-id: 20190301202921.21209-1-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
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20180313153458.26822-5-peter.maydell@linaro.org
14
---
11
---
15
hw/arm/bcm2836.c | 2 +-
12
target/arm/translate.c | 2 +-
16
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
17
14
18
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/arm/bcm2836.c
17
--- a/target/arm/translate.c
21
+++ b/hw/arm/bcm2836.c
18
+++ b/target/arm/translate.c
22
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
19
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
23
20
} else if (i == rn) {
24
static const TypeInfo bcm2836_type_info = {
21
loaded_var = tmp;
25
.name = TYPE_BCM2836,
22
loaded_base = 1;
26
- .parent = TYPE_SYS_BUS_DEVICE,
23
- } else if (rn == 15 && exc_return) {
27
+ .parent = TYPE_DEVICE,
24
+ } else if (i == 15 && exc_return) {
28
.instance_size = sizeof(BCM2836State),
25
store_pc_exc_ret(s, tmp);
29
.instance_init = bcm2836_init,
26
} else {
30
.class_init = bcm2836_class_init,
27
store_reg_from_load(s, i, tmp);
31
--
28
--
32
2.16.2
29
2.20.1
33
30
34
31
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Minimize the number of places that will need updating when
4
the virtual host extensions are added.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190301200501.16533-2-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/cpu.h | 26 ++++++++++++++++----------
12
target/arm/helper.c | 8 ++------
13
2 files changed, 18 insertions(+), 16 deletions(-)
14
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ static inline bool arm_sctlr_b(CPUARMState *env)
20
(env->cp15.sctlr_el[1] & SCTLR_B) != 0;
21
}
22
23
+static inline uint64_t arm_sctlr(CPUARMState *env, int el)
24
+{
25
+ if (el == 0) {
26
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
27
+ return env->cp15.sctlr_el[1];
28
+ } else {
29
+ return env->cp15.sctlr_el[el];
30
+ }
31
+}
32
+
33
+
34
/* Return true if the processor is in big-endian mode. */
35
static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
36
{
37
- int cur_el;
38
-
39
/* In 32bit endianness is determined by looking at CPSR's E bit */
40
if (!is_a64(env)) {
41
return
42
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_data_is_big_endian(CPUARMState *env)
43
arm_sctlr_b(env) ||
44
#endif
45
((env->uncached_cpsr & CPSR_E) ? 1 : 0);
46
+ } else {
47
+ int cur_el = arm_current_el(env);
48
+ uint64_t sctlr = arm_sctlr(env, cur_el);
49
+
50
+ return (sctlr & (cur_el ? SCTLR_EE : SCTLR_E0E)) != 0;
51
}
52
-
53
- cur_el = arm_current_el(env);
54
-
55
- if (cur_el == 0) {
56
- return (env->cp15.sctlr_el[1] & SCTLR_E0E) != 0;
57
- }
58
-
59
- return (env->cp15.sctlr_el[cur_el] & SCTLR_EE) != 0;
60
}
61
62
#include "exec/cpu-all.h"
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/helper.c
66
+++ b/target/arm/helper.c
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
68
flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
69
}
70
71
- if (current_el == 0) {
72
- /* FIXME: ARMv8.1-VHE S2 translation regime. */
73
- sctlr = env->cp15.sctlr_el[1];
74
- } else {
75
- sctlr = env->cp15.sctlr_el[current_el];
76
- }
77
+ sctlr = arm_sctlr(env, current_el);
78
+
79
if (cpu_isar_feature(aa64_pauth, cpu)) {
80
/*
81
* In order to save space in flags, we record only whether
82
--
83
2.20.1
84
85
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20190301200501.16533-3-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 | 10 ++++++++++
9
linux-user/elfload.c | 1 +
10
target/arm/cpu.c | 1 +
11
target/arm/cpu64.c | 2 ++
12
target/arm/translate-a64.c | 14 ++++++++++++++
13
target/arm/translate.c | 22 ++++++++++++++++++++++
14
6 files changed, 50 insertions(+)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id)
21
return FIELD_EX32(id->id_isar6, ID_ISAR6, FHM) != 0;
22
}
23
24
+static inline bool isar_feature_aa32_sb(const ARMISARegisters *id)
25
+{
26
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0;
27
+}
28
+
29
static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
30
{
31
/*
32
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
33
FIELD_DP64(0, ID_AA64ISAR1, GPI, 0xf))) != 0;
34
}
35
36
+static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
37
+{
38
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
39
+}
40
+
41
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
42
{
43
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
44
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/linux-user/elfload.c
47
+++ b/linux-user/elfload.c
48
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
49
GET_FEATURE_ID(aa64_pauth, ARM_HWCAP_A64_PACA | ARM_HWCAP_A64_PACG);
50
GET_FEATURE_ID(aa64_fhm, ARM_HWCAP_A64_ASIMDFHM);
51
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
52
+ GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
53
54
#undef GET_FEATURE_ID
55
56
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/cpu.c
59
+++ b/target/arm/cpu.c
60
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
61
t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1);
62
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
63
t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
64
+ t = FIELD_DP32(t, ID_ISAR6, SB, 1);
65
cpu->isar.id_isar6 = t;
66
67
t = cpu->id_mmfr4;
68
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/cpu64.c
71
+++ b/target/arm/cpu64.c
72
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
73
t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
74
t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
75
t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
76
+ t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
77
cpu->isar.id_aa64isar1 = t;
78
79
t = cpu->isar.id_aa64pfr0;
80
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
81
u = FIELD_DP32(u, ID_ISAR6, JSCVT, 1);
82
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
83
u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
84
+ u = FIELD_DP32(u, ID_ISAR6, SB, 1);
85
cpu->isar.id_isar6 = u;
86
87
/*
88
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/arm/translate-a64.c
91
+++ b/target/arm/translate-a64.c
92
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
93
reset_btype(s);
94
gen_goto_tb(s, 0, s->pc);
95
return;
96
+
97
+ case 7: /* SB */
98
+ if (crm != 0 || !dc_isar_feature(aa64_sb, s)) {
99
+ goto do_unallocated;
100
+ }
101
+ /*
102
+ * TODO: There is no speculation barrier opcode for TCG;
103
+ * MB and end the TB instead.
104
+ */
105
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
106
+ gen_goto_tb(s, 0, s->pc);
107
+ return;
108
+
109
default:
110
+ do_unallocated:
111
unallocated_encoding(s);
112
return;
113
}
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
115
index XXXXXXX..XXXXXXX 100644
116
--- a/target/arm/translate.c
117
+++ b/target/arm/translate.c
118
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
119
*/
120
gen_goto_tb(s, 0, s->pc & ~1);
121
return;
122
+ case 7: /* sb */
123
+ if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
124
+ goto illegal_op;
125
+ }
126
+ /*
127
+ * TODO: There is no speculation barrier opcode
128
+ * for TCG; MB and end the TB instead.
129
+ */
130
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
131
+ gen_goto_tb(s, 0, s->pc & ~1);
132
+ return;
133
default:
134
goto illegal_op;
135
}
136
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
137
*/
138
gen_goto_tb(s, 0, s->pc & ~1);
139
break;
140
+ case 7: /* sb */
141
+ if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
142
+ goto illegal_op;
143
+ }
144
+ /*
145
+ * TODO: There is no speculation barrier opcode
146
+ * for TCG; MB and end the TB instead.
147
+ */
148
+ tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
149
+ gen_goto_tb(s, 0, s->pc & ~1);
150
+ break;
151
default:
152
goto illegal_op;
153
}
154
--
155
2.20.1
156
157
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
4
Message-id: 20190301200501.16533-4-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 | 13 ++++++++++-
9
target/arm/cpu.c | 1 +
10
target/arm/cpu64.c | 2 ++
11
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++++++++
12
4 files changed, 70 insertions(+), 1 deletion(-)
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 @@ void pmu_init(ARMCPU *cpu);
19
#define SCTLR_R (1U << 9) /* up to v6; RAZ in v7 */
20
#define SCTLR_UMA (1U << 9) /* v8 onward, AArch64 only */
21
#define SCTLR_F (1U << 10) /* up to v6 */
22
-#define SCTLR_SW (1U << 10) /* v7, RES0 in v8 */
23
+#define SCTLR_SW (1U << 10) /* v7 */
24
+#define SCTLR_EnRCTX (1U << 10) /* in v8.0-PredInv */
25
#define SCTLR_Z (1U << 11) /* in v7, RES1 in v8 */
26
#define SCTLR_EOS (1U << 11) /* v8.5-ExS */
27
#define SCTLR_I (1U << 12)
28
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa32_sb(const ARMISARegisters *id)
29
return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0;
30
}
31
32
+static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
33
+{
34
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
35
+}
36
+
37
static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
38
{
39
/*
40
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
41
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
42
}
43
44
+static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id)
45
+{
46
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SPECRES) != 0;
47
+}
48
+
49
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
50
{
51
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
52
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/arm/cpu.c
55
+++ b/target/arm/cpu.c
56
@@ -XXX,XX +XXX,XX @@ static void arm_max_initfn(Object *obj)
57
t = FIELD_DP32(t, ID_ISAR6, DP, 1);
58
t = FIELD_DP32(t, ID_ISAR6, FHM, 1);
59
t = FIELD_DP32(t, ID_ISAR6, SB, 1);
60
+ t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1);
61
cpu->isar.id_isar6 = t;
62
63
t = cpu->id_mmfr4;
64
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
65
index XXXXXXX..XXXXXXX 100644
66
--- a/target/arm/cpu64.c
67
+++ b/target/arm/cpu64.c
68
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
69
t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
70
t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
71
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
72
+ t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
73
cpu->isar.id_aa64isar1 = t;
74
75
t = cpu->isar.id_aa64pfr0;
76
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
77
u = FIELD_DP32(u, ID_ISAR6, DP, 1);
78
u = FIELD_DP32(u, ID_ISAR6, FHM, 1);
79
u = FIELD_DP32(u, ID_ISAR6, SB, 1);
80
+ u = FIELD_DP32(u, ID_ISAR6, SPECRES, 1);
81
cpu->isar.id_isar6 = u;
82
83
/*
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pauth_reginfo[] = {
89
};
90
#endif
91
92
+static CPAccessResult access_predinv(CPUARMState *env, const ARMCPRegInfo *ri,
93
+ bool isread)
94
+{
95
+ int el = arm_current_el(env);
96
+
97
+ if (el == 0) {
98
+ uint64_t sctlr = arm_sctlr(env, el);
99
+ if (!(sctlr & SCTLR_EnRCTX)) {
100
+ return CP_ACCESS_TRAP;
101
+ }
102
+ } else if (el == 1) {
103
+ uint64_t hcr = arm_hcr_el2_eff(env);
104
+ if (hcr & HCR_NV) {
105
+ return CP_ACCESS_TRAP_EL2;
106
+ }
107
+ }
108
+ return CP_ACCESS_OK;
109
+}
110
+
111
+static const ARMCPRegInfo predinv_reginfo[] = {
112
+ { .name = "CFP_RCTX", .state = ARM_CP_STATE_AA64,
113
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 4,
114
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
115
+ { .name = "DVP_RCTX", .state = ARM_CP_STATE_AA64,
116
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 5,
117
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
118
+ { .name = "CPP_RCTX", .state = ARM_CP_STATE_AA64,
119
+ .opc0 = 1, .opc1 = 3, .crn = 7, .crm = 3, .opc2 = 7,
120
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
121
+ /*
122
+ * Note the AArch32 opcodes have a different OPC1.
123
+ */
124
+ { .name = "CFPRCTX", .state = ARM_CP_STATE_AA32,
125
+ .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 4,
126
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
127
+ { .name = "DVPRCTX", .state = ARM_CP_STATE_AA32,
128
+ .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 5,
129
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
130
+ { .name = "CPPRCTX", .state = ARM_CP_STATE_AA32,
131
+ .cp = 15, .opc1 = 0, .crn = 7, .crm = 3, .opc2 = 7,
132
+ .type = ARM_CP_NOP, .access = PL0_W, .accessfn = access_predinv },
133
+ REGINFO_SENTINEL
134
+};
135
+
136
void register_cp_regs_for_features(ARMCPU *cpu)
137
{
138
/* Register all the coprocessor registers based on feature bits */
139
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
140
define_arm_cp_regs(cpu, pauth_reginfo);
141
}
142
#endif
143
+
144
+ /*
145
+ * While all v8.0 cpus support aarch64, QEMU does have configurations
146
+ * that do not set ID_AA64ISAR1, e.g. user-only qemu-arm -cpu max,
147
+ * which will set ID_ISAR6.
148
+ */
149
+ if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
150
+ ? cpu_isar_feature(aa64_predinv, cpu)
151
+ : cpu_isar_feature(aa32_predinv, cpu)) {
152
+ define_arm_cp_regs(cpu, predinv_reginfo);
153
+ }
154
}
155
156
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
157
--
158
2.20.1
159
160
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
The EL0+UMA check is unique to DAIF. While SPSel had avoided the
4
check by nature of already checking EL >= 1, the other post v8.0
5
extensions to MSR (imm) allow EL0 and do not require UMA. Avoid
6
the unconditional write to pc and use raise_exception_ra to unwind.
7
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190301200501.16533-5-richard.henderson@linaro.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/helper-a64.h | 3 +++
14
target/arm/helper.h | 1 -
15
target/arm/internals.h | 15 ++++++++++++++
16
target/arm/helper-a64.c | 30 +++++++++++++++++++++++++++
17
target/arm/op_helper.c | 42 --------------------------------------
18
target/arm/translate-a64.c | 41 ++++++++++++++++++++++---------------
19
6 files changed, 73 insertions(+), 59 deletions(-)
20
21
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper-a64.h
24
+++ b/target/arm/helper-a64.h
25
@@ -XXX,XX +XXX,XX @@
26
DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
27
DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
28
DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
29
+DEF_HELPER_2(msr_i_spsel, void, env, i32)
30
+DEF_HELPER_2(msr_i_daifset, void, env, i32)
31
+DEF_HELPER_2(msr_i_daifclear, void, env, i32)
32
DEF_HELPER_3(vfp_cmph_a64, i64, f16, f16, ptr)
33
DEF_HELPER_3(vfp_cmpeh_a64, i64, f16, f16, ptr)
34
DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
35
diff --git a/target/arm/helper.h b/target/arm/helper.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.h
38
+++ b/target/arm/helper.h
39
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_cp_reg, i32, env, ptr)
40
DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
41
DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
42
43
-DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
44
DEF_HELPER_1(clear_pstate_ss, void, env)
45
46
DEF_HELPER_2(get_r13_banked, i32, env, i32)
47
diff --git a/target/arm/internals.h b/target/arm/internals.h
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/internals.h
50
+++ b/target/arm/internals.h
51
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
52
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
53
ARMMMUIdx mmu_idx, bool data);
54
55
+static inline int exception_target_el(CPUARMState *env)
56
+{
57
+ int target_el = MAX(1, arm_current_el(env));
58
+
59
+ /*
60
+ * No such thing as secure EL1 if EL3 is aarch32,
61
+ * so update the target EL to EL3 in this case.
62
+ */
63
+ if (arm_is_secure(env) && !arm_el_is_aa64(env, 3) && target_el == 1) {
64
+ target_el = 3;
65
+ }
66
+
67
+ return target_el;
68
+}
69
+
70
#endif
71
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/helper-a64.c
74
+++ b/target/arm/helper-a64.c
75
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(rbit64)(uint64_t x)
76
return revbit64(x);
77
}
78
79
+void HELPER(msr_i_spsel)(CPUARMState *env, uint32_t imm)
80
+{
81
+ update_spsel(env, imm);
82
+}
83
+
84
+static void daif_check(CPUARMState *env, uint32_t op,
85
+ uint32_t imm, uintptr_t ra)
86
+{
87
+ /* DAIF update to PSTATE. This is OK from EL0 only if UMA is set. */
88
+ if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
89
+ raise_exception_ra(env, EXCP_UDEF,
90
+ syn_aa64_sysregtrap(0, extract32(op, 0, 3),
91
+ extract32(op, 3, 3), 4,
92
+ imm, 0x1f, 0),
93
+ exception_target_el(env), ra);
94
+ }
95
+}
96
+
97
+void HELPER(msr_i_daifset)(CPUARMState *env, uint32_t imm)
98
+{
99
+ daif_check(env, 0x1e, imm, GETPC());
100
+ env->daif |= (imm << 6) & PSTATE_DAIF;
101
+}
102
+
103
+void HELPER(msr_i_daifclear)(CPUARMState *env, uint32_t imm)
104
+{
105
+ daif_check(env, 0x1f, imm, GETPC());
106
+ env->daif &= ~((imm << 6) & PSTATE_DAIF);
107
+}
108
+
109
/* Convert a softfloat float_relation_ (as returned by
110
* the float*_compare functions) to the correct ARM
111
* NZCV flag state.
112
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/op_helper.c
115
+++ b/target/arm/op_helper.c
116
@@ -XXX,XX +XXX,XX @@ void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
117
cpu_loop_exit_restore(cs, ra);
118
}
119
120
-static int exception_target_el(CPUARMState *env)
121
-{
122
- int target_el = MAX(1, arm_current_el(env));
123
-
124
- /* No such thing as secure EL1 if EL3 is aarch32, so update the target EL
125
- * to EL3 in this case.
126
- */
127
- if (arm_is_secure(env) && !arm_el_is_aa64(env, 3) && target_el == 1) {
128
- target_el = 3;
129
- }
130
-
131
- return target_el;
132
-}
133
-
134
uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, void *vn,
135
uint32_t maxindex)
136
{
137
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
138
return res;
139
}
140
141
-void HELPER(msr_i_pstate)(CPUARMState *env, uint32_t op, uint32_t imm)
142
-{
143
- /* MSR_i to update PSTATE. This is OK from EL0 only if UMA is set.
144
- * Note that SPSel is never OK from EL0; we rely on handle_msr_i()
145
- * to catch that case at translate time.
146
- */
147
- if (arm_current_el(env) == 0 && !(env->cp15.sctlr_el[1] & SCTLR_UMA)) {
148
- uint32_t syndrome = syn_aa64_sysregtrap(0, extract32(op, 0, 3),
149
- extract32(op, 3, 3), 4,
150
- imm, 0x1f, 0);
151
- raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
152
- }
153
-
154
- switch (op) {
155
- case 0x05: /* SPSel */
156
- update_spsel(env, imm);
157
- break;
158
- case 0x1e: /* DAIFSet */
159
- env->daif |= (imm << 6) & PSTATE_DAIF;
160
- break;
161
- case 0x1f: /* DAIFClear */
162
- env->daif &= ~((imm << 6) & PSTATE_DAIF);
163
- break;
164
- default:
165
- g_assert_not_reached();
166
- }
167
-}
168
-
169
void HELPER(clear_pstate_ss)(CPUARMState *env)
170
{
171
env->pstate &= ~PSTATE_SS;
172
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/target/arm/translate-a64.c
175
+++ b/target/arm/translate-a64.c
176
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
177
static void handle_msr_i(DisasContext *s, uint32_t insn,
178
unsigned int op1, unsigned int op2, unsigned int crm)
179
{
180
+ TCGv_i32 t1;
181
int op = op1 << 3 | op2;
182
+
183
+ /* End the TB by default, chaining is ok. */
184
+ s->base.is_jmp = DISAS_TOO_MANY;
185
+
186
switch (op) {
187
case 0x05: /* SPSel */
188
if (s->current_el == 0) {
189
- unallocated_encoding(s);
190
- return;
191
+ goto do_unallocated;
192
}
193
- /* fall through */
194
- case 0x1e: /* DAIFSet */
195
- case 0x1f: /* DAIFClear */
196
- {
197
- TCGv_i32 tcg_imm = tcg_const_i32(crm);
198
- TCGv_i32 tcg_op = tcg_const_i32(op);
199
- gen_a64_set_pc_im(s->pc - 4);
200
- gen_helper_msr_i_pstate(cpu_env, tcg_op, tcg_imm);
201
- tcg_temp_free_i32(tcg_imm);
202
- tcg_temp_free_i32(tcg_op);
203
- /* For DAIFClear, exit the cpu loop to re-evaluate pending IRQs. */
204
- gen_a64_set_pc_im(s->pc);
205
- s->base.is_jmp = (op == 0x1f ? DISAS_EXIT : DISAS_JUMP);
206
+ t1 = tcg_const_i32(crm & PSTATE_SP);
207
+ gen_helper_msr_i_spsel(cpu_env, t1);
208
+ tcg_temp_free_i32(t1);
209
break;
210
- }
211
+
212
+ case 0x1e: /* DAIFSet */
213
+ t1 = tcg_const_i32(crm);
214
+ gen_helper_msr_i_daifset(cpu_env, t1);
215
+ tcg_temp_free_i32(t1);
216
+ break;
217
+
218
+ case 0x1f: /* DAIFClear */
219
+ t1 = tcg_const_i32(crm);
220
+ gen_helper_msr_i_daifclear(cpu_env, t1);
221
+ tcg_temp_free_i32(t1);
222
+ /* For DAIFClear, exit the cpu loop to re-evaluate pending IRQs. */
223
+ s->base.is_jmp = DISAS_UPDATE;
224
+ break;
225
+
226
default:
227
+ do_unallocated:
228
unallocated_encoding(s);
229
return;
230
}
231
--
232
2.20.1
233
234
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Code of imx_update() is slightly confusing since the "flags" variable
3
We do not need an out-of-line helper for manipulating bits in pstate.
4
doesn't really corespond to anything in real hardware and server as a
4
While changing things, share the implementation of gen_ss_advance.
5
kitchensink accumulating events normally reported via USR1 and USR2
6
registers.
7
5
8
Change the code to explicitly evaluate state of interrupts reported
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
via USR1 and USR2 against corresponding masking bits and use the to
7
Message-id: 20190301200501.16533-6-richard.henderson@linaro.org
10
detemine if IRQ line should be asserted or not.
11
12
NOTE: Check for UTS1_TXEMPTY being set has been dropped for two
13
reasons:
14
15
1. Emulation code implements a single character FIFO, so this flag
16
will always be set since characters are trasmitted as a part of
17
the code emulating "push" into the FIFO
18
19
2. imx_update() is really just a function doing ORing and maksing
20
of reported events, so checking for UTS1_TXEMPTY should happen,
21
if it's ever really needed should probably happen outside of
22
it.
23
24
Cc: qemu-devel@nongnu.org
25
Cc: qemu-arm@nongnu.org
26
Cc: Bill Paul <wpaul@windriver.com>
27
Cc: Peter Maydell <peter.maydell@linaro.org>
28
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
29
Message-id: 20180315191141.6789-1-andrew.smirnov@gmail.com
30
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
---
10
---
33
hw/char/imx_serial.c | 24 ++++++++++++++++--------
11
target/arm/helper.h | 2 --
34
1 file changed, 16 insertions(+), 8 deletions(-)
12
target/arm/translate.h | 34 ++++++++++++++++++++++++++++++++++
13
target/arm/op_helper.c | 5 -----
14
target/arm/translate-a64.c | 11 -----------
15
target/arm/translate.c | 11 -----------
16
5 files changed, 34 insertions(+), 29 deletions(-)
35
17
36
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
18
diff --git a/target/arm/helper.h b/target/arm/helper.h
37
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/char/imx_serial.c
20
--- a/target/arm/helper.h
39
+++ b/hw/char/imx_serial.c
21
+++ b/target/arm/helper.h
40
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
22
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_cp_reg, i32, env, ptr)
41
23
DEF_HELPER_3(set_cp_reg64, void, env, ptr, i64)
42
static void imx_update(IMXSerialState *s)
24
DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
25
26
-DEF_HELPER_1(clear_pstate_ss, void, env)
27
-
28
DEF_HELPER_2(get_r13_banked, i32, env, i32)
29
DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
30
31
diff --git a/target/arm/translate.h b/target/arm/translate.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/translate.h
34
+++ b/target/arm/translate.h
35
@@ -XXX,XX +XXX,XX @@ static inline TCGv_i32 get_ahp_flag(void)
36
return ret;
37
}
38
39
+/* Set bits within PSTATE. */
40
+static inline void set_pstate_bits(uint32_t bits)
41
+{
42
+ TCGv_i32 p = tcg_temp_new_i32();
43
+
44
+ tcg_debug_assert(!(bits & CACHED_PSTATE_BITS));
45
+
46
+ tcg_gen_ld_i32(p, cpu_env, offsetof(CPUARMState, pstate));
47
+ tcg_gen_ori_i32(p, p, bits);
48
+ tcg_gen_st_i32(p, cpu_env, offsetof(CPUARMState, pstate));
49
+ tcg_temp_free_i32(p);
50
+}
51
+
52
+/* Clear bits within PSTATE. */
53
+static inline void clear_pstate_bits(uint32_t bits)
54
+{
55
+ TCGv_i32 p = tcg_temp_new_i32();
56
+
57
+ tcg_debug_assert(!(bits & CACHED_PSTATE_BITS));
58
+
59
+ tcg_gen_ld_i32(p, cpu_env, offsetof(CPUARMState, pstate));
60
+ tcg_gen_andi_i32(p, p, ~bits);
61
+ tcg_gen_st_i32(p, cpu_env, offsetof(CPUARMState, pstate));
62
+ tcg_temp_free_i32(p);
63
+}
64
+
65
+/* If the singlestep state is Active-not-pending, advance to Active-pending. */
66
+static inline void gen_ss_advance(DisasContext *s)
67
+{
68
+ if (s->ss_active) {
69
+ s->pstate_ss = 0;
70
+ clear_pstate_bits(PSTATE_SS);
71
+ }
72
+}
73
74
/* Vector operations shared between ARM and AArch64. */
75
extern const GVecGen3 bsl_op;
76
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/arm/op_helper.c
79
+++ b/target/arm/op_helper.c
80
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
81
return res;
82
}
83
84
-void HELPER(clear_pstate_ss)(CPUARMState *env)
85
-{
86
- env->pstate &= ~PSTATE_SS;
87
-}
88
-
89
void HELPER(pre_hvc)(CPUARMState *env)
43
{
90
{
44
- uint32_t flags;
91
ARMCPU *cpu = arm_env_get_cpu(env);
45
+ uint32_t usr1;
92
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
46
+ uint32_t usr2;
93
index XXXXXXX..XXXXXXX 100644
47
+ uint32_t mask;
94
--- a/target/arm/translate-a64.c
48
95
+++ b/target/arm/translate-a64.c
49
- flags = (s->usr1 & s->ucr1) & (USR1_TRDY|USR1_RRDY);
96
@@ -XXX,XX +XXX,XX @@ static void gen_exception_bkpt_insn(DisasContext *s, int offset,
50
- if (s->ucr1 & UCR1_TXMPTYEN) {
97
s->base.is_jmp = DISAS_NORETURN;
51
- flags |= (s->uts1 & UTS1_TXEMPTY);
98
}
52
- } else {
99
53
- flags &= ~USR1_TRDY;
100
-static void gen_ss_advance(DisasContext *s)
101
-{
102
- /* If the singlestep state is Active-not-pending, advance to
103
- * Active-pending.
104
- */
105
- if (s->ss_active) {
106
- s->pstate_ss = 0;
107
- gen_helper_clear_pstate_ss(cpu_env);
54
- }
108
- }
55
+ /*
109
-}
56
+ * Lucky for us TRDY and RRDY has the same offset in both USR1 and
110
-
57
+ * UCR1, so we can get away with something as simple as the
111
static void gen_step_complete_exception(DisasContext *s)
58
+ * following:
112
{
59
+ */
113
/* We just completed step of an insn. Move from Active-not-pending
60
+ usr1 = s->usr1 & s->ucr1 & (USR1_TRDY | USR1_RRDY);
114
diff --git a/target/arm/translate.c b/target/arm/translate.c
61
+ /*
115
index XXXXXXX..XXXXXXX 100644
62
+ * Bits that we want in USR2 are not as conveniently laid out,
116
--- a/target/arm/translate.c
63
+ * unfortunately.
117
+++ b/target/arm/translate.c
64
+ */
118
@@ -XXX,XX +XXX,XX @@ static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
65
+ mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
119
tcg_temp_free_i32(tcg_excp);
66
+ usr2 = s->usr2 & mask;
67
68
- qemu_set_irq(s->irq, !!flags);
69
+ qemu_set_irq(s->irq, usr1 || usr2);
70
}
120
}
71
121
72
static void imx_serial_reset(IMXSerialState *s)
122
-static void gen_ss_advance(DisasContext *s)
123
-{
124
- /* If the singlestep state is Active-not-pending, advance to
125
- * Active-pending.
126
- */
127
- if (s->ss_active) {
128
- s->pstate_ss = 0;
129
- gen_helper_clear_pstate_ss(cpu_env);
130
- }
131
-}
132
-
133
static void gen_step_complete_exception(DisasContext *s)
134
{
135
/* We just completed step of an insn. Move from Active-not-pending
73
--
136
--
74
2.16.2
137
2.20.1
75
138
76
139
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for "TX complete"/TXDC interrupt generate by real HW since
3
This decoding more closely matches the ARMv8.4 Table C4-6,
4
it is needed to support guests other than Linux.
4
Encoding table for Data Processing - Register Group.
5
5
6
Based on the patch by Bill Paul as found here:
6
In particular, op2 == 0 is now more than just Add/sub (with carry).
7
https://bugs.launchpad.net/qemu/+bug/1753314
8
7
9
Cc: qemu-devel@nongnu.org
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Cc: qemu-arm@nongnu.org
9
Message-id: 20190301200501.16533-7-richard.henderson@linaro.org
11
Cc: Bill Paul <wpaul@windriver.com>
12
Cc: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Bill Paul <wpaul@windriver.com>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Message-id: 20180315191141.6789-2-andrew.smirnov@gmail.com
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
12
---
19
include/hw/char/imx_serial.h | 3 +++
13
target/arm/translate-a64.c | 98 ++++++++++++++++++++++----------------
20
hw/char/imx_serial.c | 20 +++++++++++++++++---
14
1 file changed, 57 insertions(+), 41 deletions(-)
21
2 files changed, 20 insertions(+), 3 deletions(-)
22
15
23
diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
24
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/char/imx_serial.h
18
--- a/target/arm/translate-a64.c
26
+++ b/include/hw/char/imx_serial.h
19
+++ b/target/arm/translate-a64.c
27
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_3src(DisasContext *s, uint32_t insn)
28
#define UCR2_RXEN (1<<1) /* Receiver enable */
21
}
29
#define UCR2_SRST (1<<0) /* Reset complete */
22
30
23
/* Add/subtract (with carry)
31
+#define UCR4_TCEN BIT(3) /* TX complete interrupt enable */
24
- * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 10 9 5 4 0
25
- * +--+--+--+------------------------+------+---------+------+-----+
26
- * |sf|op| S| 1 1 0 1 0 0 0 0 | rm | opcode2 | Rn | Rd |
27
- * +--+--+--+------------------------+------+---------+------+-----+
28
- * [000000]
29
+ * 31 30 29 28 27 26 25 24 23 22 21 20 16 15 10 9 5 4 0
30
+ * +--+--+--+------------------------+------+-------------+------+-----+
31
+ * |sf|op| S| 1 1 0 1 0 0 0 0 | rm | 0 0 0 0 0 0 | Rn | Rd |
32
+ * +--+--+--+------------------------+------+-------------+------+-----+
33
*/
34
35
static void disas_adc_sbc(DisasContext *s, uint32_t insn)
36
@@ -XXX,XX +XXX,XX @@ static void disas_adc_sbc(DisasContext *s, uint32_t insn)
37
unsigned int sf, op, setflags, rm, rn, rd;
38
TCGv_i64 tcg_y, tcg_rn, tcg_rd;
39
40
- if (extract32(insn, 10, 6) != 0) {
41
- unallocated_encoding(s);
42
- return;
43
- }
44
-
45
sf = extract32(insn, 31, 1);
46
op = extract32(insn, 30, 1);
47
setflags = extract32(insn, 29, 1);
48
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
49
}
50
}
51
52
-/* Data processing - register */
53
+/*
54
+ * Data processing - register
55
+ * 31 30 29 28 25 21 20 16 10 0
56
+ * +--+---+--+---+-------+-----+-------+-------+---------+
57
+ * | |op0| |op1| 1 0 1 | op2 | | op3 | |
58
+ * +--+---+--+---+-------+-----+-------+-------+---------+
59
+ */
60
static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
61
{
62
- switch (extract32(insn, 24, 5)) {
63
- case 0x0a: /* Logical (shifted register) */
64
- disas_logic_reg(s, insn);
65
- break;
66
- case 0x0b: /* Add/subtract */
67
- if (insn & (1 << 21)) { /* (extended register) */
68
- disas_add_sub_ext_reg(s, insn);
69
+ int op0 = extract32(insn, 30, 1);
70
+ int op1 = extract32(insn, 28, 1);
71
+ int op2 = extract32(insn, 21, 4);
72
+ int op3 = extract32(insn, 10, 6);
32
+
73
+
33
#define UTS1_TXEMPTY (1<<6)
74
+ if (!op1) {
34
#define UTS1_RXEMPTY (1<<5)
75
+ if (op2 & 8) {
35
#define UTS1_TXFULL (1<<4)
76
+ if (op2 & 1) {
36
@@ -XXX,XX +XXX,XX @@ typedef struct IMXSerialState {
77
+ /* Add/sub (extended register) */
37
uint32_t ubmr;
78
+ disas_add_sub_ext_reg(s, insn);
38
uint32_t ubrc;
79
+ } else {
39
uint32_t ucr3;
80
+ /* Add/sub (shifted register) */
40
+ uint32_t ucr4;
81
+ disas_add_sub_reg(s, insn);
41
82
+ }
42
qemu_irq irq;
83
} else {
43
CharBackend chr;
84
- disas_add_sub_reg(s, insn);
44
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
85
+ /* Logical (shifted register) */
45
index XXXXXXX..XXXXXXX 100644
86
+ disas_logic_reg(s, insn);
46
--- a/hw/char/imx_serial.c
87
}
47
+++ b/hw/char/imx_serial.c
88
- break;
48
@@ -XXX,XX +XXX,XX @@
89
- case 0x1b: /* Data-processing (3 source) */
49
90
- disas_data_proc_3src(s, insn);
50
static const VMStateDescription vmstate_imx_serial = {
91
- break;
51
.name = TYPE_IMX_SERIAL,
92
- case 0x1a:
52
- .version_id = 1,
93
- switch (extract32(insn, 21, 3)) {
53
- .minimum_version_id = 1,
94
- case 0x0: /* Add/subtract (with carry) */
54
+ .version_id = 2,
95
+ return;
55
+ .minimum_version_id = 2,
96
+ }
56
.fields = (VMStateField[]) {
57
VMSTATE_INT32(readbuff, IMXSerialState),
58
VMSTATE_UINT32(usr1, IMXSerialState),
59
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_serial = {
60
VMSTATE_UINT32(ubmr, IMXSerialState),
61
VMSTATE_UINT32(ubrc, IMXSerialState),
62
VMSTATE_UINT32(ucr3, IMXSerialState),
63
+ VMSTATE_UINT32(ucr4, IMXSerialState),
64
VMSTATE_END_OF_LIST()
65
},
66
};
67
@@ -XXX,XX +XXX,XX @@ static void imx_update(IMXSerialState *s)
68
* unfortunately.
69
*/
70
mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
71
+ /*
72
+ * TCEN and TXDC are both bit 3
73
+ */
74
+ mask |= s->ucr4 & UCR4_TCEN;
75
+
97
+
76
usr2 = s->usr2 & mask;
98
+ switch (op2) {
77
99
+ case 0x0:
78
qemu_set_irq(s->irq, usr1 || usr2);
100
+ switch (op3) {
79
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_serial_read(void *opaque, hwaddr offset,
101
+ case 0x00: /* Add/subtract (with carry) */
80
return s->ucr3;
102
disas_adc_sbc(s, insn);
81
103
break;
82
case 0x23: /* UCR4 */
104
- case 0x2: /* Conditional compare */
83
+ return s->ucr4;
105
- disas_cc(s, insn); /* both imm and reg forms */
106
- break;
107
- case 0x4: /* Conditional select */
108
- disas_cond_select(s, insn);
109
- break;
110
- case 0x6: /* Data-processing */
111
- if (insn & (1 << 30)) { /* (1 source) */
112
- disas_data_proc_1src(s, insn);
113
- } else { /* (2 source) */
114
- disas_data_proc_2src(s, insn);
115
- }
116
- break;
84
+
117
+
85
case 0x29: /* BRM Incremental */
118
default:
86
return 0x0; /* TODO */
119
- unallocated_encoding(s);
87
120
- break;
88
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
121
+ goto do_unallocated;
89
* qemu_chr_fe_write and background I/O callbacks */
90
qemu_chr_fe_write_all(&s->chr, &ch, 1);
91
s->usr1 &= ~USR1_TRDY;
92
+ s->usr2 &= ~USR2_TXDC;
93
imx_update(s);
94
s->usr1 |= USR1_TRDY;
95
+ s->usr2 |= USR2_TXDC;
96
imx_update(s);
97
}
122
}
98
break;
123
break;
99
@@ -XXX,XX +XXX,XX @@ static void imx_serial_write(void *opaque, hwaddr offset,
124
+
100
s->ucr3 = value & 0xffff;
125
+ case 0x2: /* Conditional compare */
101
break;
126
+ disas_cc(s, insn); /* both imm and reg forms */
102
103
- case 0x2d: /* UTS1 */
104
case 0x23: /* UCR4 */
105
+ s->ucr4 = value & 0xffff;
106
+ imx_update(s);
107
+ break;
127
+ break;
108
+
128
+
109
+ case 0x2d: /* UTS1 */
129
+ case 0x4: /* Conditional select */
110
qemu_log_mask(LOG_UNIMP, "[%s]%s: Unimplemented reg 0x%"
130
+ disas_cond_select(s, insn);
111
HWADDR_PRIx "\n", TYPE_IMX_SERIAL, __func__, offset);
131
+ break;
112
/* TODO */
132
+
133
+ case 0x6: /* Data-processing */
134
+ if (op0) { /* (1 source) */
135
+ disas_data_proc_1src(s, insn);
136
+ } else { /* (2 source) */
137
+ disas_data_proc_2src(s, insn);
138
+ }
139
+ break;
140
+ case 0x8 ... 0xf: /* (3 source) */
141
+ disas_data_proc_3src(s, insn);
142
+ break;
143
+
144
default:
145
+ do_unallocated:
146
unallocated_encoding(s);
147
break;
148
}
113
--
149
--
114
2.16.2
150
2.20.1
115
151
116
152
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190301200501.16533-8-richard.henderson@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
[PMM: fixed up block comment style]
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/cpu.h | 5 ++
11
linux-user/elfload.c | 1 +
12
target/arm/cpu64.c | 1 +
13
target/arm/translate-a64.c | 99 +++++++++++++++++++++++++++++++++++++-
14
4 files changed, 105 insertions(+), 1 deletion(-)
15
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.h
19
+++ b/target/arm/cpu.h
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id)
21
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, FHM) != 0;
22
}
23
24
+static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id)
25
+{
26
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) != 0;
27
+}
28
+
29
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
30
{
31
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
32
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/linux-user/elfload.c
35
+++ b/linux-user/elfload.c
36
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
37
GET_FEATURE_ID(aa64_fhm, ARM_HWCAP_A64_ASIMDFHM);
38
GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
39
GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
40
+ GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
41
42
#undef GET_FEATURE_ID
43
44
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/target/arm/cpu64.c
47
+++ b/target/arm/cpu64.c
48
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
49
t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
50
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
51
t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
52
+ t = FIELD_DP64(t, ID_AA64ISAR0, TS, 1);
53
cpu->isar.id_aa64isar0 = t;
54
55
t = cpu->isar.id_aa64isar1;
56
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/target/arm/translate-a64.c
59
+++ b/target/arm/translate-a64.c
60
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
61
s->base.is_jmp = DISAS_TOO_MANY;
62
63
switch (op) {
64
+ case 0x00: /* CFINV */
65
+ if (crm != 0 || !dc_isar_feature(aa64_condm_4, s)) {
66
+ goto do_unallocated;
67
+ }
68
+ tcg_gen_xori_i32(cpu_CF, cpu_CF, 1);
69
+ s->base.is_jmp = DISAS_NEXT;
70
+ break;
71
+
72
case 0x05: /* SPSel */
73
if (s->current_el == 0) {
74
goto do_unallocated;
75
@@ -XXX,XX +XXX,XX @@ static void gen_get_nzcv(TCGv_i64 tcg_rt)
76
}
77
78
static void gen_set_nzcv(TCGv_i64 tcg_rt)
79
-
80
{
81
TCGv_i32 nzcv = tcg_temp_new_i32();
82
83
@@ -XXX,XX +XXX,XX @@ static void disas_adc_sbc(DisasContext *s, uint32_t insn)
84
}
85
}
86
87
+/*
88
+ * Rotate right into flags
89
+ * 31 30 29 21 15 10 5 4 0
90
+ * +--+--+--+-----------------+--------+-----------+------+--+------+
91
+ * |sf|op| S| 1 1 0 1 0 0 0 0 | imm6 | 0 0 0 0 1 | Rn |o2| mask |
92
+ * +--+--+--+-----------------+--------+-----------+------+--+------+
93
+ */
94
+static void disas_rotate_right_into_flags(DisasContext *s, uint32_t insn)
95
+{
96
+ int mask = extract32(insn, 0, 4);
97
+ int o2 = extract32(insn, 4, 1);
98
+ int rn = extract32(insn, 5, 5);
99
+ int imm6 = extract32(insn, 15, 6);
100
+ int sf_op_s = extract32(insn, 29, 3);
101
+ TCGv_i64 tcg_rn;
102
+ TCGv_i32 nzcv;
103
+
104
+ if (sf_op_s != 5 || o2 != 0 || !dc_isar_feature(aa64_condm_4, s)) {
105
+ unallocated_encoding(s);
106
+ return;
107
+ }
108
+
109
+ tcg_rn = read_cpu_reg(s, rn, 1);
110
+ tcg_gen_rotri_i64(tcg_rn, tcg_rn, imm6);
111
+
112
+ nzcv = tcg_temp_new_i32();
113
+ tcg_gen_extrl_i64_i32(nzcv, tcg_rn);
114
+
115
+ if (mask & 8) { /* N */
116
+ tcg_gen_shli_i32(cpu_NF, nzcv, 31 - 3);
117
+ }
118
+ if (mask & 4) { /* Z */
119
+ tcg_gen_not_i32(cpu_ZF, nzcv);
120
+ tcg_gen_andi_i32(cpu_ZF, cpu_ZF, 4);
121
+ }
122
+ if (mask & 2) { /* C */
123
+ tcg_gen_extract_i32(cpu_CF, nzcv, 1, 1);
124
+ }
125
+ if (mask & 1) { /* V */
126
+ tcg_gen_shli_i32(cpu_VF, nzcv, 31 - 0);
127
+ }
128
+
129
+ tcg_temp_free_i32(nzcv);
130
+}
131
+
132
+/*
133
+ * Evaluate into flags
134
+ * 31 30 29 21 15 14 10 5 4 0
135
+ * +--+--+--+-----------------+---------+----+---------+------+--+------+
136
+ * |sf|op| S| 1 1 0 1 0 0 0 0 | opcode2 | sz | 0 0 1 0 | Rn |o3| mask |
137
+ * +--+--+--+-----------------+---------+----+---------+------+--+------+
138
+ */
139
+static void disas_evaluate_into_flags(DisasContext *s, uint32_t insn)
140
+{
141
+ int o3_mask = extract32(insn, 0, 5);
142
+ int rn = extract32(insn, 5, 5);
143
+ int o2 = extract32(insn, 15, 6);
144
+ int sz = extract32(insn, 14, 1);
145
+ int sf_op_s = extract32(insn, 29, 3);
146
+ TCGv_i32 tmp;
147
+ int shift;
148
+
149
+ if (sf_op_s != 1 || o2 != 0 || o3_mask != 0xd ||
150
+ !dc_isar_feature(aa64_condm_4, s)) {
151
+ unallocated_encoding(s);
152
+ return;
153
+ }
154
+ shift = sz ? 16 : 24; /* SETF16 or SETF8 */
155
+
156
+ tmp = tcg_temp_new_i32();
157
+ tcg_gen_extrl_i64_i32(tmp, cpu_reg(s, rn));
158
+ tcg_gen_shli_i32(cpu_NF, tmp, shift);
159
+ tcg_gen_shli_i32(cpu_VF, tmp, shift - 1);
160
+ tcg_gen_mov_i32(cpu_ZF, cpu_NF);
161
+ tcg_gen_xor_i32(cpu_VF, cpu_VF, cpu_NF);
162
+ tcg_temp_free_i32(tmp);
163
+}
164
+
165
/* Conditional compare (immediate / register)
166
* 31 30 29 28 27 26 25 24 23 22 21 20 16 15 12 11 10 9 5 4 3 0
167
* +--+--+--+------------------------+--------+------+----+--+------+--+-----+
168
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
169
disas_adc_sbc(s, insn);
170
break;
171
172
+ case 0x01: /* Rotate right into flags */
173
+ case 0x21:
174
+ disas_rotate_right_into_flags(s, insn);
175
+ break;
176
+
177
+ case 0x02: /* Evaluate into flags */
178
+ case 0x12:
179
+ case 0x22:
180
+ case 0x32:
181
+ disas_evaluate_into_flags(s, insn);
182
+ break;
183
+
184
default:
185
goto do_unallocated;
186
}
187
--
188
2.20.1
189
190
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190301200501.16533-9-richard.henderson@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
target/arm/cpu.h | 5 ++++
10
target/arm/cpu64.c | 2 +-
11
target/arm/translate-a64.c | 58 ++++++++++++++++++++++++++++++++++++++
12
3 files changed, 64 insertions(+), 1 deletion(-)
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 @@ static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id)
19
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) != 0;
20
}
21
22
+static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id)
23
+{
24
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2;
25
+}
26
+
27
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
28
{
29
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
30
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu64.c
33
+++ b/target/arm/cpu64.c
34
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
35
t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
36
t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
37
t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
38
- t = FIELD_DP64(t, ID_AA64ISAR0, TS, 1);
39
+ t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2); /* v8.5-CondM */
40
cpu->isar.id_aa64isar0 = t;
41
42
t = cpu->isar.id_aa64isar1;
43
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/translate-a64.c
46
+++ b/target/arm/translate-a64.c
47
@@ -XXX,XX +XXX,XX @@ static void handle_sync(DisasContext *s, uint32_t insn,
48
}
49
}
50
51
+static void gen_xaflag(void)
52
+{
53
+ TCGv_i32 z = tcg_temp_new_i32();
54
+
55
+ tcg_gen_setcondi_i32(TCG_COND_EQ, z, cpu_ZF, 0);
56
+
57
+ /*
58
+ * (!C & !Z) << 31
59
+ * (!(C | Z)) << 31
60
+ * ~((C | Z) << 31)
61
+ * ~-(C | Z)
62
+ * (C | Z) - 1
63
+ */
64
+ tcg_gen_or_i32(cpu_NF, cpu_CF, z);
65
+ tcg_gen_subi_i32(cpu_NF, cpu_NF, 1);
66
+
67
+ /* !(Z & C) */
68
+ tcg_gen_and_i32(cpu_ZF, z, cpu_CF);
69
+ tcg_gen_xori_i32(cpu_ZF, cpu_ZF, 1);
70
+
71
+ /* (!C & Z) << 31 -> -(Z & ~C) */
72
+ tcg_gen_andc_i32(cpu_VF, z, cpu_CF);
73
+ tcg_gen_neg_i32(cpu_VF, cpu_VF);
74
+
75
+ /* C | Z */
76
+ tcg_gen_or_i32(cpu_CF, cpu_CF, z);
77
+
78
+ tcg_temp_free_i32(z);
79
+}
80
+
81
+static void gen_axflag(void)
82
+{
83
+ tcg_gen_sari_i32(cpu_VF, cpu_VF, 31); /* V ? -1 : 0 */
84
+ tcg_gen_andc_i32(cpu_CF, cpu_CF, cpu_VF); /* C & !V */
85
+
86
+ /* !(Z | V) -> !(!ZF | V) -> ZF & !V -> ZF & ~VF */
87
+ tcg_gen_andc_i32(cpu_ZF, cpu_ZF, cpu_VF);
88
+
89
+ tcg_gen_movi_i32(cpu_NF, 0);
90
+ tcg_gen_movi_i32(cpu_VF, 0);
91
+}
92
+
93
/* MSR (immediate) - move immediate to processor state field */
94
static void handle_msr_i(DisasContext *s, uint32_t insn,
95
unsigned int op1, unsigned int op2, unsigned int crm)
96
@@ -XXX,XX +XXX,XX @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
97
s->base.is_jmp = DISAS_NEXT;
98
break;
99
100
+ case 0x01: /* XAFlag */
101
+ if (crm != 0 || !dc_isar_feature(aa64_condm_5, s)) {
102
+ goto do_unallocated;
103
+ }
104
+ gen_xaflag();
105
+ s->base.is_jmp = DISAS_NEXT;
106
+ break;
107
+
108
+ case 0x02: /* AXFlag */
109
+ if (crm != 0 || !dc_isar_feature(aa64_condm_5, s)) {
110
+ goto do_unallocated;
111
+ }
112
+ gen_axflag();
113
+ s->base.is_jmp = DISAS_NEXT;
114
+ break;
115
+
116
case 0x05: /* SPSel */
117
if (s->current_el == 0) {
118
goto do_unallocated;
119
--
120
2.20.1
121
122
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
This will allow sharing code that adjusts rmode beyond
4
the existing users.
5
6
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190301200501.16533-10-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 | 90 +++++++++++++++++++++-----------------
13
1 file changed, 49 insertions(+), 41 deletions(-)
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_1src_half(DisasContext *s, int opcode, int rd, int rn)
20
/* Floating-point data-processing (1 source) - single precision */
21
static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
22
{
23
+ void (*gen_fpst)(TCGv_i32, TCGv_i32, TCGv_ptr);
24
+ TCGv_i32 tcg_op, tcg_res;
25
TCGv_ptr fpst;
26
- TCGv_i32 tcg_op;
27
- TCGv_i32 tcg_res;
28
+ int rmode = -1;
29
30
- fpst = get_fpstatus_ptr(false);
31
tcg_op = read_fp_sreg(s, rn);
32
tcg_res = tcg_temp_new_i32();
33
34
switch (opcode) {
35
case 0x0: /* FMOV */
36
tcg_gen_mov_i32(tcg_res, tcg_op);
37
- break;
38
+ goto done;
39
case 0x1: /* FABS */
40
gen_helper_vfp_abss(tcg_res, tcg_op);
41
- break;
42
+ goto done;
43
case 0x2: /* FNEG */
44
gen_helper_vfp_negs(tcg_res, tcg_op);
45
- break;
46
+ goto done;
47
case 0x3: /* FSQRT */
48
gen_helper_vfp_sqrts(tcg_res, tcg_op, cpu_env);
49
- break;
50
+ goto done;
51
case 0x8: /* FRINTN */
52
case 0x9: /* FRINTP */
53
case 0xa: /* FRINTM */
54
case 0xb: /* FRINTZ */
55
case 0xc: /* FRINTA */
56
- {
57
- TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
58
-
59
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
60
- gen_helper_rints(tcg_res, tcg_op, fpst);
61
-
62
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
63
- tcg_temp_free_i32(tcg_rmode);
64
+ rmode = arm_rmode_to_sf(opcode & 7);
65
+ gen_fpst = gen_helper_rints;
66
break;
67
- }
68
case 0xe: /* FRINTX */
69
- gen_helper_rints_exact(tcg_res, tcg_op, fpst);
70
+ gen_fpst = gen_helper_rints_exact;
71
break;
72
case 0xf: /* FRINTI */
73
- gen_helper_rints(tcg_res, tcg_op, fpst);
74
+ gen_fpst = gen_helper_rints;
75
break;
76
default:
77
- abort();
78
+ g_assert_not_reached();
79
}
80
81
- write_fp_sreg(s, rd, tcg_res);
82
-
83
+ fpst = get_fpstatus_ptr(false);
84
+ if (rmode >= 0) {
85
+ TCGv_i32 tcg_rmode = tcg_const_i32(rmode);
86
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
87
+ gen_fpst(tcg_res, tcg_op, fpst);
88
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
89
+ tcg_temp_free_i32(tcg_rmode);
90
+ } else {
91
+ gen_fpst(tcg_res, tcg_op, fpst);
92
+ }
93
tcg_temp_free_ptr(fpst);
94
+
95
+ done:
96
+ write_fp_sreg(s, rd, tcg_res);
97
tcg_temp_free_i32(tcg_op);
98
tcg_temp_free_i32(tcg_res);
99
}
100
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
101
/* Floating-point data-processing (1 source) - double precision */
102
static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
103
{
104
+ void (*gen_fpst)(TCGv_i64, TCGv_i64, TCGv_ptr);
105
+ TCGv_i64 tcg_op, tcg_res;
106
TCGv_ptr fpst;
107
- TCGv_i64 tcg_op;
108
- TCGv_i64 tcg_res;
109
+ int rmode = -1;
110
111
switch (opcode) {
112
case 0x0: /* FMOV */
113
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
114
return;
115
}
116
117
- fpst = get_fpstatus_ptr(false);
118
tcg_op = read_fp_dreg(s, rn);
119
tcg_res = tcg_temp_new_i64();
120
121
switch (opcode) {
122
case 0x1: /* FABS */
123
gen_helper_vfp_absd(tcg_res, tcg_op);
124
- break;
125
+ goto done;
126
case 0x2: /* FNEG */
127
gen_helper_vfp_negd(tcg_res, tcg_op);
128
- break;
129
+ goto done;
130
case 0x3: /* FSQRT */
131
gen_helper_vfp_sqrtd(tcg_res, tcg_op, cpu_env);
132
- break;
133
+ goto done;
134
case 0x8: /* FRINTN */
135
case 0x9: /* FRINTP */
136
case 0xa: /* FRINTM */
137
case 0xb: /* FRINTZ */
138
case 0xc: /* FRINTA */
139
- {
140
- TCGv_i32 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(opcode & 7));
141
-
142
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
143
- gen_helper_rintd(tcg_res, tcg_op, fpst);
144
-
145
- gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
146
- tcg_temp_free_i32(tcg_rmode);
147
+ rmode = arm_rmode_to_sf(opcode & 7);
148
+ gen_fpst = gen_helper_rintd;
149
break;
150
- }
151
case 0xe: /* FRINTX */
152
- gen_helper_rintd_exact(tcg_res, tcg_op, fpst);
153
+ gen_fpst = gen_helper_rintd_exact;
154
break;
155
case 0xf: /* FRINTI */
156
- gen_helper_rintd(tcg_res, tcg_op, fpst);
157
+ gen_fpst = gen_helper_rintd;
158
break;
159
default:
160
- abort();
161
+ g_assert_not_reached();
162
}
163
164
- write_fp_dreg(s, rd, tcg_res);
165
-
166
+ fpst = get_fpstatus_ptr(false);
167
+ if (rmode >= 0) {
168
+ TCGv_i32 tcg_rmode = tcg_const_i32(rmode);
169
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
170
+ gen_fpst(tcg_res, tcg_op, fpst);
171
+ gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
172
+ tcg_temp_free_i32(tcg_rmode);
173
+ } else {
174
+ gen_fpst(tcg_res, tcg_op, fpst);
175
+ }
176
tcg_temp_free_ptr(fpst);
177
+
178
+ done:
179
+ write_fp_dreg(s, rd, tcg_res);
180
tcg_temp_free_i64(tcg_op);
181
tcg_temp_free_i64(tcg_res);
182
}
183
--
184
2.20.1
185
186
diff view generated by jsdifflib
1
From: Guenter Roeck <linux@roeck-us.net>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The sabrelite machine model used by qemu-system-arm is based on the
3
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
4
Freescale/NXP i.MX6Q processor. This SoC has an on-board ethernet
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
controller which is supported in QEMU using the imx_fec.c module
5
Message-id: 20190301200501.16533-11-richard.henderson@linaro.org
6
(actually called imx.enet for this model.)
7
8
The include/hw/arm/fsm-imx6.h file defines the interrupt vectors for the
9
imx.enet device like this:
10
11
#define FSL_IMX6_ENET_MAC_1588_IRQ 118
12
#define FSL_IMX6_ENET_MAC_IRQ 119
13
14
According to https://www.nxp.com/docs/en/reference-manual/IMX6DQRM.pdf,
15
page 225, in Table 3-1. ARM Cortex A9 domain interrupt summary,
16
interrupts are as follows.
17
18
150 ENET MAC 0 IRQ
19
151 ENET MAC 0 1588 Timer interrupt
20
21
where
22
23
150 - 32 == 118
24
151 - 32 == 119
25
26
In other words, the vector definitions in the fsl-imx6.h file are reversed.
27
28
Fixing the interrupts alone causes problems with older Linux kernels:
29
The Ethernet interface will fail to probe with Linux v4.9 and earlier.
30
Linux v4.1 and earlier will crash due to a bug in Ethernet driver probe
31
error handling. This is a Linux kernel problem, not a qemu problem:
32
the Linux kernel only worked by accident since it requested both interrupts.
33
34
For backward compatibility, generate the Ethernet interrupt on both interrupt
35
lines. This was shown to work from all Linux kernel releases starting with
36
v3.16.
37
38
Link: https://bugs.launchpad.net/qemu/+bug/1753309
39
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
40
Message-id: 1520723090-22130-1-git-send-email-linux@roeck-us.net
41
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
42
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
43
---
8
---
44
include/hw/arm/fsl-imx6.h | 4 ++--
9
target/arm/cpu.h | 5 ++
45
hw/net/imx_fec.c | 28 +++++++++++++++++++++++++++-
10
target/arm/helper.h | 5 ++
46
2 files changed, 29 insertions(+), 3 deletions(-)
11
target/arm/cpu64.c | 1 +
12
target/arm/translate-a64.c | 71 ++++++++++++++++++++++++++--
13
target/arm/vfp_helper.c | 96 ++++++++++++++++++++++++++++++++++++++
14
5 files changed, 173 insertions(+), 5 deletions(-)
47
15
48
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
16
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
49
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
50
--- a/include/hw/arm/fsl-imx6.h
18
--- a/target/arm/cpu.h
51
+++ b/include/hw/arm/fsl-imx6.h
19
+++ b/target/arm/cpu.h
52
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX6State {
20
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id)
53
#define FSL_IMX6_HDMI_MASTER_IRQ 115
21
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SPECRES) != 0;
54
#define FSL_IMX6_HDMI_CEC_IRQ 116
22
}
55
#define FSL_IMX6_MLB150_LOW_IRQ 117
23
56
-#define FSL_IMX6_ENET_MAC_1588_IRQ 118
24
+static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
57
-#define FSL_IMX6_ENET_MAC_IRQ 119
25
+{
58
+#define FSL_IMX6_ENET_MAC_IRQ 118
26
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
59
+#define FSL_IMX6_ENET_MAC_1588_IRQ 119
27
+}
60
#define FSL_IMX6_PCIE1_IRQ 120
28
+
61
#define FSL_IMX6_PCIE2_IRQ 121
29
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
62
#define FSL_IMX6_PCIE3_IRQ 122
63
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/net/imx_fec.c
66
+++ b/hw/net/imx_fec.c
67
@@ -XXX,XX +XXX,XX @@ static void imx_enet_write_bd(IMXENETBufDesc *bd, dma_addr_t addr)
68
69
static void imx_eth_update(IMXFECState *s)
70
{
30
{
71
- if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] & ENET_INT_TS_TIMER) {
31
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
32
diff --git a/target/arm/helper.h b/target/arm/helper.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.h
35
+++ b/target/arm/helper.h
36
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_5(gvec_fmlal_idx_a32, TCG_CALL_NO_RWG,
37
DEF_HELPER_FLAGS_5(gvec_fmlal_idx_a64, TCG_CALL_NO_RWG,
38
void, ptr, ptr, ptr, ptr, i32)
39
40
+DEF_HELPER_FLAGS_2(frint32_s, TCG_CALL_NO_RWG, f32, f32, ptr)
41
+DEF_HELPER_FLAGS_2(frint64_s, TCG_CALL_NO_RWG, f32, f32, ptr)
42
+DEF_HELPER_FLAGS_2(frint32_d, TCG_CALL_NO_RWG, f64, f64, ptr)
43
+DEF_HELPER_FLAGS_2(frint64_d, TCG_CALL_NO_RWG, f64, f64, ptr)
44
+
45
#ifdef TARGET_AARCH64
46
#include "helper-a64.h"
47
#include "helper-sve.h"
48
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/cpu64.c
51
+++ b/target/arm/cpu64.c
52
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
53
t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
54
t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
55
t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
56
+ t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
57
cpu->isar.id_aa64isar1 = t;
58
59
t = cpu->isar.id_aa64pfr0;
60
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/arm/translate-a64.c
63
+++ b/target/arm/translate-a64.c
64
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_single(DisasContext *s, int opcode, int rd, int rn)
65
case 0xf: /* FRINTI */
66
gen_fpst = gen_helper_rints;
67
break;
68
+ case 0x10: /* FRINT32Z */
69
+ rmode = float_round_to_zero;
70
+ gen_fpst = gen_helper_frint32_s;
71
+ break;
72
+ case 0x11: /* FRINT32X */
73
+ gen_fpst = gen_helper_frint32_s;
74
+ break;
75
+ case 0x12: /* FRINT64Z */
76
+ rmode = float_round_to_zero;
77
+ gen_fpst = gen_helper_frint64_s;
78
+ break;
79
+ case 0x13: /* FRINT64X */
80
+ gen_fpst = gen_helper_frint64_s;
81
+ break;
82
default:
83
g_assert_not_reached();
84
}
85
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
86
case 0xf: /* FRINTI */
87
gen_fpst = gen_helper_rintd;
88
break;
89
+ case 0x10: /* FRINT32Z */
90
+ rmode = float_round_to_zero;
91
+ gen_fpst = gen_helper_frint32_d;
92
+ break;
93
+ case 0x11: /* FRINT32X */
94
+ gen_fpst = gen_helper_frint32_d;
95
+ break;
96
+ case 0x12: /* FRINT64Z */
97
+ rmode = float_round_to_zero;
98
+ gen_fpst = gen_helper_frint64_d;
99
+ break;
100
+ case 0x13: /* FRINT64X */
101
+ gen_fpst = gen_helper_frint64_d;
102
+ break;
103
default:
104
g_assert_not_reached();
105
}
106
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
107
handle_fp_fcvt(s, opcode, rd, rn, dtype, type);
108
break;
109
}
110
+
111
+ case 0x10 ... 0x13: /* FRINT{32,64}{X,Z} */
112
+ if (type > 1 || !dc_isar_feature(aa64_frint, s)) {
113
+ unallocated_encoding(s);
114
+ return;
115
+ }
116
+ /* fall through */
117
case 0x0 ... 0x3:
118
case 0x8 ... 0xc:
119
case 0xe ... 0xf:
120
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
121
if (!fp_access_check(s)) {
122
return;
123
}
124
-
125
handle_fp_1src_single(s, opcode, rd, rn);
126
break;
127
case 1:
128
if (!fp_access_check(s)) {
129
return;
130
}
131
-
132
handle_fp_1src_double(s, opcode, rd, rn);
133
break;
134
case 3:
135
@@ -XXX,XX +XXX,XX @@ static void disas_fp_1src(DisasContext *s, uint32_t insn)
136
if (!fp_access_check(s)) {
137
return;
138
}
139
-
140
handle_fp_1src_half(s, opcode, rd, rn);
141
break;
142
default:
143
unallocated_encoding(s);
144
}
145
break;
146
+
147
default:
148
unallocated_encoding(s);
149
break;
150
@@ -XXX,XX +XXX,XX @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u,
151
case 0x59: /* FRINTX */
152
gen_helper_rintd_exact(tcg_rd, tcg_rn, tcg_fpstatus);
153
break;
154
+ case 0x1e: /* FRINT32Z */
155
+ case 0x5e: /* FRINT32X */
156
+ gen_helper_frint32_d(tcg_rd, tcg_rn, tcg_fpstatus);
157
+ break;
158
+ case 0x1f: /* FRINT64Z */
159
+ case 0x5f: /* FRINT64X */
160
+ gen_helper_frint64_d(tcg_rd, tcg_rn, tcg_fpstatus);
161
+ break;
162
default:
163
g_assert_not_reached();
164
}
165
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
166
}
167
break;
168
case 0xc ... 0xf:
169
- case 0x16 ... 0x1d:
170
- case 0x1f:
171
+ case 0x16 ... 0x1f:
172
{
173
/* Floating point: U, size[1] and opcode indicate operation;
174
* size[0] indicates single or double precision.
175
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
176
}
177
need_fpstatus = true;
178
break;
179
+ case 0x1e: /* FRINT32Z */
180
+ case 0x1f: /* FRINT64Z */
181
+ need_rmode = true;
182
+ rmode = FPROUNDING_ZERO;
183
+ /* fall through */
184
+ case 0x5e: /* FRINT32X */
185
+ case 0x5f: /* FRINT64X */
186
+ need_fpstatus = true;
187
+ if ((size == 3 && !is_q) || !dc_isar_feature(aa64_frint, s)) {
188
+ unallocated_encoding(s);
189
+ return;
190
+ }
191
+ break;
192
default:
193
unallocated_encoding(s);
194
return;
195
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
196
case 0x7c: /* URSQRTE */
197
gen_helper_rsqrte_u32(tcg_res, tcg_op, tcg_fpstatus);
198
break;
199
+ case 0x1e: /* FRINT32Z */
200
+ case 0x5e: /* FRINT32X */
201
+ gen_helper_frint32_s(tcg_res, tcg_op, tcg_fpstatus);
202
+ break;
203
+ case 0x1f: /* FRINT64Z */
204
+ case 0x5f: /* FRINT64X */
205
+ gen_helper_frint64_s(tcg_res, tcg_op, tcg_fpstatus);
206
+ break;
207
default:
208
g_assert_not_reached();
209
}
210
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
211
index XXXXXXX..XXXXXXX 100644
212
--- a/target/arm/vfp_helper.c
213
+++ b/target/arm/vfp_helper.c
214
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vjcvt)(float64 value, CPUARMState *env)
215
216
return result;
217
}
218
+
219
+/* Round a float32 to an integer that fits in int32_t or int64_t. */
220
+static float32 frint_s(float32 f, float_status *fpst, int intsize)
221
+{
222
+ int old_flags = get_float_exception_flags(fpst);
223
+ uint32_t exp = extract32(f, 23, 8);
224
+
225
+ if (unlikely(exp == 0xff)) {
226
+ /* NaN or Inf. */
227
+ goto overflow;
228
+ }
229
+
230
+ /* Round and re-extract the exponent. */
231
+ f = float32_round_to_int(f, fpst);
232
+ exp = extract32(f, 23, 8);
233
+
234
+ /* Validate the range of the result. */
235
+ if (exp < 126 + intsize) {
236
+ /* abs(F) <= INT{N}_MAX */
237
+ return f;
238
+ }
239
+ if (exp == 126 + intsize) {
240
+ uint32_t sign = extract32(f, 31, 1);
241
+ uint32_t frac = extract32(f, 0, 23);
242
+ if (sign && frac == 0) {
243
+ /* F == INT{N}_MIN */
244
+ return f;
245
+ }
246
+ }
247
+
248
+ overflow:
72
+ /*
249
+ /*
73
+ * Previous versions of qemu had the ENET_INT_MAC and ENET_INT_TS_TIMER
250
+ * Raise Invalid and return INT{N}_MIN as a float. Revert any
74
+ * interrupts swapped. This worked with older versions of Linux (4.14
251
+ * inexact exception float32_round_to_int may have raised.
75
+ * and older) since Linux associated both interrupt lines with Ethernet
76
+ * MAC interrupts. Specifically,
77
+ * - Linux 4.15 and later have separate interrupt handlers for the MAC and
78
+ * timer interrupts. Those versions of Linux fail with versions of QEMU
79
+ * with swapped interrupt assignments.
80
+ * - In linux 4.14, both interrupt lines were registered with the Ethernet
81
+ * MAC interrupt handler. As a result, all versions of qemu happen to
82
+ * work, though that is accidental.
83
+ * - In Linux 4.9 and older, the timer interrupt was registered directly
84
+ * with the Ethernet MAC interrupt handler. The MAC interrupt was
85
+ * redirected to a GPIO interrupt to work around erratum ERR006687.
86
+ * This was implemented using the SOC's IOMUX block. In qemu, this GPIO
87
+ * interrupt never fired since IOMUX is currently not supported in qemu.
88
+ * Linux instead received MAC interrupts on the timer interrupt.
89
+ * As a result, qemu versions with the swapped interrupt assignment work,
90
+ * albeit accidentally, but qemu versions with the correct interrupt
91
+ * assignment fail.
92
+ *
93
+ * To ensure that all versions of Linux work, generate ENET_INT_MAC
94
+ * interrrupts on both interrupt lines. This should be changed if and when
95
+ * qemu supports IOMUX.
96
+ */
252
+ */
97
+ if (s->regs[ENET_EIR] & s->regs[ENET_EIMR] &
253
+ set_float_exception_flags(old_flags | float_flag_invalid, fpst);
98
+ (ENET_INT_MAC | ENET_INT_TS_TIMER)) {
254
+ return (0x100u + 126u + intsize) << 23;
99
qemu_set_irq(s->irq[1], 1);
255
+}
100
} else {
256
+
101
qemu_set_irq(s->irq[1], 0);
257
+float32 HELPER(frint32_s)(float32 f, void *fpst)
258
+{
259
+ return frint_s(f, fpst, 32);
260
+}
261
+
262
+float32 HELPER(frint64_s)(float32 f, void *fpst)
263
+{
264
+ return frint_s(f, fpst, 64);
265
+}
266
+
267
+/* Round a float64 to an integer that fits in int32_t or int64_t. */
268
+static float64 frint_d(float64 f, float_status *fpst, int intsize)
269
+{
270
+ int old_flags = get_float_exception_flags(fpst);
271
+ uint32_t exp = extract64(f, 52, 11);
272
+
273
+ if (unlikely(exp == 0x7ff)) {
274
+ /* NaN or Inf. */
275
+ goto overflow;
276
+ }
277
+
278
+ /* Round and re-extract the exponent. */
279
+ f = float64_round_to_int(f, fpst);
280
+ exp = extract64(f, 52, 11);
281
+
282
+ /* Validate the range of the result. */
283
+ if (exp < 1022 + intsize) {
284
+ /* abs(F) <= INT{N}_MAX */
285
+ return f;
286
+ }
287
+ if (exp == 1022 + intsize) {
288
+ uint64_t sign = extract64(f, 63, 1);
289
+ uint64_t frac = extract64(f, 0, 52);
290
+ if (sign && frac == 0) {
291
+ /* F == INT{N}_MIN */
292
+ return f;
293
+ }
294
+ }
295
+
296
+ overflow:
297
+ /*
298
+ * Raise Invalid and return INT{N}_MIN as a float. Revert any
299
+ * inexact exception float64_round_to_int may have raised.
300
+ */
301
+ set_float_exception_flags(old_flags | float_flag_invalid, fpst);
302
+ return (uint64_t)(0x800 + 1022 + intsize) << 52;
303
+}
304
+
305
+float64 HELPER(frint32_d)(float64 f, void *fpst)
306
+{
307
+ return frint_d(f, fpst, 32);
308
+}
309
+
310
+float64 HELPER(frint64_d)(float64 f, void *fpst)
311
+{
312
+ return frint_d(f, fpst, 64);
313
+}
102
--
314
--
103
2.16.2
315
2.20.1
104
316
105
317
diff view generated by jsdifflib
1
If we're directly booting a Linux kernel and the CPU supports both
1
From: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
2
EL3 and EL2, we start the kernel in EL2, as it expects. We must also
3
set the SCR_EL3.HCE bit in this situation, so that the HVC
4
instruction is enabled rather than UNDEFing. Otherwise at least some
5
kernels will panic when trying to initialize KVM in the guest.
6
2
3
We introduce an helper to create a memory node.
4
5
Signed-off-by: Eric Auger <eric.auger@redhat.com>
6
Signed-off-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
7
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190304101339.25970-2-eric.auger@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20180313153458.26822-4-peter.maydell@linaro.org
9
---
11
---
10
hw/arm/boot.c | 5 +++++
12
hw/arm/boot.c | 54 ++++++++++++++++++++++++++++++++-------------------
11
1 file changed, 5 insertions(+)
13
1 file changed, 34 insertions(+), 20 deletions(-)
12
14
13
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
15
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/boot.c
17
--- a/hw/arm/boot.c
16
+++ b/hw/arm/boot.c
18
+++ b/hw/arm/boot.c
17
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
19
@@ -XXX,XX +XXX,XX @@ static void set_kernel_args_old(const struct arm_boot_info *info,
18
assert(!info->secure_board_setup);
20
}
19
}
21
}
20
22
21
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
23
+static int fdt_add_memory_node(void *fdt, uint32_t acells, hwaddr mem_base,
22
+ /* If we have EL2 then Linux expects the HVC insn to work */
24
+ uint32_t scells, hwaddr mem_len,
23
+ env->cp15.scr_el3 |= SCR_HCE;
25
+ int numa_node_id)
24
+ }
26
+{
27
+ char *nodename;
28
+ int ret;
25
+
29
+
26
/* Set to non-secure if not a secure boot */
30
+ nodename = g_strdup_printf("/memory@%" PRIx64, mem_base);
27
if (!info->secure_boot &&
31
+ qemu_fdt_add_subnode(fdt, nodename);
28
(cs != first_cpu || !info->secure_board_setup)) {
32
+ qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
33
+ ret = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", acells, mem_base,
34
+ scells, mem_len);
35
+ if (ret < 0) {
36
+ goto out;
37
+ }
38
+
39
+ /* only set the NUMA ID if it is specified */
40
+ if (numa_node_id >= 0) {
41
+ ret = qemu_fdt_setprop_cell(fdt, nodename,
42
+ "numa-node-id", numa_node_id);
43
+ }
44
+out:
45
+ g_free(nodename);
46
+ return ret;
47
+}
48
+
49
static void fdt_add_psci_node(void *fdt)
50
{
51
uint32_t cpu_suspend_fn;
52
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
53
void *fdt = NULL;
54
int size, rc, n = 0;
55
uint32_t acells, scells;
56
- char *nodename;
57
unsigned int i;
58
hwaddr mem_base, mem_len;
59
char **node_path;
60
@@ -XXX,XX +XXX,XX @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
61
mem_base = binfo->loader_start;
62
for (i = 0; i < nb_numa_nodes; i++) {
63
mem_len = numa_info[i].node_mem;
64
- nodename = g_strdup_printf("/memory@%" PRIx64, mem_base);
65
- qemu_fdt_add_subnode(fdt, nodename);
66
- qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
67
- rc = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
68
- acells, mem_base,
69
- scells, mem_len);
70
+ rc = fdt_add_memory_node(fdt, acells, mem_base,
71
+ scells, mem_len, i);
72
if (rc < 0) {
73
- fprintf(stderr, "couldn't set %s/reg for node %d\n", nodename,
74
- i);
75
+ fprintf(stderr, "couldn't add /memory@%"PRIx64" node\n",
76
+ mem_base);
77
goto fail;
78
}
79
80
- qemu_fdt_setprop_cell(fdt, nodename, "numa-node-id", i);
81
mem_base += mem_len;
82
- g_free(nodename);
83
}
84
} else {
85
- nodename = g_strdup_printf("/memory@%" PRIx64, binfo->loader_start);
86
- qemu_fdt_add_subnode(fdt, nodename);
87
- qemu_fdt_setprop_string(fdt, nodename, "device_type", "memory");
88
-
89
- rc = qemu_fdt_setprop_sized_cells(fdt, nodename, "reg",
90
- acells, binfo->loader_start,
91
- scells, binfo->ram_size);
92
+ rc = fdt_add_memory_node(fdt, acells, binfo->loader_start,
93
+ scells, binfo->ram_size, -1);
94
if (rc < 0) {
95
- fprintf(stderr, "couldn't set %s reg\n", nodename);
96
+ fprintf(stderr, "couldn't add /memory@%"PRIx64" node\n",
97
+ binfo->loader_start);
98
goto fail;
99
}
100
- g_free(nodename);
101
}
102
103
rc = fdt_path_offset(fdt, "/chosen");
29
--
104
--
30
2.16.2
105
2.20.1
31
106
32
107
diff view generated by jsdifflib
New patch
1
From: Eric Auger <eric.auger@redhat.com>
1
2
3
In preparation for a split of the memory map into a static
4
part and a dynamic part floating after the RAM, let's rename the
5
regions located after the RAM
6
7
Signed-off-by: Eric Auger <eric.auger@redhat.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Message-id: 20190304101339.25970-3-eric.auger@redhat.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
include/hw/arm/virt.h | 8 ++++----
14
hw/arm/virt-acpi-build.c | 10 ++++++----
15
hw/arm/virt.c | 33 ++++++++++++++++++---------------
16
3 files changed, 28 insertions(+), 23 deletions(-)
17
18
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/arm/virt.h
21
+++ b/include/hw/arm/virt.h
22
@@ -XXX,XX +XXX,XX @@ enum {
23
VIRT_GIC_VCPU,
24
VIRT_GIC_ITS,
25
VIRT_GIC_REDIST,
26
- VIRT_GIC_REDIST2,
27
+ VIRT_HIGH_GIC_REDIST2,
28
VIRT_SMMU,
29
VIRT_UART,
30
VIRT_MMIO,
31
@@ -XXX,XX +XXX,XX @@ enum {
32
VIRT_PCIE_MMIO,
33
VIRT_PCIE_PIO,
34
VIRT_PCIE_ECAM,
35
- VIRT_PCIE_ECAM_HIGH,
36
+ VIRT_HIGH_PCIE_ECAM,
37
VIRT_PLATFORM_BUS,
38
- VIRT_PCIE_MMIO_HIGH,
39
+ VIRT_HIGH_PCIE_MMIO,
40
VIRT_GPIO,
41
VIRT_SECURE_UART,
42
VIRT_SECURE_MEM,
43
@@ -XXX,XX +XXX,XX @@ typedef struct {
44
int psci_conduit;
45
} VirtMachineState;
46
47
-#define VIRT_ECAM_ID(high) (high ? VIRT_PCIE_ECAM_HIGH : VIRT_PCIE_ECAM)
48
+#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
49
50
#define TYPE_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
51
#define VIRT_MACHINE(obj) \
52
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/arm/virt-acpi-build.c
55
+++ b/hw/arm/virt-acpi-build.c
56
@@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
57
size_pio));
58
59
if (use_highmem) {
60
- hwaddr base_mmio_high = memmap[VIRT_PCIE_MMIO_HIGH].base;
61
- hwaddr size_mmio_high = memmap[VIRT_PCIE_MMIO_HIGH].size;
62
+ hwaddr base_mmio_high = memmap[VIRT_HIGH_PCIE_MMIO].base;
63
+ hwaddr size_mmio_high = memmap[VIRT_HIGH_PCIE_MMIO].size;
64
65
aml_append(rbuf,
66
aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
67
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
68
gicr = acpi_data_push(table_data, sizeof(*gicr));
69
gicr->type = ACPI_APIC_GENERIC_REDISTRIBUTOR;
70
gicr->length = sizeof(*gicr);
71
- gicr->base_address = cpu_to_le64(memmap[VIRT_GIC_REDIST2].base);
72
- gicr->range_length = cpu_to_le32(memmap[VIRT_GIC_REDIST2].size);
73
+ gicr->base_address =
74
+ cpu_to_le64(memmap[VIRT_HIGH_GIC_REDIST2].base);
75
+ gicr->range_length =
76
+ cpu_to_le32(memmap[VIRT_HIGH_GIC_REDIST2].size);
77
}
78
79
if (its_class_name() && !vmc->no_its) {
80
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/hw/arm/virt.c
83
+++ b/hw/arm/virt.c
84
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry a15memmap[] = {
85
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
86
[VIRT_MEM] = { 0x40000000, RAMLIMIT_BYTES },
87
/* Additional 64 MB redist region (can contain up to 512 redistributors) */
88
- [VIRT_GIC_REDIST2] = { 0x4000000000ULL, 0x4000000 },
89
- [VIRT_PCIE_ECAM_HIGH] = { 0x4010000000ULL, 0x10000000 },
90
+ [VIRT_HIGH_GIC_REDIST2] = { 0x4000000000ULL, 0x4000000 },
91
+ [VIRT_HIGH_PCIE_ECAM] = { 0x4010000000ULL, 0x10000000 },
92
/* Second PCIe window, 512GB wide at the 512GB boundary */
93
- [VIRT_PCIE_MMIO_HIGH] = { 0x8000000000ULL, 0x8000000000ULL },
94
+ [VIRT_HIGH_PCIE_MMIO] = { 0x8000000000ULL, 0x8000000000ULL },
95
};
96
97
static const int a15irqmap[] = {
98
@@ -XXX,XX +XXX,XX @@ static void fdt_add_gic_node(VirtMachineState *vms)
99
2, vms->memmap[VIRT_GIC_REDIST].size);
100
} else {
101
qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg",
102
- 2, vms->memmap[VIRT_GIC_DIST].base,
103
- 2, vms->memmap[VIRT_GIC_DIST].size,
104
- 2, vms->memmap[VIRT_GIC_REDIST].base,
105
- 2, vms->memmap[VIRT_GIC_REDIST].size,
106
- 2, vms->memmap[VIRT_GIC_REDIST2].base,
107
- 2, vms->memmap[VIRT_GIC_REDIST2].size);
108
+ 2, vms->memmap[VIRT_GIC_DIST].base,
109
+ 2, vms->memmap[VIRT_GIC_DIST].size,
110
+ 2, vms->memmap[VIRT_GIC_REDIST].base,
111
+ 2, vms->memmap[VIRT_GIC_REDIST].size,
112
+ 2, vms->memmap[VIRT_HIGH_GIC_REDIST2].base,
113
+ 2, vms->memmap[VIRT_HIGH_GIC_REDIST2].size);
114
}
115
116
if (vms->virt) {
117
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
118
119
if (nb_redist_regions == 2) {
120
uint32_t redist1_capacity =
121
- vms->memmap[VIRT_GIC_REDIST2].size / GICV3_REDIST_SIZE;
122
+ vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
123
124
qdev_prop_set_uint32(gicdev, "redist-region-count[1]",
125
MIN(smp_cpus - redist0_count, redist1_capacity));
126
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, qemu_irq *pic)
127
if (type == 3) {
128
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_REDIST].base);
129
if (nb_redist_regions == 2) {
130
- sysbus_mmio_map(gicbusdev, 2, vms->memmap[VIRT_GIC_REDIST2].base);
131
+ sysbus_mmio_map(gicbusdev, 2,
132
+ vms->memmap[VIRT_HIGH_GIC_REDIST2].base);
133
}
134
} else {
135
sysbus_mmio_map(gicbusdev, 1, vms->memmap[VIRT_GIC_CPU].base);
136
@@ -XXX,XX +XXX,XX @@ static void create_pcie(VirtMachineState *vms, qemu_irq *pic)
137
{
138
hwaddr base_mmio = vms->memmap[VIRT_PCIE_MMIO].base;
139
hwaddr size_mmio = vms->memmap[VIRT_PCIE_MMIO].size;
140
- hwaddr base_mmio_high = vms->memmap[VIRT_PCIE_MMIO_HIGH].base;
141
- hwaddr size_mmio_high = vms->memmap[VIRT_PCIE_MMIO_HIGH].size;
142
+ hwaddr base_mmio_high = vms->memmap[VIRT_HIGH_PCIE_MMIO].base;
143
+ hwaddr size_mmio_high = vms->memmap[VIRT_HIGH_PCIE_MMIO].size;
144
hwaddr base_pio = vms->memmap[VIRT_PCIE_PIO].base;
145
hwaddr size_pio = vms->memmap[VIRT_PCIE_PIO].size;
146
hwaddr base_ecam, size_ecam;
147
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
148
* many redistributors we can fit into the memory map.
149
*/
150
if (vms->gic_version == 3) {
151
- virt_max_cpus = vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
152
- virt_max_cpus += vms->memmap[VIRT_GIC_REDIST2].size / GICV3_REDIST_SIZE;
153
+ virt_max_cpus =
154
+ vms->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
155
+ virt_max_cpus +=
156
+ vms->memmap[VIRT_HIGH_GIC_REDIST2].size / GICV3_REDIST_SIZE;
157
} else {
158
virt_max_cpus = GIC_NCPU;
159
}
160
--
161
2.20.1
162
163
diff view generated by jsdifflib
1
The bcm2837 is pretty similar to the bcm2836, but it does have
1
From: Eric Auger <eric.auger@redhat.com>
2
some differences. Notably, the MPIDR affinity aff1 values it
3
sets for the CPUs are 0x0, rather than the 0xf that the bcm2836
4
uses, and if this is wrong Linux will not boot.
5
2
6
Rather than trying to have one device with properties that
3
In the prospect to introduce an extended memory map supporting more
7
configure it differently for the two cases, create two
4
RAM, let's split the memory map array into two parts:
8
separate QOM devices for the two SoCs. We use the same approach
9
as hw/arm/aspeed_soc.c and share code and have a data table
10
that might differ per-SoC. For the moment the two types don't
11
actually have different behaviour.
12
5
6
- the former a15memmap, renamed base_memmap, contains regions below
7
and including the RAM. MemMapEntries initialized in this array
8
have a static size and base address.
9
- extended_memmap, only initialized with entries located after the
10
RAM. MemMapEntries initialized in this array only get their size
11
initialized. Their base address is dynamically computed depending
12
on the the top of the RAM, with same alignment as their size.
13
14
Eventually base_memmap entries are copied into the extended_memmap
15
array. Using two separate arrays however clarifies which entries
16
are statically allocated and those which are dynamically allocated.
17
18
This new split will allow to grow the RAM size without changing the
19
description of the high IO entries.
20
21
We introduce a new virt_set_memmap() helper function which
22
"freezes" the memory map. We call it in machvirt_init as
23
memory attributes of the machine are not yet set when
24
virt_instance_init() gets called.
25
26
The memory map is unchanged (the top of the initial RAM still is
27
256GiB). Then come the high IO regions with same layout as before.
28
29
Signed-off-by: Eric Auger <eric.auger@redhat.com>
30
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
31
Message-id: 20190304101339.25970-4-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20180313153458.26822-7-peter.maydell@linaro.org
16
---
33
---
17
include/hw/arm/bcm2836.h | 19 +++++++++++++++++++
34
include/hw/arm/virt.h | 13 +++++++----
18
hw/arm/bcm2836.c | 37 ++++++++++++++++++++++++++++++++-----
35
hw/arm/virt.c | 50 +++++++++++++++++++++++++++++++++++++------
19
hw/arm/raspi.c | 3 ++-
36
2 files changed, 53 insertions(+), 10 deletions(-)
20
3 files changed, 53 insertions(+), 6 deletions(-)
21
37
22
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
38
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
23
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/arm/bcm2836.h
40
--- a/include/hw/arm/virt.h
25
+++ b/include/hw/arm/bcm2836.h
41
+++ b/include/hw/arm/virt.h
26
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@ enum {
27
43
VIRT_GIC_VCPU,
28
#define BCM283X_NCPUS 4
44
VIRT_GIC_ITS,
29
45
VIRT_GIC_REDIST,
30
+/* These type names are for specific SoCs; other than instantiating
46
- VIRT_HIGH_GIC_REDIST2,
31
+ * them, code using these devices should always handle them via the
47
VIRT_SMMU,
32
+ * BCM283x base class, so they have no BCM2836(obj) etc macros.
48
VIRT_UART,
33
+ */
49
VIRT_MMIO,
34
+#define TYPE_BCM2836 "bcm2836"
50
@@ -XXX,XX +XXX,XX @@ enum {
35
+#define TYPE_BCM2837 "bcm2837"
51
VIRT_PCIE_MMIO,
36
+
52
VIRT_PCIE_PIO,
37
typedef struct BCM283XState {
53
VIRT_PCIE_ECAM,
38
/*< private >*/
54
- VIRT_HIGH_PCIE_ECAM,
39
DeviceState parent_obj;
55
VIRT_PLATFORM_BUS,
40
@@ -XXX,XX +XXX,XX @@ typedef struct BCM283XState {
56
- VIRT_HIGH_PCIE_MMIO,
41
BCM2835PeripheralState peripherals;
57
VIRT_GPIO,
42
} BCM283XState;
58
VIRT_SECURE_UART,
43
59
VIRT_SECURE_MEM,
44
+typedef struct BCM283XInfo BCM283XInfo;
60
+ VIRT_LOWMEMMAP_LAST,
45
+
46
+typedef struct BCM283XClass {
47
+ DeviceClass parent_class;
48
+ const BCM283XInfo *info;
49
+} BCM283XClass;
50
+
51
+#define BCM283X_CLASS(klass) \
52
+ OBJECT_CLASS_CHECK(BCM283XClass, (klass), TYPE_BCM283X)
53
+#define BCM283X_GET_CLASS(obj) \
54
+ OBJECT_GET_CLASS(BCM283XClass, (obj), TYPE_BCM283X)
55
+
56
#endif /* BCM2836_H */
57
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/arm/bcm2836.c
60
+++ b/hw/arm/bcm2836.c
61
@@ -XXX,XX +XXX,XX @@
62
/* "QA7" (Pi2) interrupt controller and mailboxes etc. */
63
#define BCM2836_CONTROL_BASE 0x40000000
64
65
+struct BCM283XInfo {
66
+ const char *name;
67
+};
61
+};
68
+
62
+
69
+static const BCM283XInfo bcm283x_socs[] = {
63
+/* indices of IO regions located after the RAM */
70
+ {
64
+enum {
71
+ .name = TYPE_BCM2836,
65
+ VIRT_HIGH_GIC_REDIST2 = VIRT_LOWMEMMAP_LAST,
72
+ },
66
+ VIRT_HIGH_PCIE_ECAM,
73
+ {
67
+ VIRT_HIGH_PCIE_MMIO,
74
+ .name = TYPE_BCM2837,
68
};
75
+ },
69
70
typedef enum VirtIOMMUType {
71
@@ -XXX,XX +XXX,XX @@ typedef struct {
72
int32_t gic_version;
73
VirtIOMMUType iommu;
74
struct arm_boot_info bootinfo;
75
- const MemMapEntry *memmap;
76
+ MemMapEntry *memmap;
77
const int *irqmap;
78
int smp_cpus;
79
void *fdt;
80
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/hw/arm/virt.c
83
+++ b/hw/arm/virt.c
84
@@ -XXX,XX +XXX,XX @@
85
*/
86
87
#include "qemu/osdep.h"
88
+#include "qemu/units.h"
89
#include "qapi/error.h"
90
#include "hw/sysbus.h"
91
#include "hw/arm/arm.h"
92
@@ -XXX,XX +XXX,XX @@
93
* Note that devices should generally be placed at multiples of 0x10000,
94
* to accommodate guests using 64K pages.
95
*/
96
-static const MemMapEntry a15memmap[] = {
97
+static const MemMapEntry base_memmap[] = {
98
/* Space up to 0x8000000 is reserved for a boot ROM */
99
[VIRT_FLASH] = { 0, 0x08000000 },
100
[VIRT_CPUPERIPHS] = { 0x08000000, 0x00020000 },
101
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry a15memmap[] = {
102
[VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
103
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
104
[VIRT_MEM] = { 0x40000000, RAMLIMIT_BYTES },
76
+};
105
+};
77
+
106
+
78
static void bcm2836_init(Object *obj)
107
+/*
79
{
108
+ * Highmem IO Regions: This memory map is floating, located after the RAM.
80
BCM283XState *s = BCM283X(obj);
109
+ * Each MemMapEntry base (GPA) will be dynamically computed, depending on the
81
@@ -XXX,XX +XXX,XX @@ static Property bcm2836_props[] = {
110
+ * top of the RAM, so that its base get the same alignment as the size,
82
DEFINE_PROP_END_OF_LIST()
111
+ * ie. a 512GiB entry will be aligned on a 512GiB boundary. If there is
112
+ * less than 256GiB of RAM, the floating area starts at the 256GiB mark.
113
+ * Note the extended_memmap is sized so that it eventually also includes the
114
+ * base_memmap entries (VIRT_HIGH_GIC_REDIST2 index is greater than the last
115
+ * index of base_memmap).
116
+ */
117
+static MemMapEntry extended_memmap[] = {
118
/* Additional 64 MB redist region (can contain up to 512 redistributors) */
119
- [VIRT_HIGH_GIC_REDIST2] = { 0x4000000000ULL, 0x4000000 },
120
- [VIRT_HIGH_PCIE_ECAM] = { 0x4010000000ULL, 0x10000000 },
121
- /* Second PCIe window, 512GB wide at the 512GB boundary */
122
- [VIRT_HIGH_PCIE_MMIO] = { 0x8000000000ULL, 0x8000000000ULL },
123
+ [VIRT_HIGH_GIC_REDIST2] = { 0x0, 64 * MiB },
124
+ [VIRT_HIGH_PCIE_ECAM] = { 0x0, 256 * MiB },
125
+ /* Second PCIe window */
126
+ [VIRT_HIGH_PCIE_MMIO] = { 0x0, 512 * GiB },
83
};
127
};
84
128
85
-static void bcm2836_class_init(ObjectClass *oc, void *data)
129
static const int a15irqmap[] = {
86
+static void bcm283x_class_init(ObjectClass *oc, void *data)
130
@@ -XXX,XX +XXX,XX @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)
87
{
131
return arm_cpu_mp_affinity(idx, clustersz);
88
DeviceClass *dc = DEVICE_CLASS(oc);
89
+ BCM283XClass *bc = BCM283X_CLASS(oc);
90
91
- dc->props = bcm2836_props;
92
+ bc->info = data;
93
dc->realize = bcm2836_realize;
94
+ dc->props = bcm2836_props;
95
}
132
}
96
133
97
-static const TypeInfo bcm2836_type_info = {
134
+static void virt_set_memmap(VirtMachineState *vms)
98
+static const TypeInfo bcm283x_type_info = {
135
+{
99
.name = TYPE_BCM283X,
136
+ hwaddr base;
100
.parent = TYPE_DEVICE,
101
.instance_size = sizeof(BCM283XState),
102
.instance_init = bcm2836_init,
103
- .class_init = bcm2836_class_init,
104
+ .class_size = sizeof(BCM283XClass),
105
+ .abstract = true,
106
};
107
108
static void bcm2836_register_types(void)
109
{
110
- type_register_static(&bcm2836_type_info);
111
+ int i;
137
+ int i;
112
+
138
+
113
+ type_register_static(&bcm283x_type_info);
139
+ vms->memmap = extended_memmap;
114
+ for (i = 0; i < ARRAY_SIZE(bcm283x_socs); i++) {
140
+
115
+ TypeInfo ti = {
141
+ for (i = 0; i < ARRAY_SIZE(base_memmap); i++) {
116
+ .name = bcm283x_socs[i].name,
142
+ vms->memmap[i] = base_memmap[i];
117
+ .parent = TYPE_BCM283X,
118
+ .class_init = bcm283x_class_init,
119
+ .class_data = (void *) &bcm283x_socs[i],
120
+ };
121
+ type_register(&ti);
122
+ }
143
+ }
144
+
145
+ base = 256 * GiB; /* Top of the legacy initial RAM region */
146
+
147
+ for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) {
148
+ hwaddr size = extended_memmap[i].size;
149
+
150
+ base = ROUND_UP(base, size);
151
+ vms->memmap[i].base = base;
152
+ vms->memmap[i].size = size;
153
+ base += size;
154
+ }
155
+}
156
+
157
static void machvirt_init(MachineState *machine)
158
{
159
VirtMachineState *vms = VIRT_MACHINE(machine);
160
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
161
bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
162
bool aarch64 = true;
163
164
+ virt_set_memmap(vms);
165
+
166
/* We can probe only here because during property set
167
* KVM is not available yet
168
*/
169
@@ -XXX,XX +XXX,XX @@ static void virt_instance_init(Object *obj)
170
"Valid values are none and smmuv3",
171
NULL);
172
173
- vms->memmap = a15memmap;
174
vms->irqmap = a15irqmap;
123
}
175
}
124
176
125
type_init(bcm2836_register_types)
126
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
127
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/arm/raspi.c
129
+++ b/hw/arm/raspi.c
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
131
BusState *bus;
132
DeviceState *carddev;
133
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
135
+ object_initialize(&s->soc, sizeof(s->soc),
136
+ version == 3 ? TYPE_BCM2837 : TYPE_BCM2836);
137
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
138
&error_abort);
139
140
--
177
--
141
2.16.2
178
2.20.1
142
179
143
180
diff view generated by jsdifflib
1
Our BCM2836 type is really a generic one that can be any of
1
From: Eric Auger <eric.auger@redhat.com>
2
the bcm283x family. Rename it accordingly. We change only
3
the names which are visible via the header file to the
4
rest of the QEMU code, leaving private function names
5
in bcm2836.c as they are.
6
2
7
This is a preliminary to making bcm283x be an abstract
3
On ARM, the kvm_type will be resolved by querying the KVMState.
8
parent class to specific types for the bcm2836 and bcm2837.
4
Let's add the MachineState handle to the callback so that we
5
can retrieve the KVMState handle. in kvm_init, when the callback
6
is called, the kvm_state variable is not yet set.
9
7
8
Signed-off-by: Eric Auger <eric.auger@redhat.com>
9
Acked-by: David Gibson <david@gibson.dropbear.id.au>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
12
Message-id: 20190304101339.25970-5-eric.auger@redhat.com
13
[ppc parts]
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Message-id: 20180313153458.26822-6-peter.maydell@linaro.org
14
---
17
---
15
include/hw/arm/bcm2836.h | 12 ++++++------
18
include/hw/boards.h | 5 ++++-
16
hw/arm/bcm2836.c | 17 +++++++++--------
19
accel/kvm/kvm-all.c | 2 +-
17
hw/arm/raspi.c | 16 ++++++++--------
20
hw/ppc/mac_newworld.c | 3 +--
18
3 files changed, 23 insertions(+), 22 deletions(-)
21
hw/ppc/mac_oldworld.c | 2 +-
22
hw/ppc/spapr.c | 2 +-
23
5 files changed, 8 insertions(+), 6 deletions(-)
19
24
20
diff --git a/include/hw/arm/bcm2836.h b/include/hw/arm/bcm2836.h
25
diff --git a/include/hw/boards.h b/include/hw/boards.h
21
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/arm/bcm2836.h
27
--- a/include/hw/boards.h
23
+++ b/include/hw/arm/bcm2836.h
28
+++ b/include/hw/boards.h
24
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ typedef struct {
25
#include "hw/arm/bcm2835_peripherals.h"
30
* should instead use "unimplemented-device" for all memory ranges where
26
#include "hw/intc/bcm2836_control.h"
31
* the guest will attempt to probe for a device that QEMU doesn't
27
32
* implement and a stub device is required.
28
-#define TYPE_BCM2836 "bcm2836"
33
+ * @kvm_type:
29
-#define BCM2836(obj) OBJECT_CHECK(BCM2836State, (obj), TYPE_BCM2836)
34
+ * Return the type of KVM corresponding to the kvm-type string option or
30
+#define TYPE_BCM283X "bcm283x"
35
+ * computed based on other criteria such as the host kernel capabilities.
31
+#define BCM283X(obj) OBJECT_CHECK(BCM283XState, (obj), TYPE_BCM283X)
36
*/
32
37
struct MachineClass {
33
-#define BCM2836_NCPUS 4
34
+#define BCM283X_NCPUS 4
35
36
-typedef struct BCM2836State {
37
+typedef struct BCM283XState {
38
/*< private >*/
38
/*< private >*/
39
DeviceState parent_obj;
39
@@ -XXX,XX +XXX,XX @@ struct MachineClass {
40
/*< public >*/
40
void (*init)(MachineState *state);
41
@@ -XXX,XX +XXX,XX @@ typedef struct BCM2836State {
41
void (*reset)(void);
42
char *cpu_type;
42
void (*hot_add_cpu)(const int64_t id, Error **errp);
43
uint32_t enabled_cpus;
43
- int (*kvm_type)(const char *arg);
44
44
+ int (*kvm_type)(MachineState *machine, const char *arg);
45
- ARMCPU cpus[BCM2836_NCPUS];
45
46
+ ARMCPU cpus[BCM283X_NCPUS];
46
BlockInterfaceType block_default_type;
47
BCM2836ControlState control;
47
int units_per_default_bus;
48
BCM2835PeripheralState peripherals;
48
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
49
-} BCM2836State;
50
+} BCM283XState;
51
52
#endif /* BCM2836_H */
53
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
54
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/bcm2836.c
50
--- a/accel/kvm/kvm-all.c
56
+++ b/hw/arm/bcm2836.c
51
+++ b/accel/kvm/kvm-all.c
57
@@ -XXX,XX +XXX,XX @@
52
@@ -XXX,XX +XXX,XX @@ static int kvm_init(MachineState *ms)
58
53
59
static void bcm2836_init(Object *obj)
54
kvm_type = qemu_opt_get(qemu_get_machine_opts(), "kvm-type");
55
if (mc->kvm_type) {
56
- type = mc->kvm_type(kvm_type);
57
+ type = mc->kvm_type(ms, kvm_type);
58
} else if (kvm_type) {
59
ret = -EINVAL;
60
fprintf(stderr, "Invalid argument kvm-type=%s\n", kvm_type);
61
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/ppc/mac_newworld.c
64
+++ b/hw/ppc/mac_newworld.c
65
@@ -XXX,XX +XXX,XX @@ static char *core99_fw_dev_path(FWPathProvider *p, BusState *bus,
66
67
return NULL;
68
}
69
-
70
-static int core99_kvm_type(const char *arg)
71
+static int core99_kvm_type(MachineState *machine, const char *arg)
60
{
72
{
61
- BCM2836State *s = BCM2836(obj);
73
/* Always force PR KVM */
62
+ BCM283XState *s = BCM283X(obj);
74
return 2;
63
75
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
64
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
76
index XXXXXXX..XXXXXXX 100644
65
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
77
--- a/hw/ppc/mac_oldworld.c
66
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
78
+++ b/hw/ppc/mac_oldworld.c
67
79
@@ -XXX,XX +XXX,XX @@ static char *heathrow_fw_dev_path(FWPathProvider *p, BusState *bus,
68
static void bcm2836_realize(DeviceState *dev, Error **errp)
80
return NULL;
81
}
82
83
-static int heathrow_kvm_type(const char *arg)
84
+static int heathrow_kvm_type(MachineState *machine, const char *arg)
69
{
85
{
70
- BCM2836State *s = BCM2836(dev);
86
/* Always force PR KVM */
71
+ BCM283XState *s = BCM283X(dev);
87
return 2;
72
Object *obj;
88
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
73
Error *err = NULL;
89
index XXXXXXX..XXXXXXX 100644
74
int n;
90
--- a/hw/ppc/spapr.c
75
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
91
+++ b/hw/ppc/spapr.c
76
/* common peripherals from bcm2835 */
92
@@ -XXX,XX +XXX,XX @@ static void spapr_machine_init(MachineState *machine)
77
93
}
78
obj = OBJECT(dev);
79
- for (n = 0; n < BCM2836_NCPUS; n++) {
80
+ for (n = 0; n < BCM283X_NCPUS; n++) {
81
object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
82
s->cpu_type);
83
object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
84
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
85
sysbus_connect_irq(SYS_BUS_DEVICE(&s->peripherals), 1,
86
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
87
88
- for (n = 0; n < BCM2836_NCPUS; n++) {
89
+ for (n = 0; n < BCM283X_NCPUS; n++) {
90
/* Mirror bcm2836, which has clusterid set to 0xf
91
* TODO: this should be converted to a property of ARM_CPU
92
*/
93
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
94
}
94
}
95
95
96
static Property bcm2836_props[] = {
96
-static int spapr_kvm_type(const char *vm_type)
97
- DEFINE_PROP_STRING("cpu-type", BCM2836State, cpu_type),
97
+static int spapr_kvm_type(MachineState *machine, const char *vm_type)
98
- DEFINE_PROP_UINT32("enabled-cpus", BCM2836State, enabled_cpus, BCM2836_NCPUS),
98
{
99
+ DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
99
if (!vm_type) {
100
+ DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
100
return 0;
101
+ BCM283X_NCPUS),
102
DEFINE_PROP_END_OF_LIST()
103
};
104
105
@@ -XXX,XX +XXX,XX @@ static void bcm2836_class_init(ObjectClass *oc, void *data)
106
}
107
108
static const TypeInfo bcm2836_type_info = {
109
- .name = TYPE_BCM2836,
110
+ .name = TYPE_BCM283X,
111
.parent = TYPE_DEVICE,
112
- .instance_size = sizeof(BCM2836State),
113
+ .instance_size = sizeof(BCM283XState),
114
.instance_init = bcm2836_init,
115
.class_init = bcm2836_class_init,
116
};
117
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
118
index XXXXXXX..XXXXXXX 100644
119
--- a/hw/arm/raspi.c
120
+++ b/hw/arm/raspi.c
121
@@ -XXX,XX +XXX,XX @@
122
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
123
124
typedef struct RasPiState {
125
- BCM2836State soc;
126
+ BCM283XState soc;
127
MemoryRegion ram;
128
} RasPiState;
129
130
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
131
BusState *bus;
132
DeviceState *carddev;
133
134
- object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM2836);
135
+ object_initialize(&s->soc, sizeof(s->soc), TYPE_BCM283X);
136
object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
137
&error_abort);
138
139
@@ -XXX,XX +XXX,XX @@ static void raspi2_machine_init(MachineClass *mc)
140
mc->no_floppy = 1;
141
mc->no_cdrom = 1;
142
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
143
- mc->max_cpus = BCM2836_NCPUS;
144
- mc->min_cpus = BCM2836_NCPUS;
145
- mc->default_cpus = BCM2836_NCPUS;
146
+ mc->max_cpus = BCM283X_NCPUS;
147
+ mc->min_cpus = BCM283X_NCPUS;
148
+ mc->default_cpus = BCM283X_NCPUS;
149
mc->default_ram_size = 1024 * 1024 * 1024;
150
mc->ignore_memory_transaction_failures = true;
151
};
152
@@ -XXX,XX +XXX,XX @@ static void raspi3_machine_init(MachineClass *mc)
153
mc->no_floppy = 1;
154
mc->no_cdrom = 1;
155
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
156
- mc->max_cpus = BCM2836_NCPUS;
157
- mc->min_cpus = BCM2836_NCPUS;
158
- mc->default_cpus = BCM2836_NCPUS;
159
+ mc->max_cpus = BCM283X_NCPUS;
160
+ mc->min_cpus = BCM283X_NCPUS;
161
+ mc->default_cpus = BCM283X_NCPUS;
162
mc->default_ram_size = 1024 * 1024 * 1024;
163
}
164
DEFINE_MACHINE("raspi3", raspi3_machine_init)
165
--
101
--
166
2.16.2
102
2.20.1
167
103
168
104
diff view generated by jsdifflib
1
Add some assertions that if we're about to boot an AArch64 kernel,
1
From: Eric Auger <eric.auger@redhat.com>
2
the board code has not mistakenly set either secure_boot or
3
secure_board_setup. It doesn't make sense to set secure_boot,
4
because all AArch64 kernels must be booted in non-secure mode.
5
2
6
It might in theory make sense to set secure_board_setup, but
3
Add the kvm_arm_get_max_vm_ipa_size() helper that returns the
7
we don't currently support that, because only the AArch32
4
number of bits in the IPA address space supported by KVM.
8
bootloader[] code calls this hook; bootloader_aarch64[] does not.
9
Since we don't have a current need for this functionality, just
10
assert that we don't try to use it. If it's needed we'll add
11
it later.
12
5
6
This capability needs to be known to create the VM with a
7
specific IPA max size (kvm_type passed along KVM_CREATE_VM ioctl.
8
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
11
Message-id: 20190304101339.25970-6-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-id: 20180313153458.26822-3-peter.maydell@linaro.org
16
---
13
---
17
hw/arm/boot.c | 7 +++++++
14
target/arm/kvm_arm.h | 13 +++++++++++++
18
1 file changed, 7 insertions(+)
15
target/arm/kvm.c | 10 ++++++++++
16
2 files changed, 23 insertions(+)
19
17
20
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
18
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/arm/boot.c
20
--- a/target/arm/kvm_arm.h
23
+++ b/hw/arm/boot.c
21
+++ b/target/arm/kvm_arm.h
24
@@ -XXX,XX +XXX,XX @@ static void do_cpu_reset(void *opaque)
22
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf);
25
} else {
23
*/
26
env->pstate = PSTATE_MODE_EL1h;
24
void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu);
27
}
25
28
+ /* AArch64 kernels never boot in secure mode */
26
+/**
29
+ assert(!info->secure_boot);
27
+ * kvm_arm_get_max_vm_ipa_size - Returns the number of bits in the
30
+ /* This hook is only supported for AArch32 currently:
28
+ * IPA address space supported by KVM
31
+ * bootloader_aarch64[] will not call the hook, and
29
+ *
32
+ * the code above has already dropped us into EL2 or EL1.
30
+ * @ms: Machine state handle
33
+ */
31
+ */
34
+ assert(!info->secure_board_setup);
32
+int kvm_arm_get_max_vm_ipa_size(MachineState *ms);
35
}
33
+
36
34
/**
37
/* Set to non-secure if not a secure boot */
35
* kvm_arm_sync_mpstate_to_kvm
36
* @cpu: ARMCPU
37
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
38
cpu->host_cpu_probe_failed = true;
39
}
40
41
+static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
42
+{
43
+ return -ENOENT;
44
+}
45
+
46
static inline int kvm_arm_vgic_probe(void)
47
{
48
return 0;
49
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/target/arm/kvm.c
52
+++ b/target/arm/kvm.c
53
@@ -XXX,XX +XXX,XX @@
54
#include "qemu/error-report.h"
55
#include "sysemu/sysemu.h"
56
#include "sysemu/kvm.h"
57
+#include "sysemu/kvm_int.h"
58
#include "kvm_arm.h"
59
#include "cpu.h"
60
#include "trace.h"
61
@@ -XXX,XX +XXX,XX @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu)
62
env->features = arm_host_cpu_features.features;
63
}
64
65
+int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
66
+{
67
+ KVMState *s = KVM_STATE(ms->accelerator);
68
+ int ret;
69
+
70
+ ret = kvm_check_extension(s, KVM_CAP_ARM_VM_IPA_SIZE);
71
+ return ret > 0 ? ret : 40;
72
+}
73
+
74
int kvm_arch_init(MachineState *ms, KVMState *s)
75
{
76
/* For ARM interrupt delivery is always asynchronous,
38
--
77
--
39
2.16.2
78
2.20.1
40
79
41
80
diff view generated by jsdifflib
1
For the rpi1 and 2 we want to boot the Linux kernel via some
1
From: Eric Auger <eric.auger@redhat.com>
2
custom setup code that makes sure that the SMC instruction
3
acts as a no-op, because it's used for cache maintenance.
4
The rpi3 boots AArch64 kernels, which don't need SMC for
5
cache maintenance and always expect to be booted non-secure.
6
Don't fill in the aarch32-specific parts of the binfo struct.
7
2
3
The machine RAM attributes will need to be analyzed during the
4
configure_accelerator() process. especially kvm_type() arm64
5
machine callback will use them to know how many IPA/GPA bits are
6
needed to model the whole RAM range. So let's assign those machine
7
state fields before calling configure_accelerator.
8
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
12
Message-id: 20190304101339.25970-7-eric.auger@redhat.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20180313153458.26822-2-peter.maydell@linaro.org
12
---
14
---
13
hw/arm/raspi.c | 17 +++++++++++++----
15
vl.c | 6 +++---
14
1 file changed, 13 insertions(+), 4 deletions(-)
16
1 file changed, 3 insertions(+), 3 deletions(-)
15
17
16
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
18
diff --git a/vl.c b/vl.c
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/raspi.c
20
--- a/vl.c
19
+++ b/hw/arm/raspi.c
21
+++ b/vl.c
20
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
22
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
21
binfo.board_id = raspi_boardid[version];
23
machine_opts = qemu_get_machine_opts();
22
binfo.ram_size = ram_size;
24
qemu_opt_foreach(machine_opts, machine_set_property, current_machine,
23
binfo.nb_cpus = smp_cpus;
25
&error_fatal);
24
- binfo.board_setup_addr = BOARDSETUP_ADDR;
26
+ current_machine->ram_size = ram_size;
25
- binfo.write_board_setup = write_board_setup;
27
+ current_machine->maxram_size = maxram_size;
26
- binfo.secure_board_setup = true;
28
+ current_machine->ram_slots = ram_slots;
27
- binfo.secure_boot = true;
29
28
+
30
configure_accelerator(current_machine, argv[0]);
29
+ if (version <= 2) {
31
30
+ /* The rpi1 and 2 require some custom setup code to run in Secure
32
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
31
+ * mode before booting a kernel (to set up the SMC vectors so
33
replay_checkpoint(CHECKPOINT_INIT);
32
+ * that we get a no-op SMC; this is used by Linux to call the
34
qdev_machine_init();
33
+ * firmware for some cache maintenance operations.
35
34
+ * The rpi3 doesn't need this.
36
- current_machine->ram_size = ram_size;
35
+ */
37
- current_machine->maxram_size = maxram_size;
36
+ binfo.board_setup_addr = BOARDSETUP_ADDR;
38
- current_machine->ram_slots = ram_slots;
37
+ binfo.write_board_setup = write_board_setup;
39
current_machine->boot_order = boot_order;
38
+ binfo.secure_board_setup = true;
40
39
+ binfo.secure_boot = true;
41
/* parse features once if machine provides default cpu_type */
40
+ }
41
42
/* Pi2 and Pi3 requires SMP setup */
43
if (version >= 2) {
44
--
42
--
45
2.16.2
43
2.20.1
46
44
47
45
diff view generated by jsdifflib
1
The BCM2837 sets the Aff1 field of the MPIDR affinity values for the
1
From: Eric Auger <eric.auger@redhat.com>
2
CPUs to 0, whereas the BCM2836 uses 0xf. Set this correctly, as it
3
is required for Linux to boot.
4
2
3
Up to now the memory map has been static and the high IO region
4
base has always been 256GiB.
5
6
This patch modifies the virt_set_memmap() function, which freezes
7
the memory map, so that the high IO range base becomes floating,
8
located after the initial RAM and the device memory.
9
10
The function computes
11
- the base of the device memory,
12
- the size of the device memory,
13
- the high IO region base
14
- the highest GPA used in the memory map.
15
16
Entries of the high IO region are assigned a base address. The
17
device memory is initialized.
18
19
The highest GPA used in the memory map will be used at VM creation
20
to choose the requested IPA size.
21
22
Setting all the existing highmem IO regions beyond the RAM
23
allows to have a single contiguous RAM region (initial RAM and
24
possible hotpluggable device memory). That way we do not need
25
to do invasive changes in the EDK2 FW to support a dynamic
26
RAM base.
27
28
Still the user cannot request an initial RAM size greater than 255GB.
29
30
Signed-off-by: Eric Auger <eric.auger@redhat.com>
31
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
32
Message-id: 20190304101339.25970-8-eric.auger@redhat.com
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20180313153458.26822-8-peter.maydell@linaro.org
9
---
34
---
10
hw/arm/bcm2836.c | 11 +++++++----
35
include/hw/arm/virt.h | 1 +
11
1 file changed, 7 insertions(+), 4 deletions(-)
36
hw/arm/virt.c | 52 ++++++++++++++++++++++++++++++++++++++-----
37
2 files changed, 47 insertions(+), 6 deletions(-)
12
38
13
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
39
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
14
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/bcm2836.c
41
--- a/include/hw/arm/virt.h
16
+++ b/hw/arm/bcm2836.c
42
+++ b/include/hw/arm/virt.h
43
@@ -XXX,XX +XXX,XX @@ typedef struct {
44
uint32_t msi_phandle;
45
uint32_t iommu_phandle;
46
int psci_conduit;
47
+ hwaddr highest_gpa;
48
} VirtMachineState;
49
50
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
51
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/arm/virt.c
54
+++ b/hw/arm/virt.c
17
@@ -XXX,XX +XXX,XX @@
55
@@ -XXX,XX +XXX,XX @@
18
56
#include "qapi/visitor.h"
19
struct BCM283XInfo {
57
#include "standard-headers/linux/input.h"
20
const char *name;
58
#include "hw/arm/smmuv3.h"
21
+ int clusterid;
59
+#include "hw/acpi/acpi.h"
60
61
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
62
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
63
@@ -XXX,XX +XXX,XX @@
64
* of a terabyte of RAM will be doing it on a host with more than a
65
* terabyte of physical address space.)
66
*/
67
-#define RAMLIMIT_GB 255
68
-#define RAMLIMIT_BYTES (RAMLIMIT_GB * 1024ULL * 1024 * 1024)
69
+#define LEGACY_RAMLIMIT_GB 255
70
+#define LEGACY_RAMLIMIT_BYTES (LEGACY_RAMLIMIT_GB * GiB)
71
72
/* Addresses and sizes of our components.
73
* 0..128MB is space for a flash device so we can run bootrom code such as UEFI.
74
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry base_memmap[] = {
75
[VIRT_PCIE_MMIO] = { 0x10000000, 0x2eff0000 },
76
[VIRT_PCIE_PIO] = { 0x3eff0000, 0x00010000 },
77
[VIRT_PCIE_ECAM] = { 0x3f000000, 0x01000000 },
78
- [VIRT_MEM] = { 0x40000000, RAMLIMIT_BYTES },
79
+ /* Actual RAM size depends on initial RAM and device memory settings */
80
+ [VIRT_MEM] = { GiB, LEGACY_RAMLIMIT_BYTES },
22
};
81
};
23
82
24
static const BCM283XInfo bcm283x_socs[] = {
83
/*
25
{
84
@@ -XXX,XX +XXX,XX @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx)
26
.name = TYPE_BCM2836,
85
27
+ .clusterid = 0xf,
86
static void virt_set_memmap(VirtMachineState *vms)
28
},
29
{
30
.name = TYPE_BCM2837,
31
+ .clusterid = 0x0,
32
},
33
};
34
35
@@ -XXX,XX +XXX,XX @@ static void bcm2836_init(Object *obj)
36
static void bcm2836_realize(DeviceState *dev, Error **errp)
37
{
87
{
38
BCM283XState *s = BCM283X(dev);
88
- hwaddr base;
39
+ BCM283XClass *bc = BCM283X_GET_CLASS(dev);
89
+ MachineState *ms = MACHINE(vms);
40
+ const BCM283XInfo *info = bc->info;
90
+ hwaddr base, device_memory_base, device_memory_size;
41
Object *obj;
91
int i;
42
Error *err = NULL;
92
43
int n;
93
vms->memmap = extended_memmap;
44
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
94
@@ -XXX,XX +XXX,XX @@ static void virt_set_memmap(VirtMachineState *vms)
45
qdev_get_gpio_in_named(DEVICE(&s->control), "gpu-fiq", 0));
95
vms->memmap[i] = base_memmap[i];
46
96
}
47
for (n = 0; n < BCM283X_NCPUS; n++) {
97
48
- /* Mirror bcm2836, which has clusterid set to 0xf
98
- base = 256 * GiB; /* Top of the legacy initial RAM region */
49
- * TODO: this should be converted to a property of ARM_CPU
99
+ if (ms->ram_slots > ACPI_MAX_RAM_SLOTS) {
50
- */
100
+ error_report("unsupported number of memory slots: %"PRIu64,
51
- s->cpus[n].mp_affinity = 0xF00 | n;
101
+ ms->ram_slots);
52
+ /* TODO: this should be converted to a property of ARM_CPU */
102
+ exit(EXIT_FAILURE);
53
+ s->cpus[n].mp_affinity = (info->clusterid << 8) | n;
103
+ }
54
104
+
55
/* set periphbase/CBAR value for CPU-local registers */
105
+ /*
56
object_property_set_int(OBJECT(&s->cpus[n]),
106
+ * We compute the base of the high IO region depending on the
107
+ * amount of initial and device memory. The device memory start/size
108
+ * is aligned on 1GiB. We never put the high IO region below 256GiB
109
+ * so that if maxram_size is < 255GiB we keep the legacy memory map.
110
+ * The device region size assumes 1GiB page max alignment per slot.
111
+ */
112
+ device_memory_base =
113
+ ROUND_UP(vms->memmap[VIRT_MEM].base + ms->ram_size, GiB);
114
+ device_memory_size = ms->maxram_size - ms->ram_size + ms->ram_slots * GiB;
115
+
116
+ /* Base address of the high IO region */
117
+ base = device_memory_base + ROUND_UP(device_memory_size, GiB);
118
+ if (base < device_memory_base) {
119
+ error_report("maxmem/slots too huge");
120
+ exit(EXIT_FAILURE);
121
+ }
122
+ if (base < vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES) {
123
+ base = vms->memmap[VIRT_MEM].base + LEGACY_RAMLIMIT_BYTES;
124
+ }
125
126
for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) {
127
hwaddr size = extended_memmap[i].size;
128
@@ -XXX,XX +XXX,XX @@ static void virt_set_memmap(VirtMachineState *vms)
129
vms->memmap[i].size = size;
130
base += size;
131
}
132
+ vms->highest_gpa = base - 1;
133
+ if (device_memory_size > 0) {
134
+ ms->device_memory = g_malloc0(sizeof(*ms->device_memory));
135
+ ms->device_memory->base = device_memory_base;
136
+ memory_region_init(&ms->device_memory->mr, OBJECT(vms),
137
+ "device-memory", device_memory_size);
138
+ }
139
}
140
141
static void machvirt_init(MachineState *machine)
142
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
143
vms->smp_cpus = smp_cpus;
144
145
if (machine->ram_size > vms->memmap[VIRT_MEM].size) {
146
- error_report("mach-virt: cannot model more than %dGB RAM", RAMLIMIT_GB);
147
+ error_report("mach-virt: cannot model more than %dGB RAM",
148
+ LEGACY_RAMLIMIT_GB);
149
exit(1);
150
}
151
152
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
153
memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
154
machine->ram_size);
155
memory_region_add_subregion(sysmem, vms->memmap[VIRT_MEM].base, ram);
156
+ if (machine->device_memory) {
157
+ memory_region_add_subregion(sysmem, machine->device_memory->base,
158
+ &machine->device_memory->mr);
159
+ }
160
161
create_flash(vms, sysmem, secure_sysmem ? secure_sysmem : sysmem);
162
57
--
163
--
58
2.16.2
164
2.20.1
59
165
60
166
diff view generated by jsdifflib
1
The raspi3 has AArch64 CPUs, which means that our smpboot
1
From: Eric Auger <eric.auger@redhat.com>
2
code for keeping the secondary CPUs in a pen needs to have
3
a version for A64 as well as A32. Without this, the
4
secondary CPUs go into an infinite loop of taking undefined
5
instruction exceptions.
6
2
3
This patch implements the machine class kvm_type() callback.
4
It returns the number of bits requested to implement the whole GPA
5
range including the RAM and IO regions located beyond.
6
The returned value is passed though the KVM_CREATE_VM ioctl and
7
this allows KVM to set the stage2 tables dynamically.
8
9
To compute the highest GPA used in the memory map, kvm_type()
10
must freeze the memory map by calling virt_set_memmap().
11
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
14
Message-id: 20190304101339.25970-9-eric.auger@redhat.com
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20180313153458.26822-10-peter.maydell@linaro.org
10
---
16
---
11
hw/arm/raspi.c | 41 ++++++++++++++++++++++++++++++++++++++++-
17
hw/arm/virt.c | 39 ++++++++++++++++++++++++++++++++++++++-
12
1 file changed, 40 insertions(+), 1 deletion(-)
18
1 file changed, 38 insertions(+), 1 deletion(-)
13
19
14
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
20
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/raspi.c
22
--- a/hw/arm/virt.c
17
+++ b/hw/arm/raspi.c
23
+++ b/hw/arm/virt.c
18
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
19
#define BOARDSETUP_ADDR (MVBAR_ADDR + 0x20) /* board setup code */
25
bool firmware_loaded = bios_name || drive_get(IF_PFLASH, 0, 0);
20
#define FIRMWARE_ADDR_2 0x8000 /* Pi 2 loads kernel.img here by default */
26
bool aarch64 = true;
21
#define FIRMWARE_ADDR_3 0x80000 /* Pi 3 loads kernel.img here by default */
27
22
+#define SPINTABLE_ADDR 0xd8 /* Pi 3 bootloader spintable */
28
- virt_set_memmap(vms);
23
29
+ /*
24
/* Table of Linux board IDs for different Pi versions */
30
+ * In accelerated mode, the memory map is computed earlier in kvm_type()
25
static const int raspi_boardid[] = {[1] = 0xc42, [2] = 0xc43, [3] = 0xc44};
31
+ * to create a VM with the right number of IPA bits.
26
@@ -XXX,XX +XXX,XX @@ static void write_smpboot(ARMCPU *cpu, const struct arm_boot_info *info)
32
+ */
27
info->smp_loader_start);
33
+ if (!vms->memmap) {
34
+ virt_set_memmap(vms);
35
+ }
36
37
/* We can probe only here because during property set
38
* KVM is not available yet
39
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
40
return NULL;
28
}
41
}
29
42
30
+static void write_smpboot64(ARMCPU *cpu, const struct arm_boot_info *info)
43
+/*
44
+ * for arm64 kvm_type [7-0] encodes the requested number of bits
45
+ * in the IPA address space
46
+ */
47
+static int virt_kvm_type(MachineState *ms, const char *type_str)
31
+{
48
+{
32
+ /* Unlike the AArch32 version we don't need to call the board setup hook.
49
+ VirtMachineState *vms = VIRT_MACHINE(ms);
33
+ * The mechanism for doing the spin-table is also entirely different.
50
+ int max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms);
34
+ * We must have four 64-bit fields at absolute addresses
51
+ int requested_pa_size;
35
+ * 0xd8, 0xe0, 0xe8, 0xf0 in RAM, which are the flag variables for
52
+
36
+ * our CPUs, and which we must ensure are zero initialized before
53
+ /* we freeze the memory map to compute the highest gpa */
37
+ * the primary CPU goes into the kernel. We put these variables inside
54
+ virt_set_memmap(vms);
38
+ * a rom blob, so that the reset for ROM contents zeroes them for us.
55
+
56
+ requested_pa_size = 64 - clz64(vms->highest_gpa);
57
+
58
+ if (requested_pa_size > max_vm_pa_size) {
59
+ error_report("-m and ,maxmem option values "
60
+ "require an IPA range (%d bits) larger than "
61
+ "the one supported by the host (%d bits)",
62
+ requested_pa_size, max_vm_pa_size);
63
+ exit(1);
64
+ }
65
+ /*
66
+ * By default we return 0 which corresponds to an implicit legacy
67
+ * 40b IPA setting. Otherwise we return the actual requested PA
68
+ * logsize
39
+ */
69
+ */
40
+ static const uint32_t smpboot[] = {
70
+ return requested_pa_size > 40 ? requested_pa_size : 0;
41
+ 0xd2801b05, /* mov x5, 0xd8 */
42
+ 0xd53800a6, /* mrs x6, mpidr_el1 */
43
+ 0x924004c6, /* and x6, x6, #0x3 */
44
+ 0xd503205f, /* spin: wfe */
45
+ 0xf86678a4, /* ldr x4, [x5,x6,lsl #3] */
46
+ 0xb4ffffc4, /* cbz x4, spin */
47
+ 0xd2800000, /* mov x0, #0x0 */
48
+ 0xd2800001, /* mov x1, #0x0 */
49
+ 0xd2800002, /* mov x2, #0x0 */
50
+ 0xd2800003, /* mov x3, #0x0 */
51
+ 0xd61f0080, /* br x4 */
52
+ };
53
+
54
+ static const uint64_t spintables[] = {
55
+ 0, 0, 0, 0
56
+ };
57
+
58
+ rom_add_blob_fixed("raspi_smpboot", smpboot, sizeof(smpboot),
59
+ info->smp_loader_start);
60
+ rom_add_blob_fixed("raspi_spintables", spintables, sizeof(spintables),
61
+ SPINTABLE_ADDR);
62
+}
71
+}
63
+
72
+
64
static void write_board_setup(ARMCPU *cpu, const struct arm_boot_info *info)
73
static void virt_machine_class_init(ObjectClass *oc, void *data)
65
{
74
{
66
arm_write_secure_board_setup_dummy_smc(cpu, info, MVBAR_ADDR);
75
MachineClass *mc = MACHINE_CLASS(oc);
67
@@ -XXX,XX +XXX,XX @@ static void setup_boot(MachineState *machine, int version, size_t ram_size)
76
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
68
/* Pi2 and Pi3 requires SMP setup */
77
mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
69
if (version >= 2) {
78
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a15");
70
binfo.smp_loader_start = SMPBOOT_ADDR;
79
mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
71
- binfo.write_secondary_boot = write_smpboot;
80
+ mc->kvm_type = virt_kvm_type;
72
+ if (version == 2) {
81
assert(!mc->get_hotplug_handler);
73
+ binfo.write_secondary_boot = write_smpboot;
82
mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
74
+ } else {
83
hc->plug = virt_machine_device_plug_cb;
75
+ binfo.write_secondary_boot = write_smpboot64;
76
+ }
77
binfo.secondary_cpu_reset_hook = reset_secondary;
78
}
79
80
--
84
--
81
2.16.2
85
2.20.1
82
86
83
87
diff view generated by jsdifflib
1
From: Wei Huang <wei@redhat.com>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
For guest kernel that supports KASLR, the load address can change every
3
We are about to allow the memory map to grow beyond 1TB and
4
time when guest VM runs. To find the physical base address correctly,
4
potentially overshoot the VCPU AA64MMFR0.PARANGE.
5
current QEMU dump searches VMCOREINFO for the string "NUMBER(phys_base)=".
6
However this string pattern is only available on x86_64. AArch64 uses a
7
different field, called "NUMBER(PHYS_OFFSET)=". This patch makes sure
8
QEMU dump uses the correct string on AArch64.
9
5
10
Signed-off-by: Wei Huang <wei@redhat.com>
6
In aarch64 mode and when highmem is set, let's check the VCPU
11
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
7
PA range is sufficient to address the highest GPA of the memory
12
Message-id: 1520615003-20869-1-git-send-email-wei@redhat.com
8
map.
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
12
Message-id: 20190304101339.25970-10-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
14
---
15
dump.c | 14 +++++++++++---
15
hw/arm/virt.c | 17 +++++++++++++++++
16
1 file changed, 11 insertions(+), 3 deletions(-)
16
1 file changed, 17 insertions(+)
17
17
18
diff --git a/dump.c b/dump.c
18
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/dump.c
20
--- a/hw/arm/virt.c
21
+++ b/dump.c
21
+++ b/hw/arm/virt.c
22
@@ -XXX,XX +XXX,XX @@ static void vmcoreinfo_update_phys_base(DumpState *s)
22
@@ -XXX,XX +XXX,XX @@
23
23
#include "standard-headers/linux/input.h"
24
lines = g_strsplit((char *)vmci, "\n", -1);
24
#include "hw/arm/smmuv3.h"
25
for (i = 0; lines[i]; i++) {
25
#include "hw/acpi/acpi.h"
26
- if (g_str_has_prefix(lines[i], "NUMBER(phys_base)=")) {
26
+#include "target/arm/internals.h"
27
- if (qemu_strtou64(lines[i] + 18, NULL, 16,
27
28
+ const char *prefix = NULL;
28
#define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \
29
static void virt_##major##_##minor##_class_init(ObjectClass *oc, \
30
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
31
fdt_add_timer_nodes(vms);
32
fdt_add_cpu_nodes(vms);
33
34
+ if (!kvm_enabled()) {
35
+ ARMCPU *cpu = ARM_CPU(first_cpu);
36
+ bool aarch64 = object_property_get_bool(OBJECT(cpu), "aarch64", NULL);
29
+
37
+
30
+ if (s->dump_info.d_machine == EM_X86_64) {
38
+ if (aarch64 && vms->highmem) {
31
+ prefix = "NUMBER(phys_base)=";
39
+ int requested_pa_size, pamax = arm_pamax(cpu);
32
+ } else if (s->dump_info.d_machine == EM_AARCH64) {
40
+
33
+ prefix = "NUMBER(PHYS_OFFSET)=";
41
+ requested_pa_size = 64 - clz64(vms->highest_gpa);
42
+ if (pamax < requested_pa_size) {
43
+ error_report("VCPU supports less PA bits (%d) than requested "
44
+ "by the memory map (%d)", pamax, requested_pa_size);
45
+ exit(1);
46
+ }
34
+ }
47
+ }
48
+ }
35
+
49
+
36
+ if (prefix && g_str_has_prefix(lines[i], prefix)) {
50
memory_region_allocate_system_memory(ram, NULL, "mach-virt.ram",
37
+ if (qemu_strtou64(lines[i] + strlen(prefix), NULL, 16,
51
machine->ram_size);
38
&phys_base) < 0) {
52
memory_region_add_subregion(sysmem, vms->memmap[VIRT_MEM].base, ram);
39
- warn_report("Failed to read NUMBER(phys_base)=");
40
+ warn_report("Failed to read %s", prefix);
41
} else {
42
s->dump_info.phys_base = phys_base;
43
}
44
--
53
--
45
2.16.2
54
2.20.1
46
55
47
56
diff view generated by jsdifflib
1
Now we have separate types for BCM2386 and BCM2387, we might as well
1
From: Eric Auger <eric.auger@redhat.com>
2
just hard-code the CPU type they use rather than having it passed
3
through as an object property. This then lets us put the initialization
4
of the CPU object in init rather than realize.
5
2
6
Note that this change means that it's no longer possible on
3
Now we have the extended memory map (high IO regions beyond the
7
the command line to use -cpu to ask for a different kind of
4
scalable RAM) and dynamic IPA range support at KVM/ARM level
8
CPU than the SoC supports. This was never a supported thing to
5
we can bump the legacy 255GB initial RAM limit. The actual maximum
9
do anyway; we were just not sanity-checking the command line.
6
RAM size now depends on the physical CPU and host kernel, in
7
accelerated mode. In TCG mode, it depends on the VCPU
8
AA64MMFR0.PARANGE.
10
9
11
This does require us to only build the bcm2837 object on
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
12
TARGET_AARCH64 configs, since otherwise it won't instantiate
11
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
13
due to the missing cortex-a53 device and "make check" will fail.
12
Message-id: 20190304101339.25970-11-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/arm/virt.c | 21 +--------------------
16
1 file changed, 1 insertion(+), 20 deletions(-)
14
17
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
16
Reviewed-by: Andrew Baumann <Andrew.Baumann@microsoft.com>
17
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
18
Message-id: 20180313153458.26822-9-peter.maydell@linaro.org
19
---
20
hw/arm/bcm2836.c | 24 +++++++++++++++---------
21
hw/arm/raspi.c | 2 --
22
2 files changed, 15 insertions(+), 11 deletions(-)
23
24
diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c
25
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/arm/bcm2836.c
20
--- a/hw/arm/virt.c
27
+++ b/hw/arm/bcm2836.c
21
+++ b/hw/arm/virt.c
28
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@
29
23
30
struct BCM283XInfo {
24
#define PLATFORM_BUS_NUM_IRQS 64
31
const char *name;
25
32
+ const char *cpu_type;
26
-/* RAM limit in GB. Since VIRT_MEM starts at the 1GB mark, this means
33
int clusterid;
27
- * RAM can go up to the 256GB mark, leaving 256GB of the physical
34
};
28
- * address space unallocated and free for future use between 256G and 512G.
35
29
- * If we need to provide more RAM to VMs in the future then we need to:
36
static const BCM283XInfo bcm283x_socs[] = {
30
- * * allocate a second bank of RAM starting at 2TB and working up
37
{
31
- * * fix the DT and ACPI table generation code in QEMU to correctly
38
.name = TYPE_BCM2836,
32
- * report two split lumps of RAM to the guest
39
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"),
33
- * * fix KVM in the host kernel to allow guests with >40 bit address spaces
40
.clusterid = 0xf,
34
- * (We don't want to fill all the way up to 512GB with RAM because
41
},
35
- * we might want it for non-RAM purposes later. Conversely it seems
42
+#ifdef TARGET_AARCH64
36
- * reasonable to assume that anybody configuring a VM with a quarter
43
{
37
- * of a terabyte of RAM will be doing it on a host with more than a
44
.name = TYPE_BCM2837,
38
- * terabyte of physical address space.)
45
+ .cpu_type = ARM_CPU_TYPE_NAME("cortex-a53"),
39
- */
46
.clusterid = 0x0,
40
+/* Legacy RAM limit in GB (< version 4.0) */
47
},
41
#define LEGACY_RAMLIMIT_GB 255
48
+#endif
42
#define LEGACY_RAMLIMIT_BYTES (LEGACY_RAMLIMIT_GB * GiB)
49
};
43
50
44
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
51
static void bcm2836_init(Object *obj)
45
52
{
46
vms->smp_cpus = smp_cpus;
53
BCM283XState *s = BCM283X(obj);
47
54
+ BCM283XClass *bc = BCM283X_GET_CLASS(obj);
48
- if (machine->ram_size > vms->memmap[VIRT_MEM].size) {
55
+ const BCM283XInfo *info = bc->info;
49
- error_report("mach-virt: cannot model more than %dGB RAM",
56
+ int n;
50
- LEGACY_RAMLIMIT_GB);
57
+
51
- exit(1);
58
+ for (n = 0; n < BCM283X_NCPUS; n++) {
59
+ object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
60
+ info->cpu_type);
61
+ object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
62
+ &error_abort);
63
+ }
64
65
object_initialize(&s->control, sizeof(s->control), TYPE_BCM2836_CONTROL);
66
object_property_add_child(obj, "control", OBJECT(&s->control), NULL);
67
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
68
69
/* common peripherals from bcm2835 */
70
71
- obj = OBJECT(dev);
72
- for (n = 0; n < BCM283X_NCPUS; n++) {
73
- object_initialize(&s->cpus[n], sizeof(s->cpus[n]),
74
- s->cpu_type);
75
- object_property_add_child(obj, "cpu[*]", OBJECT(&s->cpus[n]),
76
- &error_abort);
77
- }
52
- }
78
-
53
-
79
obj = object_property_get_link(OBJECT(dev), "ram", &err);
54
if (vms->virt && kvm_enabled()) {
80
if (obj == NULL) {
55
error_report("mach-virt: KVM does not support providing "
81
error_setg(errp, "%s: required ram link not found: %s",
56
"Virtualization extensions to the guest CPU");
82
@@ -XXX,XX +XXX,XX @@ static void bcm2836_realize(DeviceState *dev, Error **errp)
83
}
84
85
static Property bcm2836_props[] = {
86
- DEFINE_PROP_STRING("cpu-type", BCM283XState, cpu_type),
87
DEFINE_PROP_UINT32("enabled-cpus", BCM283XState, enabled_cpus,
88
BCM283X_NCPUS),
89
DEFINE_PROP_END_OF_LIST()
90
diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/hw/arm/raspi.c
93
+++ b/hw/arm/raspi.c
94
@@ -XXX,XX +XXX,XX @@ static void raspi_init(MachineState *machine, int version)
95
/* Setup the SOC */
96
object_property_add_const_link(OBJECT(&s->soc), "ram", OBJECT(&s->ram),
97
&error_abort);
98
- object_property_set_str(OBJECT(&s->soc), machine->cpu_type, "cpu-type",
99
- &error_abort);
100
object_property_set_int(OBJECT(&s->soc), smp_cpus, "enabled-cpus",
101
&error_abort);
102
int board_rev = version == 3 ? 0xa02082 : 0xa21041;
103
--
57
--
104
2.16.2
58
2.20.1
105
59
106
60
diff view generated by jsdifflib
New patch
1
1
From: Michel Heily <michelheily@gmail.com>
2
3
Implement the watchdog timer for the stellaris boards.
4
This device is a close variant of the CMSDK APB watchdog
5
device, so we can model it by subclassing that device and
6
tweaking the behaviour of some of its registers.
7
8
Signed-off-by: Michel Heily <michelheily@gmail.com>
9
Reviewed-by: Peter Maydell <petser.maydell@linaro.org>
10
[PMM: rewrote commit message, fixed a few checkpatch nits,
11
added comment giving the URL of the spec for the Stellaris
12
variant of the watchdog device]
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
include/hw/watchdog/cmsdk-apb-watchdog.h | 8 +++
16
hw/arm/stellaris.c | 22 ++++++-
17
hw/watchdog/cmsdk-apb-watchdog.c | 74 +++++++++++++++++++++++-
18
3 files changed, 100 insertions(+), 4 deletions(-)
19
20
diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/watchdog/cmsdk-apb-watchdog.h
23
+++ b/include/hw/watchdog/cmsdk-apb-watchdog.h
24
@@ -XXX,XX +XXX,XX @@
25
#define CMSDK_APB_WATCHDOG(obj) OBJECT_CHECK(CMSDKAPBWatchdog, (obj), \
26
TYPE_CMSDK_APB_WATCHDOG)
27
28
+/*
29
+ * This shares the same struct (and cast macro) as the base
30
+ * cmsdk-apb-watchdog device.
31
+ */
32
+#define TYPE_LUMINARY_WATCHDOG "luminary-watchdog"
33
+
34
typedef struct CMSDKAPBWatchdog {
35
/*< private >*/
36
SysBusDevice parent_obj;
37
@@ -XXX,XX +XXX,XX @@ typedef struct CMSDKAPBWatchdog {
38
MemoryRegion iomem;
39
qemu_irq wdogint;
40
uint32_t wdogclk_frq;
41
+ bool is_luminary;
42
struct ptimer_state *timer;
43
44
uint32_t control;
45
@@ -XXX,XX +XXX,XX @@ typedef struct CMSDKAPBWatchdog {
46
uint32_t itcr;
47
uint32_t itop;
48
uint32_t resetstatus;
49
+ const uint32_t *id;
50
} CMSDKAPBWatchdog;
51
52
#endif
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/arm/stellaris.c
56
+++ b/hw/arm/stellaris.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "sysemu/sysemu.h"
59
#include "hw/arm/armv7m.h"
60
#include "hw/char/pl011.h"
61
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
62
#include "hw/misc/unimp.h"
63
#include "cpu.h"
64
65
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
66
* Stellaris LM3S6965 Microcontroller Data Sheet (rev I)
67
* http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
68
*
69
- * 40000000 wdtimer (unimplemented)
70
+ * 40000000 wdtimer
71
* 40002000 i2c (unimplemented)
72
* 40004000 GPIO
73
* 40005000 GPIO
74
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
75
stellaris_sys_init(0x400fe000, qdev_get_gpio_in(nvic, 28),
76
board, nd_table[0].macaddr.a);
77
78
+
79
+ if (board->dc1 & (1 << 3)) { /* watchdog present */
80
+ dev = qdev_create(NULL, TYPE_LUMINARY_WATCHDOG);
81
+
82
+ /* system_clock_scale is valid now */
83
+ uint32_t mainclk = NANOSECONDS_PER_SECOND / system_clock_scale;
84
+ qdev_prop_set_uint32(dev, "wdogclk-frq", mainclk);
85
+
86
+ qdev_init_nofail(dev);
87
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev),
88
+ 0,
89
+ 0x40000000u);
90
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev),
91
+ 0,
92
+ qdev_get_gpio_in(nvic, 18));
93
+ }
94
+
95
+
96
for (i = 0; i < 7; i++) {
97
if (board->dc4 & (1 << i)) {
98
gpio_dev[i] = sysbus_create_simple("pl061_luminary", gpio_addr[i],
99
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
100
/* Add dummy regions for the devices we don't implement yet,
101
* so guest accesses don't cause unlogged crashes.
102
*/
103
- create_unimplemented_device("wdtimer", 0x40000000, 0x1000);
104
create_unimplemented_device("i2c-0", 0x40002000, 0x1000);
105
create_unimplemented_device("i2c-2", 0x40021000, 0x1000);
106
create_unimplemented_device("PWM", 0x40028000, 0x1000);
107
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/hw/watchdog/cmsdk-apb-watchdog.c
110
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
111
@@ -XXX,XX +XXX,XX @@
112
* System Design Kit (CMSDK) and documented in the Cortex-M System
113
* Design Kit Technical Reference Manual (ARM DDI0479C):
114
* https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
115
+ *
116
+ * We also support the variant of this device found in the TI
117
+ * Stellaris/Luminary boards and documented in:
118
+ * http://www.ti.com/lit/ds/symlink/lm3s6965.pdf
119
*/
120
121
#include "qemu/osdep.h"
122
@@ -XXX,XX +XXX,XX @@ REG32(WDOGINTCLR, 0xc)
123
REG32(WDOGRIS, 0x10)
124
FIELD(WDOGRIS, INT, 0, 1)
125
REG32(WDOGMIS, 0x14)
126
+REG32(WDOGTEST, 0x418) /* only in Stellaris/Luminary version of the device */
127
REG32(WDOGLOCK, 0xc00)
128
#define WDOG_UNLOCK_VALUE 0x1ACCE551
129
REG32(WDOGITCR, 0xf00)
130
@@ -XXX,XX +XXX,XX @@ REG32(CID2, 0xff8)
131
REG32(CID3, 0xffc)
132
133
/* PID/CID values */
134
-static const int watchdog_id[] = {
135
+static const uint32_t cmsdk_apb_watchdog_id[] = {
136
0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
137
0x24, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
138
0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
139
};
140
141
+static const uint32_t luminary_watchdog_id[] = {
142
+ 0x00, 0x00, 0x00, 0x00, /* PID4..PID7 */
143
+ 0x05, 0x18, 0x18, 0x01, /* PID0..PID3 */
144
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
145
+};
146
+
147
static bool cmsdk_apb_watchdog_intstatus(CMSDKAPBWatchdog *s)
148
{
149
/* Return masked interrupt status */
150
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_update(CMSDKAPBWatchdog *s)
151
bool wdogres;
152
153
if (s->itcr) {
154
+ /*
155
+ * Not checking that !s->is_luminary since s->itcr can't be written
156
+ * when s->is_luminary in the first place.
157
+ */
158
wdogint = s->itop & R_WDOGITOP_WDOGINT_MASK;
159
wdogres = s->itop & R_WDOGITOP_WDOGRES_MASK;
160
} else {
161
@@ -XXX,XX +XXX,XX @@ static uint64_t cmsdk_apb_watchdog_read(void *opaque, hwaddr offset,
162
r = s->lock;
163
break;
164
case A_WDOGITCR:
165
+ if (s->is_luminary) {
166
+ goto bad_offset;
167
+ }
168
r = s->itcr;
169
break;
170
case A_PID4 ... A_CID3:
171
- r = watchdog_id[(offset - A_PID4) / 4];
172
+ r = s->id[(offset - A_PID4) / 4];
173
break;
174
case A_WDOGINTCLR:
175
case A_WDOGITOP:
176
+ if (s->is_luminary) {
177
+ goto bad_offset;
178
+ }
179
qemu_log_mask(LOG_GUEST_ERROR,
180
"CMSDK APB watchdog read: read of WO offset %x\n",
181
(int)offset);
182
r = 0;
183
break;
184
+ case A_WDOGTEST:
185
+ if (!s->is_luminary) {
186
+ goto bad_offset;
187
+ }
188
+ qemu_log_mask(LOG_UNIMP,
189
+ "Luminary watchdog read: stall not implemented\n");
190
+ r = 0;
191
+ break;
192
default:
193
+bad_offset:
194
qemu_log_mask(LOG_GUEST_ERROR,
195
"CMSDK APB watchdog read: bad offset %x\n", (int)offset);
196
r = 0;
197
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
198
ptimer_run(s->timer, 0);
199
break;
200
case A_WDOGCONTROL:
201
+ if (s->is_luminary && 0 != (R_WDOGCONTROL_INTEN_MASK & s->control)) {
202
+ /*
203
+ * The Luminary version of this device ignores writes to
204
+ * this register after the guest has enabled interrupts
205
+ * (so they can only be disabled again via reset).
206
+ */
207
+ break;
208
+ }
209
s->control = value & R_WDOGCONTROL_VALID_MASK;
210
cmsdk_apb_watchdog_update(s);
211
break;
212
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
213
s->lock = (value != WDOG_UNLOCK_VALUE);
214
break;
215
case A_WDOGITCR:
216
+ if (s->is_luminary) {
217
+ goto bad_offset;
218
+ }
219
s->itcr = value & R_WDOGITCR_VALID_MASK;
220
cmsdk_apb_watchdog_update(s);
221
break;
222
case A_WDOGITOP:
223
+ if (s->is_luminary) {
224
+ goto bad_offset;
225
+ }
226
s->itop = value & R_WDOGITOP_VALID_MASK;
227
cmsdk_apb_watchdog_update(s);
228
break;
229
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
230
"CMSDK APB watchdog write: write to RO offset 0x%x\n",
231
(int)offset);
232
break;
233
+ case A_WDOGTEST:
234
+ if (!s->is_luminary) {
235
+ goto bad_offset;
236
+ }
237
+ qemu_log_mask(LOG_UNIMP,
238
+ "Luminary watchdog write: stall not implemented\n");
239
+ break;
240
default:
241
+bad_offset:
242
qemu_log_mask(LOG_GUEST_ERROR,
243
"CMSDK APB watchdog write: bad offset 0x%x\n",
244
(int)offset);
245
@@ -XXX,XX +XXX,XX @@ static void cmsdk_apb_watchdog_init(Object *obj)
246
s, "cmsdk-apb-watchdog", 0x1000);
247
sysbus_init_mmio(sbd, &s->iomem);
248
sysbus_init_irq(sbd, &s->wdogint);
249
+
250
+ s->is_luminary = false;
251
+ s->id = cmsdk_apb_watchdog_id;
252
}
253
254
static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
255
@@ -XXX,XX +XXX,XX @@ static const TypeInfo cmsdk_apb_watchdog_info = {
256
.class_init = cmsdk_apb_watchdog_class_init,
257
};
258
259
+static void luminary_watchdog_init(Object *obj)
260
+{
261
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(obj);
262
+
263
+ s->is_luminary = true;
264
+ s->id = luminary_watchdog_id;
265
+}
266
+
267
+static const TypeInfo luminary_watchdog_info = {
268
+ .name = TYPE_LUMINARY_WATCHDOG,
269
+ .parent = TYPE_CMSDK_APB_WATCHDOG,
270
+ .instance_init = luminary_watchdog_init
271
+};
272
+
273
static void cmsdk_apb_watchdog_register_types(void)
274
{
275
type_register_static(&cmsdk_apb_watchdog_info);
276
+ type_register_static(&luminary_watchdog_info);
277
}
278
279
type_init(cmsdk_apb_watchdog_register_types);
280
--
281
2.20.1
282
283
diff view generated by jsdifflib