1
The following changes since commit ad1b4ec39caa5b3f17cbd8160283a03a3dcfe2ae:
1
Less than a day of post-3.0 code review and already enough
2
patches for another pullreq :-)
2
3
3
Merge remote-tracking branch 'remotes/kraxel/tags/input-20180515-pull-request' into staging (2018-05-15 12:50:06 +0100)
4
thanks
5
-- PMM
6
7
The following changes since commit c542a9f9794ec8e0bc3fcf5956d3cc8bce667789:
8
9
Merge remote-tracking branch 'remotes/armbru/tags/pull-tests-2018-08-16' into staging (2018-08-16 09:50:54 +0100)
4
10
5
are available in the Git repository at:
11
are available in the Git repository at:
6
12
7
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180515
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180816
8
14
9
for you to fetch changes up to ae7651804748c6b479d5ae09aeac4edb9c44f76e:
15
for you to fetch changes up to fcf13ca556f462b52956059bf8fa622bc8575edb:
10
16
11
tcg: Optionally log FPU state in TCG -d cpu logging (2018-05-15 14:58:44 +0100)
17
hw/arm/mps2-tz: Replace init_sysbus_child() with sysbus_init_child_obj() (2018-08-16 14:29:58 +0100)
12
18
13
----------------------------------------------------------------
19
----------------------------------------------------------------
14
target-arm queue:
20
target-arm queue:
15
* Fix coverity nit in int_to_float code
21
* Fixes for various bugs in SVE instructions
16
* Don't set Invalid for float-to-int(MAXINT)
22
* Add model of Freescale i.MX6 UltraLite 14x14 EVK Board
17
* Fix fp_status_f16 tininess before rounding
23
* hw/arm: make bitbanded IO optional on ARMv7-M
18
* Add various missing insns from the v8.2-FP16 extension
24
* Add model of Cortex-M0 CPU
19
* Fix sqrt_f16 exception raising
25
* Add support for loading Intel HEX files to the generic loader
20
* sdcard: Correct CRC16 offset in sd_function_switch()
26
* imx_spi: Unset XCH when TX FIFO becomes empty
21
* tcg: Optionally log FPU state in TCG -d cpu logging
27
* aspeed_sdmc: fix various bugs
28
* Fix bugs in Arm FP16 instruction support
29
* Fix aa64 FCADD and FCMLA decode
30
* softfloat: Fix missing inexact for floating-point add
31
* hw/arm/mps2-tz: Replace init_sysbus_child() with sysbus_init_child_obj()
22
32
23
----------------------------------------------------------------
33
----------------------------------------------------------------
24
Alex Bennée (5):
34
Cédric Le Goater (1):
25
fpu/softfloat: int_to_float ensure r fully initialised
35
aspeed: add a max_ram_size property to the memory controller
26
target/arm: Implement FCMP for fp16
27
target/arm: Implement FCSEL for fp16
28
target/arm: Implement FMOV (immediate) for fp16
29
target/arm: Fix sqrt_f16 exception raising
30
36
31
Peter Maydell (3):
37
Jean-Christophe Dubois (3):
32
fpu/softfloat: Don't set Invalid for float-to-int(MAXINT)
38
i.MX6UL: Add i.MX6UL specific CCM device
33
target/arm: Fix fp_status_f16 tininess before rounding
39
i.MX6UL: Add i.MX6UL SOC
34
tcg: Optionally log FPU state in TCG -d cpu logging
40
i.MX6UL: Add Freescale i.MX6 UltraLite 14x14 EVK Board
35
41
36
Philippe Mathieu-Daudé (1):
42
Joel Stanley (5):
37
sdcard: Correct CRC16 offset in sd_function_switch()
43
aspeed_sdmc: Extend number of valid registers
44
aspeed_sdmc: Fix saved values
45
aspeed_sdmc: Set 'cache initial sequence' always true
46
aspeed_sdmc: Init status always idle
47
aspeed_sdmc: Handle ECC training
38
48
39
Richard Henderson (7):
49
Richard Henderson (13):
40
target/arm: Implement FMOV (general) for fp16
50
target/arm: Fix typo in helper_sve_ld1hss_r
41
target/arm: Early exit after unallocated_encoding in disas_fp_int_conv
51
target/arm: Fix sign-extension in sve do_ldr/do_str
42
target/arm: Implement FCVT (scalar, integer) for fp16
52
target/arm: Fix offset for LD1R instructions
43
target/arm: Implement FCVT (scalar, fixed-point) for fp16
53
target/arm: Fix offset scaling for LD_zprr and ST_zprr
44
target/arm: Introduce and use read_fp_hreg
54
target/arm: Reformat integer register dump
45
target/arm: Implement FP data-processing (2 source) for fp16
55
target/arm: Dump SVE state if enabled
46
target/arm: Implement FP data-processing (3 source) for fp16
56
target/arm: Add sve-max-vq cpu property to -cpu max
57
target/arm: Adjust FPCR_MASK for FZ16
58
target/arm: Ignore float_flag_input_denormal from fp_status_f16
59
target/arm: Use fp_status_fp16 for do_fmpa_zpzzz_h
60
target/arm: Use FZ not FZ16 for SVE FCVT single-half and double-half
61
target/arm: Fix aa64 FCADD and FCMLA decode
62
softfloat: Fix missing inexact for floating-point add
47
63
48
include/qemu/log.h | 1 +
64
Stefan Hajnoczi (4):
49
target/arm/helper-a64.h | 2 +
65
hw/arm: make bitbanded IO optional on ARMv7-M
50
target/arm/helper.h | 6 +
66
target/arm: add "cortex-m0" CPU model
51
accel/tcg/cpu-exec.c | 9 +-
67
loader: extract rom_free() function
52
fpu/softfloat.c | 6 +-
68
loader: add rom transaction API
53
hw/sd/sd.c | 2 +-
54
target/arm/cpu.c | 2 +
55
target/arm/helper-a64.c | 10 ++
56
target/arm/helper.c | 38 +++-
57
target/arm/translate-a64.c | 421 ++++++++++++++++++++++++++++++++++++++-------
58
util/log.c | 2 +
59
11 files changed, 428 insertions(+), 71 deletions(-)
60
69
70
Su Hang (2):
71
loader: Implement .hex file loader
72
Add QTest testcase for the Intel Hexadecimal
73
74
Thomas Huth (1):
75
hw/arm/mps2-tz: Replace init_sysbus_child() with sysbus_init_child_obj()
76
77
Trent Piepho (1):
78
imx_spi: Unset XCH when TX FIFO becomes empty
79
80
configure | 4 +
81
hw/arm/Makefile.objs | 1 +
82
hw/misc/Makefile.objs | 1 +
83
tests/Makefile.include | 2 +
84
include/hw/arm/armv7m.h | 2 +
85
include/hw/arm/fsl-imx6ul.h | 339 ++++++++++++++
86
include/hw/loader.h | 31 ++
87
include/hw/misc/aspeed_sdmc.h | 4 +-
88
include/hw/misc/imx6ul_ccm.h | 226 +++++++++
89
target/arm/cpu.h | 5 +-
90
fpu/softfloat.c | 2 +-
91
hw/arm/armv7m.c | 37 +-
92
hw/arm/aspeed.c | 31 ++
93
hw/arm/aspeed_soc.c | 2 +
94
hw/arm/fsl-imx6ul.c | 617 ++++++++++++++++++++++++
95
hw/arm/mcimx6ul-evk.c | 85 ++++
96
hw/arm/mps2-tz.c | 32 +-
97
hw/arm/mps2.c | 1 +
98
hw/arm/msf2-soc.c | 1 +
99
hw/arm/stellaris.c | 1 +
100
hw/arm/stm32f205_soc.c | 1 +
101
hw/core/generic-loader.c | 4 +
102
hw/core/loader.c | 302 +++++++++++-
103
hw/misc/aspeed_sdmc.c | 55 ++-
104
hw/misc/imx6ul_ccm.c | 886 +++++++++++++++++++++++++++++++++++
105
hw/ssi/imx_spi.c | 3 +-
106
linux-user/syscall.c | 19 +-
107
target/arm/cpu.c | 17 +-
108
target/arm/cpu64.c | 29 ++
109
target/arm/helper.c | 18 +-
110
target/arm/sve_helper.c | 4 +-
111
target/arm/translate-a64.c | 120 ++++-
112
target/arm/translate-sve.c | 30 +-
113
tests/hexloader-test.c | 45 ++
114
MAINTAINERS | 6 +
115
default-configs/arm-softmmu.mak | 1 +
116
hw/misc/trace-events | 7 +
117
tests/hex-loader-check-data/test.hex | 18 +
118
38 files changed, 2863 insertions(+), 126 deletions(-)
119
create mode 100644 include/hw/arm/fsl-imx6ul.h
120
create mode 100644 include/hw/misc/imx6ul_ccm.h
121
create mode 100644 hw/arm/fsl-imx6ul.c
122
create mode 100644 hw/arm/mcimx6ul-evk.c
123
create mode 100644 hw/misc/imx6ul_ccm.c
124
create mode 100644 tests/hexloader-test.c
125
create mode 100644 tests/hex-loader-check-data/test.hex
126
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Cc: qemu-stable@nongnu.org (3.0.1)
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/sve_helper.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
10
11
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/sve_helper.c
14
+++ b/target/arm/sve_helper.c
15
@@ -XXX,XX +XXX,XX @@ DO_LD1(sve_ld1bdu_r, cpu_ldub_data_ra, uint64_t, uint8_t, )
16
DO_LD1(sve_ld1bds_r, cpu_ldsb_data_ra, uint64_t, int8_t, )
17
18
DO_LD1(sve_ld1hsu_r, cpu_lduw_data_ra, uint32_t, uint16_t, H1_4)
19
-DO_LD1(sve_ld1hss_r, cpu_ldsw_data_ra, uint32_t, int8_t, H1_4)
20
+DO_LD1(sve_ld1hss_r, cpu_ldsw_data_ra, uint32_t, int16_t, H1_4)
21
DO_LD1(sve_ld1hdu_r, cpu_lduw_data_ra, uint64_t, uint16_t, )
22
DO_LD1(sve_ld1hds_r, cpu_ldsw_data_ra, uint64_t, int16_t, )
23
24
--
25
2.18.0
26
27
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The expression (int) imm + (uint32_t) len_align turns into uint32_t
4
and thus with negative imm produces a memory operation at the wrong
5
offset. None of the numbers involved are particularly large, so
6
change everything to use int.
7
8
Cc: qemu-stable@nongnu.org (3.0.1)
9
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
target/arm/translate-sve.c | 18 ++++++++----------
15
1 file changed, 8 insertions(+), 10 deletions(-)
16
17
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/translate-sve.c
20
+++ b/target/arm/translate-sve.c
21
@@ -XXX,XX +XXX,XX @@ static bool trans_UCVTF_dd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
22
* The load should begin at the address Rn + IMM.
23
*/
24
25
-static void do_ldr(DisasContext *s, uint32_t vofs, uint32_t len,
26
- int rn, int imm)
27
+static void do_ldr(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
28
{
29
- uint32_t len_align = QEMU_ALIGN_DOWN(len, 8);
30
- uint32_t len_remain = len % 8;
31
- uint32_t nparts = len / 8 + ctpop8(len_remain);
32
+ int len_align = QEMU_ALIGN_DOWN(len, 8);
33
+ int len_remain = len % 8;
34
+ int nparts = len / 8 + ctpop8(len_remain);
35
int midx = get_mem_index(s);
36
TCGv_i64 addr, t0, t1;
37
38
@@ -XXX,XX +XXX,XX @@ static void do_ldr(DisasContext *s, uint32_t vofs, uint32_t len,
39
}
40
41
/* Similarly for stores. */
42
-static void do_str(DisasContext *s, uint32_t vofs, uint32_t len,
43
- int rn, int imm)
44
+static void do_str(DisasContext *s, uint32_t vofs, int len, int rn, int imm)
45
{
46
- uint32_t len_align = QEMU_ALIGN_DOWN(len, 8);
47
- uint32_t len_remain = len % 8;
48
- uint32_t nparts = len / 8 + ctpop8(len_remain);
49
+ int len_align = QEMU_ALIGN_DOWN(len, 8);
50
+ int len_remain = len % 8;
51
+ int nparts = len / 8 + ctpop8(len_remain);
52
int midx = get_mem_index(s);
53
TCGv_i64 addr, t0;
54
55
--
56
2.18.0
57
58
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The immediate should be scaled by the size of the memory reference,
4
not the size of the elements into which it is loaded.
5
6
Cc: qemu-stable@nongnu.org (3.0.1)
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/translate-sve.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-sve.c
19
+++ b/target/arm/translate-sve.c
20
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
21
unsigned vsz = vec_full_reg_size(s);
22
unsigned psz = pred_full_reg_size(s);
23
unsigned esz = dtype_esz[a->dtype];
24
+ unsigned msz = dtype_msz(a->dtype);
25
TCGLabel *over = gen_new_label();
26
TCGv_i64 temp;
27
28
@@ -XXX,XX +XXX,XX @@ static bool trans_LD1R_zpri(DisasContext *s, arg_rpri_load *a, uint32_t insn)
29
30
/* Load the data. */
31
temp = tcg_temp_new_i64();
32
- tcg_gen_addi_i64(temp, cpu_reg_sp(s, a->rn), a->imm << esz);
33
+ tcg_gen_addi_i64(temp, cpu_reg_sp(s, a->rn), a->imm << msz);
34
tcg_gen_qemu_ld_i64(temp, temp, get_mem_index(s),
35
s->be_data | dtype_mop[a->dtype]);
36
37
--
38
2.18.0
39
40
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
The scaling should be solely on the memory operation size; the number
4
of registers being loaded does not come in to the initial computation.
5
6
Cc: qemu-stable@nongnu.org (3.0.1)
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
target/arm/translate-sve.c | 5 ++---
14
1 file changed, 2 insertions(+), 3 deletions(-)
15
16
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-sve.c
19
+++ b/target/arm/translate-sve.c
20
@@ -XXX,XX +XXX,XX @@ static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a, uint32_t insn)
21
}
22
if (sve_access_check(s)) {
23
TCGv_i64 addr = new_tmp_a64(s);
24
- tcg_gen_muli_i64(addr, cpu_reg(s, a->rm),
25
- (a->nreg + 1) << dtype_msz(a->dtype));
26
+ tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), dtype_msz(a->dtype));
27
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
28
do_ld_zpa(s, a->rd, a->pg, addr, a->dtype, a->nreg);
29
}
30
@@ -XXX,XX +XXX,XX @@ static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a, uint32_t insn)
31
}
32
if (sve_access_check(s)) {
33
TCGv_i64 addr = new_tmp_a64(s);
34
- tcg_gen_muli_i64(addr, cpu_reg(s, a->rm), (a->nreg + 1) << a->msz);
35
+ tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->msz);
36
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
37
do_st_zpa(s, a->rd, a->pg, addr, a->msz, a->esz, a->nreg);
38
}
39
--
40
2.18.0
41
42
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Cc: qemu-stable@nongnu.org
3
With PC, there are 33 registers. Three per line lines up nicely
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
without overflowing 80 columns.
5
6
Cc: qemu-stable@nongnu.org (3.0.1)
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 20180512003217.9105-6-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
target/arm/translate-a64.c | 30 ++++++++++++++----------------
11
target/arm/translate-a64.c | 13 ++++++-------
11
1 file changed, 14 insertions(+), 16 deletions(-)
12
1 file changed, 6 insertions(+), 7 deletions(-)
12
13
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
16
--- a/target/arm/translate-a64.c
16
+++ b/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
17
@@ -XXX,XX +XXX,XX @@ static TCGv_i32 read_fp_sreg(DisasContext *s, int reg)
18
@@ -XXX,XX +XXX,XX @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
18
return v;
19
int el = arm_current_el(env);
19
}
20
const char *ns_status;
20
21
21
+static TCGv_i32 read_fp_hreg(DisasContext *s, int reg)
22
- cpu_fprintf(f, "PC=%016"PRIx64" SP=%016"PRIx64"\n",
22
+{
23
- env->pc, env->xregs[31]);
23
+ TCGv_i32 v = tcg_temp_new_i32();
24
- for (i = 0; i < 31; i++) {
24
+
25
- cpu_fprintf(f, "X%02d=%016"PRIx64, i, env->xregs[i]);
25
+ tcg_gen_ld16u_i32(v, cpu_env, fp_reg_offset(s, reg, MO_16));
26
- if ((i % 4) == 3) {
26
+ return v;
27
- cpu_fprintf(f, "\n");
27
+}
28
+ cpu_fprintf(f, " PC=%016" PRIx64 " ", env->pc);
28
+
29
+ for (i = 0; i < 32; i++) {
29
/* Clear the bits above an N-bit vector, for N = (is_q ? 128 : 64).
30
+ if (i == 31) {
30
* If SVE is not enabled, then there are only 128 bits in the vector.
31
+ cpu_fprintf(f, " SP=%016" PRIx64 "\n", env->xregs[i]);
31
*/
32
} else {
32
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
33
- cpu_fprintf(f, " ");
33
static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
34
+ cpu_fprintf(f, "X%02d=%016" PRIx64 "%s", i, env->xregs[i],
34
{
35
+ (i + 2) % 3 ? " " : "\n");
35
TCGv_ptr fpst = NULL;
36
}
36
- TCGv_i32 tcg_op = tcg_temp_new_i32();
37
+ TCGv_i32 tcg_op = read_fp_hreg(s, rn);
38
TCGv_i32 tcg_res = tcg_temp_new_i32();
39
40
- read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
41
-
42
switch (opcode) {
43
case 0x0: /* FMOV */
44
tcg_gen_mov_i32(tcg_res, tcg_op);
45
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_diff(DisasContext *s, uint32_t insn)
46
tcg_temp_free_i64(tcg_op2);
47
tcg_temp_free_i64(tcg_res);
48
} else {
49
- TCGv_i32 tcg_op1 = tcg_temp_new_i32();
50
- TCGv_i32 tcg_op2 = tcg_temp_new_i32();
51
+ TCGv_i32 tcg_op1 = read_fp_hreg(s, rn);
52
+ TCGv_i32 tcg_op2 = read_fp_hreg(s, rm);
53
TCGv_i64 tcg_res = tcg_temp_new_i64();
54
55
- read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
56
- read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
57
-
58
gen_helper_neon_mull_s16(tcg_res, tcg_op1, tcg_op2);
59
gen_helper_neon_addl_saturate_s32(tcg_res, cpu_env, tcg_res, tcg_res);
60
61
@@ -XXX,XX +XXX,XX @@ static void disas_simd_scalar_three_reg_same_fp16(DisasContext *s,
62
63
fpst = get_fpstatus_ptr(true);
64
65
- tcg_op1 = tcg_temp_new_i32();
66
- tcg_op2 = tcg_temp_new_i32();
67
+ tcg_op1 = read_fp_hreg(s, rn);
68
+ tcg_op2 = read_fp_hreg(s, rm);
69
tcg_res = tcg_temp_new_i32();
70
71
- read_vec_element_i32(s, tcg_op1, rn, 0, MO_16);
72
- read_vec_element_i32(s, tcg_op2, rm, 0, MO_16);
73
-
74
switch (fpopcode) {
75
case 0x03: /* FMULX */
76
gen_helper_advsimd_mulxh(tcg_res, tcg_op1, tcg_op2, fpst);
77
@@ -XXX,XX +XXX,XX @@ static void disas_simd_two_reg_misc_fp16(DisasContext *s, uint32_t insn)
78
}
37
}
79
38
80
if (is_scalar) {
81
- TCGv_i32 tcg_op = tcg_temp_new_i32();
82
+ TCGv_i32 tcg_op = read_fp_hreg(s, rn);
83
TCGv_i32 tcg_res = tcg_temp_new_i32();
84
85
- read_vec_element_i32(s, tcg_op, rn, 0, MO_16);
86
-
87
switch (fpop) {
88
case 0x1a: /* FCVTNS */
89
case 0x1b: /* FCVTMS */
90
--
39
--
91
2.17.0
40
2.18.0
92
41
93
42
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Adding the fp16 moves to/from general registers.
3
Also fold the FPCR/FPSR state onto the same line as PSTATE,
4
and mention but do not dump disabled FPU state.
4
5
5
Cc: qemu-stable@nongnu.org
6
Cc: qemu-stable@nongnu.org (3.0.1)
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Tested-by: Alex Bennée <alex.bennee@linaro.org>
8
Message-id: 20180512003217.9105-2-richard.henderson@linaro.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
target/arm/translate-a64.c | 21 +++++++++++++++++++++
12
target/arm/translate-a64.c | 95 +++++++++++++++++++++++++++++++++-----
13
1 file changed, 21 insertions(+)
13
1 file changed, 83 insertions(+), 12 deletions(-)
14
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
19
@@ -XXX,XX +XXX,XX @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
20
tcg_gen_st_i64(tcg_rn, cpu_env, fp_reg_hi_offset(s, rd));
20
} else {
21
clear_vec_high(s, true, rd);
21
ns_status = "";
22
break;
22
}
23
+ case 3:
23
-
24
+ /* 16 bit */
24
- cpu_fprintf(f, "\nPSTATE=%08x %c%c%c%c %sEL%d%c\n",
25
+ tmp = tcg_temp_new_i64();
25
+ cpu_fprintf(f, "PSTATE=%08x %c%c%c%c %sEL%d%c",
26
+ tcg_gen_ext16u_i64(tmp, tcg_rn);
26
psr,
27
+ write_fp_dreg(s, rd, tmp);
27
psr & PSTATE_N ? 'N' : '-',
28
+ tcg_temp_free_i64(tmp);
28
psr & PSTATE_Z ? 'Z' : '-',
29
+ break;
29
@@ -XXX,XX +XXX,XX @@ void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
30
+ default:
30
el,
31
+ g_assert_not_reached();
31
psr & PSTATE_SP ? 'h' : 't');
32
33
- if (flags & CPU_DUMP_FPU) {
34
- int numvfpregs = 32;
35
- for (i = 0; i < numvfpregs; i++) {
36
- uint64_t *q = aa64_vfp_qreg(env, i);
37
- uint64_t vlo = q[0];
38
- uint64_t vhi = q[1];
39
- cpu_fprintf(f, "q%02d=%016" PRIx64 ":%016" PRIx64 "%c",
40
- i, vhi, vlo, (i & 1 ? '\n' : ' '));
41
+ if (!(flags & CPU_DUMP_FPU)) {
42
+ cpu_fprintf(f, "\n");
43
+ return;
44
+ }
45
+ cpu_fprintf(f, " FPCR=%08x FPSR=%08x\n",
46
+ vfp_get_fpcr(env), vfp_get_fpsr(env));
47
+
48
+ if (arm_feature(env, ARM_FEATURE_SVE)) {
49
+ int j, zcr_len = env->vfp.zcr_el[1] & 0xf; /* fix for system mode */
50
+
51
+ for (i = 0; i <= FFR_PRED_NUM; i++) {
52
+ bool eol;
53
+ if (i == FFR_PRED_NUM) {
54
+ cpu_fprintf(f, "FFR=");
55
+ /* It's last, so end the line. */
56
+ eol = true;
57
+ } else {
58
+ cpu_fprintf(f, "P%02d=", i);
59
+ switch (zcr_len) {
60
+ case 0:
61
+ eol = i % 8 == 7;
62
+ break;
63
+ case 1:
64
+ eol = i % 6 == 5;
65
+ break;
66
+ case 2:
67
+ case 3:
68
+ eol = i % 3 == 2;
69
+ break;
70
+ default:
71
+ /* More than one quadword per predicate. */
72
+ eol = true;
73
+ break;
74
+ }
75
+ }
76
+ for (j = zcr_len / 4; j >= 0; j--) {
77
+ int digits;
78
+ if (j * 4 + 4 <= zcr_len + 1) {
79
+ digits = 16;
80
+ } else {
81
+ digits = (zcr_len % 4 + 1) * 4;
82
+ }
83
+ cpu_fprintf(f, "%0*" PRIx64 "%s", digits,
84
+ env->vfp.pregs[i].p[j],
85
+ j ? ":" : eol ? "\n" : " ");
86
+ }
87
+ }
88
+
89
+ for (i = 0; i < 32; i++) {
90
+ if (zcr_len == 0) {
91
+ cpu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64 "%s",
92
+ i, env->vfp.zregs[i].d[1],
93
+ env->vfp.zregs[i].d[0], i & 1 ? "\n" : " ");
94
+ } else if (zcr_len == 1) {
95
+ cpu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64
96
+ ":%016" PRIx64 ":%016" PRIx64 "\n",
97
+ i, env->vfp.zregs[i].d[3], env->vfp.zregs[i].d[2],
98
+ env->vfp.zregs[i].d[1], env->vfp.zregs[i].d[0]);
99
+ } else {
100
+ for (j = zcr_len; j >= 0; j--) {
101
+ bool odd = (zcr_len - j) % 2 != 0;
102
+ if (j == zcr_len) {
103
+ cpu_fprintf(f, "Z%02d[%x-%x]=", i, j, j - 1);
104
+ } else if (!odd) {
105
+ if (j > 0) {
106
+ cpu_fprintf(f, " [%x-%x]=", j, j - 1);
107
+ } else {
108
+ cpu_fprintf(f, " [%x]=", j);
109
+ }
110
+ }
111
+ cpu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%s",
112
+ env->vfp.zregs[i].d[j * 2 + 1],
113
+ env->vfp.zregs[i].d[j * 2],
114
+ odd || j == 0 ? "\n" : ":");
115
+ }
116
+ }
117
+ }
118
+ } else {
119
+ for (i = 0; i < 32; i++) {
120
+ uint64_t *q = aa64_vfp_qreg(env, i);
121
+ cpu_fprintf(f, "Q%02d=%016" PRIx64 ":%016" PRIx64 "%s",
122
+ i, q[1], q[0], (i & 1 ? "\n" : " "));
32
}
123
}
33
} else {
124
- cpu_fprintf(f, "FPCR: %08x FPSR: %08x\n",
34
TCGv_i64 tcg_rd = cpu_reg(s, rd);
125
- vfp_get_fpcr(env), vfp_get_fpsr(env));
35
@@ -XXX,XX +XXX,XX @@ static void handle_fmov(DisasContext *s, int rd, int rn, int type, bool itof)
36
/* 64 bits from top half */
37
tcg_gen_ld_i64(tcg_rd, cpu_env, fp_reg_hi_offset(s, rn));
38
break;
39
+ case 3:
40
+ /* 16 bit */
41
+ tcg_gen_ld16u_i64(tcg_rd, cpu_env, fp_reg_offset(s, rn, MO_16));
42
+ break;
43
+ default:
44
+ g_assert_not_reached();
45
}
46
}
126
}
47
}
127
}
48
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
128
49
case 0xa: /* 64 bit */
50
case 0xd: /* 64 bit to top half of quad */
51
break;
52
+ case 0x6: /* 16-bit float, 32-bit int */
53
+ case 0xe: /* 16-bit float, 64-bit int */
54
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
55
+ break;
56
+ }
57
+ /* fallthru */
58
default:
59
/* all other sf/type/rmode combinations are invalid */
60
unallocated_encoding(s);
61
--
129
--
62
2.17.0
130
2.18.0
63
131
64
132
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
These where missed out from the rest of the half-precision work.
3
This allows the default (and maximum) vector length to be set
4
from the command-line. Which is extraordinarily helpful in
5
debugging problems depending on vector length without having to
6
bake knowledge of PR_SET_SVE_VL into every guest binary.
4
7
5
Cc: qemu-stable@nongnu.org
8
Cc: qemu-stable@nongnu.org (3.0.1)
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
10
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
11
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180512003217.9105-9-richard.henderson@linaro.org
11
[rth: Diagnose lack of FP16 before fp_access_check]
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
13
---
15
target/arm/helper-a64.h | 2 +
14
target/arm/cpu.h | 3 +++
16
target/arm/helper-a64.c | 10 +++++
15
linux-user/syscall.c | 19 +++++++++++++------
17
target/arm/translate-a64.c | 88 ++++++++++++++++++++++++++++++--------
16
target/arm/cpu.c | 6 +++---
18
3 files changed, 83 insertions(+), 17 deletions(-)
17
target/arm/cpu64.c | 29 +++++++++++++++++++++++++++++
18
target/arm/helper.c | 7 +++++--
19
5 files changed, 53 insertions(+), 11 deletions(-)
19
20
20
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
21
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper-a64.h
23
--- a/target/arm/cpu.h
23
+++ b/target/arm/helper-a64.h
24
+++ b/target/arm/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
26
27
/* Used to synchronize KVM and QEMU in-kernel device levels */
28
uint8_t device_irq_level;
29
+
30
+ /* Used to set the maximum vector length the cpu will support. */
31
+ uint32_t sve_max_vq;
32
};
33
34
static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
35
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/linux-user/syscall.c
38
+++ b/linux-user/syscall.c
39
@@ -XXX,XX +XXX,XX @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
40
#endif
41
#ifdef TARGET_AARCH64
42
case TARGET_PR_SVE_SET_VL:
43
- /* We cannot support either PR_SVE_SET_VL_ONEXEC
44
- or PR_SVE_VL_INHERIT. Therefore, anything above
45
- ARM_MAX_VQ results in EINVAL. */
46
+ /*
47
+ * We cannot support either PR_SVE_SET_VL_ONEXEC or
48
+ * PR_SVE_VL_INHERIT. Note the kernel definition
49
+ * of sve_vl_valid allows for VQ=512, i.e. VL=8192,
50
+ * even though the current architectural maximum is VQ=16.
51
+ */
52
ret = -TARGET_EINVAL;
53
if (arm_feature(cpu_env, ARM_FEATURE_SVE)
54
- && arg2 >= 0 && arg2 <= ARM_MAX_VQ * 16 && !(arg2 & 15)) {
55
+ && arg2 >= 0 && arg2 <= 512 * 16 && !(arg2 & 15)) {
56
CPUARMState *env = cpu_env;
57
- int old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
58
- int vq = MAX(arg2 / 16, 1);
59
+ ARMCPU *cpu = arm_env_get_cpu(env);
60
+ uint32_t vq, old_vq;
61
+
62
+ old_vq = (env->vfp.zcr_el[1] & 0xf) + 1;
63
+ vq = MAX(arg2 / 16, 1);
64
+ vq = MIN(vq, cpu->sve_max_vq);
65
66
if (vq < old_vq) {
67
aarch64_sve_narrow_vq(env, vq);
68
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/cpu.c
71
+++ b/target/arm/cpu.c
72
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
73
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
74
env->cp15.cptr_el[3] |= CPTR_EZ;
75
/* with maximum vector length */
76
- env->vfp.zcr_el[1] = ARM_MAX_VQ - 1;
77
- env->vfp.zcr_el[2] = ARM_MAX_VQ - 1;
78
- env->vfp.zcr_el[3] = ARM_MAX_VQ - 1;
79
+ env->vfp.zcr_el[1] = cpu->sve_max_vq - 1;
80
+ env->vfp.zcr_el[2] = env->vfp.zcr_el[1];
81
+ env->vfp.zcr_el[3] = env->vfp.zcr_el[1];
82
#else
83
/* Reset into the highest available EL */
84
if (arm_feature(env, ARM_FEATURE_EL3)) {
85
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/target/arm/cpu64.c
88
+++ b/target/arm/cpu64.c
24
@@ -XXX,XX +XXX,XX @@
89
@@ -XXX,XX +XXX,XX @@
25
DEF_HELPER_FLAGS_2(udiv64, TCG_CALL_NO_RWG_SE, i64, i64, i64)
90
#include "sysemu/sysemu.h"
26
DEF_HELPER_FLAGS_2(sdiv64, TCG_CALL_NO_RWG_SE, s64, s64, s64)
91
#include "sysemu/kvm.h"
27
DEF_HELPER_FLAGS_1(rbit64, TCG_CALL_NO_RWG_SE, i64, i64)
92
#include "kvm_arm.h"
28
+DEF_HELPER_3(vfp_cmph_a64, i64, f16, f16, ptr)
93
+#include "qapi/visitor.h"
29
+DEF_HELPER_3(vfp_cmpeh_a64, i64, f16, f16, ptr)
94
30
DEF_HELPER_3(vfp_cmps_a64, i64, f32, f32, ptr)
95
static inline void set_feature(CPUARMState *env, int feature)
31
DEF_HELPER_3(vfp_cmpes_a64, i64, f32, f32, ptr)
96
{
32
DEF_HELPER_3(vfp_cmpd_a64, i64, f64, f64, ptr)
97
@@ -XXX,XX +XXX,XX @@ static void aarch64_a53_initfn(Object *obj)
33
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
98
define_arm_cp_regs(cpu, cortex_a57_a53_cp_reginfo);
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/helper-a64.c
36
+++ b/target/arm/helper-a64.c
37
@@ -XXX,XX +XXX,XX @@ static inline uint32_t float_rel_to_flags(int res)
38
return flags;
39
}
99
}
40
100
41
+uint64_t HELPER(vfp_cmph_a64)(float16 x, float16 y, void *fp_status)
101
+static void cpu_max_get_sve_vq(Object *obj, Visitor *v, const char *name,
102
+ void *opaque, Error **errp)
42
+{
103
+{
43
+ return float_rel_to_flags(float16_compare_quiet(x, y, fp_status));
104
+ ARMCPU *cpu = ARM_CPU(obj);
105
+ visit_type_uint32(v, name, &cpu->sve_max_vq, errp);
44
+}
106
+}
45
+
107
+
46
+uint64_t HELPER(vfp_cmpeh_a64)(float16 x, float16 y, void *fp_status)
108
+static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
109
+ void *opaque, Error **errp)
47
+{
110
+{
48
+ return float_rel_to_flags(float16_compare(x, y, fp_status));
111
+ ARMCPU *cpu = ARM_CPU(obj);
112
+ Error *err = NULL;
113
+
114
+ visit_type_uint32(v, name, &cpu->sve_max_vq, &err);
115
+
116
+ if (!err && (cpu->sve_max_vq == 0 || cpu->sve_max_vq > ARM_MAX_VQ)) {
117
+ error_setg(&err, "unsupported SVE vector length");
118
+ error_append_hint(&err, "Valid sve-max-vq in range [1-%d]\n",
119
+ ARM_MAX_VQ);
120
+ }
121
+ error_propagate(errp, err);
49
+}
122
+}
50
+
123
+
51
uint64_t HELPER(vfp_cmps_a64)(float32 x, float32 y, void *fp_status)
124
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
52
{
125
* otherwise, a CPU with as many features enabled as our emulation supports.
53
return float_rel_to_flags(float32_compare_quiet(x, y, fp_status));
126
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
54
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
127
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
55
index XXXXXXX..XXXXXXX 100644
128
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
56
--- a/target/arm/translate-a64.c
129
cpu->dcz_blocksize = 7; /* 512 bytes */
57
+++ b/target/arm/translate-a64.c
130
#endif
58
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_reg(DisasContext *s, uint32_t insn)
131
+
132
+ cpu->sve_max_vq = ARM_MAX_VQ;
133
+ object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_vq,
134
+ cpu_max_set_sve_vq, NULL, NULL, &error_fatal);
59
}
135
}
60
}
136
}
61
137
62
-static void handle_fp_compare(DisasContext *s, bool is_double,
138
@@ -XXX,XX +XXX,XX @@ void aarch64_sve_narrow_vq(CPUARMState *env, unsigned vq)
63
+static void handle_fp_compare(DisasContext *s, int size,
139
uint64_t pmask;
64
unsigned int rn, unsigned int rm,
140
65
bool cmp_with_zero, bool signal_all_nans)
141
assert(vq >= 1 && vq <= ARM_MAX_VQ);
66
{
142
+ assert(vq <= arm_env_get_cpu(env)->sve_max_vq);
67
TCGv_i64 tcg_flags = tcg_temp_new_i64();
143
68
- TCGv_ptr fpst = get_fpstatus_ptr(false);
144
/* Zap the high bits of the zregs. */
69
+ TCGv_ptr fpst = get_fpstatus_ptr(size == MO_16);
145
for (i = 0; i < 32; i++) {
70
146
diff --git a/target/arm/helper.c b/target/arm/helper.c
71
- if (is_double) {
147
index XXXXXXX..XXXXXXX 100644
72
+ if (size == MO_64) {
148
--- a/target/arm/helper.c
73
TCGv_i64 tcg_vn, tcg_vm;
149
+++ b/target/arm/helper.c
74
150
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
75
tcg_vn = read_fp_dreg(s, rn);
151
zcr_len = 0;
76
@@ -XXX,XX +XXX,XX @@ static void handle_fp_compare(DisasContext *s, bool is_double,
77
tcg_temp_free_i64(tcg_vn);
78
tcg_temp_free_i64(tcg_vm);
79
} else {
80
- TCGv_i32 tcg_vn, tcg_vm;
81
+ TCGv_i32 tcg_vn = tcg_temp_new_i32();
82
+ TCGv_i32 tcg_vm = tcg_temp_new_i32();
83
84
- tcg_vn = read_fp_sreg(s, rn);
85
+ read_vec_element_i32(s, tcg_vn, rn, 0, size);
86
if (cmp_with_zero) {
87
- tcg_vm = tcg_const_i32(0);
88
+ tcg_gen_movi_i32(tcg_vm, 0);
89
} else {
152
} else {
90
- tcg_vm = read_fp_sreg(s, rm);
153
int current_el = arm_current_el(env);
91
+ read_vec_element_i32(s, tcg_vm, rm, 0, size);
154
+ ARMCPU *cpu = arm_env_get_cpu(env);
92
}
155
93
- if (signal_all_nans) {
156
- zcr_len = env->vfp.zcr_el[current_el <= 1 ? 1 : current_el];
94
- gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
157
- zcr_len &= 0xf;
95
- } else {
158
+ zcr_len = cpu->sve_max_vq - 1;
96
- gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
159
+ if (current_el <= 1) {
97
+
160
+ zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[1]);
98
+ switch (size) {
99
+ case MO_32:
100
+ if (signal_all_nans) {
101
+ gen_helper_vfp_cmpes_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
102
+ } else {
103
+ gen_helper_vfp_cmps_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
104
+ }
161
+ }
105
+ break;
162
if (current_el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
106
+ case MO_16:
163
zcr_len = MIN(zcr_len, 0xf & (uint32_t)env->vfp.zcr_el[2]);
107
+ if (signal_all_nans) {
164
}
108
+ gen_helper_vfp_cmpeh_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
109
+ } else {
110
+ gen_helper_vfp_cmph_a64(tcg_flags, tcg_vn, tcg_vm, fpst);
111
+ }
112
+ break;
113
+ default:
114
+ g_assert_not_reached();
115
}
116
+
117
tcg_temp_free_i32(tcg_vn);
118
tcg_temp_free_i32(tcg_vm);
119
}
120
@@ -XXX,XX +XXX,XX @@ static void handle_fp_compare(DisasContext *s, bool is_double,
121
static void disas_fp_compare(DisasContext *s, uint32_t insn)
122
{
123
unsigned int mos, type, rm, op, rn, opc, op2r;
124
+ int size;
125
126
mos = extract32(insn, 29, 3);
127
- type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
128
+ type = extract32(insn, 22, 2);
129
rm = extract32(insn, 16, 5);
130
op = extract32(insn, 14, 2);
131
rn = extract32(insn, 5, 5);
132
opc = extract32(insn, 3, 2);
133
op2r = extract32(insn, 0, 3);
134
135
- if (mos || op || op2r || type > 1) {
136
+ if (mos || op || op2r) {
137
+ unallocated_encoding(s);
138
+ return;
139
+ }
140
+
141
+ switch (type) {
142
+ case 0:
143
+ size = MO_32;
144
+ break;
145
+ case 1:
146
+ size = MO_64;
147
+ break;
148
+ case 3:
149
+ size = MO_16;
150
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
151
+ break;
152
+ }
153
+ /* fallthru */
154
+ default:
155
unallocated_encoding(s);
156
return;
157
}
158
@@ -XXX,XX +XXX,XX @@ static void disas_fp_compare(DisasContext *s, uint32_t insn)
159
return;
160
}
161
162
- handle_fp_compare(s, type, rn, rm, opc & 1, opc & 2);
163
+ handle_fp_compare(s, size, rn, rm, opc & 1, opc & 2);
164
}
165
166
/* Floating point conditional compare
167
@@ -XXX,XX +XXX,XX @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
168
unsigned int mos, type, rm, cond, rn, op, nzcv;
169
TCGv_i64 tcg_flags;
170
TCGLabel *label_continue = NULL;
171
+ int size;
172
173
mos = extract32(insn, 29, 3);
174
- type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
175
+ type = extract32(insn, 22, 2);
176
rm = extract32(insn, 16, 5);
177
cond = extract32(insn, 12, 4);
178
rn = extract32(insn, 5, 5);
179
op = extract32(insn, 4, 1);
180
nzcv = extract32(insn, 0, 4);
181
182
- if (mos || type > 1) {
183
+ if (mos) {
184
+ unallocated_encoding(s);
185
+ return;
186
+ }
187
+
188
+ switch (type) {
189
+ case 0:
190
+ size = MO_32;
191
+ break;
192
+ case 1:
193
+ size = MO_64;
194
+ break;
195
+ case 3:
196
+ size = MO_16;
197
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
198
+ break;
199
+ }
200
+ /* fallthru */
201
+ default:
202
unallocated_encoding(s);
203
return;
204
}
205
@@ -XXX,XX +XXX,XX @@ static void disas_fp_ccomp(DisasContext *s, uint32_t insn)
206
gen_set_label(label_match);
207
}
208
209
- handle_fp_compare(s, type, rn, rm, false, op);
210
+ handle_fp_compare(s, size, rn, rm, false, op);
211
212
if (cond < 0x0e) {
213
gen_set_label(label_continue);
214
--
165
--
215
2.17.0
166
2.18.0
216
167
217
168
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
We missed all of the scalar fp16 binary operations.
3
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
4
4
Message-id: 34b6704ceb81b49e35ce1ad162bf758e5141ff87.1532984236.git.jcd@tribudubois.net
5
Cc: qemu-stable@nongnu.org
5
[PMM: fixed some comment typos etc]
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180512003217.9105-7-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
target/arm/translate-a64.c | 65 ++++++++++++++++++++++++++++++++++++++
9
hw/misc/Makefile.objs | 1 +
13
1 file changed, 65 insertions(+)
10
include/hw/misc/imx6ul_ccm.h | 226 +++++++++
11
hw/misc/imx6ul_ccm.c | 886 +++++++++++++++++++++++++++++++++++
12
hw/misc/trace-events | 7 +
13
4 files changed, 1120 insertions(+)
14
create mode 100644 include/hw/misc/imx6ul_ccm.h
15
create mode 100644 hw/misc/imx6ul_ccm.c
14
16
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
19
--- a/hw/misc/Makefile.objs
18
+++ b/target/arm/translate-a64.c
20
+++ b/hw/misc/Makefile.objs
19
@@ -XXX,XX +XXX,XX @@ static void handle_fp_2src_double(DisasContext *s, int opcode,
21
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_IMX) += imx_ccm.o
20
tcg_temp_free_i64(tcg_res);
22
obj-$(CONFIG_IMX) += imx31_ccm.o
21
}
23
obj-$(CONFIG_IMX) += imx25_ccm.o
22
24
obj-$(CONFIG_IMX) += imx6_ccm.o
23
+/* Floating-point data-processing (2 source) - half precision */
25
+obj-$(CONFIG_IMX) += imx6ul_ccm.o
24
+static void handle_fp_2src_half(DisasContext *s, int opcode,
26
obj-$(CONFIG_IMX) += imx6_src.o
25
+ int rd, int rn, int rm)
27
obj-$(CONFIG_IMX) += imx7_ccm.o
26
+{
28
obj-$(CONFIG_IMX) += imx2_wdt.o
27
+ TCGv_i32 tcg_op1;
29
diff --git a/include/hw/misc/imx6ul_ccm.h b/include/hw/misc/imx6ul_ccm.h
28
+ TCGv_i32 tcg_op2;
30
new file mode 100644
29
+ TCGv_i32 tcg_res;
31
index XXXXXXX..XXXXXXX
30
+ TCGv_ptr fpst;
32
--- /dev/null
31
+
33
+++ b/include/hw/misc/imx6ul_ccm.h
32
+ tcg_res = tcg_temp_new_i32();
34
@@ -XXX,XX +XXX,XX @@
33
+ fpst = get_fpstatus_ptr(true);
35
+/*
34
+ tcg_op1 = read_fp_hreg(s, rn);
36
+ * IMX6UL Clock Control Module
35
+ tcg_op2 = read_fp_hreg(s, rm);
37
+ *
36
+
38
+ * Copyright (C) 2018 by Jean-Christophe Dubois <jcd@tribudubois.net>
37
+ switch (opcode) {
39
+ *
38
+ case 0x0: /* FMUL */
40
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
39
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
41
+ * See the COPYING file in the top-level directory.
40
+ break;
42
+ */
41
+ case 0x1: /* FDIV */
43
+
42
+ gen_helper_advsimd_divh(tcg_res, tcg_op1, tcg_op2, fpst);
44
+#ifndef IMX6UL_CCM_H
43
+ break;
45
+#define IMX6UL_CCM_H
44
+ case 0x2: /* FADD */
46
+
45
+ gen_helper_advsimd_addh(tcg_res, tcg_op1, tcg_op2, fpst);
47
+#include "hw/misc/imx_ccm.h"
46
+ break;
48
+#include "qemu/bitops.h"
47
+ case 0x3: /* FSUB */
49
+
48
+ gen_helper_advsimd_subh(tcg_res, tcg_op1, tcg_op2, fpst);
50
+#define CCM_CCR 0
49
+ break;
51
+#define CCM_CCDR 1
50
+ case 0x4: /* FMAX */
52
+#define CCM_CSR 2
51
+ gen_helper_advsimd_maxh(tcg_res, tcg_op1, tcg_op2, fpst);
53
+#define CCM_CCSR 3
52
+ break;
54
+#define CCM_CACRR 4
53
+ case 0x5: /* FMIN */
55
+#define CCM_CBCDR 5
54
+ gen_helper_advsimd_minh(tcg_res, tcg_op1, tcg_op2, fpst);
56
+#define CCM_CBCMR 6
55
+ break;
57
+#define CCM_CSCMR1 7
56
+ case 0x6: /* FMAXNM */
58
+#define CCM_CSCMR2 8
57
+ gen_helper_advsimd_maxnumh(tcg_res, tcg_op1, tcg_op2, fpst);
59
+#define CCM_CSCDR1 9
58
+ break;
60
+#define CCM_CS1CDR 10
59
+ case 0x7: /* FMINNM */
61
+#define CCM_CS2CDR 11
60
+ gen_helper_advsimd_minnumh(tcg_res, tcg_op1, tcg_op2, fpst);
62
+#define CCM_CDCDR 12
61
+ break;
63
+#define CCM_CHSCCDR 13
62
+ case 0x8: /* FNMUL */
64
+#define CCM_CSCDR2 14
63
+ gen_helper_advsimd_mulh(tcg_res, tcg_op1, tcg_op2, fpst);
65
+#define CCM_CSCDR3 15
64
+ tcg_gen_xori_i32(tcg_res, tcg_res, 0x8000);
66
+#define CCM_CDHIPR 18
67
+#define CCM_CTOR 20
68
+#define CCM_CLPCR 21
69
+#define CCM_CISR 22
70
+#define CCM_CIMR 23
71
+#define CCM_CCOSR 24
72
+#define CCM_CGPR 25
73
+#define CCM_CCGR0 26
74
+#define CCM_CCGR1 27
75
+#define CCM_CCGR2 28
76
+#define CCM_CCGR3 29
77
+#define CCM_CCGR4 30
78
+#define CCM_CCGR5 31
79
+#define CCM_CCGR6 32
80
+#define CCM_CMEOR 34
81
+#define CCM_MAX 35
82
+
83
+#define CCM_ANALOG_PLL_ARM 0
84
+#define CCM_ANALOG_PLL_ARM_SET 1
85
+#define CCM_ANALOG_PLL_ARM_CLR 2
86
+#define CCM_ANALOG_PLL_ARM_TOG 3
87
+#define CCM_ANALOG_PLL_USB1 4
88
+#define CCM_ANALOG_PLL_USB1_SET 5
89
+#define CCM_ANALOG_PLL_USB1_CLR 6
90
+#define CCM_ANALOG_PLL_USB1_TOG 7
91
+#define CCM_ANALOG_PLL_USB2 8
92
+#define CCM_ANALOG_PLL_USB2_SET 9
93
+#define CCM_ANALOG_PLL_USB2_CLR 10
94
+#define CCM_ANALOG_PLL_USB2_TOG 11
95
+#define CCM_ANALOG_PLL_SYS 12
96
+#define CCM_ANALOG_PLL_SYS_SET 13
97
+#define CCM_ANALOG_PLL_SYS_CLR 14
98
+#define CCM_ANALOG_PLL_SYS_TOG 15
99
+#define CCM_ANALOG_PLL_SYS_SS 16
100
+#define CCM_ANALOG_PLL_SYS_NUM 20
101
+#define CCM_ANALOG_PLL_SYS_DENOM 24
102
+#define CCM_ANALOG_PLL_AUDIO 28
103
+#define CCM_ANALOG_PLL_AUDIO_SET 29
104
+#define CCM_ANALOG_PLL_AUDIO_CLR 30
105
+#define CCM_ANALOG_PLL_AUDIO_TOG 31
106
+#define CCM_ANALOG_PLL_AUDIO_NUM 32
107
+#define CCM_ANALOG_PLL_AUDIO_DENOM 36
108
+#define CCM_ANALOG_PLL_VIDEO 40
109
+#define CCM_ANALOG_PLL_VIDEO_SET 41
110
+#define CCM_ANALOG_PLL_VIDEO_CLR 42
111
+#define CCM_ANALOG_PLL_VIDEO_TOG 44
112
+#define CCM_ANALOG_PLL_VIDEO_NUM 46
113
+#define CCM_ANALOG_PLL_VIDEO_DENOM 48
114
+#define CCM_ANALOG_PLL_ENET 56
115
+#define CCM_ANALOG_PLL_ENET_SET 57
116
+#define CCM_ANALOG_PLL_ENET_CLR 58
117
+#define CCM_ANALOG_PLL_ENET_TOG 59
118
+#define CCM_ANALOG_PFD_480 60
119
+#define CCM_ANALOG_PFD_480_SET 61
120
+#define CCM_ANALOG_PFD_480_CLR 62
121
+#define CCM_ANALOG_PFD_480_TOG 63
122
+#define CCM_ANALOG_PFD_528 64
123
+#define CCM_ANALOG_PFD_528_SET 65
124
+#define CCM_ANALOG_PFD_528_CLR 66
125
+#define CCM_ANALOG_PFD_528_TOG 67
126
+
127
+/* PMU registers */
128
+#define PMU_REG_1P1 68
129
+#define PMU_REG_3P0 72
130
+#define PMU_REG_2P5 76
131
+#define PMU_REG_CORE 80
132
+
133
+#define CCM_ANALOG_MISC0 84
134
+#define PMU_MISC0 CCM_ANALOG_MISC0
135
+#define CCM_ANALOG_MISC0_SET 85
136
+#define PMU_MISC0_SET CCM_ANALOG_MISC0_SET
137
+#define CCM_ANALOG_MISC0_CLR 86
138
+#define PMU_MISC0_CLR CCM_ANALOG_MISC0_CLR
139
+#define CCM_ANALOG_MISC0_TOG 87
140
+#define PMU_MISC0_TOG CCM_ANALOG_MISC0_TOG
141
+
142
+#define CCM_ANALOG_MISC1 88
143
+#define PMU_MISC1 CCM_ANALOG_MISC1
144
+#define CCM_ANALOG_MISC1_SET 89
145
+#define PMU_MISC1_SET CCM_ANALOG_MISC1_SET
146
+#define CCM_ANALOG_MISC1_CLR 90
147
+#define PMU_MISC1_CLR CCM_ANALOG_MISC1_CLR
148
+#define CCM_ANALOG_MISC1_TOG 91
149
+#define PMU_MISC1_TOG CCM_ANALOG_MISC1_TOG
150
+
151
+#define CCM_ANALOG_MISC2 92
152
+#define PMU_MISC2 CCM_ANALOG_MISC2
153
+#define CCM_ANALOG_MISC2_SET 93
154
+#define PMU_MISC2_SET CCM_ANALOG_MISC2_SET
155
+#define CCM_ANALOG_MISC2_CLR 94
156
+#define PMU_MISC2_CLR CCM_ANALOG_MISC2_CLR
157
+#define CCM_ANALOG_MISC2_TOG 95
158
+#define PMU_MISC2_TOG CCM_ANALOG_MISC2_TOG
159
+
160
+#define TEMPMON_TEMPSENSE0 96
161
+#define TEMPMON_TEMPSENSE0_SET 97
162
+#define TEMPMON_TEMPSENSE0_CLR 98
163
+#define TEMPMON_TEMPSENSE0_TOG 99
164
+#define TEMPMON_TEMPSENSE1 100
165
+#define TEMPMON_TEMPSENSE1_SET 101
166
+#define TEMPMON_TEMPSENSE1_CLR 102
167
+#define TEMPMON_TEMPSENSE1_TOG 103
168
+#define TEMPMON_TEMPSENSE2 164
169
+#define TEMPMON_TEMPSENSE2_SET 165
170
+#define TEMPMON_TEMPSENSE2_CLR 166
171
+#define TEMPMON_TEMPSENSE2_TOG 167
172
+
173
+#define PMU_LOWPWR_CTRL 155
174
+#define PMU_LOWPWR_CTRL_SET 156
175
+#define PMU_LOWPWR_CTRL_CLR 157
176
+#define PMU_LOWPWR_CTRL_TOG 158
177
+
178
+#define USB_ANALOG_USB1_VBUS_DETECT 104
179
+#define USB_ANALOG_USB1_VBUS_DETECT_SET 105
180
+#define USB_ANALOG_USB1_VBUS_DETECT_CLR 106
181
+#define USB_ANALOG_USB1_VBUS_DETECT_TOG 107
182
+#define USB_ANALOG_USB1_CHRG_DETECT 108
183
+#define USB_ANALOG_USB1_CHRG_DETECT_SET 109
184
+#define USB_ANALOG_USB1_CHRG_DETECT_CLR 110
185
+#define USB_ANALOG_USB1_CHRG_DETECT_TOG 111
186
+#define USB_ANALOG_USB1_VBUS_DETECT_STAT 112
187
+#define USB_ANALOG_USB1_CHRG_DETECT_STAT 116
188
+#define USB_ANALOG_USB1_MISC 124
189
+#define USB_ANALOG_USB1_MISC_SET 125
190
+#define USB_ANALOG_USB1_MISC_CLR 126
191
+#define USB_ANALOG_USB1_MISC_TOG 127
192
+#define USB_ANALOG_USB2_VBUS_DETECT 128
193
+#define USB_ANALOG_USB2_VBUS_DETECT_SET 129
194
+#define USB_ANALOG_USB2_VBUS_DETECT_CLR 130
195
+#define USB_ANALOG_USB2_VBUS_DETECT_TOG 131
196
+#define USB_ANALOG_USB2_CHRG_DETECT 132
197
+#define USB_ANALOG_USB2_CHRG_DETECT_SET 133
198
+#define USB_ANALOG_USB2_CHRG_DETECT_CLR 134
199
+#define USB_ANALOG_USB2_CHRG_DETECT_TOG 135
200
+#define USB_ANALOG_USB2_VBUS_DETECT_STAT 136
201
+#define USB_ANALOG_USB2_CHRG_DETECT_STAT 140
202
+#define USB_ANALOG_USB2_MISC 148
203
+#define USB_ANALOG_USB2_MISC_SET 149
204
+#define USB_ANALOG_USB2_MISC_CLR 150
205
+#define USB_ANALOG_USB2_MISC_TOG 151
206
+#define USB_ANALOG_DIGPROG 152
207
+#define CCM_ANALOG_MAX 4096
208
+
209
+/* CCM_CBCMR */
210
+#define R_CBCMR_PRE_PERIPH_CLK_SEL_SHIFT (18)
211
+#define R_CBCMR_PRE_PERIPH_CLK_SEL_LENGTH (2)
212
+#define R_CBCMR_PERIPH_CLK2_SEL_SHIFT (12)
213
+#define R_CBCMR_PERIPH_CLK2_SEL_LENGTH (2)
214
+
215
+/* CCM_CBCDR */
216
+#define R_CBCDR_AHB_PODF_SHIFT (10)
217
+#define R_CBCDR_AHB_PODF_LENGTH (3)
218
+#define R_CBCDR_IPG_PODF_SHIFT (8)
219
+#define R_CBCDR_IPG_PODF_LENGTH (2)
220
+#define R_CBCDR_PERIPH_CLK_SEL_SHIFT (25)
221
+#define R_CBCDR_PERIPH_CLK_SEL_LENGTH (1)
222
+#define R_CBCDR_PERIPH_CLK2_PODF_SHIFT (27)
223
+#define R_CBCDR_PERIPH_CLK2_PODF_LENGTH (3)
224
+
225
+/* CCM_CSCMR1 */
226
+#define R_CSCMR1_PERCLK_PODF_SHIFT (0)
227
+#define R_CSCMR1_PERCLK_PODF_LENGTH (6)
228
+#define R_CSCMR1_PERCLK_CLK_SEL_SHIFT (6)
229
+#define R_CSCMR1_PERCLK_CLK_SEL_LENGTH (1)
230
+
231
+/* CCM_ANALOG_PFD_528 */
232
+#define R_ANALOG_PFD_528_PFD0_FRAC_SHIFT (0)
233
+#define R_ANALOG_PFD_528_PFD0_FRAC_LENGTH (6)
234
+#define R_ANALOG_PFD_528_PFD2_FRAC_SHIFT (16)
235
+#define R_ANALOG_PFD_528_PFD2_FRAC_LENGTH (6)
236
+
237
+/* CCM_ANALOG_PLL_SYS */
238
+#define R_ANALOG_PLL_SYS_DIV_SELECT_SHIFT (0)
239
+#define R_ANALOG_PLL_SYS_DIV_SELECT_LENGTH (1)
240
+
241
+#define CCM_ANALOG_PLL_LOCK (1 << 31);
242
+
243
+#define TYPE_IMX6UL_CCM "imx6ul.ccm"
244
+#define IMX6UL_CCM(obj) OBJECT_CHECK(IMX6ULCCMState, (obj), TYPE_IMX6UL_CCM)
245
+
246
+typedef struct IMX6ULCCMState {
247
+ /* <private> */
248
+ IMXCCMState parent_obj;
249
+
250
+ /* <public> */
251
+ MemoryRegion container;
252
+ MemoryRegion ioccm;
253
+ MemoryRegion ioanalog;
254
+
255
+ uint32_t ccm[CCM_MAX];
256
+ uint32_t analog[CCM_ANALOG_MAX];
257
+
258
+} IMX6ULCCMState;
259
+
260
+#endif /* IMX6UL_CCM_H */
261
diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c
262
new file mode 100644
263
index XXXXXXX..XXXXXXX
264
--- /dev/null
265
+++ b/hw/misc/imx6ul_ccm.c
266
@@ -XXX,XX +XXX,XX @@
267
+/*
268
+ * IMX6UL Clock Control Module
269
+ *
270
+ * Copyright (c) 2018 Jean-Christophe Dubois <jcd@tribudubois.net>
271
+ *
272
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
273
+ * See the COPYING file in the top-level directory.
274
+ *
275
+ * To get the timer frequencies right, we need to emulate at least part of
276
+ * the CCM.
277
+ */
278
+
279
+#include "qemu/osdep.h"
280
+#include "hw/registerfields.h"
281
+#include "hw/misc/imx6ul_ccm.h"
282
+#include "qemu/log.h"
283
+
284
+#include "trace.h"
285
+
286
+static const char *imx6ul_ccm_reg_name(uint32_t reg)
287
+{
288
+ static char unknown[20];
289
+
290
+ switch (reg) {
291
+ case CCM_CCR:
292
+ return "CCR";
293
+ case CCM_CCDR:
294
+ return "CCDR";
295
+ case CCM_CSR:
296
+ return "CSR";
297
+ case CCM_CCSR:
298
+ return "CCSR";
299
+ case CCM_CACRR:
300
+ return "CACRR";
301
+ case CCM_CBCDR:
302
+ return "CBCDR";
303
+ case CCM_CBCMR:
304
+ return "CBCMR";
305
+ case CCM_CSCMR1:
306
+ return "CSCMR1";
307
+ case CCM_CSCMR2:
308
+ return "CSCMR2";
309
+ case CCM_CSCDR1:
310
+ return "CSCDR1";
311
+ case CCM_CS1CDR:
312
+ return "CS1CDR";
313
+ case CCM_CS2CDR:
314
+ return "CS2CDR";
315
+ case CCM_CDCDR:
316
+ return "CDCDR";
317
+ case CCM_CHSCCDR:
318
+ return "CHSCCDR";
319
+ case CCM_CSCDR2:
320
+ return "CSCDR2";
321
+ case CCM_CSCDR3:
322
+ return "CSCDR3";
323
+ case CCM_CDHIPR:
324
+ return "CDHIPR";
325
+ case CCM_CTOR:
326
+ return "CTOR";
327
+ case CCM_CLPCR:
328
+ return "CLPCR";
329
+ case CCM_CISR:
330
+ return "CISR";
331
+ case CCM_CIMR:
332
+ return "CIMR";
333
+ case CCM_CCOSR:
334
+ return "CCOSR";
335
+ case CCM_CGPR:
336
+ return "CGPR";
337
+ case CCM_CCGR0:
338
+ return "CCGR0";
339
+ case CCM_CCGR1:
340
+ return "CCGR1";
341
+ case CCM_CCGR2:
342
+ return "CCGR2";
343
+ case CCM_CCGR3:
344
+ return "CCGR3";
345
+ case CCM_CCGR4:
346
+ return "CCGR4";
347
+ case CCM_CCGR5:
348
+ return "CCGR5";
349
+ case CCM_CCGR6:
350
+ return "CCGR6";
351
+ case CCM_CMEOR:
352
+ return "CMEOR";
353
+ default:
354
+ sprintf(unknown, "%d ?", reg);
355
+ return unknown;
356
+ }
357
+}
358
+
359
+static const char *imx6ul_analog_reg_name(uint32_t reg)
360
+{
361
+ static char unknown[20];
362
+
363
+ switch (reg) {
364
+ case CCM_ANALOG_PLL_ARM:
365
+ return "PLL_ARM";
366
+ case CCM_ANALOG_PLL_ARM_SET:
367
+ return "PLL_ARM_SET";
368
+ case CCM_ANALOG_PLL_ARM_CLR:
369
+ return "PLL_ARM_CLR";
370
+ case CCM_ANALOG_PLL_ARM_TOG:
371
+ return "PLL_ARM_TOG";
372
+ case CCM_ANALOG_PLL_USB1:
373
+ return "PLL_USB1";
374
+ case CCM_ANALOG_PLL_USB1_SET:
375
+ return "PLL_USB1_SET";
376
+ case CCM_ANALOG_PLL_USB1_CLR:
377
+ return "PLL_USB1_CLR";
378
+ case CCM_ANALOG_PLL_USB1_TOG:
379
+ return "PLL_USB1_TOG";
380
+ case CCM_ANALOG_PLL_USB2:
381
+ return "PLL_USB2";
382
+ case CCM_ANALOG_PLL_USB2_SET:
383
+ return "PLL_USB2_SET";
384
+ case CCM_ANALOG_PLL_USB2_CLR:
385
+ return "PLL_USB2_CLR";
386
+ case CCM_ANALOG_PLL_USB2_TOG:
387
+ return "PLL_USB2_TOG";
388
+ case CCM_ANALOG_PLL_SYS:
389
+ return "PLL_SYS";
390
+ case CCM_ANALOG_PLL_SYS_SET:
391
+ return "PLL_SYS_SET";
392
+ case CCM_ANALOG_PLL_SYS_CLR:
393
+ return "PLL_SYS_CLR";
394
+ case CCM_ANALOG_PLL_SYS_TOG:
395
+ return "PLL_SYS_TOG";
396
+ case CCM_ANALOG_PLL_SYS_SS:
397
+ return "PLL_SYS_SS";
398
+ case CCM_ANALOG_PLL_SYS_NUM:
399
+ return "PLL_SYS_NUM";
400
+ case CCM_ANALOG_PLL_SYS_DENOM:
401
+ return "PLL_SYS_DENOM";
402
+ case CCM_ANALOG_PLL_AUDIO:
403
+ return "PLL_AUDIO";
404
+ case CCM_ANALOG_PLL_AUDIO_SET:
405
+ return "PLL_AUDIO_SET";
406
+ case CCM_ANALOG_PLL_AUDIO_CLR:
407
+ return "PLL_AUDIO_CLR";
408
+ case CCM_ANALOG_PLL_AUDIO_TOG:
409
+ return "PLL_AUDIO_TOG";
410
+ case CCM_ANALOG_PLL_AUDIO_NUM:
411
+ return "PLL_AUDIO_NUM";
412
+ case CCM_ANALOG_PLL_AUDIO_DENOM:
413
+ return "PLL_AUDIO_DENOM";
414
+ case CCM_ANALOG_PLL_VIDEO:
415
+ return "PLL_VIDEO";
416
+ case CCM_ANALOG_PLL_VIDEO_SET:
417
+ return "PLL_VIDEO_SET";
418
+ case CCM_ANALOG_PLL_VIDEO_CLR:
419
+ return "PLL_VIDEO_CLR";
420
+ case CCM_ANALOG_PLL_VIDEO_TOG:
421
+ return "PLL_VIDEO_TOG";
422
+ case CCM_ANALOG_PLL_VIDEO_NUM:
423
+ return "PLL_VIDEO_NUM";
424
+ case CCM_ANALOG_PLL_VIDEO_DENOM:
425
+ return "PLL_VIDEO_DENOM";
426
+ case CCM_ANALOG_PLL_ENET:
427
+ return "PLL_ENET";
428
+ case CCM_ANALOG_PLL_ENET_SET:
429
+ return "PLL_ENET_SET";
430
+ case CCM_ANALOG_PLL_ENET_CLR:
431
+ return "PLL_ENET_CLR";
432
+ case CCM_ANALOG_PLL_ENET_TOG:
433
+ return "PLL_ENET_TOG";
434
+ case CCM_ANALOG_PFD_480:
435
+ return "PFD_480";
436
+ case CCM_ANALOG_PFD_480_SET:
437
+ return "PFD_480_SET";
438
+ case CCM_ANALOG_PFD_480_CLR:
439
+ return "PFD_480_CLR";
440
+ case CCM_ANALOG_PFD_480_TOG:
441
+ return "PFD_480_TOG";
442
+ case CCM_ANALOG_PFD_528:
443
+ return "PFD_528";
444
+ case CCM_ANALOG_PFD_528_SET:
445
+ return "PFD_528_SET";
446
+ case CCM_ANALOG_PFD_528_CLR:
447
+ return "PFD_528_CLR";
448
+ case CCM_ANALOG_PFD_528_TOG:
449
+ return "PFD_528_TOG";
450
+ case CCM_ANALOG_MISC0:
451
+ return "MISC0";
452
+ case CCM_ANALOG_MISC0_SET:
453
+ return "MISC0_SET";
454
+ case CCM_ANALOG_MISC0_CLR:
455
+ return "MISC0_CLR";
456
+ case CCM_ANALOG_MISC0_TOG:
457
+ return "MISC0_TOG";
458
+ case CCM_ANALOG_MISC2:
459
+ return "MISC2";
460
+ case CCM_ANALOG_MISC2_SET:
461
+ return "MISC2_SET";
462
+ case CCM_ANALOG_MISC2_CLR:
463
+ return "MISC2_CLR";
464
+ case CCM_ANALOG_MISC2_TOG:
465
+ return "MISC2_TOG";
466
+ case PMU_REG_1P1:
467
+ return "PMU_REG_1P1";
468
+ case PMU_REG_3P0:
469
+ return "PMU_REG_3P0";
470
+ case PMU_REG_2P5:
471
+ return "PMU_REG_2P5";
472
+ case PMU_REG_CORE:
473
+ return "PMU_REG_CORE";
474
+ case PMU_MISC1:
475
+ return "PMU_MISC1";
476
+ case PMU_MISC1_SET:
477
+ return "PMU_MISC1_SET";
478
+ case PMU_MISC1_CLR:
479
+ return "PMU_MISC1_CLR";
480
+ case PMU_MISC1_TOG:
481
+ return "PMU_MISC1_TOG";
482
+ case USB_ANALOG_DIGPROG:
483
+ return "USB_ANALOG_DIGPROG";
484
+ default:
485
+ sprintf(unknown, "%d ?", reg);
486
+ return unknown;
487
+ }
488
+}
489
+
490
+#define CKIH_FREQ 24000000 /* 24MHz crystal input */
491
+
492
+static const VMStateDescription vmstate_imx6ul_ccm = {
493
+ .name = TYPE_IMX6UL_CCM,
494
+ .version_id = 1,
495
+ .minimum_version_id = 1,
496
+ .fields = (VMStateField[]) {
497
+ VMSTATE_UINT32_ARRAY(ccm, IMX6ULCCMState, CCM_MAX),
498
+ VMSTATE_UINT32_ARRAY(analog, IMX6ULCCMState, CCM_ANALOG_MAX),
499
+ VMSTATE_END_OF_LIST()
500
+ },
501
+};
502
+
503
+static uint64_t imx6ul_analog_get_osc_clk(IMX6ULCCMState *dev)
504
+{
505
+ uint64_t freq = CKIH_FREQ;
506
+
507
+ trace_ccm_freq((uint32_t)freq);
508
+
509
+ return freq;
510
+}
511
+
512
+static uint64_t imx6ul_analog_get_pll2_clk(IMX6ULCCMState *dev)
513
+{
514
+ uint64_t freq = imx6ul_analog_get_osc_clk(dev);
515
+
516
+ if (FIELD_EX32(dev->analog[CCM_ANALOG_PLL_SYS],
517
+ ANALOG_PLL_SYS, DIV_SELECT)) {
518
+ freq *= 22;
519
+ } else {
520
+ freq *= 20;
521
+ }
522
+
523
+ trace_ccm_freq((uint32_t)freq);
524
+
525
+ return freq;
526
+}
527
+
528
+static uint64_t imx6ul_analog_get_pll3_clk(IMX6ULCCMState *dev)
529
+{
530
+ uint64_t freq = imx6ul_analog_get_osc_clk(dev) * 20;
531
+
532
+ trace_ccm_freq((uint32_t)freq);
533
+
534
+ return freq;
535
+}
536
+
537
+static uint64_t imx6ul_analog_get_pll2_pfd0_clk(IMX6ULCCMState *dev)
538
+{
539
+ uint64_t freq = 0;
540
+
541
+ freq = imx6ul_analog_get_pll2_clk(dev) * 18
542
+ / FIELD_EX32(dev->analog[CCM_ANALOG_PFD_528],
543
+ ANALOG_PFD_528, PFD0_FRAC);
544
+
545
+ trace_ccm_freq((uint32_t)freq);
546
+
547
+ return freq;
548
+}
549
+
550
+static uint64_t imx6ul_analog_get_pll2_pfd2_clk(IMX6ULCCMState *dev)
551
+{
552
+ uint64_t freq = 0;
553
+
554
+ freq = imx6ul_analog_get_pll2_clk(dev) * 18
555
+ / FIELD_EX32(dev->analog[CCM_ANALOG_PFD_528],
556
+ ANALOG_PFD_528, PFD2_FRAC);
557
+
558
+ trace_ccm_freq((uint32_t)freq);
559
+
560
+ return freq;
561
+}
562
+
563
+static uint64_t imx6ul_analog_pll2_bypass_clk(IMX6ULCCMState *dev)
564
+{
565
+ uint64_t freq = 0;
566
+
567
+ trace_ccm_freq((uint32_t)freq);
568
+
569
+ return freq;
570
+}
571
+
572
+static uint64_t imx6ul_ccm_get_periph_clk2_sel_clk(IMX6ULCCMState *dev)
573
+{
574
+ uint64_t freq = 0;
575
+
576
+ switch (FIELD_EX32(dev->ccm[CCM_CBCMR], CBCMR, PERIPH_CLK2_SEL)) {
577
+ case 0:
578
+ freq = imx6ul_analog_get_pll3_clk(dev);
579
+ break;
580
+ case 1:
581
+ freq = imx6ul_analog_get_osc_clk(dev);
582
+ break;
583
+ case 2:
584
+ freq = imx6ul_analog_pll2_bypass_clk(dev);
585
+ break;
586
+ case 3:
587
+ /* We should never get there as 3 is a reserved value */
588
+ qemu_log_mask(LOG_GUEST_ERROR,
589
+ "[%s]%s: unsupported PERIPH_CLK2_SEL value 3\n",
590
+ TYPE_IMX6UL_CCM, __func__);
591
+ /* freq is set to 0 as we don't know what it should be */
65
+ break;
592
+ break;
66
+ default:
593
+ default:
67
+ g_assert_not_reached();
594
+ g_assert_not_reached();
68
+ }
595
+ }
69
+
596
+
70
+ write_fp_sreg(s, rd, tcg_res);
597
+ trace_ccm_freq((uint32_t)freq);
71
+
598
+
72
+ tcg_temp_free_ptr(fpst);
599
+ return freq;
73
+ tcg_temp_free_i32(tcg_op1);
600
+}
74
+ tcg_temp_free_i32(tcg_op2);
601
+
75
+ tcg_temp_free_i32(tcg_res);
602
+static uint64_t imx6ul_ccm_get_periph_clk_sel_clk(IMX6ULCCMState *dev)
76
+}
603
+{
77
+
604
+ uint64_t freq = 0;
78
/* Floating point data-processing (2 source)
605
+
79
* 31 30 29 28 24 23 22 21 20 16 15 12 11 10 9 5 4 0
606
+ switch (FIELD_EX32(dev->ccm[CCM_CBCMR], CBCMR, PRE_PERIPH_CLK_SEL)) {
80
* +---+---+---+-----------+------+---+------+--------+-----+------+------+
607
+ case 0:
81
@@ -XXX,XX +XXX,XX @@ static void disas_fp_2src(DisasContext *s, uint32_t insn)
608
+ freq = imx6ul_analog_get_pll2_clk(dev);
82
}
609
+ break;
83
handle_fp_2src_double(s, opcode, rd, rn, rm);
610
+ case 1:
84
break;
611
+ freq = imx6ul_analog_get_pll2_pfd2_clk(dev);
612
+ break;
613
+ case 2:
614
+ freq = imx6ul_analog_get_pll2_pfd0_clk(dev);
615
+ break;
85
+ case 3:
616
+ case 3:
86
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
617
+ freq = imx6ul_analog_get_pll2_pfd2_clk(dev) / 2;
87
+ unallocated_encoding(s);
618
+ break;
88
+ return;
619
+ default:
89
+ }
620
+ g_assert_not_reached();
90
+ if (!fp_access_check(s)) {
621
+ }
91
+ return;
622
+
92
+ }
623
+ trace_ccm_freq((uint32_t)freq);
93
+ handle_fp_2src_half(s, opcode, rd, rn, rm);
624
+
94
+ break;
625
+ return freq;
95
default:
626
+}
96
unallocated_encoding(s);
627
+
97
}
628
+static uint64_t imx6ul_ccm_get_periph_clk2_clk(IMX6ULCCMState *dev)
629
+{
630
+ uint64_t freq = 0;
631
+
632
+ freq = imx6ul_ccm_get_periph_clk2_sel_clk(dev)
633
+ / (1 + FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, PERIPH_CLK2_PODF));
634
+
635
+ trace_ccm_freq((uint32_t)freq);
636
+
637
+ return freq;
638
+}
639
+
640
+static uint64_t imx6ul_ccm_get_periph_sel_clk(IMX6ULCCMState *dev)
641
+{
642
+ uint64_t freq = 0;
643
+
644
+ switch (FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, PERIPH_CLK_SEL)) {
645
+ case 0:
646
+ freq = imx6ul_ccm_get_periph_clk_sel_clk(dev);
647
+ break;
648
+ case 1:
649
+ freq = imx6ul_ccm_get_periph_clk2_clk(dev);
650
+ break;
651
+ default:
652
+ g_assert_not_reached();
653
+ }
654
+
655
+ trace_ccm_freq((uint32_t)freq);
656
+
657
+ return freq;
658
+}
659
+
660
+static uint64_t imx6ul_ccm_get_ahb_clk(IMX6ULCCMState *dev)
661
+{
662
+ uint64_t freq = 0;
663
+
664
+ freq = imx6ul_ccm_get_periph_sel_clk(dev)
665
+ / (1 + FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, AHB_PODF));
666
+
667
+ trace_ccm_freq((uint32_t)freq);
668
+
669
+ return freq;
670
+}
671
+
672
+static uint64_t imx6ul_ccm_get_ipg_clk(IMX6ULCCMState *dev)
673
+{
674
+ uint64_t freq = 0;
675
+
676
+ freq = imx6ul_ccm_get_ahb_clk(dev)
677
+ / (1 + FIELD_EX32(dev->ccm[CCM_CBCDR], CBCDR, IPG_PODF));
678
+
679
+ trace_ccm_freq((uint32_t)freq);
680
+
681
+ return freq;
682
+}
683
+
684
+static uint64_t imx6ul_ccm_get_per_sel_clk(IMX6ULCCMState *dev)
685
+{
686
+ uint64_t freq = 0;
687
+
688
+ switch (FIELD_EX32(dev->ccm[CCM_CSCMR1], CSCMR1, PERCLK_CLK_SEL)) {
689
+ case 0:
690
+ freq = imx6ul_ccm_get_ipg_clk(dev);
691
+ break;
692
+ case 1:
693
+ freq = imx6ul_analog_get_osc_clk(dev);
694
+ break;
695
+ default:
696
+ g_assert_not_reached();
697
+ }
698
+
699
+ trace_ccm_freq((uint32_t)freq);
700
+
701
+ return freq;
702
+}
703
+
704
+static uint64_t imx6ul_ccm_get_per_clk(IMX6ULCCMState *dev)
705
+{
706
+ uint64_t freq = 0;
707
+
708
+ freq = imx6ul_ccm_get_per_sel_clk(dev)
709
+ / (1 + FIELD_EX32(dev->ccm[CCM_CSCMR1], CSCMR1, PERCLK_PODF));
710
+
711
+ trace_ccm_freq((uint32_t)freq);
712
+
713
+ return freq;
714
+}
715
+
716
+static uint32_t imx6ul_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
717
+{
718
+ uint32_t freq = 0;
719
+ IMX6ULCCMState *s = IMX6UL_CCM(dev);
720
+
721
+ switch (clock) {
722
+ case CLK_NONE:
723
+ break;
724
+ case CLK_IPG:
725
+ freq = imx6ul_ccm_get_ipg_clk(s);
726
+ break;
727
+ case CLK_IPG_HIGH:
728
+ freq = imx6ul_ccm_get_per_clk(s);
729
+ break;
730
+ case CLK_32k:
731
+ freq = CKIL_FREQ;
732
+ break;
733
+ case CLK_HIGH:
734
+ freq = CKIH_FREQ;
735
+ break;
736
+ case CLK_HIGH_DIV:
737
+ freq = CKIH_FREQ / 8;
738
+ break;
739
+ default:
740
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
741
+ TYPE_IMX6UL_CCM, __func__, clock);
742
+ break;
743
+ }
744
+
745
+ trace_ccm_clock_freq(clock, freq);
746
+
747
+ return freq;
748
+}
749
+
750
+static void imx6ul_ccm_reset(DeviceState *dev)
751
+{
752
+ IMX6ULCCMState *s = IMX6UL_CCM(dev);
753
+
754
+ trace_ccm_entry();
755
+
756
+ s->ccm[CCM_CCR] = 0x0401167F;
757
+ s->ccm[CCM_CCDR] = 0x00000000;
758
+ s->ccm[CCM_CSR] = 0x00000010;
759
+ s->ccm[CCM_CCSR] = 0x00000100;
760
+ s->ccm[CCM_CACRR] = 0x00000000;
761
+ s->ccm[CCM_CBCDR] = 0x00018D00;
762
+ s->ccm[CCM_CBCMR] = 0x24860324;
763
+ s->ccm[CCM_CSCMR1] = 0x04900080;
764
+ s->ccm[CCM_CSCMR2] = 0x03192F06;
765
+ s->ccm[CCM_CSCDR1] = 0x00490B00;
766
+ s->ccm[CCM_CS1CDR] = 0x0EC102C1;
767
+ s->ccm[CCM_CS2CDR] = 0x000336C1;
768
+ s->ccm[CCM_CDCDR] = 0x33F71F92;
769
+ s->ccm[CCM_CHSCCDR] = 0x000248A4;
770
+ s->ccm[CCM_CSCDR2] = 0x00029B48;
771
+ s->ccm[CCM_CSCDR3] = 0x00014841;
772
+ s->ccm[CCM_CDHIPR] = 0x00000000;
773
+ s->ccm[CCM_CTOR] = 0x00000000;
774
+ s->ccm[CCM_CLPCR] = 0x00000079;
775
+ s->ccm[CCM_CISR] = 0x00000000;
776
+ s->ccm[CCM_CIMR] = 0xFFFFFFFF;
777
+ s->ccm[CCM_CCOSR] = 0x000A0001;
778
+ s->ccm[CCM_CGPR] = 0x0000FE62;
779
+ s->ccm[CCM_CCGR0] = 0xFFFFFFFF;
780
+ s->ccm[CCM_CCGR1] = 0xFFFFFFFF;
781
+ s->ccm[CCM_CCGR2] = 0xFC3FFFFF;
782
+ s->ccm[CCM_CCGR3] = 0xFFFFFFFF;
783
+ s->ccm[CCM_CCGR4] = 0xFFFFFFFF;
784
+ s->ccm[CCM_CCGR5] = 0xFFFFFFFF;
785
+ s->ccm[CCM_CCGR6] = 0xFFFFFFFF;
786
+ s->ccm[CCM_CMEOR] = 0xFFFFFFFF;
787
+
788
+ s->analog[CCM_ANALOG_PLL_ARM] = 0x00013063;
789
+ s->analog[CCM_ANALOG_PLL_USB1] = 0x00012000;
790
+ s->analog[CCM_ANALOG_PLL_USB2] = 0x00012000;
791
+ s->analog[CCM_ANALOG_PLL_SYS] = 0x00013001;
792
+ s->analog[CCM_ANALOG_PLL_SYS_SS] = 0x00000000;
793
+ s->analog[CCM_ANALOG_PLL_SYS_NUM] = 0x00000000;
794
+ s->analog[CCM_ANALOG_PLL_SYS_DENOM] = 0x00000012;
795
+ s->analog[CCM_ANALOG_PLL_AUDIO] = 0x00011006;
796
+ s->analog[CCM_ANALOG_PLL_AUDIO_NUM] = 0x05F5E100;
797
+ s->analog[CCM_ANALOG_PLL_AUDIO_DENOM] = 0x2964619C;
798
+ s->analog[CCM_ANALOG_PLL_VIDEO] = 0x0001100C;
799
+ s->analog[CCM_ANALOG_PLL_VIDEO_NUM] = 0x05F5E100;
800
+ s->analog[CCM_ANALOG_PLL_VIDEO_DENOM] = 0x10A24447;
801
+ s->analog[CCM_ANALOG_PLL_ENET] = 0x00011001;
802
+ s->analog[CCM_ANALOG_PFD_480] = 0x1311100C;
803
+ s->analog[CCM_ANALOG_PFD_528] = 0x1018101B;
804
+
805
+ s->analog[PMU_REG_1P1] = 0x00001073;
806
+ s->analog[PMU_REG_3P0] = 0x00000F74;
807
+ s->analog[PMU_REG_2P5] = 0x00001073;
808
+ s->analog[PMU_REG_CORE] = 0x00482012;
809
+ s->analog[PMU_MISC0] = 0x04000000;
810
+ s->analog[PMU_MISC1] = 0x00000000;
811
+ s->analog[PMU_MISC2] = 0x00272727;
812
+ s->analog[PMU_LOWPWR_CTRL] = 0x00004009;
813
+
814
+ s->analog[USB_ANALOG_USB1_VBUS_DETECT] = 0x01000004;
815
+ s->analog[USB_ANALOG_USB1_CHRG_DETECT] = 0x00000000;
816
+ s->analog[USB_ANALOG_USB1_VBUS_DETECT_STAT] = 0x00000000;
817
+ s->analog[USB_ANALOG_USB1_CHRG_DETECT_STAT] = 0x00000000;
818
+ s->analog[USB_ANALOG_USB1_MISC] = 0x00000002;
819
+ s->analog[USB_ANALOG_USB2_VBUS_DETECT] = 0x01000004;
820
+ s->analog[USB_ANALOG_USB2_CHRG_DETECT] = 0x00000000;
821
+ s->analog[USB_ANALOG_USB2_MISC] = 0x00000002;
822
+ s->analog[USB_ANALOG_DIGPROG] = 0x00640000;
823
+
824
+ /* all PLLs need to be locked */
825
+ s->analog[CCM_ANALOG_PLL_ARM] |= CCM_ANALOG_PLL_LOCK;
826
+ s->analog[CCM_ANALOG_PLL_USB1] |= CCM_ANALOG_PLL_LOCK;
827
+ s->analog[CCM_ANALOG_PLL_USB2] |= CCM_ANALOG_PLL_LOCK;
828
+ s->analog[CCM_ANALOG_PLL_SYS] |= CCM_ANALOG_PLL_LOCK;
829
+ s->analog[CCM_ANALOG_PLL_AUDIO] |= CCM_ANALOG_PLL_LOCK;
830
+ s->analog[CCM_ANALOG_PLL_VIDEO] |= CCM_ANALOG_PLL_LOCK;
831
+ s->analog[CCM_ANALOG_PLL_ENET] |= CCM_ANALOG_PLL_LOCK;
832
+
833
+ s->analog[TEMPMON_TEMPSENSE0] = 0x00000001;
834
+ s->analog[TEMPMON_TEMPSENSE1] = 0x00000001;
835
+ s->analog[TEMPMON_TEMPSENSE2] = 0x00000000;
836
+}
837
+
838
+static uint64_t imx6ul_ccm_read(void *opaque, hwaddr offset, unsigned size)
839
+{
840
+ uint32_t value = 0;
841
+ uint32_t index = offset >> 2;
842
+ IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
843
+
844
+ assert(index < CCM_MAX);
845
+
846
+ value = s->ccm[index];
847
+
848
+ trace_ccm_read_reg(imx6ul_ccm_reg_name(index), (uint32_t)value);
849
+
850
+ return (uint64_t)value;
851
+}
852
+
853
+static void imx6ul_ccm_write(void *opaque, hwaddr offset, uint64_t value,
854
+ unsigned size)
855
+{
856
+ uint32_t index = offset >> 2;
857
+ IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
858
+
859
+ assert(index < CCM_MAX);
860
+
861
+ trace_ccm_write_reg(imx6ul_ccm_reg_name(index), (uint32_t)value);
862
+
863
+ /*
864
+ * We will do a better implementation later. In particular some bits
865
+ * cannot be written to.
866
+ */
867
+ s->ccm[index] = (uint32_t)value;
868
+}
869
+
870
+static uint64_t imx6ul_analog_read(void *opaque, hwaddr offset, unsigned size)
871
+{
872
+ uint32_t value;
873
+ uint32_t index = offset >> 2;
874
+ IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
875
+
876
+ assert(index < CCM_ANALOG_MAX);
877
+
878
+ switch (index) {
879
+ case CCM_ANALOG_PLL_ARM_SET:
880
+ case CCM_ANALOG_PLL_USB1_SET:
881
+ case CCM_ANALOG_PLL_USB2_SET:
882
+ case CCM_ANALOG_PLL_SYS_SET:
883
+ case CCM_ANALOG_PLL_AUDIO_SET:
884
+ case CCM_ANALOG_PLL_VIDEO_SET:
885
+ case CCM_ANALOG_PLL_ENET_SET:
886
+ case CCM_ANALOG_PFD_480_SET:
887
+ case CCM_ANALOG_PFD_528_SET:
888
+ case CCM_ANALOG_MISC0_SET:
889
+ case PMU_MISC1_SET:
890
+ case CCM_ANALOG_MISC2_SET:
891
+ case USB_ANALOG_USB1_VBUS_DETECT_SET:
892
+ case USB_ANALOG_USB1_CHRG_DETECT_SET:
893
+ case USB_ANALOG_USB1_MISC_SET:
894
+ case USB_ANALOG_USB2_VBUS_DETECT_SET:
895
+ case USB_ANALOG_USB2_CHRG_DETECT_SET:
896
+ case USB_ANALOG_USB2_MISC_SET:
897
+ case TEMPMON_TEMPSENSE0_SET:
898
+ case TEMPMON_TEMPSENSE1_SET:
899
+ case TEMPMON_TEMPSENSE2_SET:
900
+ /*
901
+ * All REG_NAME_SET register access are in fact targeting
902
+ * the REG_NAME register.
903
+ */
904
+ value = s->analog[index - 1];
905
+ break;
906
+ case CCM_ANALOG_PLL_ARM_CLR:
907
+ case CCM_ANALOG_PLL_USB1_CLR:
908
+ case CCM_ANALOG_PLL_USB2_CLR:
909
+ case CCM_ANALOG_PLL_SYS_CLR:
910
+ case CCM_ANALOG_PLL_AUDIO_CLR:
911
+ case CCM_ANALOG_PLL_VIDEO_CLR:
912
+ case CCM_ANALOG_PLL_ENET_CLR:
913
+ case CCM_ANALOG_PFD_480_CLR:
914
+ case CCM_ANALOG_PFD_528_CLR:
915
+ case CCM_ANALOG_MISC0_CLR:
916
+ case PMU_MISC1_CLR:
917
+ case CCM_ANALOG_MISC2_CLR:
918
+ case USB_ANALOG_USB1_VBUS_DETECT_CLR:
919
+ case USB_ANALOG_USB1_CHRG_DETECT_CLR:
920
+ case USB_ANALOG_USB1_MISC_CLR:
921
+ case USB_ANALOG_USB2_VBUS_DETECT_CLR:
922
+ case USB_ANALOG_USB2_CHRG_DETECT_CLR:
923
+ case USB_ANALOG_USB2_MISC_CLR:
924
+ case TEMPMON_TEMPSENSE0_CLR:
925
+ case TEMPMON_TEMPSENSE1_CLR:
926
+ case TEMPMON_TEMPSENSE2_CLR:
927
+ /*
928
+ * All REG_NAME_CLR register access are in fact targeting
929
+ * the REG_NAME register.
930
+ */
931
+ value = s->analog[index - 2];
932
+ break;
933
+ case CCM_ANALOG_PLL_ARM_TOG:
934
+ case CCM_ANALOG_PLL_USB1_TOG:
935
+ case CCM_ANALOG_PLL_USB2_TOG:
936
+ case CCM_ANALOG_PLL_SYS_TOG:
937
+ case CCM_ANALOG_PLL_AUDIO_TOG:
938
+ case CCM_ANALOG_PLL_VIDEO_TOG:
939
+ case CCM_ANALOG_PLL_ENET_TOG:
940
+ case CCM_ANALOG_PFD_480_TOG:
941
+ case CCM_ANALOG_PFD_528_TOG:
942
+ case CCM_ANALOG_MISC0_TOG:
943
+ case PMU_MISC1_TOG:
944
+ case CCM_ANALOG_MISC2_TOG:
945
+ case USB_ANALOG_USB1_VBUS_DETECT_TOG:
946
+ case USB_ANALOG_USB1_CHRG_DETECT_TOG:
947
+ case USB_ANALOG_USB1_MISC_TOG:
948
+ case USB_ANALOG_USB2_VBUS_DETECT_TOG:
949
+ case USB_ANALOG_USB2_CHRG_DETECT_TOG:
950
+ case USB_ANALOG_USB2_MISC_TOG:
951
+ case TEMPMON_TEMPSENSE0_TOG:
952
+ case TEMPMON_TEMPSENSE1_TOG:
953
+ case TEMPMON_TEMPSENSE2_TOG:
954
+ /*
955
+ * All REG_NAME_TOG register access are in fact targeting
956
+ * the REG_NAME register.
957
+ */
958
+ value = s->analog[index - 3];
959
+ break;
960
+ default:
961
+ value = s->analog[index];
962
+ break;
963
+ }
964
+
965
+ trace_ccm_read_reg(imx6ul_analog_reg_name(index), (uint32_t)value);
966
+
967
+ return (uint64_t)value;
968
+}
969
+
970
+static void imx6ul_analog_write(void *opaque, hwaddr offset, uint64_t value,
971
+ unsigned size)
972
+{
973
+ uint32_t index = offset >> 2;
974
+ IMX6ULCCMState *s = (IMX6ULCCMState *)opaque;
975
+
976
+ assert(index < CCM_ANALOG_MAX);
977
+
978
+ trace_ccm_write_reg(imx6ul_analog_reg_name(index), (uint32_t)value);
979
+
980
+ switch (index) {
981
+ case CCM_ANALOG_PLL_ARM_SET:
982
+ case CCM_ANALOG_PLL_USB1_SET:
983
+ case CCM_ANALOG_PLL_USB2_SET:
984
+ case CCM_ANALOG_PLL_SYS_SET:
985
+ case CCM_ANALOG_PLL_AUDIO_SET:
986
+ case CCM_ANALOG_PLL_VIDEO_SET:
987
+ case CCM_ANALOG_PLL_ENET_SET:
988
+ case CCM_ANALOG_PFD_480_SET:
989
+ case CCM_ANALOG_PFD_528_SET:
990
+ case CCM_ANALOG_MISC0_SET:
991
+ case PMU_MISC1_SET:
992
+ case CCM_ANALOG_MISC2_SET:
993
+ case USB_ANALOG_USB1_VBUS_DETECT_SET:
994
+ case USB_ANALOG_USB1_CHRG_DETECT_SET:
995
+ case USB_ANALOG_USB1_MISC_SET:
996
+ case USB_ANALOG_USB2_VBUS_DETECT_SET:
997
+ case USB_ANALOG_USB2_CHRG_DETECT_SET:
998
+ case USB_ANALOG_USB2_MISC_SET:
999
+ /*
1000
+ * All REG_NAME_SET register access are in fact targeting
1001
+ * the REG_NAME register. So we change the value of the
1002
+ * REG_NAME register, setting bits passed in the value.
1003
+ */
1004
+ s->analog[index - 1] |= value;
1005
+ break;
1006
+ case CCM_ANALOG_PLL_ARM_CLR:
1007
+ case CCM_ANALOG_PLL_USB1_CLR:
1008
+ case CCM_ANALOG_PLL_USB2_CLR:
1009
+ case CCM_ANALOG_PLL_SYS_CLR:
1010
+ case CCM_ANALOG_PLL_AUDIO_CLR:
1011
+ case CCM_ANALOG_PLL_VIDEO_CLR:
1012
+ case CCM_ANALOG_PLL_ENET_CLR:
1013
+ case CCM_ANALOG_PFD_480_CLR:
1014
+ case CCM_ANALOG_PFD_528_CLR:
1015
+ case CCM_ANALOG_MISC0_CLR:
1016
+ case PMU_MISC1_CLR:
1017
+ case CCM_ANALOG_MISC2_CLR:
1018
+ case USB_ANALOG_USB1_VBUS_DETECT_CLR:
1019
+ case USB_ANALOG_USB1_CHRG_DETECT_CLR:
1020
+ case USB_ANALOG_USB1_MISC_CLR:
1021
+ case USB_ANALOG_USB2_VBUS_DETECT_CLR:
1022
+ case USB_ANALOG_USB2_CHRG_DETECT_CLR:
1023
+ case USB_ANALOG_USB2_MISC_CLR:
1024
+ /*
1025
+ * All REG_NAME_CLR register access are in fact targeting
1026
+ * the REG_NAME register. So we change the value of the
1027
+ * REG_NAME register, unsetting bits passed in the value.
1028
+ */
1029
+ s->analog[index - 2] &= ~value;
1030
+ break;
1031
+ case CCM_ANALOG_PLL_ARM_TOG:
1032
+ case CCM_ANALOG_PLL_USB1_TOG:
1033
+ case CCM_ANALOG_PLL_USB2_TOG:
1034
+ case CCM_ANALOG_PLL_SYS_TOG:
1035
+ case CCM_ANALOG_PLL_AUDIO_TOG:
1036
+ case CCM_ANALOG_PLL_VIDEO_TOG:
1037
+ case CCM_ANALOG_PLL_ENET_TOG:
1038
+ case CCM_ANALOG_PFD_480_TOG:
1039
+ case CCM_ANALOG_PFD_528_TOG:
1040
+ case CCM_ANALOG_MISC0_TOG:
1041
+ case PMU_MISC1_TOG:
1042
+ case CCM_ANALOG_MISC2_TOG:
1043
+ case USB_ANALOG_USB1_VBUS_DETECT_TOG:
1044
+ case USB_ANALOG_USB1_CHRG_DETECT_TOG:
1045
+ case USB_ANALOG_USB1_MISC_TOG:
1046
+ case USB_ANALOG_USB2_VBUS_DETECT_TOG:
1047
+ case USB_ANALOG_USB2_CHRG_DETECT_TOG:
1048
+ case USB_ANALOG_USB2_MISC_TOG:
1049
+ /*
1050
+ * All REG_NAME_TOG register access are in fact targeting
1051
+ * the REG_NAME register. So we change the value of the
1052
+ * REG_NAME register, toggling bits passed in the value.
1053
+ */
1054
+ s->analog[index - 3] ^= value;
1055
+ break;
1056
+ default:
1057
+ /*
1058
+ * We will do a better implementation later. In particular some bits
1059
+ * cannot be written to.
1060
+ */
1061
+ s->analog[index] = value;
1062
+ break;
1063
+ }
1064
+}
1065
+
1066
+static const struct MemoryRegionOps imx6ul_ccm_ops = {
1067
+ .read = imx6ul_ccm_read,
1068
+ .write = imx6ul_ccm_write,
1069
+ .endianness = DEVICE_NATIVE_ENDIAN,
1070
+ .valid = {
1071
+ /*
1072
+ * Our device would not work correctly if the guest was doing
1073
+ * unaligned access. This might not be a limitation on the real
1074
+ * device but in practice there is no reason for a guest to access
1075
+ * this device unaligned.
1076
+ */
1077
+ .min_access_size = 4,
1078
+ .max_access_size = 4,
1079
+ .unaligned = false,
1080
+ },
1081
+};
1082
+
1083
+static const struct MemoryRegionOps imx6ul_analog_ops = {
1084
+ .read = imx6ul_analog_read,
1085
+ .write = imx6ul_analog_write,
1086
+ .endianness = DEVICE_NATIVE_ENDIAN,
1087
+ .valid = {
1088
+ /*
1089
+ * Our device would not work correctly if the guest was doing
1090
+ * unaligned access. This might not be a limitation on the real
1091
+ * device but in practice there is no reason for a guest to access
1092
+ * this device unaligned.
1093
+ */
1094
+ .min_access_size = 4,
1095
+ .max_access_size = 4,
1096
+ .unaligned = false,
1097
+ },
1098
+};
1099
+
1100
+static void imx6ul_ccm_init(Object *obj)
1101
+{
1102
+ DeviceState *dev = DEVICE(obj);
1103
+ SysBusDevice *sd = SYS_BUS_DEVICE(obj);
1104
+ IMX6ULCCMState *s = IMX6UL_CCM(obj);
1105
+
1106
+ /* initialize a container for the all memory range */
1107
+ memory_region_init(&s->container, OBJECT(dev), TYPE_IMX6UL_CCM, 0x8000);
1108
+
1109
+ /* We initialize an IO memory region for the CCM part */
1110
+ memory_region_init_io(&s->ioccm, OBJECT(dev), &imx6ul_ccm_ops, s,
1111
+ TYPE_IMX6UL_CCM ".ccm", CCM_MAX * sizeof(uint32_t));
1112
+
1113
+ /* Add the CCM as a subregion at offset 0 */
1114
+ memory_region_add_subregion(&s->container, 0, &s->ioccm);
1115
+
1116
+ /* We initialize an IO memory region for the ANALOG part */
1117
+ memory_region_init_io(&s->ioanalog, OBJECT(dev), &imx6ul_analog_ops, s,
1118
+ TYPE_IMX6UL_CCM ".analog",
1119
+ CCM_ANALOG_MAX * sizeof(uint32_t));
1120
+
1121
+ /* Add the ANALOG as a subregion at offset 0x4000 */
1122
+ memory_region_add_subregion(&s->container, 0x4000, &s->ioanalog);
1123
+
1124
+ sysbus_init_mmio(sd, &s->container);
1125
+}
1126
+
1127
+static void imx6ul_ccm_class_init(ObjectClass *klass, void *data)
1128
+{
1129
+ DeviceClass *dc = DEVICE_CLASS(klass);
1130
+ IMXCCMClass *ccm = IMX_CCM_CLASS(klass);
1131
+
1132
+ dc->reset = imx6ul_ccm_reset;
1133
+ dc->vmsd = &vmstate_imx6ul_ccm;
1134
+ dc->desc = "i.MX6UL Clock Control Module";
1135
+
1136
+ ccm->get_clock_frequency = imx6ul_ccm_get_clock_frequency;
1137
+}
1138
+
1139
+static const TypeInfo imx6ul_ccm_info = {
1140
+ .name = TYPE_IMX6UL_CCM,
1141
+ .parent = TYPE_IMX_CCM,
1142
+ .instance_size = sizeof(IMX6ULCCMState),
1143
+ .instance_init = imx6ul_ccm_init,
1144
+ .class_init = imx6ul_ccm_class_init,
1145
+};
1146
+
1147
+static void imx6ul_ccm_register_types(void)
1148
+{
1149
+ type_register_static(&imx6ul_ccm_info);
1150
+}
1151
+
1152
+type_init(imx6ul_ccm_register_types)
1153
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
1154
index XXXXXXX..XXXXXXX 100644
1155
--- a/hw/misc/trace-events
1156
+++ b/hw/misc/trace-events
1157
@@ -XXX,XX +XXX,XX @@ iotkit_secctl_s_write(uint32_t offset, uint64_t data, unsigned size) "IoTKit Sec
1158
iotkit_secctl_ns_read(uint32_t offset, uint64_t data, unsigned size) "IoTKit SecCtl NS regs read: offset 0x%x data 0x%" PRIx64 " size %u"
1159
iotkit_secctl_ns_write(uint32_t offset, uint64_t data, unsigned size) "IoTKit SecCtl NS regs write: offset 0x%x data 0x%" PRIx64 " size %u"
1160
iotkit_secctl_reset(void) "IoTKit SecCtl: reset"
1161
+
1162
+# hw/misc/imx6ul_ccm.c
1163
+ccm_entry(void) "\n"
1164
+ccm_freq(uint32_t freq) "freq = %d\n"
1165
+ccm_clock_freq(uint32_t clock, uint32_t freq) "(Clock = %d) = %d\n"
1166
+ccm_read_reg(const char *reg_name, uint32_t value) "reg[%s] <= 0x%" PRIx32 "\n"
1167
+ccm_write_reg(const char *reg_name, uint32_t value) "reg[%s] => 0x%" PRIx32 "\n"
98
--
1168
--
99
2.17.0
1169
2.18.0
100
1170
101
1171
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
These were missed out from the rest of the half-precision work.
3
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
4
4
Message-id: 3853ec555d68e7e25d726170833b775796151a07.1532984236.git.jcd@tribudubois.net
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20180512003217.9105-10-richard.henderson@linaro.org
11
[rth: Fix erroneous check vs type]
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
7
---
15
target/arm/translate-a64.c | 31 +++++++++++++++++++++++++------
8
hw/arm/Makefile.objs | 1 +
16
1 file changed, 25 insertions(+), 6 deletions(-)
9
include/hw/arm/fsl-imx6ul.h | 339 ++++++++++++++++++
10
hw/arm/fsl-imx6ul.c | 617 ++++++++++++++++++++++++++++++++
11
default-configs/arm-softmmu.mak | 1 +
12
4 files changed, 958 insertions(+)
13
create mode 100644 include/hw/arm/fsl-imx6ul.h
14
create mode 100644 hw/arm/fsl-imx6ul.c
17
15
18
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
19
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate-a64.c
18
--- a/hw/arm/Makefile.objs
21
+++ b/target/arm/translate-a64.c
19
+++ b/hw/arm/Makefile.objs
22
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
20
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
23
unsigned int mos, type, rm, cond, rn, rd;
21
obj-$(CONFIG_IOTKIT) += iotkit.o
24
TCGv_i64 t_true, t_false, t_zero;
22
obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
25
DisasCompare64 c;
23
obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
26
+ TCGMemOp sz;
24
+obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o
27
25
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
28
mos = extract32(insn, 29, 3);
26
new file mode 100644
29
- type = extract32(insn, 22, 2); /* 0 = single, 1 = double */
27
index XXXXXXX..XXXXXXX
30
+ type = extract32(insn, 22, 2);
28
--- /dev/null
31
rm = extract32(insn, 16, 5);
29
+++ b/include/hw/arm/fsl-imx6ul.h
32
cond = extract32(insn, 12, 4);
30
@@ -XXX,XX +XXX,XX @@
33
rn = extract32(insn, 5, 5);
31
+/*
34
rd = extract32(insn, 0, 5);
32
+ * Copyright (c) 2018 Jean-Christophe Dubois <jcd@tribudubois.net>
35
33
+ *
36
- if (mos || type > 1) {
34
+ * i.MX6ul SoC definitions
37
+ if (mos) {
35
+ *
38
+ unallocated_encoding(s);
36
+ * This program is free software; you can redistribute it and/or modify
37
+ * it under the terms of the GNU General Public License as published by
38
+ * the Free Software Foundation; either version 2 of the License, or
39
+ * (at your option) any later version.
40
+ *
41
+ * This program is distributed in the hope that it will be useful,
42
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
43
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
44
+ * GNU General Public License for more details.
45
+ */
46
+
47
+#ifndef FSL_IMX6UL_H
48
+#define FSL_IMX6UL_H
49
+
50
+#include "hw/arm/arm.h"
51
+#include "hw/cpu/a15mpcore.h"
52
+#include "hw/misc/imx6ul_ccm.h"
53
+#include "hw/misc/imx6_src.h"
54
+#include "hw/misc/imx7_snvs.h"
55
+#include "hw/misc/imx7_gpr.h"
56
+#include "hw/intc/imx_gpcv2.h"
57
+#include "hw/misc/imx2_wdt.h"
58
+#include "hw/gpio/imx_gpio.h"
59
+#include "hw/char/imx_serial.h"
60
+#include "hw/timer/imx_gpt.h"
61
+#include "hw/timer/imx_epit.h"
62
+#include "hw/i2c/imx_i2c.h"
63
+#include "hw/gpio/imx_gpio.h"
64
+#include "hw/sd/sdhci.h"
65
+#include "hw/ssi/imx_spi.h"
66
+#include "hw/net/imx_fec.h"
67
+#include "exec/memory.h"
68
+#include "cpu.h"
69
+
70
+#define TYPE_FSL_IMX6UL "fsl,imx6ul"
71
+#define FSL_IMX6UL(obj) OBJECT_CHECK(FslIMX6ULState, (obj), TYPE_FSL_IMX6UL)
72
+
73
+enum FslIMX6ULConfiguration {
74
+ FSL_IMX6UL_NUM_CPUS = 1,
75
+ FSL_IMX6UL_NUM_UARTS = 8,
76
+ FSL_IMX6UL_NUM_ETHS = 2,
77
+ FSL_IMX6UL_ETH_NUM_TX_RINGS = 2,
78
+ FSL_IMX6UL_NUM_USDHCS = 2,
79
+ FSL_IMX6UL_NUM_WDTS = 3,
80
+ FSL_IMX6UL_NUM_GPTS = 2,
81
+ FSL_IMX6UL_NUM_EPITS = 2,
82
+ FSL_IMX6UL_NUM_IOMUXCS = 2,
83
+ FSL_IMX6UL_NUM_GPIOS = 5,
84
+ FSL_IMX6UL_NUM_I2CS = 4,
85
+ FSL_IMX6UL_NUM_ECSPIS = 4,
86
+ FSL_IMX6UL_NUM_ADCS = 2,
87
+};
88
+
89
+typedef struct FslIMX6ULState {
90
+ /*< private >*/
91
+ DeviceState parent_obj;
92
+
93
+ /*< public >*/
94
+ ARMCPU cpu[FSL_IMX6UL_NUM_CPUS];
95
+ A15MPPrivState a7mpcore;
96
+ IMXGPTState gpt[FSL_IMX6UL_NUM_GPTS];
97
+ IMXEPITState epit[FSL_IMX6UL_NUM_EPITS];
98
+ IMXGPIOState gpio[FSL_IMX6UL_NUM_GPIOS];
99
+ IMX6ULCCMState ccm;
100
+ IMX6SRCState src;
101
+ IMX7SNVSState snvs;
102
+ IMXGPCv2State gpcv2;
103
+ IMX7GPRState gpr;
104
+ IMXSPIState spi[FSL_IMX6UL_NUM_ECSPIS];
105
+ IMXI2CState i2c[FSL_IMX6UL_NUM_I2CS];
106
+ IMXSerialState uart[FSL_IMX6UL_NUM_UARTS];
107
+ IMXFECState eth[FSL_IMX6UL_NUM_ETHS];
108
+ SDHCIState usdhc[FSL_IMX6UL_NUM_USDHCS];
109
+ IMX2WdtState wdt[FSL_IMX6UL_NUM_WDTS];
110
+ MemoryRegion rom;
111
+ MemoryRegion caam;
112
+ MemoryRegion ocram;
113
+ MemoryRegion ocram_alias;
114
+} FslIMX6ULState;
115
+
116
+enum FslIMX6ULMemoryMap {
117
+ FSL_IMX6UL_MMDC_ADDR = 0x80000000,
118
+ FSL_IMX6UL_MMDC_SIZE = 2 * 1024 * 1024 * 1024UL,
119
+
120
+ FSL_IMX6UL_QSPI1_MEM_ADDR = 0x60000000,
121
+ FSL_IMX6UL_EIM_ALIAS_ADDR = 0x58000000,
122
+ FSL_IMX6UL_EIM_CS_ADDR = 0x50000000,
123
+ FSL_IMX6UL_AES_ENCRYPT_ADDR = 0x10000000,
124
+ FSL_IMX6UL_QSPI1_RX_ADDR = 0x0C000000,
125
+
126
+ /* AIPS-2 */
127
+ FSL_IMX6UL_UART6_ADDR = 0x021FC000,
128
+ FSL_IMX6UL_I2C4_ADDR = 0x021F8000,
129
+ FSL_IMX6UL_UART5_ADDR = 0x021F4000,
130
+ FSL_IMX6UL_UART4_ADDR = 0x021F0000,
131
+ FSL_IMX6UL_UART3_ADDR = 0x021EC000,
132
+ FSL_IMX6UL_UART2_ADDR = 0x021E8000,
133
+ FSL_IMX6UL_WDOG3_ADDR = 0x021E4000,
134
+ FSL_IMX6UL_QSPI_ADDR = 0x021E0000,
135
+ FSL_IMX6UL_SYS_CNT_CTRL_ADDR = 0x021DC000,
136
+ FSL_IMX6UL_SYS_CNT_CMP_ADDR = 0x021D8000,
137
+ FSL_IMX6UL_SYS_CNT_RD_ADDR = 0x021D4000,
138
+ FSL_IMX6UL_TZASC_ADDR = 0x021D0000,
139
+ FSL_IMX6UL_PXP_ADDR = 0x021CC000,
140
+ FSL_IMX6UL_LCDIF_ADDR = 0x021C8000,
141
+ FSL_IMX6UL_CSI_ADDR = 0x021C4000,
142
+ FSL_IMX6UL_CSU_ADDR = 0x021C0000,
143
+ FSL_IMX6UL_OCOTP_CTRL_ADDR = 0x021BC000,
144
+ FSL_IMX6UL_EIM_ADDR = 0x021B8000,
145
+ FSL_IMX6UL_SIM2_ADDR = 0x021B4000,
146
+ FSL_IMX6UL_MMDC_CFG_ADDR = 0x021B0000,
147
+ FSL_IMX6UL_ROMCP_ADDR = 0x021AC000,
148
+ FSL_IMX6UL_I2C3_ADDR = 0x021A8000,
149
+ FSL_IMX6UL_I2C2_ADDR = 0x021A4000,
150
+ FSL_IMX6UL_I2C1_ADDR = 0x021A0000,
151
+ FSL_IMX6UL_ADC2_ADDR = 0x0219C000,
152
+ FSL_IMX6UL_ADC1_ADDR = 0x02198000,
153
+ FSL_IMX6UL_USDHC2_ADDR = 0x02194000,
154
+ FSL_IMX6UL_USDHC1_ADDR = 0x02190000,
155
+ FSL_IMX6UL_SIM1_ADDR = 0x0218C000,
156
+ FSL_IMX6UL_ENET1_ADDR = 0x02188000,
157
+ FSL_IMX6UL_USBO2_USBMISC_ADDR = 0x02184800,
158
+ FSL_IMX6UL_USBO2_USB_ADDR = 0x02184000,
159
+ FSL_IMX6UL_USBO2_PL301_ADDR = 0x02180000,
160
+ FSL_IMX6UL_AIPS2_CFG_ADDR = 0x0217C000,
161
+ FSL_IMX6UL_CAAM_ADDR = 0x02140000,
162
+ FSL_IMX6UL_A7MPCORE_DAP_ADDR = 0x02100000,
163
+
164
+ /* AIPS-1 */
165
+ FSL_IMX6UL_PWM8_ADDR = 0x020FC000,
166
+ FSL_IMX6UL_PWM7_ADDR = 0x020F8000,
167
+ FSL_IMX6UL_PWM6_ADDR = 0x020F4000,
168
+ FSL_IMX6UL_PWM5_ADDR = 0x020F0000,
169
+ FSL_IMX6UL_SDMA_ADDR = 0x020EC000,
170
+ FSL_IMX6UL_GPT2_ADDR = 0x020E8000,
171
+ FSL_IMX6UL_IOMUXC_GPR_ADDR = 0x020E4000,
172
+ FSL_IMX6UL_IOMUXC_ADDR = 0x020E0000,
173
+ FSL_IMX6UL_GPC_ADDR = 0x020DC000,
174
+ FSL_IMX6UL_SRC_ADDR = 0x020D8000,
175
+ FSL_IMX6UL_EPIT2_ADDR = 0x020D4000,
176
+ FSL_IMX6UL_EPIT1_ADDR = 0x020D0000,
177
+ FSL_IMX6UL_SNVS_HP_ADDR = 0x020CC000,
178
+ FSL_IMX6UL_ANALOG_ADDR = 0x020C8000,
179
+ FSL_IMX6UL_CCM_ADDR = 0x020C4000,
180
+ FSL_IMX6UL_WDOG2_ADDR = 0x020C0000,
181
+ FSL_IMX6UL_WDOG1_ADDR = 0x020BC000,
182
+ FSL_IMX6UL_KPP_ADDR = 0x020B8000,
183
+ FSL_IMX6UL_ENET2_ADDR = 0x020B4000,
184
+ FSL_IMX6UL_SNVS_LP_ADDR = 0x020B0000,
185
+ FSL_IMX6UL_GPIO5_ADDR = 0x020AC000,
186
+ FSL_IMX6UL_GPIO4_ADDR = 0x020A8000,
187
+ FSL_IMX6UL_GPIO3_ADDR = 0x020A4000,
188
+ FSL_IMX6UL_GPIO2_ADDR = 0x020A0000,
189
+ FSL_IMX6UL_GPIO1_ADDR = 0x0209C000,
190
+ FSL_IMX6UL_GPT1_ADDR = 0x02098000,
191
+ FSL_IMX6UL_CAN2_ADDR = 0x02094000,
192
+ FSL_IMX6UL_CAN1_ADDR = 0x02090000,
193
+ FSL_IMX6UL_PWM4_ADDR = 0x0208C000,
194
+ FSL_IMX6UL_PWM3_ADDR = 0x02088000,
195
+ FSL_IMX6UL_PWM2_ADDR = 0x02084000,
196
+ FSL_IMX6UL_PWM1_ADDR = 0x02080000,
197
+ FSL_IMX6UL_AIPS1_CFG_ADDR = 0x0207C000,
198
+ FSL_IMX6UL_BEE_ADDR = 0x02044000,
199
+ FSL_IMX6UL_TOUCH_CTRL_ADDR = 0x02040000,
200
+ FSL_IMX6UL_SPBA_ADDR = 0x0203C000,
201
+ FSL_IMX6UL_ASRC_ADDR = 0x02034000,
202
+ FSL_IMX6UL_SAI3_ADDR = 0x02030000,
203
+ FSL_IMX6UL_SAI2_ADDR = 0x0202C000,
204
+ FSL_IMX6UL_SAI1_ADDR = 0x02028000,
205
+ FSL_IMX6UL_UART8_ADDR = 0x02024000,
206
+ FSL_IMX6UL_UART1_ADDR = 0x02020000,
207
+ FSL_IMX6UL_UART7_ADDR = 0x02018000,
208
+ FSL_IMX6UL_ECSPI4_ADDR = 0x02014000,
209
+ FSL_IMX6UL_ECSPI3_ADDR = 0x02010000,
210
+ FSL_IMX6UL_ECSPI2_ADDR = 0x0200C000,
211
+ FSL_IMX6UL_ECSPI1_ADDR = 0x02008000,
212
+ FSL_IMX6UL_SPDIF_ADDR = 0x02004000,
213
+
214
+ FSL_IMX6UL_APBH_DMA_ADDR = 0x01804000,
215
+ FSL_IMX6UL_APBH_DMA_SIZE = (32 * 1024),
216
+
217
+ FSL_IMX6UL_A7MPCORE_ADDR = 0x00A00000,
218
+
219
+ FSL_IMX6UL_OCRAM_ALIAS_ADDR = 0x00920000,
220
+ FSL_IMX6UL_OCRAM_ALIAS_SIZE = 0x00060000,
221
+ FSL_IMX6UL_OCRAM_MEM_ADDR = 0x00900000,
222
+ FSL_IMX6UL_OCRAM_MEM_SIZE = 0x00020000,
223
+ FSL_IMX6UL_CAAM_MEM_ADDR = 0x00100000,
224
+ FSL_IMX6UL_CAAM_MEM_SIZE = 0x00008000,
225
+ FSL_IMX6UL_ROM_ADDR = 0x00000000,
226
+ FSL_IMX6UL_ROM_SIZE = 0x00018000,
227
+};
228
+
229
+enum FslIMX6ULIRQs {
230
+ FSL_IMX6UL_IOMUXC_IRQ = 0,
231
+ FSL_IMX6UL_DAP_IRQ = 1,
232
+ FSL_IMX6UL_SDMA_IRQ = 2,
233
+ FSL_IMX6UL_TSC_IRQ = 3,
234
+ FSL_IMX6UL_SNVS_IRQ = 4,
235
+ FSL_IMX6UL_LCDIF_IRQ = 5,
236
+ FSL_IMX6UL_BEE_IRQ = 6,
237
+ FSL_IMX6UL_CSI_IRQ = 7,
238
+ FSL_IMX6UL_PXP_IRQ = 8,
239
+ FSL_IMX6UL_SCTR1_IRQ = 9,
240
+ FSL_IMX6UL_SCTR2_IRQ = 10,
241
+ FSL_IMX6UL_WDOG3_IRQ = 11,
242
+ FSL_IMX6UL_APBH_DMA_IRQ = 13,
243
+ FSL_IMX6UL_WEIM_IRQ = 14,
244
+ FSL_IMX6UL_RAWNAND1_IRQ = 15,
245
+ FSL_IMX6UL_RAWNAND2_IRQ = 16,
246
+ FSL_IMX6UL_UART6_IRQ = 17,
247
+ FSL_IMX6UL_SRTC_IRQ = 19,
248
+ FSL_IMX6UL_SRTC_SEC_IRQ = 20,
249
+ FSL_IMX6UL_CSU_IRQ = 21,
250
+ FSL_IMX6UL_USDHC1_IRQ = 22,
251
+ FSL_IMX6UL_USDHC2_IRQ = 23,
252
+ FSL_IMX6UL_SAI3_IRQ = 24,
253
+ FSL_IMX6UL_SAI32_IRQ = 25,
254
+
255
+ FSL_IMX6UL_UART1_IRQ = 26,
256
+ FSL_IMX6UL_UART2_IRQ = 27,
257
+ FSL_IMX6UL_UART3_IRQ = 28,
258
+ FSL_IMX6UL_UART4_IRQ = 29,
259
+ FSL_IMX6UL_UART5_IRQ = 30,
260
+
261
+ FSL_IMX6UL_ECSPI1_IRQ = 31,
262
+ FSL_IMX6UL_ECSPI2_IRQ = 32,
263
+ FSL_IMX6UL_ECSPI3_IRQ = 33,
264
+ FSL_IMX6UL_ECSPI4_IRQ = 34,
265
+
266
+ FSL_IMX6UL_I2C4_IRQ = 35,
267
+ FSL_IMX6UL_I2C1_IRQ = 36,
268
+ FSL_IMX6UL_I2C2_IRQ = 37,
269
+ FSL_IMX6UL_I2C3_IRQ = 38,
270
+
271
+ FSL_IMX6UL_UART7_IRQ = 39,
272
+ FSL_IMX6UL_UART8_IRQ = 40,
273
+
274
+ FSL_IMX6UL_USB1_IRQ = 42,
275
+ FSL_IMX6UL_USB2_IRQ = 43,
276
+ FSL_IMX6UL_USB_PHY1_IRQ = 44,
277
+ FSL_IMX6UL_USB_PHY2_IRQ = 44,
278
+
279
+ FSL_IMX6UL_CAAM_JQ2_IRQ = 46,
280
+ FSL_IMX6UL_CAAM_ERR_IRQ = 47,
281
+ FSL_IMX6UL_CAAM_RTIC_IRQ = 48,
282
+ FSL_IMX6UL_TEMP_IRQ = 49,
283
+ FSL_IMX6UL_ASRC_IRQ = 50,
284
+ FSL_IMX6UL_SPDIF_IRQ = 52,
285
+ FSL_IMX6UL_PMU_REG_IRQ = 54,
286
+ FSL_IMX6UL_GPT1_IRQ = 55,
287
+
288
+ FSL_IMX6UL_EPIT1_IRQ = 56,
289
+ FSL_IMX6UL_EPIT2_IRQ = 57,
290
+
291
+ FSL_IMX6UL_GPIO1_INT7_IRQ = 58,
292
+ FSL_IMX6UL_GPIO1_INT6_IRQ = 59,
293
+ FSL_IMX6UL_GPIO1_INT5_IRQ = 60,
294
+ FSL_IMX6UL_GPIO1_INT4_IRQ = 61,
295
+ FSL_IMX6UL_GPIO1_INT3_IRQ = 62,
296
+ FSL_IMX6UL_GPIO1_INT2_IRQ = 63,
297
+ FSL_IMX6UL_GPIO1_INT1_IRQ = 64,
298
+ FSL_IMX6UL_GPIO1_INT0_IRQ = 65,
299
+ FSL_IMX6UL_GPIO1_LOW_IRQ = 66,
300
+ FSL_IMX6UL_GPIO1_HIGH_IRQ = 67,
301
+ FSL_IMX6UL_GPIO2_LOW_IRQ = 68,
302
+ FSL_IMX6UL_GPIO2_HIGH_IRQ = 69,
303
+ FSL_IMX6UL_GPIO3_LOW_IRQ = 70,
304
+ FSL_IMX6UL_GPIO3_HIGH_IRQ = 71,
305
+ FSL_IMX6UL_GPIO4_LOW_IRQ = 72,
306
+ FSL_IMX6UL_GPIO4_HIGH_IRQ = 73,
307
+ FSL_IMX6UL_GPIO5_LOW_IRQ = 74,
308
+ FSL_IMX6UL_GPIO5_HIGH_IRQ = 75,
309
+
310
+ FSL_IMX6UL_WDOG1_IRQ = 80,
311
+ FSL_IMX6UL_WDOG2_IRQ = 81,
312
+
313
+ FSL_IMX6UL_KPP_IRQ = 82,
314
+
315
+ FSL_IMX6UL_PWM1_IRQ = 83,
316
+ FSL_IMX6UL_PWM2_IRQ = 84,
317
+ FSL_IMX6UL_PWM3_IRQ = 85,
318
+ FSL_IMX6UL_PWM4_IRQ = 86,
319
+
320
+ FSL_IMX6UL_CCM1_IRQ = 87,
321
+ FSL_IMX6UL_CCM2_IRQ = 88,
322
+
323
+ FSL_IMX6UL_GPC_IRQ = 89,
324
+
325
+ FSL_IMX6UL_SRC_IRQ = 91,
326
+
327
+ FSL_IMX6UL_CPU_PERF_IRQ = 94,
328
+ FSL_IMX6UL_CPU_CTI_IRQ = 95,
329
+
330
+ FSL_IMX6UL_SRC_WDOG_IRQ = 96,
331
+
332
+ FSL_IMX6UL_SAI1_IRQ = 97,
333
+ FSL_IMX6UL_SAI2_IRQ = 98,
334
+
335
+ FSL_IMX6UL_ADC1_IRQ = 100,
336
+ FSL_IMX6UL_ADC2_IRQ = 101,
337
+
338
+ FSL_IMX6UL_SJC_IRQ = 104,
339
+
340
+ FSL_IMX6UL_CAAM_RING0_IRQ = 105,
341
+ FSL_IMX6UL_CAAM_RING1_IRQ = 106,
342
+
343
+ FSL_IMX6UL_QSPI_IRQ = 107,
344
+
345
+ FSL_IMX6UL_TZASC_IRQ = 108,
346
+
347
+ FSL_IMX6UL_GPT2_IRQ = 109,
348
+
349
+ FSL_IMX6UL_CAN1_IRQ = 110,
350
+ FSL_IMX6UL_CAN2_IRQ = 111,
351
+
352
+ FSL_IMX6UL_SIM1_IRQ = 112,
353
+ FSL_IMX6UL_SIM2_IRQ = 113,
354
+
355
+ FSL_IMX6UL_PWM5_IRQ = 114,
356
+ FSL_IMX6UL_PWM6_IRQ = 115,
357
+ FSL_IMX6UL_PWM7_IRQ = 116,
358
+ FSL_IMX6UL_PWM8_IRQ = 117,
359
+
360
+ FSL_IMX6UL_ENET1_IRQ = 118,
361
+ FSL_IMX6UL_ENET1_TIMER_IRQ = 119,
362
+ FSL_IMX6UL_ENET2_IRQ = 120,
363
+ FSL_IMX6UL_ENET2_TIMER_IRQ = 121,
364
+
365
+ FSL_IMX6UL_PMU_CORE_IRQ = 127,
366
+ FSL_IMX6UL_MAX_IRQ = 128,
367
+};
368
+
369
+#endif /* FSL_IMX6UL_H */
370
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
371
new file mode 100644
372
index XXXXXXX..XXXXXXX
373
--- /dev/null
374
+++ b/hw/arm/fsl-imx6ul.c
375
@@ -XXX,XX +XXX,XX @@
376
+/*
377
+ * Copyright (c) 2018 Jean-Christophe Dubois <jcd@tribudubois.net>
378
+ *
379
+ * i.MX6UL SOC emulation.
380
+ *
381
+ * Based on hw/arm/fsl-imx7.c
382
+ *
383
+ * This program is free software; you can redistribute it and/or modify
384
+ * it under the terms of the GNU General Public License as published by
385
+ * the Free Software Foundation; either version 2 of the License, or
386
+ * (at your option) any later version.
387
+ *
388
+ * This program is distributed in the hope that it will be useful,
389
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
390
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
391
+ * GNU General Public License for more details.
392
+ */
393
+
394
+#include "qemu/osdep.h"
395
+#include "qapi/error.h"
396
+#include "qemu-common.h"
397
+#include "hw/arm/fsl-imx6ul.h"
398
+#include "hw/misc/unimp.h"
399
+#include "sysemu/sysemu.h"
400
+#include "qemu/error-report.h"
401
+
402
+#define NAME_SIZE 20
403
+
404
+static void fsl_imx6ul_init(Object *obj)
405
+{
406
+ FslIMX6ULState *s = FSL_IMX6UL(obj);
407
+ char name[NAME_SIZE];
408
+ int i;
409
+
410
+ for (i = 0; i < MIN(smp_cpus, FSL_IMX6UL_NUM_CPUS); i++) {
411
+ snprintf(name, NAME_SIZE, "cpu%d", i);
412
+ object_initialize_child(obj, name, &s->cpu[i], sizeof(s->cpu[i]),
413
+ "cortex-a7-" TYPE_ARM_CPU, &error_abort, NULL);
414
+ }
415
+
416
+ /*
417
+ * A7MPCORE
418
+ */
419
+ sysbus_init_child_obj(obj, "a7mpcore", &s->a7mpcore, sizeof(s->a7mpcore),
420
+ TYPE_A15MPCORE_PRIV);
421
+
422
+ /*
423
+ * CCM
424
+ */
425
+ sysbus_init_child_obj(obj, "ccm", &s->ccm, sizeof(s->ccm), TYPE_IMX6UL_CCM);
426
+
427
+ /*
428
+ * SRC
429
+ */
430
+ sysbus_init_child_obj(obj, "src", &s->src, sizeof(s->src), TYPE_IMX6_SRC);
431
+
432
+ /*
433
+ * GPCv2
434
+ */
435
+ sysbus_init_child_obj(obj, "gpcv2", &s->gpcv2, sizeof(s->gpcv2),
436
+ TYPE_IMX_GPCV2);
437
+
438
+ /*
439
+ * SNVS
440
+ */
441
+ sysbus_init_child_obj(obj, "snvs", &s->snvs, sizeof(s->snvs),
442
+ TYPE_IMX7_SNVS);
443
+
444
+ /*
445
+ * GPR
446
+ */
447
+ sysbus_init_child_obj(obj, "gpr", &s->gpr, sizeof(s->gpr),
448
+ TYPE_IMX7_GPR);
449
+
450
+ /*
451
+ * GPIOs 1 to 5
452
+ */
453
+ for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
454
+ snprintf(name, NAME_SIZE, "gpio%d", i);
455
+ sysbus_init_child_obj(obj, name, &s->gpio[i], sizeof(s->gpio[i]),
456
+ TYPE_IMX_GPIO);
457
+ }
458
+
459
+ /*
460
+ * GPT 1, 2
461
+ */
462
+ for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
463
+ snprintf(name, NAME_SIZE, "gpt%d", i);
464
+ sysbus_init_child_obj(obj, name, &s->gpt[i], sizeof(s->gpt[i]),
465
+ TYPE_IMX7_GPT);
466
+ }
467
+
468
+ /*
469
+ * EPIT 1, 2
470
+ */
471
+ for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
472
+ snprintf(name, NAME_SIZE, "epit%d", i + 1);
473
+ sysbus_init_child_obj(obj, name, &s->epit[i], sizeof(s->epit[i]),
474
+ TYPE_IMX_EPIT);
475
+ }
476
+
477
+ /*
478
+ * eCSPI
479
+ */
480
+ for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
481
+ snprintf(name, NAME_SIZE, "spi%d", i + 1);
482
+ sysbus_init_child_obj(obj, name, &s->spi[i], sizeof(s->spi[i]),
483
+ TYPE_IMX_SPI);
484
+ }
485
+
486
+ /*
487
+ * I2C
488
+ */
489
+ for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
490
+ snprintf(name, NAME_SIZE, "i2c%d", i + 1);
491
+ sysbus_init_child_obj(obj, name, &s->i2c[i], sizeof(s->i2c[i]),
492
+ TYPE_IMX_I2C);
493
+ }
494
+
495
+ /*
496
+ * UART
497
+ */
498
+ for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
499
+ snprintf(name, NAME_SIZE, "uart%d", i);
500
+ sysbus_init_child_obj(obj, name, &s->uart[i], sizeof(s->uart[i]),
501
+ TYPE_IMX_SERIAL);
502
+ }
503
+
504
+ /*
505
+ * Ethernet
506
+ */
507
+ for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
508
+ snprintf(name, NAME_SIZE, "eth%d", i);
509
+ sysbus_init_child_obj(obj, name, &s->eth[i], sizeof(s->eth[i]),
510
+ TYPE_IMX_ENET);
511
+ }
512
+
513
+ /*
514
+ * SDHCI
515
+ */
516
+ for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
517
+ snprintf(name, NAME_SIZE, "usdhc%d", i);
518
+ sysbus_init_child_obj(obj, name, &s->usdhc[i], sizeof(s->usdhc[i]),
519
+ TYPE_IMX_USDHC);
520
+ }
521
+
522
+ /*
523
+ * Watchdog
524
+ */
525
+ for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
526
+ snprintf(name, NAME_SIZE, "wdt%d", i);
527
+ sysbus_init_child_obj(obj, name, &s->wdt[i], sizeof(s->wdt[i]),
528
+ TYPE_IMX2_WDT);
529
+ }
530
+}
531
+
532
+static void fsl_imx6ul_realize(DeviceState *dev, Error **errp)
533
+{
534
+ FslIMX6ULState *s = FSL_IMX6UL(dev);
535
+ int i;
536
+ qemu_irq irq;
537
+ char name[NAME_SIZE];
538
+
539
+ if (smp_cpus > FSL_IMX6UL_NUM_CPUS) {
540
+ error_setg(errp, "%s: Only %d CPUs are supported (%d requested)",
541
+ TYPE_FSL_IMX6UL, FSL_IMX6UL_NUM_CPUS, smp_cpus);
39
+ return;
542
+ return;
40
+ }
543
+ }
41
+
544
+
42
+ switch (type) {
545
+ for (i = 0; i < smp_cpus; i++) {
43
+ case 0:
546
+ Object *o = OBJECT(&s->cpu[i]);
44
+ sz = MO_32;
547
+
45
+ break;
548
+ object_property_set_int(o, QEMU_PSCI_CONDUIT_SMC,
46
+ case 1:
549
+ "psci-conduit", &error_abort);
47
+ sz = MO_64;
550
+
48
+ break;
551
+ /* On uniprocessor, the CBAR is set to 0 */
49
+ case 3:
552
+ if (smp_cpus > 1) {
50
+ sz = MO_16;
553
+ object_property_set_int(o, FSL_IMX6UL_A7MPCORE_ADDR,
51
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
554
+ "reset-cbar", &error_abort);
52
+ break;
53
+ }
555
+ }
54
+ /* fallthru */
556
+
55
+ default:
557
+ if (i) {
56
unallocated_encoding(s);
558
+ /* Secondary CPUs start in PSCI powered-down state */
57
return;
559
+ object_property_set_bool(o, true,
58
}
560
+ "start-powered-off", &error_abort);
59
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
561
+ }
60
return;
562
+
61
}
563
+ object_property_set_bool(o, true, "realized", &error_abort);
62
564
+ }
63
- /* Zero extend sreg inputs to 64 bits now. */
565
+
64
+ /* Zero extend sreg & hreg inputs to 64 bits now. */
566
+ /*
65
t_true = tcg_temp_new_i64();
567
+ * A7MPCORE
66
t_false = tcg_temp_new_i64();
568
+ */
67
- read_vec_element(s, t_true, rn, 0, type ? MO_64 : MO_32);
569
+ object_property_set_int(OBJECT(&s->a7mpcore), smp_cpus, "num-cpu",
68
- read_vec_element(s, t_false, rm, 0, type ? MO_64 : MO_32);
570
+ &error_abort);
69
+ read_vec_element(s, t_true, rn, 0, sz);
571
+ object_property_set_int(OBJECT(&s->a7mpcore),
70
+ read_vec_element(s, t_false, rm, 0, sz);
572
+ FSL_IMX6UL_MAX_IRQ + GIC_INTERNAL,
71
573
+ "num-irq", &error_abort);
72
a64_test_cc(&c, cond);
574
+ object_property_set_bool(OBJECT(&s->a7mpcore), true, "realized",
73
t_zero = tcg_const_i64(0);
575
+ &error_abort);
74
@@ -XXX,XX +XXX,XX @@ static void disas_fp_csel(DisasContext *s, uint32_t insn)
576
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->a7mpcore), 0, FSL_IMX6UL_A7MPCORE_ADDR);
75
tcg_temp_free_i64(t_false);
577
+
76
a64_free_cc(&c);
578
+ for (i = 0; i < smp_cpus; i++) {
77
579
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->a7mpcore);
78
- /* Note that sregs write back zeros to the high bits,
580
+ DeviceState *d = DEVICE(qemu_get_cpu(i));
79
+ /* Note that sregs & hregs write back zeros to the high bits,
581
+
80
and we've already done the zero-extension. */
582
+ irq = qdev_get_gpio_in(d, ARM_CPU_IRQ);
81
write_fp_dreg(s, rd, t_true);
583
+ sysbus_connect_irq(sbd, i, irq);
82
tcg_temp_free_i64(t_true);
584
+ sysbus_connect_irq(sbd, i + smp_cpus, qdev_get_gpio_in(d, ARM_CPU_FIQ));
585
+ }
586
+
587
+ /*
588
+ * A7MPCORE DAP
589
+ */
590
+ create_unimplemented_device("a7mpcore-dap", FSL_IMX6UL_A7MPCORE_DAP_ADDR,
591
+ 0x100000);
592
+
593
+ /*
594
+ * GPT 1, 2
595
+ */
596
+ for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
597
+ static const hwaddr FSL_IMX6UL_GPTn_ADDR[FSL_IMX6UL_NUM_GPTS] = {
598
+ FSL_IMX6UL_GPT1_ADDR,
599
+ FSL_IMX6UL_GPT2_ADDR,
600
+ };
601
+
602
+ static const int FSL_IMX6UL_GPTn_IRQ[FSL_IMX6UL_NUM_GPTS] = {
603
+ FSL_IMX6UL_GPT1_IRQ,
604
+ FSL_IMX6UL_GPT2_IRQ,
605
+ };
606
+
607
+ s->gpt[i].ccm = IMX_CCM(&s->ccm);
608
+ object_property_set_bool(OBJECT(&s->gpt[i]), true, "realized",
609
+ &error_abort);
610
+
611
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0,
612
+ FSL_IMX6UL_GPTn_ADDR[i]);
613
+
614
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
615
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
616
+ FSL_IMX6UL_GPTn_IRQ[i]));
617
+ }
618
+
619
+ /*
620
+ * EPIT 1, 2
621
+ */
622
+ for (i = 0; i < FSL_IMX6UL_NUM_EPITS; i++) {
623
+ static const hwaddr FSL_IMX6UL_EPITn_ADDR[FSL_IMX6UL_NUM_EPITS] = {
624
+ FSL_IMX6UL_EPIT1_ADDR,
625
+ FSL_IMX6UL_EPIT2_ADDR,
626
+ };
627
+
628
+ static const int FSL_IMX6UL_EPITn_IRQ[FSL_IMX6UL_NUM_EPITS] = {
629
+ FSL_IMX6UL_EPIT1_IRQ,
630
+ FSL_IMX6UL_EPIT2_IRQ,
631
+ };
632
+
633
+ s->epit[i].ccm = IMX_CCM(&s->ccm);
634
+ object_property_set_bool(OBJECT(&s->epit[i]), true, "realized",
635
+ &error_abort);
636
+
637
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->epit[i]), 0,
638
+ FSL_IMX6UL_EPITn_ADDR[i]);
639
+
640
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->epit[i]), 0,
641
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
642
+ FSL_IMX6UL_EPITn_IRQ[i]));
643
+ }
644
+
645
+ /*
646
+ * GPIO
647
+ */
648
+ for (i = 0; i < FSL_IMX6UL_NUM_GPIOS; i++) {
649
+ static const hwaddr FSL_IMX6UL_GPIOn_ADDR[FSL_IMX6UL_NUM_GPIOS] = {
650
+ FSL_IMX6UL_GPIO1_ADDR,
651
+ FSL_IMX6UL_GPIO2_ADDR,
652
+ FSL_IMX6UL_GPIO3_ADDR,
653
+ FSL_IMX6UL_GPIO4_ADDR,
654
+ FSL_IMX6UL_GPIO5_ADDR,
655
+ };
656
+
657
+ static const int FSL_IMX6UL_GPIOn_LOW_IRQ[FSL_IMX6UL_NUM_GPIOS] = {
658
+ FSL_IMX6UL_GPIO1_LOW_IRQ,
659
+ FSL_IMX6UL_GPIO2_LOW_IRQ,
660
+ FSL_IMX6UL_GPIO3_LOW_IRQ,
661
+ FSL_IMX6UL_GPIO4_LOW_IRQ,
662
+ FSL_IMX6UL_GPIO5_LOW_IRQ,
663
+ };
664
+
665
+ static const int FSL_IMX6UL_GPIOn_HIGH_IRQ[FSL_IMX6UL_NUM_GPIOS] = {
666
+ FSL_IMX6UL_GPIO1_HIGH_IRQ,
667
+ FSL_IMX6UL_GPIO2_HIGH_IRQ,
668
+ FSL_IMX6UL_GPIO3_HIGH_IRQ,
669
+ FSL_IMX6UL_GPIO4_HIGH_IRQ,
670
+ FSL_IMX6UL_GPIO5_HIGH_IRQ,
671
+ };
672
+
673
+ object_property_set_bool(OBJECT(&s->gpio[i]), true, "realized",
674
+ &error_abort);
675
+
676
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0,
677
+ FSL_IMX6UL_GPIOn_ADDR[i]);
678
+
679
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
680
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
681
+ FSL_IMX6UL_GPIOn_LOW_IRQ[i]));
682
+
683
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
684
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
685
+ FSL_IMX6UL_GPIOn_HIGH_IRQ[i]));
686
+ }
687
+
688
+ /*
689
+ * IOMUXC and IOMUXC_GPR
690
+ */
691
+ for (i = 0; i < 1; i++) {
692
+ static const hwaddr FSL_IMX6UL_IOMUXCn_ADDR[FSL_IMX6UL_NUM_IOMUXCS] = {
693
+ FSL_IMX6UL_IOMUXC_ADDR,
694
+ FSL_IMX6UL_IOMUXC_GPR_ADDR,
695
+ };
696
+
697
+ snprintf(name, NAME_SIZE, "iomuxc%d", i);
698
+ create_unimplemented_device(name, FSL_IMX6UL_IOMUXCn_ADDR[i], 0x4000);
699
+ }
700
+
701
+ /*
702
+ * CCM
703
+ */
704
+ object_property_set_bool(OBJECT(&s->ccm), true, "realized", &error_abort);
705
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->ccm), 0, FSL_IMX6UL_CCM_ADDR);
706
+
707
+ /*
708
+ * SRC
709
+ */
710
+ object_property_set_bool(OBJECT(&s->src), true, "realized", &error_abort);
711
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->src), 0, FSL_IMX6UL_SRC_ADDR);
712
+
713
+ /*
714
+ * GPCv2
715
+ */
716
+ object_property_set_bool(OBJECT(&s->gpcv2), true,
717
+ "realized", &error_abort);
718
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpcv2), 0, FSL_IMX6UL_GPC_ADDR);
719
+
720
+ /* Initialize all ECSPI */
721
+ for (i = 0; i < FSL_IMX6UL_NUM_ECSPIS; i++) {
722
+ static const hwaddr FSL_IMX6UL_SPIn_ADDR[FSL_IMX6UL_NUM_ECSPIS] = {
723
+ FSL_IMX6UL_ECSPI1_ADDR,
724
+ FSL_IMX6UL_ECSPI2_ADDR,
725
+ FSL_IMX6UL_ECSPI3_ADDR,
726
+ FSL_IMX6UL_ECSPI4_ADDR,
727
+ };
728
+
729
+ static const int FSL_IMX6UL_SPIn_IRQ[FSL_IMX6UL_NUM_ECSPIS] = {
730
+ FSL_IMX6UL_ECSPI1_IRQ,
731
+ FSL_IMX6UL_ECSPI2_IRQ,
732
+ FSL_IMX6UL_ECSPI3_IRQ,
733
+ FSL_IMX6UL_ECSPI4_IRQ,
734
+ };
735
+
736
+ /* Initialize the SPI */
737
+ object_property_set_bool(OBJECT(&s->spi[i]), true, "realized",
738
+ &error_abort);
739
+
740
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->spi[i]), 0,
741
+ FSL_IMX6UL_SPIn_ADDR[i]);
742
+
743
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->spi[i]), 0,
744
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
745
+ FSL_IMX6UL_SPIn_IRQ[i]));
746
+ }
747
+
748
+ /*
749
+ * I2C
750
+ */
751
+ for (i = 0; i < FSL_IMX6UL_NUM_I2CS; i++) {
752
+ static const hwaddr FSL_IMX6UL_I2Cn_ADDR[FSL_IMX6UL_NUM_I2CS] = {
753
+ FSL_IMX6UL_I2C1_ADDR,
754
+ FSL_IMX6UL_I2C2_ADDR,
755
+ FSL_IMX6UL_I2C3_ADDR,
756
+ FSL_IMX6UL_I2C4_ADDR,
757
+ };
758
+
759
+ static const int FSL_IMX6UL_I2Cn_IRQ[FSL_IMX6UL_NUM_I2CS] = {
760
+ FSL_IMX6UL_I2C1_IRQ,
761
+ FSL_IMX6UL_I2C2_IRQ,
762
+ FSL_IMX6UL_I2C3_IRQ,
763
+ FSL_IMX6UL_I2C4_IRQ,
764
+ };
765
+
766
+ object_property_set_bool(OBJECT(&s->i2c[i]), true, "realized",
767
+ &error_abort);
768
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->i2c[i]), 0, FSL_IMX6UL_I2Cn_ADDR[i]);
769
+
770
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->i2c[i]), 0,
771
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
772
+ FSL_IMX6UL_I2Cn_IRQ[i]));
773
+ }
774
+
775
+ /*
776
+ * UART
777
+ */
778
+ for (i = 0; i < FSL_IMX6UL_NUM_UARTS; i++) {
779
+ static const hwaddr FSL_IMX6UL_UARTn_ADDR[FSL_IMX6UL_NUM_UARTS] = {
780
+ FSL_IMX6UL_UART1_ADDR,
781
+ FSL_IMX6UL_UART2_ADDR,
782
+ FSL_IMX6UL_UART3_ADDR,
783
+ FSL_IMX6UL_UART4_ADDR,
784
+ FSL_IMX6UL_UART5_ADDR,
785
+ FSL_IMX6UL_UART6_ADDR,
786
+ FSL_IMX6UL_UART7_ADDR,
787
+ FSL_IMX6UL_UART8_ADDR,
788
+ };
789
+
790
+ static const int FSL_IMX6UL_UARTn_IRQ[FSL_IMX6UL_NUM_UARTS] = {
791
+ FSL_IMX6UL_UART1_IRQ,
792
+ FSL_IMX6UL_UART2_IRQ,
793
+ FSL_IMX6UL_UART3_IRQ,
794
+ FSL_IMX6UL_UART4_IRQ,
795
+ FSL_IMX6UL_UART5_IRQ,
796
+ FSL_IMX6UL_UART6_IRQ,
797
+ FSL_IMX6UL_UART7_IRQ,
798
+ FSL_IMX6UL_UART8_IRQ,
799
+ };
800
+
801
+ qdev_prop_set_chr(DEVICE(&s->uart[i]), "chardev", serial_hd(i));
802
+
803
+ object_property_set_bool(OBJECT(&s->uart[i]), true, "realized",
804
+ &error_abort);
805
+
806
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart[i]), 0,
807
+ FSL_IMX6UL_UARTn_ADDR[i]);
808
+
809
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart[i]), 0,
810
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
811
+ FSL_IMX6UL_UARTn_IRQ[i]));
812
+ }
813
+
814
+ /*
815
+ * Ethernet
816
+ */
817
+ for (i = 0; i < FSL_IMX6UL_NUM_ETHS; i++) {
818
+ static const hwaddr FSL_IMX6UL_ENETn_ADDR[FSL_IMX6UL_NUM_ETHS] = {
819
+ FSL_IMX6UL_ENET1_ADDR,
820
+ FSL_IMX6UL_ENET2_ADDR,
821
+ };
822
+
823
+ static const int FSL_IMX6UL_ENETn_IRQ[FSL_IMX6UL_NUM_ETHS] = {
824
+ FSL_IMX6UL_ENET1_IRQ,
825
+ FSL_IMX6UL_ENET2_IRQ,
826
+ };
827
+
828
+ static const int FSL_IMX6UL_ENETn_TIMER_IRQ[FSL_IMX6UL_NUM_ETHS] = {
829
+ FSL_IMX6UL_ENET1_TIMER_IRQ,
830
+ FSL_IMX6UL_ENET2_TIMER_IRQ,
831
+ };
832
+
833
+ object_property_set_uint(OBJECT(&s->eth[i]),
834
+ FSL_IMX6UL_ETH_NUM_TX_RINGS,
835
+ "tx-ring-num", &error_abort);
836
+ qdev_set_nic_properties(DEVICE(&s->eth[i]), &nd_table[i]);
837
+ object_property_set_bool(OBJECT(&s->eth[i]), true, "realized",
838
+ &error_abort);
839
+
840
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->eth[i]), 0,
841
+ FSL_IMX6UL_ENETn_ADDR[i]);
842
+
843
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 0,
844
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
845
+ FSL_IMX6UL_ENETn_IRQ[i]));
846
+
847
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->eth[i]), 1,
848
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
849
+ FSL_IMX6UL_ENETn_TIMER_IRQ[i]));
850
+ }
851
+
852
+ /*
853
+ * USDHC
854
+ */
855
+ for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
856
+ static const hwaddr FSL_IMX6UL_USDHCn_ADDR[FSL_IMX6UL_NUM_USDHCS] = {
857
+ FSL_IMX6UL_USDHC1_ADDR,
858
+ FSL_IMX6UL_USDHC2_ADDR,
859
+ };
860
+
861
+ static const int FSL_IMX6UL_USDHCn_IRQ[FSL_IMX6UL_NUM_USDHCS] = {
862
+ FSL_IMX6UL_USDHC1_IRQ,
863
+ FSL_IMX6UL_USDHC2_IRQ,
864
+ };
865
+
866
+ object_property_set_bool(OBJECT(&s->usdhc[i]), true, "realized",
867
+ &error_abort);
868
+
869
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
870
+ FSL_IMX6UL_USDHCn_ADDR[i]);
871
+
872
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->usdhc[i]), 0,
873
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
874
+ FSL_IMX6UL_USDHCn_IRQ[i]));
875
+ }
876
+
877
+ /*
878
+ * SNVS
879
+ */
880
+ object_property_set_bool(OBJECT(&s->snvs), true, "realized", &error_abort);
881
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->snvs), 0, FSL_IMX6UL_SNVS_HP_ADDR);
882
+
883
+ /*
884
+ * Watchdog
885
+ */
886
+ for (i = 0; i < FSL_IMX6UL_NUM_WDTS; i++) {
887
+ static const hwaddr FSL_IMX6UL_WDOGn_ADDR[FSL_IMX6UL_NUM_WDTS] = {
888
+ FSL_IMX6UL_WDOG1_ADDR,
889
+ FSL_IMX6UL_WDOG2_ADDR,
890
+ FSL_IMX6UL_WDOG3_ADDR,
891
+ };
892
+
893
+ object_property_set_bool(OBJECT(&s->wdt[i]), true, "realized",
894
+ &error_abort);
895
+
896
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->wdt[i]), 0,
897
+ FSL_IMX6UL_WDOGn_ADDR[i]);
898
+ }
899
+
900
+ /*
901
+ * GPR
902
+ */
903
+ object_property_set_bool(OBJECT(&s->gpr), true, "realized",
904
+ &error_abort);
905
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpr), 0, FSL_IMX6UL_IOMUXC_GPR_ADDR);
906
+
907
+ /*
908
+ * SDMA
909
+ */
910
+ create_unimplemented_device("sdma", FSL_IMX6UL_SDMA_ADDR, 0x4000);
911
+
912
+ /*
913
+ * APHB_DMA
914
+ */
915
+ create_unimplemented_device("aphb_dma", FSL_IMX6UL_APBH_DMA_ADDR,
916
+ FSL_IMX6UL_APBH_DMA_SIZE);
917
+
918
+ /*
919
+ * ADCs
920
+ */
921
+ for (i = 0; i < FSL_IMX6UL_NUM_ADCS; i++) {
922
+ static const hwaddr FSL_IMX6UL_ADCn_ADDR[FSL_IMX6UL_NUM_ADCS] = {
923
+ FSL_IMX6UL_ADC1_ADDR,
924
+ FSL_IMX6UL_ADC2_ADDR,
925
+ };
926
+
927
+ snprintf(name, NAME_SIZE, "adc%d", i);
928
+ create_unimplemented_device(name, FSL_IMX6UL_ADCn_ADDR[i], 0x4000);
929
+ }
930
+
931
+ /*
932
+ * LCD
933
+ */
934
+ create_unimplemented_device("lcdif", FSL_IMX6UL_LCDIF_ADDR, 0x4000);
935
+
936
+ /*
937
+ * ROM memory
938
+ */
939
+ memory_region_init_rom(&s->rom, NULL, "imx6ul.rom",
940
+ FSL_IMX6UL_ROM_SIZE, &error_abort);
941
+ memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_ROM_ADDR,
942
+ &s->rom);
943
+
944
+ /*
945
+ * CAAM memory
946
+ */
947
+ memory_region_init_rom(&s->caam, NULL, "imx6ul.caam",
948
+ FSL_IMX6UL_CAAM_MEM_SIZE, &error_abort);
949
+ memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_CAAM_MEM_ADDR,
950
+ &s->caam);
951
+
952
+ /*
953
+ * OCRAM memory
954
+ */
955
+ memory_region_init_ram(&s->ocram, NULL, "imx6ul.ocram",
956
+ FSL_IMX6UL_OCRAM_MEM_SIZE,
957
+ &error_abort);
958
+ memory_region_add_subregion(get_system_memory(), FSL_IMX6UL_OCRAM_MEM_ADDR,
959
+ &s->ocram);
960
+
961
+ /*
962
+ * internal OCRAM (128 KB) is aliased over 512 KB
963
+ */
964
+ memory_region_init_alias(&s->ocram_alias, NULL, "imx6ul.ocram_alias",
965
+ &s->ocram, 0, FSL_IMX6UL_OCRAM_ALIAS_SIZE);
966
+ memory_region_add_subregion(get_system_memory(),
967
+ FSL_IMX6UL_OCRAM_ALIAS_ADDR, &s->ocram_alias);
968
+}
969
+
970
+static void fsl_imx6ul_class_init(ObjectClass *oc, void *data)
971
+{
972
+ DeviceClass *dc = DEVICE_CLASS(oc);
973
+
974
+ dc->realize = fsl_imx6ul_realize;
975
+ dc->desc = "i.MX6UL SOC";
976
+ /* Reason: Uses serial_hds and nd_table in realize() directly */
977
+ dc->user_creatable = false;
978
+}
979
+
980
+static const TypeInfo fsl_imx6ul_type_info = {
981
+ .name = TYPE_FSL_IMX6UL,
982
+ .parent = TYPE_DEVICE,
983
+ .instance_size = sizeof(FslIMX6ULState),
984
+ .instance_init = fsl_imx6ul_init,
985
+ .class_init = fsl_imx6ul_class_init,
986
+};
987
+
988
+static void fsl_imx6ul_register_types(void)
989
+{
990
+ type_register_static(&fsl_imx6ul_type_info);
991
+}
992
+type_init(fsl_imx6ul_register_types)
993
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
994
index XXXXXXX..XXXXXXX 100644
995
--- a/default-configs/arm-softmmu.mak
996
+++ b/default-configs/arm-softmmu.mak
997
@@ -XXX,XX +XXX,XX @@ CONFIG_FSL_IMX6=y
998
CONFIG_FSL_IMX31=y
999
CONFIG_FSL_IMX25=y
1000
CONFIG_FSL_IMX7=y
1001
+CONFIG_FSL_IMX6UL=y
1002
1003
CONFIG_IMX_I2C=y
1004
83
--
1005
--
84
2.17.0
1006
2.18.0
85
1007
86
1008
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
We missed all of the scalar fp16 fma operations.
3
Tested by booting linux 4.18 (built using imx_v6_v7_defconfig) on the
4
emulated board.
4
5
5
Cc: qemu-stable@nongnu.org
6
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
7
Message-id: 3f8eb4300206634dc01e04b12f65b73c0ad2f955.1532984236.git.jcd@tribudubois.net
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Message-id: 20180512003217.9105-8-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
10
---
12
target/arm/translate-a64.c | 48 ++++++++++++++++++++++++++++++++++++++
11
hw/arm/Makefile.objs | 2 +-
13
1 file changed, 48 insertions(+)
12
hw/arm/mcimx6ul-evk.c | 85 +++++++++++++++++++++++++++++++++++++++++++
13
2 files changed, 86 insertions(+), 1 deletion(-)
14
create mode 100644 hw/arm/mcimx6ul-evk.c
14
15
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
--- a/hw/arm/Makefile.objs
18
+++ b/target/arm/translate-a64.c
19
+++ b/hw/arm/Makefile.objs
19
@@ -XXX,XX +XXX,XX @@ static void handle_fp_3src_double(DisasContext *s, bool o0, bool o1,
20
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_MSF2) += msf2-soc.o msf2-som.o
20
tcg_temp_free_i64(tcg_res);
21
obj-$(CONFIG_IOTKIT) += iotkit.o
21
}
22
obj-$(CONFIG_FSL_IMX7) += fsl-imx7.o mcimx7d-sabre.o
22
23
obj-$(CONFIG_ARM_SMMUV3) += smmu-common.o smmuv3.o
23
+/* Floating-point data-processing (3 source) - half precision */
24
-obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o
24
+static void handle_fp_3src_half(DisasContext *s, bool o0, bool o1,
25
+obj-$(CONFIG_FSL_IMX6UL) += fsl-imx6ul.o mcimx6ul-evk.o
25
+ int rd, int rn, int rm, int ra)
26
diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
27
new file mode 100644
28
index XXXXXXX..XXXXXXX
29
--- /dev/null
30
+++ b/hw/arm/mcimx6ul-evk.c
31
@@ -XXX,XX +XXX,XX @@
32
+/*
33
+ * Copyright (c) 2018 Jean-Christophe Dubois <jcd@tribudubois.net>
34
+ *
35
+ * MCIMX6UL_EVK Board System emulation.
36
+ *
37
+ * This code is licensed under the GPL, version 2 or later.
38
+ * See the file `COPYING' in the top level directory.
39
+ *
40
+ * It (partially) emulates a mcimx6ul_evk board, with a Freescale
41
+ * i.MX6ul SoC
42
+ */
43
+
44
+#include "qemu/osdep.h"
45
+#include "qapi/error.h"
46
+#include "qemu-common.h"
47
+#include "hw/arm/fsl-imx6ul.h"
48
+#include "hw/boards.h"
49
+#include "sysemu/sysemu.h"
50
+#include "qemu/error-report.h"
51
+#include "sysemu/qtest.h"
52
+
53
+typedef struct {
54
+ FslIMX6ULState soc;
55
+ MemoryRegion ram;
56
+} MCIMX6ULEVK;
57
+
58
+static void mcimx6ul_evk_init(MachineState *machine)
26
+{
59
+{
27
+ TCGv_i32 tcg_op1, tcg_op2, tcg_op3;
60
+ static struct arm_boot_info boot_info;
28
+ TCGv_i32 tcg_res = tcg_temp_new_i32();
61
+ MCIMX6ULEVK *s = g_new0(MCIMX6ULEVK, 1);
29
+ TCGv_ptr fpst = get_fpstatus_ptr(true);
62
+ int i;
30
+
63
+
31
+ tcg_op1 = read_fp_hreg(s, rn);
64
+ if (machine->ram_size > FSL_IMX6UL_MMDC_SIZE) {
32
+ tcg_op2 = read_fp_hreg(s, rm);
65
+ error_report("RAM size " RAM_ADDR_FMT " above max supported (%08x)",
33
+ tcg_op3 = read_fp_hreg(s, ra);
66
+ machine->ram_size, FSL_IMX6UL_MMDC_SIZE);
34
+
67
+ exit(1);
35
+ /* These are fused multiply-add, and must be done as one
36
+ * floating point operation with no rounding between the
37
+ * multiplication and addition steps.
38
+ * NB that doing the negations here as separate steps is
39
+ * correct : an input NaN should come out with its sign bit
40
+ * flipped if it is a negated-input.
41
+ */
42
+ if (o1 == true) {
43
+ tcg_gen_xori_i32(tcg_op3, tcg_op3, 0x8000);
44
+ }
68
+ }
45
+
69
+
46
+ if (o0 != o1) {
70
+ boot_info = (struct arm_boot_info) {
47
+ tcg_gen_xori_i32(tcg_op1, tcg_op1, 0x8000);
71
+ .loader_start = FSL_IMX6UL_MMDC_ADDR,
72
+ .board_id = -1,
73
+ .ram_size = machine->ram_size,
74
+ .kernel_filename = machine->kernel_filename,
75
+ .kernel_cmdline = machine->kernel_cmdline,
76
+ .initrd_filename = machine->initrd_filename,
77
+ .nb_cpus = smp_cpus,
78
+ };
79
+
80
+ object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc),
81
+ TYPE_FSL_IMX6UL, &error_fatal, NULL);
82
+
83
+ object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);
84
+
85
+ memory_region_allocate_system_memory(&s->ram, NULL, "mcimx6ul-evk.ram",
86
+ machine->ram_size);
87
+ memory_region_add_subregion(get_system_memory(),
88
+ FSL_IMX6UL_MMDC_ADDR, &s->ram);
89
+
90
+ for (i = 0; i < FSL_IMX6UL_NUM_USDHCS; i++) {
91
+ BusState *bus;
92
+ DeviceState *carddev;
93
+ DriveInfo *di;
94
+ BlockBackend *blk;
95
+
96
+ di = drive_get_next(IF_SD);
97
+ blk = di ? blk_by_legacy_dinfo(di) : NULL;
98
+ bus = qdev_get_child_bus(DEVICE(&s->soc.usdhc[i]), "sd-bus");
99
+ carddev = qdev_create(bus, TYPE_SD_CARD);
100
+ qdev_prop_set_drive(carddev, "drive", blk, &error_fatal);
101
+ object_property_set_bool(OBJECT(carddev), true,
102
+ "realized", &error_fatal);
48
+ }
103
+ }
49
+
104
+
50
+ gen_helper_advsimd_muladdh(tcg_res, tcg_op1, tcg_op2, tcg_op3, fpst);
105
+ if (!qtest_enabled()) {
51
+
106
+ arm_load_kernel(&s->soc.cpu[0], &boot_info);
52
+ write_fp_sreg(s, rd, tcg_res);
107
+ }
53
+
54
+ tcg_temp_free_ptr(fpst);
55
+ tcg_temp_free_i32(tcg_op1);
56
+ tcg_temp_free_i32(tcg_op2);
57
+ tcg_temp_free_i32(tcg_op3);
58
+ tcg_temp_free_i32(tcg_res);
59
+}
108
+}
60
+
109
+
61
/* Floating point data-processing (3 source)
110
+static void mcimx6ul_evk_machine_init(MachineClass *mc)
62
* 31 30 29 28 24 23 22 21 20 16 15 14 10 9 5 4 0
111
+{
63
* +---+---+---+-----------+------+----+------+----+------+------+------+
112
+ mc->desc = "Freescale i.MX6UL Evaluation Kit (Cortex A7)";
64
@@ -XXX,XX +XXX,XX @@ static void disas_fp_3src(DisasContext *s, uint32_t insn)
113
+ mc->init = mcimx6ul_evk_init;
65
}
114
+ mc->max_cpus = FSL_IMX6UL_NUM_CPUS;
66
handle_fp_3src_double(s, o0, o1, rd, rn, rm, ra);
115
+}
67
break;
116
+DEFINE_MACHINE("mcimx6ul-evk", mcimx6ul_evk_machine_init)
68
+ case 3:
69
+ if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
70
+ unallocated_encoding(s);
71
+ return;
72
+ }
73
+ if (!fp_access_check(s)) {
74
+ return;
75
+ }
76
+ handle_fp_3src_half(s, o0, o1, rd, rn, rm, ra);
77
+ break;
78
default:
79
unallocated_encoding(s);
80
}
81
--
117
--
82
2.17.0
118
2.18.0
83
119
84
120
diff view generated by jsdifflib
New patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
2
3
Some ARM CPUs have bitbanded IO, a memory region that allows convenient
4
bit access via 32-bit memory loads/stores. This eliminates the need for
5
read-modify-update instruction sequences.
6
7
This patch makes this optional feature an ARMv7MState qdev property,
8
allowing boards to choose whether they want bitbanding or not.
9
10
Status of boards:
11
* iotkit (Cortex M33), no bitband
12
* mps2 (Cortex M3), bitband
13
* msf2 (Cortex M3), bitband
14
* stellaris (Cortex M3), bitband
15
* stm32f205 (Cortex M3), bitband
16
17
As a side-effect of this patch, Peter Maydell noted that the Ethernet
18
controller on mps2 board is now accessible. Previously they were hidden
19
by the bitband region (which does not exist on the real board).
20
21
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
22
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
23
Message-id: 20180814162739.11814-2-stefanha@redhat.com
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
25
---
26
include/hw/arm/armv7m.h | 2 ++
27
hw/arm/armv7m.c | 37 ++++++++++++++++++++-----------------
28
hw/arm/mps2.c | 1 +
29
hw/arm/msf2-soc.c | 1 +
30
hw/arm/stellaris.c | 1 +
31
hw/arm/stm32f205_soc.c | 1 +
32
6 files changed, 26 insertions(+), 17 deletions(-)
33
34
diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/arm/armv7m.h
37
+++ b/include/hw/arm/armv7m.h
38
@@ -XXX,XX +XXX,XX @@ typedef struct {
39
* devices will be automatically layered on top of this view.)
40
* + Property "idau": IDAU interface (forwarded to CPU object)
41
* + Property "init-svtor": secure VTOR reset value (forwarded to CPU object)
42
+ * + Property "enable-bitband": expose bitbanded IO
43
*/
44
typedef struct ARMv7MState {
45
/*< private >*/
46
@@ -XXX,XX +XXX,XX @@ typedef struct ARMv7MState {
47
MemoryRegion *board_memory;
48
Object *idau;
49
uint32_t init_svtor;
50
+ bool enable_bitband;
51
} ARMv7MState;
52
53
#endif
54
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/armv7m.c
57
+++ b/hw/arm/armv7m.c
58
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
59
memory_region_add_subregion(&s->container, 0xe000e000,
60
sysbus_mmio_get_region(sbd, 0));
61
62
- for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
63
- Object *obj = OBJECT(&s->bitband[i]);
64
- SysBusDevice *sbd = SYS_BUS_DEVICE(&s->bitband[i]);
65
+ if (s->enable_bitband) {
66
+ for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
67
+ Object *obj = OBJECT(&s->bitband[i]);
68
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->bitband[i]);
69
70
- object_property_set_int(obj, bitband_input_addr[i], "base", &err);
71
- if (err != NULL) {
72
- error_propagate(errp, err);
73
- return;
74
- }
75
- object_property_set_link(obj, OBJECT(s->board_memory),
76
- "source-memory", &error_abort);
77
- object_property_set_bool(obj, true, "realized", &err);
78
- if (err != NULL) {
79
- error_propagate(errp, err);
80
- return;
81
- }
82
+ object_property_set_int(obj, bitband_input_addr[i], "base", &err);
83
+ if (err != NULL) {
84
+ error_propagate(errp, err);
85
+ return;
86
+ }
87
+ object_property_set_link(obj, OBJECT(s->board_memory),
88
+ "source-memory", &error_abort);
89
+ object_property_set_bool(obj, true, "realized", &err);
90
+ if (err != NULL) {
91
+ error_propagate(errp, err);
92
+ return;
93
+ }
94
95
- memory_region_add_subregion(&s->container, bitband_output_addr[i],
96
- sysbus_mmio_get_region(sbd, 0));
97
+ memory_region_add_subregion(&s->container, bitband_output_addr[i],
98
+ sysbus_mmio_get_region(sbd, 0));
99
+ }
100
}
101
}
102
103
@@ -XXX,XX +XXX,XX @@ static Property armv7m_properties[] = {
104
MemoryRegion *),
105
DEFINE_PROP_LINK("idau", ARMv7MState, idau, TYPE_IDAU_INTERFACE, Object *),
106
DEFINE_PROP_UINT32("init-svtor", ARMv7MState, init_svtor, 0),
107
+ DEFINE_PROP_BOOL("enable-bitband", ARMv7MState, enable_bitband, false),
108
DEFINE_PROP_END_OF_LIST(),
109
};
110
111
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/hw/arm/mps2.c
114
+++ b/hw/arm/mps2.c
115
@@ -XXX,XX +XXX,XX @@ static void mps2_common_init(MachineState *machine)
116
g_assert_not_reached();
117
}
118
qdev_prop_set_string(armv7m, "cpu-type", machine->cpu_type);
119
+ qdev_prop_set_bit(armv7m, "enable-bitband", true);
120
object_property_set_link(OBJECT(&mms->armv7m), OBJECT(system_memory),
121
"memory", &error_abort);
122
object_property_set_bool(OBJECT(&mms->armv7m), true, "realized",
123
diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c
124
index XXXXXXX..XXXXXXX 100644
125
--- a/hw/arm/msf2-soc.c
126
+++ b/hw/arm/msf2-soc.c
127
@@ -XXX,XX +XXX,XX @@ static void m2sxxx_soc_realize(DeviceState *dev_soc, Error **errp)
128
armv7m = DEVICE(&s->armv7m);
129
qdev_prop_set_uint32(armv7m, "num-irq", 81);
130
qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
131
+ qdev_prop_set_bit(armv7m, "enable-bitband", true);
132
object_property_set_link(OBJECT(&s->armv7m), OBJECT(get_system_memory()),
133
"memory", &error_abort);
134
object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
135
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
136
index XXXXXXX..XXXXXXX 100644
137
--- a/hw/arm/stellaris.c
138
+++ b/hw/arm/stellaris.c
139
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
140
nvic = qdev_create(NULL, TYPE_ARMV7M);
141
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
142
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
143
+ qdev_prop_set_bit(nvic, "enable-bitband", true);
144
object_property_set_link(OBJECT(nvic), OBJECT(get_system_memory()),
145
"memory", &error_abort);
146
/* This will exit with an error if the user passed us a bad cpu_type */
147
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
148
index XXXXXXX..XXXXXXX 100644
149
--- a/hw/arm/stm32f205_soc.c
150
+++ b/hw/arm/stm32f205_soc.c
151
@@ -XXX,XX +XXX,XX @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
152
armv7m = DEVICE(&s->armv7m);
153
qdev_prop_set_uint32(armv7m, "num-irq", 96);
154
qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
155
+ qdev_prop_set_bit(armv7m, "enable-bitband", true);
156
object_property_set_link(OBJECT(&s->armv7m), OBJECT(get_system_memory()),
157
"memory", &error_abort);
158
object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
159
--
160
2.18.0
161
162
diff view generated by jsdifflib
1
In commit d81ce0ef2c4f105 we added an extra float_status field
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
fp_status_fp16 for Arm, but forgot to initialize it correctly
3
by setting it to float_tininess_before_rounding. This currently
4
will only cause problems for the new V8_FP16 feature, since the
5
float-to-float conversion code doesn't use it yet. The effect
6
would be that we failed to set the Underflow IEEE exception flag
7
in all the cases where we should.
8
2
9
Add the missing initialization.
3
Define a "cortex-m0" ARMv6-M CPU model.
10
4
11
Fixes: d81ce0ef2c4f105
5
Most of the register reset values set by other CPU models are not
12
Cc: qemu-stable@nongnu.org
6
relevant for the cut-down ARMv6-M architecture.
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
14
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20180814162739.11814-3-stefanha@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Message-id: 20180512004311.9299-16-richard.henderson@linaro.org
17
---
13
---
18
target/arm/cpu.c | 2 ++
14
target/arm/cpu.c | 11 +++++++++++
19
1 file changed, 2 insertions(+)
15
1 file changed, 11 insertions(+)
20
16
21
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
22
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/cpu.c
19
--- a/target/arm/cpu.c
24
+++ b/target/arm/cpu.c
20
+++ b/target/arm/cpu.c
25
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
21
@@ -XXX,XX +XXX,XX @@ static void arm11mpcore_initfn(Object *obj)
26
&env->vfp.fp_status);
22
cpu->reset_auxcr = 1;
27
set_float_detect_tininess(float_tininess_before_rounding,
23
}
28
&env->vfp.standard_fp_status);
24
29
+ set_float_detect_tininess(float_tininess_before_rounding,
25
+static void cortex_m0_initfn(Object *obj)
30
+ &env->vfp.fp_status_f16);
26
+{
31
#ifndef CONFIG_USER_ONLY
27
+ ARMCPU *cpu = ARM_CPU(obj);
32
if (kvm_enabled()) {
28
+ set_feature(&cpu->env, ARM_FEATURE_V6);
33
kvm_arm_reset_vcpu(cpu);
29
+ set_feature(&cpu->env, ARM_FEATURE_M);
30
+
31
+ cpu->midr = 0x410cc200;
32
+}
33
+
34
static void cortex_m3_initfn(Object *obj)
35
{
36
ARMCPU *cpu = ARM_CPU(obj);
37
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_cpus[] = {
38
{ .name = "arm1136", .initfn = arm1136_initfn },
39
{ .name = "arm1176", .initfn = arm1176_initfn },
40
{ .name = "arm11mpcore", .initfn = arm11mpcore_initfn },
41
+ { .name = "cortex-m0", .initfn = cortex_m0_initfn,
42
+ .class_init = arm_v7m_class_init },
43
{ .name = "cortex-m3", .initfn = cortex_m3_initfn,
44
.class_init = arm_v7m_class_init },
45
{ .name = "cortex-m4", .initfn = cortex_m4_initfn,
34
--
46
--
35
2.17.0
47
2.18.0
36
48
37
49
diff view generated by jsdifflib
New patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
2
3
The next patch will need to free a rom. There is already code to do
4
this in rom_add_file().
5
6
Note that rom_add_file() uses:
7
8
rom = g_malloc0(sizeof(*rom));
9
...
10
if (rom->fw_dir) {
11
g_free(rom->fw_dir);
12
g_free(rom->fw_file);
13
}
14
15
The conditional is unnecessary since g_free(NULL) is a no-op.
16
17
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Message-id: 20180814162739.11814-4-stefanha@redhat.com
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
hw/core/loader.c | 21 ++++++++++++---------
24
1 file changed, 12 insertions(+), 9 deletions(-)
25
26
diff --git a/hw/core/loader.c b/hw/core/loader.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/core/loader.c
29
+++ b/hw/core/loader.c
30
@@ -XXX,XX +XXX,XX @@ struct Rom {
31
static FWCfgState *fw_cfg;
32
static QTAILQ_HEAD(, Rom) roms = QTAILQ_HEAD_INITIALIZER(roms);
33
34
+/* rom->data must be heap-allocated (do not use with rom_add_elf_program()) */
35
+static void rom_free(Rom *rom)
36
+{
37
+ g_free(rom->data);
38
+ g_free(rom->path);
39
+ g_free(rom->name);
40
+ g_free(rom->fw_dir);
41
+ g_free(rom->fw_file);
42
+ g_free(rom);
43
+}
44
+
45
static inline bool rom_order_compare(Rom *rom, Rom *item)
46
{
47
return ((uintptr_t)(void *)rom->as > (uintptr_t)(void *)item->as) ||
48
@@ -XXX,XX +XXX,XX @@ err:
49
if (fd != -1)
50
close(fd);
51
52
- g_free(rom->data);
53
- g_free(rom->path);
54
- g_free(rom->name);
55
- if (fw_dir) {
56
- g_free(rom->fw_dir);
57
- g_free(rom->fw_file);
58
- }
59
- g_free(rom);
60
-
61
+ rom_free(rom);
62
return -1;
63
}
64
65
--
66
2.18.0
67
68
diff view generated by jsdifflib
New patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
1
2
3
Image file loaders may add a series of roms. If an error occurs partway
4
through loading there is no easy way to drop previously added roms.
5
6
This patch adds a transaction mechanism that works like this:
7
8
rom_transaction_begin();
9
...call rom_add_*()...
10
rom_transaction_end(ok);
11
12
If ok is false then roms added in this transaction are dropped.
13
14
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20180814162739.11814-5-stefanha@redhat.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
include/hw/loader.h | 19 +++++++++++++++++++
20
hw/core/loader.c | 32 ++++++++++++++++++++++++++++++++
21
2 files changed, 51 insertions(+)
22
23
diff --git a/include/hw/loader.h b/include/hw/loader.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/loader.h
26
+++ b/include/hw/loader.h
27
@@ -XXX,XX +XXX,XX @@ int rom_check_and_register_reset(void);
28
void rom_set_fw(FWCfgState *f);
29
void rom_set_order_override(int order);
30
void rom_reset_order_override(void);
31
+
32
+/**
33
+ * rom_transaction_begin:
34
+ *
35
+ * Call this before of a series of rom_add_*() calls. Call
36
+ * rom_transaction_end() afterwards to commit or abort. These functions are
37
+ * useful for undoing a series of rom_add_*() calls if image file loading fails
38
+ * partway through.
39
+ */
40
+void rom_transaction_begin(void);
41
+
42
+/**
43
+ * rom_transaction_end:
44
+ * @commit: true to commit added roms, false to drop added roms
45
+ *
46
+ * Call this after a series of rom_add_*() calls. See rom_transaction_begin().
47
+ */
48
+void rom_transaction_end(bool commit);
49
+
50
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
51
void *rom_ptr(hwaddr addr, size_t size);
52
void hmp_info_roms(Monitor *mon, const QDict *qdict);
53
diff --git a/hw/core/loader.c b/hw/core/loader.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/core/loader.c
56
+++ b/hw/core/loader.c
57
@@ -XXX,XX +XXX,XX @@ struct Rom {
58
char *fw_dir;
59
char *fw_file;
60
61
+ bool committed;
62
+
63
hwaddr addr;
64
QTAILQ_ENTRY(Rom) next;
65
};
66
@@ -XXX,XX +XXX,XX @@ static void rom_insert(Rom *rom)
67
rom->as = &address_space_memory;
68
}
69
70
+ rom->committed = false;
71
+
72
/* List is ordered by load address in the same address space */
73
QTAILQ_FOREACH(item, &roms, next) {
74
if (rom_order_compare(rom, item)) {
75
@@ -XXX,XX +XXX,XX @@ void rom_reset_order_override(void)
76
fw_cfg_reset_order_override(fw_cfg);
77
}
78
79
+void rom_transaction_begin(void)
80
+{
81
+ Rom *rom;
82
+
83
+ /* Ignore ROMs added without the transaction API */
84
+ QTAILQ_FOREACH(rom, &roms, next) {
85
+ rom->committed = true;
86
+ }
87
+}
88
+
89
+void rom_transaction_end(bool commit)
90
+{
91
+ Rom *rom;
92
+ Rom *tmp;
93
+
94
+ QTAILQ_FOREACH_SAFE(rom, &roms, next, tmp) {
95
+ if (rom->committed) {
96
+ continue;
97
+ }
98
+ if (commit) {
99
+ rom->committed = true;
100
+ } else {
101
+ QTAILQ_REMOVE(&roms, rom, next);
102
+ rom_free(rom);
103
+ }
104
+ }
105
+}
106
+
107
static Rom *find_rom(hwaddr addr, size_t size)
108
{
109
Rom *rom;
110
--
111
2.18.0
112
113
diff view generated by jsdifflib
New patch
1
1
From: Su Hang <suhang16@mails.ucas.ac.cn>
2
3
This patch adds Intel Hexadecimal Object File format support to the
4
generic loader device. The file format specification is available here:
5
http://www.piclist.com/techref/fileext/hex/intel.htm
6
7
This file format is often used with microcontrollers such as the
8
micro:bit, Arduino, STM32, etc. Users expect to be able to run .hex
9
files directly with without first converting them to ELF. Most
10
micro:bit code is developed in web-based IDEs without direct user access
11
to binutils so it is important for QEMU to handle this file format
12
natively.
13
14
Signed-off-by: Su Hang <suhang16@mails.ucas.ac.cn>
15
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
16
Acked-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-id: 20180814162739.11814-6-stefanha@redhat.com
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
include/hw/loader.h | 12 ++
21
hw/core/generic-loader.c | 4 +
22
hw/core/loader.c | 249 +++++++++++++++++++++++++++++++++++++++
23
3 files changed, 265 insertions(+)
24
25
diff --git a/include/hw/loader.h b/include/hw/loader.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/loader.h
28
+++ b/include/hw/loader.h
29
@@ -XXX,XX +XXX,XX @@ ssize_t load_image_size(const char *filename, void *addr, size_t size);
30
int load_image_targphys_as(const char *filename,
31
hwaddr addr, uint64_t max_sz, AddressSpace *as);
32
33
+/**load_targphys_hex_as:
34
+ * @filename: Path to the .hex file
35
+ * @entry: Store the entry point given by the .hex file
36
+ * @as: The AddressSpace to load the .hex file to. The value of
37
+ * address_space_memory is used if nothing is supplied here.
38
+ *
39
+ * Load a fixed .hex file into memory.
40
+ *
41
+ * Returns the size of the loaded .hex file on success, -1 otherwise.
42
+ */
43
+int load_targphys_hex_as(const char *filename, hwaddr *entry, AddressSpace *as);
44
+
45
/** load_image_targphys:
46
* Same as load_image_targphys_as(), but doesn't allow the caller to specify
47
* an AddressSpace.
48
diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c
49
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/core/generic-loader.c
51
+++ b/hw/core/generic-loader.c
52
@@ -XXX,XX +XXX,XX @@ static void generic_loader_realize(DeviceState *dev, Error **errp)
53
size = load_uimage_as(s->file, &entry, NULL, NULL, NULL, NULL,
54
as);
55
}
56
+
57
+ if (size < 0) {
58
+ size = load_targphys_hex_as(s->file, &entry, as);
59
+ }
60
}
61
62
if (size < 0 || s->force_raw) {
63
diff --git a/hw/core/loader.c b/hw/core/loader.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/hw/core/loader.c
66
+++ b/hw/core/loader.c
67
@@ -XXX,XX +XXX,XX @@ void hmp_info_roms(Monitor *mon, const QDict *qdict)
68
}
69
}
70
}
71
+
72
+typedef enum HexRecord HexRecord;
73
+enum HexRecord {
74
+ DATA_RECORD = 0,
75
+ EOF_RECORD,
76
+ EXT_SEG_ADDR_RECORD,
77
+ START_SEG_ADDR_RECORD,
78
+ EXT_LINEAR_ADDR_RECORD,
79
+ START_LINEAR_ADDR_RECORD,
80
+};
81
+
82
+/* Each record contains a 16-bit address which is combined with the upper 16
83
+ * bits of the implicit "next address" to form a 32-bit address.
84
+ */
85
+#define NEXT_ADDR_MASK 0xffff0000
86
+
87
+#define DATA_FIELD_MAX_LEN 0xff
88
+#define LEN_EXCEPT_DATA 0x5
89
+/* 0x5 = sizeof(byte_count) + sizeof(address) + sizeof(record_type) +
90
+ * sizeof(checksum) */
91
+typedef struct {
92
+ uint8_t byte_count;
93
+ uint16_t address;
94
+ uint8_t record_type;
95
+ uint8_t data[DATA_FIELD_MAX_LEN];
96
+ uint8_t checksum;
97
+} HexLine;
98
+
99
+/* return 0 or -1 if error */
100
+static bool parse_record(HexLine *line, uint8_t *our_checksum, const uint8_t c,
101
+ uint32_t *index, const bool in_process)
102
+{
103
+ /* +-------+---------------+-------+---------------------+--------+
104
+ * | byte | |record | | |
105
+ * | count | address | type | data |checksum|
106
+ * +-------+---------------+-------+---------------------+--------+
107
+ * ^ ^ ^ ^ ^ ^
108
+ * |1 byte | 2 bytes |1 byte | 0-255 bytes | 1 byte |
109
+ */
110
+ uint8_t value = 0;
111
+ uint32_t idx = *index;
112
+ /* ignore space */
113
+ if (g_ascii_isspace(c)) {
114
+ return true;
115
+ }
116
+ if (!g_ascii_isxdigit(c) || !in_process) {
117
+ return false;
118
+ }
119
+ value = g_ascii_xdigit_value(c);
120
+ value = (idx & 0x1) ? (value & 0xf) : (value << 4);
121
+ if (idx < 2) {
122
+ line->byte_count |= value;
123
+ } else if (2 <= idx && idx < 6) {
124
+ line->address <<= 4;
125
+ line->address += g_ascii_xdigit_value(c);
126
+ } else if (6 <= idx && idx < 8) {
127
+ line->record_type |= value;
128
+ } else if (8 <= idx && idx < 8 + 2 * line->byte_count) {
129
+ line->data[(idx - 8) >> 1] |= value;
130
+ } else if (8 + 2 * line->byte_count <= idx &&
131
+ idx < 10 + 2 * line->byte_count) {
132
+ line->checksum |= value;
133
+ } else {
134
+ return false;
135
+ }
136
+ *our_checksum += value;
137
+ ++(*index);
138
+ return true;
139
+}
140
+
141
+typedef struct {
142
+ const char *filename;
143
+ HexLine line;
144
+ uint8_t *bin_buf;
145
+ hwaddr *start_addr;
146
+ int total_size;
147
+ uint32_t next_address_to_write;
148
+ uint32_t current_address;
149
+ uint32_t current_rom_index;
150
+ uint32_t rom_start_address;
151
+ AddressSpace *as;
152
+} HexParser;
153
+
154
+/* return size or -1 if error */
155
+static int handle_record_type(HexParser *parser)
156
+{
157
+ HexLine *line = &(parser->line);
158
+ switch (line->record_type) {
159
+ case DATA_RECORD:
160
+ parser->current_address =
161
+ (parser->next_address_to_write & NEXT_ADDR_MASK) | line->address;
162
+ /* verify this is a contiguous block of memory */
163
+ if (parser->current_address != parser->next_address_to_write) {
164
+ if (parser->current_rom_index != 0) {
165
+ rom_add_blob_fixed_as(parser->filename, parser->bin_buf,
166
+ parser->current_rom_index,
167
+ parser->rom_start_address, parser->as);
168
+ }
169
+ parser->rom_start_address = parser->current_address;
170
+ parser->current_rom_index = 0;
171
+ }
172
+
173
+ /* copy from line buffer to output bin_buf */
174
+ memcpy(parser->bin_buf + parser->current_rom_index, line->data,
175
+ line->byte_count);
176
+ parser->current_rom_index += line->byte_count;
177
+ parser->total_size += line->byte_count;
178
+ /* save next address to write */
179
+ parser->next_address_to_write =
180
+ parser->current_address + line->byte_count;
181
+ break;
182
+
183
+ case EOF_RECORD:
184
+ if (parser->current_rom_index != 0) {
185
+ rom_add_blob_fixed_as(parser->filename, parser->bin_buf,
186
+ parser->current_rom_index,
187
+ parser->rom_start_address, parser->as);
188
+ }
189
+ return parser->total_size;
190
+ case EXT_SEG_ADDR_RECORD:
191
+ case EXT_LINEAR_ADDR_RECORD:
192
+ if (line->byte_count != 2 && line->address != 0) {
193
+ return -1;
194
+ }
195
+
196
+ if (parser->current_rom_index != 0) {
197
+ rom_add_blob_fixed_as(parser->filename, parser->bin_buf,
198
+ parser->current_rom_index,
199
+ parser->rom_start_address, parser->as);
200
+ }
201
+
202
+ /* save next address to write,
203
+ * in case of non-contiguous block of memory */
204
+ parser->next_address_to_write = (line->data[0] << 12) |
205
+ (line->data[1] << 4);
206
+ if (line->record_type == EXT_LINEAR_ADDR_RECORD) {
207
+ parser->next_address_to_write <<= 12;
208
+ }
209
+
210
+ parser->rom_start_address = parser->next_address_to_write;
211
+ parser->current_rom_index = 0;
212
+ break;
213
+
214
+ case START_SEG_ADDR_RECORD:
215
+ if (line->byte_count != 4 && line->address != 0) {
216
+ return -1;
217
+ }
218
+
219
+ /* x86 16-bit CS:IP segmented addressing */
220
+ *(parser->start_addr) = (((line->data[0] << 8) | line->data[1]) << 4) +
221
+ ((line->data[2] << 8) | line->data[3]);
222
+ break;
223
+
224
+ case START_LINEAR_ADDR_RECORD:
225
+ if (line->byte_count != 4 && line->address != 0) {
226
+ return -1;
227
+ }
228
+
229
+ *(parser->start_addr) = ldl_be_p(line->data);
230
+ break;
231
+
232
+ default:
233
+ return -1;
234
+ }
235
+
236
+ return parser->total_size;
237
+}
238
+
239
+/* return size or -1 if error */
240
+static int parse_hex_blob(const char *filename, hwaddr *addr, uint8_t *hex_blob,
241
+ size_t hex_blob_size, AddressSpace *as)
242
+{
243
+ bool in_process = false; /* avoid re-enter and
244
+ * check whether record begin with ':' */
245
+ uint8_t *end = hex_blob + hex_blob_size;
246
+ uint8_t our_checksum = 0;
247
+ uint32_t record_index = 0;
248
+ HexParser parser = {
249
+ .filename = filename,
250
+ .bin_buf = g_malloc(hex_blob_size),
251
+ .start_addr = addr,
252
+ .as = as,
253
+ };
254
+
255
+ rom_transaction_begin();
256
+
257
+ for (; hex_blob < end; ++hex_blob) {
258
+ switch (*hex_blob) {
259
+ case '\r':
260
+ case '\n':
261
+ if (!in_process) {
262
+ break;
263
+ }
264
+
265
+ in_process = false;
266
+ if ((LEN_EXCEPT_DATA + parser.line.byte_count) * 2 !=
267
+ record_index ||
268
+ our_checksum != 0) {
269
+ parser.total_size = -1;
270
+ goto out;
271
+ }
272
+
273
+ if (handle_record_type(&parser) == -1) {
274
+ parser.total_size = -1;
275
+ goto out;
276
+ }
277
+ break;
278
+
279
+ /* start of a new record. */
280
+ case ':':
281
+ memset(&parser.line, 0, sizeof(HexLine));
282
+ in_process = true;
283
+ record_index = 0;
284
+ break;
285
+
286
+ /* decoding lines */
287
+ default:
288
+ if (!parse_record(&parser.line, &our_checksum, *hex_blob,
289
+ &record_index, in_process)) {
290
+ parser.total_size = -1;
291
+ goto out;
292
+ }
293
+ break;
294
+ }
295
+ }
296
+
297
+out:
298
+ g_free(parser.bin_buf);
299
+ rom_transaction_end(parser.total_size != -1);
300
+ return parser.total_size;
301
+}
302
+
303
+/* return size or -1 if error */
304
+int load_targphys_hex_as(const char *filename, hwaddr *entry, AddressSpace *as)
305
+{
306
+ gsize hex_blob_size;
307
+ gchar *hex_blob;
308
+ int total_size = 0;
309
+
310
+ if (!g_file_get_contents(filename, &hex_blob, &hex_blob_size, NULL)) {
311
+ return -1;
312
+ }
313
+
314
+ total_size = parse_hex_blob(filename, entry, (uint8_t *)hex_blob,
315
+ hex_blob_size, as);
316
+
317
+ g_free(hex_blob);
318
+ return total_size;
319
+}
320
--
321
2.18.0
322
323
diff view generated by jsdifflib
New patch
1
From: Su Hang <suhang16@mails.ucas.ac.cn>
1
2
3
'test.hex' file is a memory test pattern stored in Hexadecimal Object
4
Format. It loads at 0x10000 in RAM and contains values from 0 through
5
255.
6
7
The test case verifies that the expected memory test pattern was loaded.
8
9
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
10
Suggested-by: Steffen Gortz <qemu.ml@steffen-goertz.de>
11
Suggested-by: Stefan Hajnoczi <stefanha@redhat.com>
12
Signed-off-by: Su Hang <suhang16@mails.ucas.ac.cn>
13
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
[PMM: changed qtest_startf() to qtest_initf() to work with
16
current master after the refactoring in commit 88b988c895e3c2]
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
configure | 4 +++
20
tests/Makefile.include | 2 ++
21
tests/hexloader-test.c | 45 ++++++++++++++++++++++++++++
22
MAINTAINERS | 6 ++++
23
tests/hex-loader-check-data/test.hex | 18 +++++++++++
24
5 files changed, 75 insertions(+)
25
create mode 100644 tests/hexloader-test.c
26
create mode 100644 tests/hex-loader-check-data/test.hex
27
28
diff --git a/configure b/configure
29
index XXXXXXX..XXXXXXX 100755
30
--- a/configure
31
+++ b/configure
32
@@ -XXX,XX +XXX,XX @@ for test_file in $(find $source_path/tests/acpi-test-data -type f)
33
do
34
FILES="$FILES tests/acpi-test-data$(echo $test_file | sed -e 's/.*acpi-test-data//')"
35
done
36
+for test_file in $(find $source_path/tests/hex-loader-check-data -type f)
37
+do
38
+ FILES="$FILES tests/hex-loader-check-data$(echo $test_file | sed -e 's/.*hex-loader-check-data//')"
39
+done
40
mkdir -p $DIRS
41
for f in $FILES ; do
42
if [ -e "$source_path/$f" ] && [ "$pwd_is_source_path" != "y" ]; then
43
diff --git a/tests/Makefile.include b/tests/Makefile.include
44
index XXXXXXX..XXXXXXX 100644
45
--- a/tests/Makefile.include
46
+++ b/tests/Makefile.include
47
@@ -XXX,XX +XXX,XX @@ check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
48
gcov-files-arm-y += hw/timer/arm_mptimer.c
49
check-qtest-arm-y += tests/boot-serial-test$(EXESUF)
50
check-qtest-arm-y += tests/sdhci-test$(EXESUF)
51
+check-qtest-arm-y += tests/hexloader-test$(EXESUF)
52
53
check-qtest-aarch64-y = tests/numa-test$(EXESUF)
54
check-qtest-aarch64-y += tests/sdhci-test$(EXESUF)
55
@@ -XXX,XX +XXX,XX @@ tests/qmp-test$(EXESUF): tests/qmp-test.o
56
tests/device-introspect-test$(EXESUF): tests/device-introspect-test.o
57
tests/rtc-test$(EXESUF): tests/rtc-test.o
58
tests/m48t59-test$(EXESUF): tests/m48t59-test.o
59
+tests/hexloader-test$(EXESUF): tests/hexloader-test.o
60
tests/endianness-test$(EXESUF): tests/endianness-test.o
61
tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y)
62
tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y)
63
diff --git a/tests/hexloader-test.c b/tests/hexloader-test.c
64
new file mode 100644
65
index XXXXXXX..XXXXXXX
66
--- /dev/null
67
+++ b/tests/hexloader-test.c
68
@@ -XXX,XX +XXX,XX @@
69
+/*
70
+ * QTest testcase for the Intel Hexadecimal Object File Loader
71
+ *
72
+ * Authors:
73
+ * Su Hang <suhang16@mails.ucas.ac.cn> 2018
74
+ *
75
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
76
+ * See the COPYING file in the top-level directory.
77
+ *
78
+ */
79
+
80
+#include "qemu/osdep.h"
81
+#include "libqtest.h"
82
+
83
+/* Load 'test.hex' and verify that the in-memory contents are as expected.
84
+ * 'test.hex' is a memory test pattern stored in Hexadecimal Object
85
+ * format. It loads at 0x10000 in RAM and contains values from 0 through
86
+ * 255.
87
+ */
88
+static void hex_loader_test(void)
89
+{
90
+ unsigned int i;
91
+ const unsigned int base_addr = 0x00010000;
92
+
93
+ QTestState *s = qtest_initf(
94
+ "-M vexpress-a9 -nographic -device loader,file=tests/hex-loader-check-data/test.hex");
95
+
96
+ for (i = 0; i < 256; ++i) {
97
+ uint8_t val = qtest_readb(s, base_addr + i);
98
+ g_assert_cmpuint(i, ==, val);
99
+ }
100
+ qtest_quit(s);
101
+}
102
+
103
+int main(int argc, char **argv)
104
+{
105
+ int ret;
106
+
107
+ g_test_init(&argc, &argv, NULL);
108
+
109
+ qtest_add_func("/tmp/hex_loader", hex_loader_test);
110
+ ret = g_test_run();
111
+
112
+ return ret;
113
+}
114
diff --git a/MAINTAINERS b/MAINTAINERS
115
index XXXXXXX..XXXXXXX 100644
116
--- a/MAINTAINERS
117
+++ b/MAINTAINERS
118
@@ -XXX,XX +XXX,XX @@ F: hw/core/generic-loader.c
119
F: include/hw/core/generic-loader.h
120
F: docs/generic-loader.txt
121
122
+Intel Hexadecimal Object File Loader
123
+M: Su Hang <suhang16@mails.ucas.ac.cn>
124
+S: Maintained
125
+F: tests/hexloader-test.c
126
+F: tests/hex-loader-check-data/test.hex
127
+
128
CHRP NVRAM
129
M: Thomas Huth <thuth@redhat.com>
130
S: Maintained
131
diff --git a/tests/hex-loader-check-data/test.hex b/tests/hex-loader-check-data/test.hex
132
new file mode 100644
133
index XXXXXXX..XXXXXXX
134
--- /dev/null
135
+++ b/tests/hex-loader-check-data/test.hex
136
@@ -XXX,XX +XXX,XX @@
137
+:020000040001F9
138
+:10000000000102030405060708090a0b0c0d0e0f78
139
+:10001000101112131415161718191a1b1c1d1e1f68
140
+:10002000202122232425262728292a2b2c2d2e2f58
141
+:10003000303132333435363738393a3b3c3d3e3f48
142
+:10004000404142434445464748494a4b4c4d4e4f38
143
+:10005000505152535455565758595a5b5c5d5e5f28
144
+:10006000606162636465666768696a6b6c6d6e6f18
145
+:10007000707172737475767778797a7b7c7d7e7f08
146
+:10008000808182838485868788898a8b8c8d8e8ff8
147
+:10009000909192939495969798999a9b9c9d9e9fe8
148
+:1000a000a0a1a2a3a4a5a6a7a8a9aaabacadaeafd8
149
+:1000b000b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc8
150
+:1000c000c0c1c2c3c4c5c6c7c8c9cacbcccdcecfb8
151
+:1000d000d0d1d2d3d4d5d6d7d8d9dadbdcdddedfa8
152
+:1000e000e0e1e2e3e4e5e6e7e8e9eaebecedeeef98
153
+:1000f000f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff88
154
+:00000001FF
155
--
156
2.18.0
157
158
diff view generated by jsdifflib
New patch
1
From: Trent Piepho <tpiepho@impinj.com>
1
2
3
The current emulation will clear the XCH bit when a burst finishes.
4
This is not quite correct. According to the i.MX7d referemce manual,
5
Rev 0.1, §10.1.7.3:
6
7
This bit [XCH] is cleared automatically when all data in the TXFIFO
8
and the shift register has been shifted out.
9
10
So XCH should be cleared when the FIFO empties, not on completion of a
11
burst. The FIFO is 64 x 32 bits = 2048 bits, while the max burst size
12
is larger at 4096 bits. So it's possible that the burst is not finished
13
after the TXFIFO empties.
14
15
Sending a large block (> 2048 bits) with the Linux driver will use a
16
burst that is larger than the TXFIFO. After the TXFIFO has emptied XCH
17
does not become unset, as the burst is not yet finished.
18
19
What should happen after the TXFIFO empties is the driver will refill it
20
and set XCH. The rising edge of XCH will trigger another transfer to
21
begin. However, since the emulation does not set XCH to 0, there is no
22
rising edge and the next trasfer never begins.
23
24
Signed-off-by: Trent Piepho <tpiepho@impinj.com>
25
Message-id: 20180731201056.29257-1-tpiepho@impinj.com
26
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
27
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
28
---
29
hw/ssi/imx_spi.c | 3 +--
30
1 file changed, 1 insertion(+), 2 deletions(-)
31
32
diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/ssi/imx_spi.c
35
+++ b/hw/ssi/imx_spi.c
36
@@ -XXX,XX +XXX,XX @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
37
}
38
39
if (s->burst_length <= 0) {
40
- s->regs[ECSPI_CONREG] &= ~ECSPI_CONREG_XCH;
41
-
42
if (!imx_spi_is_multiple_master_burst(s)) {
43
s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
44
break;
45
@@ -XXX,XX +XXX,XX @@ static void imx_spi_flush_txfifo(IMXSPIState *s)
46
47
if (fifo32_is_empty(&s->tx_fifo)) {
48
s->regs[ECSPI_STATREG] |= ECSPI_STATREG_TC;
49
+ s->regs[ECSPI_CONREG] &= ~ECSPI_CONREG_XCH;
50
}
51
52
/* TODO: We should also use TDR and RDR bits */
53
--
54
2.18.0
55
56
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
The SDMC on the ast2500 has 170 registers.
4
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Tested-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20180807075757.7242-2-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/misc/aspeed_sdmc.h | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/include/hw/misc/aspeed_sdmc.h b/include/hw/misc/aspeed_sdmc.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/misc/aspeed_sdmc.h
17
+++ b/include/hw/misc/aspeed_sdmc.h
18
@@ -XXX,XX +XXX,XX @@
19
#define TYPE_ASPEED_SDMC "aspeed.sdmc"
20
#define ASPEED_SDMC(obj) OBJECT_CHECK(AspeedSDMCState, (obj), TYPE_ASPEED_SDMC)
21
22
-#define ASPEED_SDMC_NR_REGS (0x8 >> 2)
23
+#define ASPEED_SDMC_NR_REGS (0x174 >> 2)
24
25
typedef struct AspeedSDMCState {
26
/*< private >*/
27
--
28
2.18.0
29
30
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
This fixes the intended protection of read-only values in the
4
configuration register. They were being always set to zero by mistake.
5
6
The read-only fields depend on the configured memory size of the system,
7
so they cannot be fixed at compile time. The most straight forward
8
option was to store them in the state structure.
9
10
Signed-off-by: Joel Stanley <joel@jms.id.au>
11
Reviewed-by: Cédric Le Goater <clg@kaod.org>
12
Tested-by: Cédric Le Goater <clg@kaod.org>
13
Message-id: 20180807075757.7242-3-joel@jms.id.au
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
include/hw/misc/aspeed_sdmc.h | 1 +
17
hw/misc/aspeed_sdmc.c | 27 ++++++++-------------------
18
2 files changed, 9 insertions(+), 19 deletions(-)
19
20
diff --git a/include/hw/misc/aspeed_sdmc.h b/include/hw/misc/aspeed_sdmc.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/misc/aspeed_sdmc.h
23
+++ b/include/hw/misc/aspeed_sdmc.h
24
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSDMCState {
25
uint32_t silicon_rev;
26
uint32_t ram_bits;
27
uint64_t ram_size;
28
+ uint32_t fixed_conf;
29
30
} AspeedSDMCState;
31
32
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/misc/aspeed_sdmc.c
35
+++ b/hw/misc/aspeed_sdmc.c
36
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
37
case AST2400_A0_SILICON_REV:
38
case AST2400_A1_SILICON_REV:
39
data &= ~ASPEED_SDMC_READONLY_MASK;
40
+ data |= s->fixed_conf;
41
break;
42
case AST2500_A0_SILICON_REV:
43
case AST2500_A1_SILICON_REV:
44
data &= ~ASPEED_SDMC_AST2500_READONLY_MASK;
45
+ data |= s->fixed_conf;
46
break;
47
default:
48
g_assert_not_reached();
49
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_reset(DeviceState *dev)
50
memset(s->regs, 0, sizeof(s->regs));
51
52
/* Set ram size bit and defaults values */
53
- switch (s->silicon_rev) {
54
- case AST2400_A0_SILICON_REV:
55
- case AST2400_A1_SILICON_REV:
56
- s->regs[R_CONF] |=
57
- ASPEED_SDMC_VGA_COMPAT |
58
- ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
59
- break;
60
-
61
- case AST2500_A0_SILICON_REV:
62
- case AST2500_A1_SILICON_REV:
63
- s->regs[R_CONF] |=
64
- ASPEED_SDMC_HW_VERSION(1) |
65
- ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
66
- ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
67
- break;
68
-
69
- default:
70
- g_assert_not_reached();
71
- }
72
+ s->regs[R_CONF] = s->fixed_conf;
73
}
74
75
static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
76
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
77
case AST2400_A0_SILICON_REV:
78
case AST2400_A1_SILICON_REV:
79
s->ram_bits = ast2400_rambits(s);
80
+ s->fixed_conf = ASPEED_SDMC_VGA_COMPAT |
81
+ ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
82
break;
83
case AST2500_A0_SILICON_REV:
84
case AST2500_A1_SILICON_REV:
85
s->ram_bits = ast2500_rambits(s);
86
+ s->fixed_conf = ASPEED_SDMC_HW_VERSION(1) |
87
+ ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
88
+ ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
89
break;
90
default:
91
g_assert_not_reached();
92
--
93
2.18.0
94
95
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
The SDRAM training routine sets the 'Enable cache initial' bit, and then
4
waits for the 'cache initial sequence' to be done.
5
6
Have it always return done, as there is no other side effects that the
7
model needs to implement. This allows the upstream u-boot training to
8
proceed on the ast2500-evb board.
9
10
Signed-off-by: Joel Stanley <joel@jms.id.au>
11
Reviewed-by: Cédric Le Goater <clg@kaod.org>
12
Tested-by: Cédric Le Goater <clg@kaod.org>
13
Message-id: 20180807075757.7242-4-joel@jms.id.au
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/misc/aspeed_sdmc.c | 1 +
17
1 file changed, 1 insertion(+)
18
19
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/misc/aspeed_sdmc.c
22
+++ b/hw/misc/aspeed_sdmc.c
23
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
24
s->ram_bits = ast2500_rambits(s);
25
s->fixed_conf = ASPEED_SDMC_HW_VERSION(1) |
26
ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
27
+ ASPEED_SDMC_CACHE_INITIAL_DONE |
28
ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
29
break;
30
default:
31
--
32
2.18.0
33
34
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Joel Stanley <joel@jms.id.au>
2
2
3
All the hard work is already done by vfp_expand_imm, we just need to
3
The ast2500 SDRAM training routine busy waits on the 'init cycle busy
4
make sure we pick up the correct size.
4
state' bit in DDR PHY Control/Status register #1 (MCR60).
5
5
6
Cc: qemu-stable@nongnu.org
6
This ensures the bit always reads zero, and allows training to
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
complete with upstream u-boot on the ast2500-evb.
8
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
8
9
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Signed-off-by: Joel Stanley <joel@jms.id.au>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 20180512003217.9105-11-richard.henderson@linaro.org
11
Tested-by: Cédric Le Goater <clg@kaod.org>
12
[rth: Merge unallocated_encoding check with TCGMemOp conversion.]
12
Message-id: 20180807075757.7242-5-joel@jms.id.au
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
14
---
16
target/arm/translate-a64.c | 20 +++++++++++++++++---
15
hw/misc/aspeed_sdmc.c | 15 +++++++++++++++
17
1 file changed, 17 insertions(+), 3 deletions(-)
16
1 file changed, 15 insertions(+)
18
17
19
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
18
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/translate-a64.c
20
--- a/hw/misc/aspeed_sdmc.c
22
+++ b/target/arm/translate-a64.c
21
+++ b/hw/misc/aspeed_sdmc.c
23
@@ -XXX,XX +XXX,XX @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
22
@@ -XXX,XX +XXX,XX @@
24
{
23
/* Configuration Register */
25
int rd = extract32(insn, 0, 5);
24
#define R_CONF (0x04 / 4)
26
int imm8 = extract32(insn, 13, 8);
25
27
- int is_double = extract32(insn, 22, 2);
26
+/* Control/Status Register #1 (ast2500) */
28
+ int type = extract32(insn, 22, 2);
27
+#define R_STATUS1 (0x60 / 4)
29
uint64_t imm;
28
+#define PHY_BUSY_STATE BIT(0)
30
TCGv_i64 tcg_res;
29
+
31
+ TCGMemOp sz;
30
/*
32
31
* Configuration register Ox4 (for Aspeed AST2400 SOC)
33
- if (is_double > 1) {
32
*
34
+ switch (type) {
33
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
35
+ case 0:
34
g_assert_not_reached();
36
+ sz = MO_32;
35
}
37
+ break;
36
}
38
+ case 1:
37
+ if (s->silicon_rev == AST2500_A0_SILICON_REV ||
39
+ sz = MO_64;
38
+ s->silicon_rev == AST2500_A1_SILICON_REV) {
40
+ break;
39
+ switch (addr) {
41
+ case 3:
40
+ case R_STATUS1:
42
+ sz = MO_16;
41
+ /* Will never return 'busy' */
43
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
42
+ data &= ~PHY_BUSY_STATE;
43
+ break;
44
+ default:
44
+ break;
45
+ break;
45
+ }
46
+ }
46
+ /* fallthru */
47
+ }
47
+ default:
48
48
unallocated_encoding(s);
49
s->regs[addr] = data;
49
return;
50
}
50
}
51
@@ -XXX,XX +XXX,XX @@ static void disas_fp_imm(DisasContext *s, uint32_t insn)
52
return;
53
}
54
55
- imm = vfp_expand_imm(MO_32 + is_double, imm8);
56
+ imm = vfp_expand_imm(sz, imm8);
57
58
tcg_res = tcg_const_i64(imm);
59
write_fp_dreg(s, rd, tcg_res);
60
--
51
--
61
2.17.0
52
2.18.0
62
53
63
54
diff view generated by jsdifflib
New patch
1
From: Joel Stanley <joel@jms.id.au>
1
2
3
This is required to ensure u-boot SDRAM training completes.
4
5
Signed-off-by: Joel Stanley <joel@jms.id.au>
6
Reviewed-by: Cédric Le Goater <clg@kaod.org>
7
Tested-by: Cédric Le Goater <clg@kaod.org>
8
Message-id: 20180807075757.7242-6-joel@jms.id.au
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/misc/aspeed_sdmc.c | 9 +++++++++
12
1 file changed, 9 insertions(+)
13
14
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/misc/aspeed_sdmc.c
17
+++ b/hw/misc/aspeed_sdmc.c
18
@@ -XXX,XX +XXX,XX @@
19
#define R_STATUS1 (0x60 / 4)
20
#define PHY_BUSY_STATE BIT(0)
21
22
+#define R_ECC_TEST_CTRL (0x70 / 4)
23
+#define ECC_TEST_FINISHED BIT(12)
24
+#define ECC_TEST_FAIL BIT(13)
25
+
26
/*
27
* Configuration register Ox4 (for Aspeed AST2400 SOC)
28
*
29
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_write(void *opaque, hwaddr addr, uint64_t data,
30
/* Will never return 'busy' */
31
data &= ~PHY_BUSY_STATE;
32
break;
33
+ case R_ECC_TEST_CTRL:
34
+ /* Always done, always happy */
35
+ data |= ECC_TEST_FINISHED;
36
+ data &= ~ECC_TEST_FAIL;
37
+ break;
38
default:
39
break;
40
}
41
--
42
2.18.0
43
44
diff view generated by jsdifflib
1
Usually the logging of the CPU state produced by -d cpu is sufficient
1
From: Cédric Le Goater <clg@kaod.org>
2
to diagnose problems, but sometimes you want to see the state of
3
the floating point registers as well. We don't want to enable that
4
by default as it adds a lot of extra data to the log; instead,
5
allow it to be optionally enabled via -d fpu.
6
2
3
This will be used to construct a memory region beyond the RAM region
4
to let firmwares scan the address space with load/store to guess how
5
much RAM the SoC has.
6
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
8
Signed-off-by: Joel Stanley <joel@jms.id.au>
9
Tested-by: Cédric Le Goater <clg@kaod.org>
10
Message-id: 20180807075757.7242-7-joel@jms.id.au
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20180510130024.31678-1-peter.maydell@linaro.org
10
---
13
---
11
include/qemu/log.h | 1 +
14
include/hw/misc/aspeed_sdmc.h | 1 +
12
accel/tcg/cpu-exec.c | 9 ++++++---
15
hw/arm/aspeed.c | 31 +++++++++++++++++++++++++++++++
13
util/log.c | 2 ++
16
hw/arm/aspeed_soc.c | 2 ++
14
3 files changed, 9 insertions(+), 3 deletions(-)
17
hw/misc/aspeed_sdmc.c | 3 +++
18
4 files changed, 37 insertions(+)
15
19
16
diff --git a/include/qemu/log.h b/include/qemu/log.h
20
diff --git a/include/hw/misc/aspeed_sdmc.h b/include/hw/misc/aspeed_sdmc.h
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/include/qemu/log.h
22
--- a/include/hw/misc/aspeed_sdmc.h
19
+++ b/include/qemu/log.h
23
+++ b/include/hw/misc/aspeed_sdmc.h
20
@@ -XXX,XX +XXX,XX @@ static inline bool qemu_log_separate(void)
24
@@ -XXX,XX +XXX,XX @@ typedef struct AspeedSDMCState {
21
#define CPU_LOG_PAGE (1 << 14)
25
uint32_t silicon_rev;
22
/* LOG_TRACE (1 << 15) is defined in log-for-trace.h */
26
uint32_t ram_bits;
23
#define CPU_LOG_TB_OP_IND (1 << 16)
27
uint64_t ram_size;
24
+#define CPU_LOG_TB_FPU (1 << 17)
28
+ uint64_t max_ram_size;
25
29
uint32_t fixed_conf;
26
/* Lock output for a series of related logs. Since this is not needed
30
27
* for a single qemu_log / qemu_log_mask / qemu_log_mask_and_addr, we
31
} AspeedSDMCState;
28
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
32
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
29
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
30
--- a/accel/tcg/cpu-exec.c
34
--- a/hw/arm/aspeed.c
31
+++ b/accel/tcg/cpu-exec.c
35
+++ b/hw/arm/aspeed.c
32
@@ -XXX,XX +XXX,XX @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
36
@@ -XXX,XX +XXX,XX @@ static struct arm_boot_info aspeed_board_binfo = {
33
if (qemu_loglevel_mask(CPU_LOG_TB_CPU)
37
typedef struct AspeedBoardState {
34
&& qemu_log_in_addr_range(itb->pc)) {
38
AspeedSoCState soc;
35
qemu_log_lock();
39
MemoryRegion ram;
36
+ int flags = 0;
40
+ MemoryRegion max_ram;
37
+ if (qemu_loglevel_mask(CPU_LOG_TB_FPU)) {
41
} AspeedBoardState;
38
+ flags |= CPU_DUMP_FPU;
42
39
+ }
43
typedef struct AspeedBoardConfig {
40
#if defined(TARGET_I386)
44
@@ -XXX,XX +XXX,XX @@ static const AspeedBoardConfig aspeed_boards[] = {
41
- log_cpu_state(cpu, CPU_DUMP_CCOP);
45
},
42
-#else
46
};
43
- log_cpu_state(cpu, 0);
47
44
+ flags |= CPU_DUMP_CCOP;
48
+/*
45
#endif
49
+ * The max ram region is for firmwares that scan the address space
46
+ log_cpu_state(cpu, flags);
50
+ * with load/store to guess how much RAM the SoC has.
47
qemu_log_unlock();
51
+ */
48
}
52
+static uint64_t max_ram_read(void *opaque, hwaddr offset, unsigned size)
49
#endif /* DEBUG_DISAS */
53
+{
50
diff --git a/util/log.c b/util/log.c
54
+ return 0;
55
+}
56
+
57
+static void max_ram_write(void *opaque, hwaddr offset, uint64_t value,
58
+ unsigned size)
59
+{
60
+ /* Discard writes */
61
+}
62
+
63
+static const MemoryRegionOps max_ram_ops = {
64
+ .read = max_ram_read,
65
+ .write = max_ram_write,
66
+ .endianness = DEVICE_NATIVE_ENDIAN,
67
+};
68
+
69
#define FIRMWARE_ADDR 0x0
70
71
static void write_boot_rom(DriveInfo *dinfo, hwaddr addr, size_t rom_size,
72
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
73
AspeedBoardState *bmc;
74
AspeedSoCClass *sc;
75
DriveInfo *drive0 = drive_get(IF_MTD, 0, 0);
76
+ ram_addr_t max_ram_size;
77
78
bmc = g_new0(AspeedBoardState, 1);
79
object_initialize(&bmc->soc, (sizeof(bmc->soc)), cfg->soc_name);
80
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
81
object_property_add_const_link(OBJECT(&bmc->soc), "ram", OBJECT(&bmc->ram),
82
&error_abort);
83
84
+ max_ram_size = object_property_get_uint(OBJECT(&bmc->soc), "max-ram-size",
85
+ &error_abort);
86
+ memory_region_init_io(&bmc->max_ram, NULL, &max_ram_ops, NULL,
87
+ "max_ram", max_ram_size - ram_size);
88
+ memory_region_add_subregion(get_system_memory(),
89
+ sc->info->sdram_base + ram_size,
90
+ &bmc->max_ram);
91
+
92
aspeed_board_init_flashes(&bmc->soc.fmc, cfg->fmc_model, &error_abort);
93
aspeed_board_init_flashes(&bmc->soc.spi[0], cfg->spi_model, &error_abort);
94
95
diff --git a/hw/arm/aspeed_soc.c b/hw/arm/aspeed_soc.c
51
index XXXXXXX..XXXXXXX 100644
96
index XXXXXXX..XXXXXXX 100644
52
--- a/util/log.c
97
--- a/hw/arm/aspeed_soc.c
53
+++ b/util/log.c
98
+++ b/hw/arm/aspeed_soc.c
54
@@ -XXX,XX +XXX,XX @@ const QEMULogItem qemu_log_items[] = {
99
@@ -XXX,XX +XXX,XX @@ static void aspeed_soc_init(Object *obj)
55
"show trace before each executed TB (lots of logs)" },
100
sc->info->silicon_rev);
56
{ CPU_LOG_TB_CPU, "cpu",
101
object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc),
57
"show CPU registers before entering a TB (lots of logs)" },
102
"ram-size", &error_abort);
58
+ { CPU_LOG_TB_FPU, "fpu",
103
+ object_property_add_alias(obj, "max-ram-size", OBJECT(&s->sdmc),
59
+ "include FPU registers in the 'cpu' logging" },
104
+ "max-ram-size", &error_abort);
60
{ CPU_LOG_MMU, "mmu",
105
61
"log MMU-related activities" },
106
for (i = 0; i < sc->info->wdts_num; i++) {
62
{ CPU_LOG_PCALL, "pcall",
107
object_initialize(&s->wdt[i], sizeof(s->wdt[i]), TYPE_ASPEED_WDT);
108
diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/hw/misc/aspeed_sdmc.c
111
+++ b/hw/misc/aspeed_sdmc.c
112
@@ -XXX,XX +XXX,XX @@ static void aspeed_sdmc_realize(DeviceState *dev, Error **errp)
113
case AST2400_A0_SILICON_REV:
114
case AST2400_A1_SILICON_REV:
115
s->ram_bits = ast2400_rambits(s);
116
+ s->max_ram_size = 512 << 20;
117
s->fixed_conf = ASPEED_SDMC_VGA_COMPAT |
118
ASPEED_SDMC_DRAM_SIZE(s->ram_bits);
119
break;
120
case AST2500_A0_SILICON_REV:
121
case AST2500_A1_SILICON_REV:
122
s->ram_bits = ast2500_rambits(s);
123
+ s->max_ram_size = 1024 << 20;
124
s->fixed_conf = ASPEED_SDMC_HW_VERSION(1) |
125
ASPEED_SDMC_VGA_APERTURE(ASPEED_SDMC_VGA_64MB) |
126
ASPEED_SDMC_CACHE_INITIAL_DONE |
127
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_aspeed_sdmc = {
128
static Property aspeed_sdmc_properties[] = {
129
DEFINE_PROP_UINT32("silicon-rev", AspeedSDMCState, silicon_rev, 0),
130
DEFINE_PROP_UINT64("ram-size", AspeedSDMCState, ram_size, 0),
131
+ DEFINE_PROP_UINT64("max-ram-size", AspeedSDMCState, max_ram_size, 0),
132
DEFINE_PROP_END_OF_LIST(),
133
};
134
63
--
135
--
64
2.17.0
136
2.18.0
65
137
66
138
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Cc: qemu-stable@nongnu.org
3
When support for FZ16 was added, we failed to include the bit
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
within FPCR_MASK, which means that it could never be set.
5
Continue to zero FZ16 when ARMv8.2-FP16 is not enabled.
6
7
Fixes: d81ce0ef2c4
8
Cc: qemu-stable@nongnu.org (3.0.1)
9
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Message-id: 20180512003217.9105-5-richard.henderson@linaro.org
12
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
13
Message-id: 20180810193129.1556-2-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
15
---
10
target/arm/translate-a64.c | 17 +++++++++++++++--
16
target/arm/cpu.h | 2 +-
11
1 file changed, 15 insertions(+), 2 deletions(-)
17
target/arm/helper.c | 5 +++++
18
2 files changed, 6 insertions(+), 1 deletion(-)
12
19
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
22
--- a/target/arm/cpu.h
16
+++ b/target/arm/translate-a64.c
23
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ static void disas_fp_fixed_conv(DisasContext *s, uint32_t insn)
24
@@ -XXX,XX +XXX,XX @@ void vfp_set_fpscr(CPUARMState *env, uint32_t val);
18
bool sf = extract32(insn, 31, 1);
25
* we store the underlying state in fpscr and just mask on read/write.
19
bool itof;
26
*/
20
27
#define FPSR_MASK 0xf800009f
21
- if (sbit || (type > 1)
28
-#define FPCR_MASK 0x07f79f00
22
- || (!sf && scale < 32)) {
29
+#define FPCR_MASK 0x07ff9f00
23
+ if (sbit || (!sf && scale < 32)) {
30
24
+ unallocated_encoding(s);
31
#define FPCR_FZ16 (1 << 19) /* ARMv8.2+, FP16 flush-to-zero */
25
+ return;
32
#define FPCR_FZ (1 << 24) /* Flush-to-zero enable bit */
33
diff --git a/target/arm/helper.c b/target/arm/helper.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/helper.c
36
+++ b/target/arm/helper.c
37
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
38
int i;
39
uint32_t changed;
40
41
+ /* When ARMv8.2-FP16 is not supported, FZ16 is RES0. */
42
+ if (!arm_feature(env, ARM_FEATURE_V8_FP16)) {
43
+ val &= ~FPCR_FZ16;
26
+ }
44
+ }
27
+
45
+
28
+ switch (type) {
46
changed = env->vfp.xregs[ARM_VFP_FPSCR];
29
+ case 0: /* float32 */
47
env->vfp.xregs[ARM_VFP_FPSCR] = (val & 0xffc8ffff);
30
+ case 1: /* float64 */
48
env->vfp.vec_len = (val >> 16) & 7;
31
+ break;
32
+ case 3: /* float16 */
33
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
34
+ break;
35
+ }
36
+ /* fallthru */
37
+ default:
38
unallocated_encoding(s);
39
return;
40
}
41
--
49
--
42
2.17.0
50
2.18.0
43
51
44
52
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Cc: qemu-stable@nongnu.org
3
When FZ is set, input_denormal exceptions are recognized, but this does
4
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
4
not happen with FZ16. The softfloat code has no way to distinguish
5
these bits and will raise such exceptions into fp_status_f16.flags,
6
so ignore them when computing the accumulated flags.
7
8
Cc: qemu-stable@nongnu.org (3.0.1)
9
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
11
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Message-id: 20180512003217.9105-4-richard.henderson@linaro.org
12
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
13
Message-id: 20180810193129.1556-3-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
15
---
10
target/arm/helper.h | 6 +++
16
target/arm/helper.c | 6 +++++-
11
target/arm/helper.c | 38 ++++++++++++++-
17
1 file changed, 5 insertions(+), 1 deletion(-)
12
target/arm/translate-a64.c | 96 +++++++++++++++++++++++++++++++-------
13
3 files changed, 122 insertions(+), 18 deletions(-)
14
18
15
diff --git a/target/arm/helper.h b/target/arm/helper.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.h
18
+++ b/target/arm/helper.h
19
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_touhd_round_to_zero, i64, f64, i32, ptr)
20
DEF_HELPER_3(vfp_tould_round_to_zero, i64, f64, i32, ptr)
21
DEF_HELPER_3(vfp_touhh, i32, f16, i32, ptr)
22
DEF_HELPER_3(vfp_toshh, i32, f16, i32, ptr)
23
+DEF_HELPER_3(vfp_toulh, i32, f16, i32, ptr)
24
+DEF_HELPER_3(vfp_toslh, i32, f16, i32, ptr)
25
+DEF_HELPER_3(vfp_touqh, i64, f16, i32, ptr)
26
+DEF_HELPER_3(vfp_tosqh, i64, f16, i32, ptr)
27
DEF_HELPER_3(vfp_toshs, i32, f32, i32, ptr)
28
DEF_HELPER_3(vfp_tosls, i32, f32, i32, ptr)
29
DEF_HELPER_3(vfp_tosqs, i64, f32, i32, ptr)
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(vfp_ultod, f64, i64, i32, ptr)
31
DEF_HELPER_3(vfp_uqtod, f64, i64, i32, ptr)
32
DEF_HELPER_3(vfp_sltoh, f16, i32, i32, ptr)
33
DEF_HELPER_3(vfp_ultoh, f16, i32, i32, ptr)
34
+DEF_HELPER_3(vfp_sqtoh, f16, i64, i32, ptr)
35
+DEF_HELPER_3(vfp_uqtoh, f16, i64, i32, ptr)
36
37
DEF_HELPER_FLAGS_2(set_rmode, TCG_CALL_NO_RWG, i32, i32, ptr)
38
DEF_HELPER_FLAGS_2(set_neon_rmode, TCG_CALL_NO_RWG, i32, i32, env)
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
21
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
22
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ VFP_CONV_FIX_A64(uq, s, 32, 64, uint64)
23
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_get_fpscr)(CPUARMState *env)
44
#undef VFP_CONV_FIX_A64
24
fpscr = (env->vfp.xregs[ARM_VFP_FPSCR] & 0xffc8ffff)
45
25
| (env->vfp.vec_len << 16)
46
/* Conversion to/from f16 can overflow to infinity before/after scaling.
26
| (env->vfp.vec_stride << 20);
47
- * Therefore we convert to f64 (which does not round), scale,
27
+
48
- * and then convert f64 to f16 (which may round).
28
i = get_float_exception_flags(&env->vfp.fp_status);
49
+ * Therefore we convert to f64, scale, and then convert f64 to f16; or
29
i |= get_float_exception_flags(&env->vfp.standard_fp_status);
50
+ * vice versa for conversion to integer.
30
- i |= get_float_exception_flags(&env->vfp.fp_status_f16);
51
+ *
31
+ /* FZ16 does not generate an input denormal exception. */
52
+ * For 16- and 32-bit integers, the conversion to f64 never rounds.
32
+ i |= (get_float_exception_flags(&env->vfp.fp_status_f16)
53
+ * For 64-bit integers, any integer that would cause rounding will also
33
+ & ~float_flag_input_denormal);
54
+ * overflow to f16 infinity, so there is no double rounding problem.
34
+
55
*/
35
fpscr |= vfp_exceptbits_from_host(i);
56
36
return fpscr;
57
static float16 do_postscale_fp16(float64 f, int shift, float_status *fpst)
58
@@ -XXX,XX +XXX,XX @@ float16 HELPER(vfp_ultoh)(uint32_t x, uint32_t shift, void *fpst)
59
return do_postscale_fp16(uint32_to_float64(x, fpst), shift, fpst);
60
}
37
}
61
62
+float16 HELPER(vfp_sqtoh)(uint64_t x, uint32_t shift, void *fpst)
63
+{
64
+ return do_postscale_fp16(int64_to_float64(x, fpst), shift, fpst);
65
+}
66
+
67
+float16 HELPER(vfp_uqtoh)(uint64_t x, uint32_t shift, void *fpst)
68
+{
69
+ return do_postscale_fp16(uint64_to_float64(x, fpst), shift, fpst);
70
+}
71
+
72
static float64 do_prescale_fp16(float16 f, int shift, float_status *fpst)
73
{
74
if (unlikely(float16_is_any_nan(f))) {
75
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(vfp_touhh)(float16 x, uint32_t shift, void *fpst)
76
return float64_to_uint16(do_prescale_fp16(x, shift, fpst), fpst);
77
}
78
79
+uint32_t HELPER(vfp_toslh)(float16 x, uint32_t shift, void *fpst)
80
+{
81
+ return float64_to_int32(do_prescale_fp16(x, shift, fpst), fpst);
82
+}
83
+
84
+uint32_t HELPER(vfp_toulh)(float16 x, uint32_t shift, void *fpst)
85
+{
86
+ return float64_to_uint32(do_prescale_fp16(x, shift, fpst), fpst);
87
+}
88
+
89
+uint64_t HELPER(vfp_tosqh)(float16 x, uint32_t shift, void *fpst)
90
+{
91
+ return float64_to_int64(do_prescale_fp16(x, shift, fpst), fpst);
92
+}
93
+
94
+uint64_t HELPER(vfp_touqh)(float16 x, uint32_t shift, void *fpst)
95
+{
96
+ return float64_to_uint64(do_prescale_fp16(x, shift, fpst), fpst);
97
+}
98
+
99
/* Set the current fp rounding mode and return the old one.
100
* The argument is a softfloat float_round_ value.
101
*/
102
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/translate-a64.c
105
+++ b/target/arm/translate-a64.c
106
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
107
bool itof, int rmode, int scale, int sf, int type)
108
{
109
bool is_signed = !(opcode & 1);
110
- bool is_double = type;
111
TCGv_ptr tcg_fpstatus;
112
- TCGv_i32 tcg_shift;
113
+ TCGv_i32 tcg_shift, tcg_single;
114
+ TCGv_i64 tcg_double;
115
116
- tcg_fpstatus = get_fpstatus_ptr(false);
117
+ tcg_fpstatus = get_fpstatus_ptr(type == 3);
118
119
tcg_shift = tcg_const_i32(64 - scale);
120
121
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
122
tcg_int = tcg_extend;
123
}
124
125
- if (is_double) {
126
- TCGv_i64 tcg_double = tcg_temp_new_i64();
127
+ switch (type) {
128
+ case 1: /* float64 */
129
+ tcg_double = tcg_temp_new_i64();
130
if (is_signed) {
131
gen_helper_vfp_sqtod(tcg_double, tcg_int,
132
tcg_shift, tcg_fpstatus);
133
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
134
}
135
write_fp_dreg(s, rd, tcg_double);
136
tcg_temp_free_i64(tcg_double);
137
- } else {
138
- TCGv_i32 tcg_single = tcg_temp_new_i32();
139
+ break;
140
+
141
+ case 0: /* float32 */
142
+ tcg_single = tcg_temp_new_i32();
143
if (is_signed) {
144
gen_helper_vfp_sqtos(tcg_single, tcg_int,
145
tcg_shift, tcg_fpstatus);
146
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
147
}
148
write_fp_sreg(s, rd, tcg_single);
149
tcg_temp_free_i32(tcg_single);
150
+ break;
151
+
152
+ case 3: /* float16 */
153
+ tcg_single = tcg_temp_new_i32();
154
+ if (is_signed) {
155
+ gen_helper_vfp_sqtoh(tcg_single, tcg_int,
156
+ tcg_shift, tcg_fpstatus);
157
+ } else {
158
+ gen_helper_vfp_uqtoh(tcg_single, tcg_int,
159
+ tcg_shift, tcg_fpstatus);
160
+ }
161
+ write_fp_sreg(s, rd, tcg_single);
162
+ tcg_temp_free_i32(tcg_single);
163
+ break;
164
+
165
+ default:
166
+ g_assert_not_reached();
167
}
168
} else {
169
TCGv_i64 tcg_int = cpu_reg(s, rd);
170
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
171
172
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
173
174
- if (is_double) {
175
- TCGv_i64 tcg_double = read_fp_dreg(s, rn);
176
+ switch (type) {
177
+ case 1: /* float64 */
178
+ tcg_double = read_fp_dreg(s, rn);
179
if (is_signed) {
180
if (!sf) {
181
gen_helper_vfp_tosld(tcg_int, tcg_double,
182
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
183
tcg_shift, tcg_fpstatus);
184
}
185
}
186
+ if (!sf) {
187
+ tcg_gen_ext32u_i64(tcg_int, tcg_int);
188
+ }
189
tcg_temp_free_i64(tcg_double);
190
- } else {
191
- TCGv_i32 tcg_single = read_fp_sreg(s, rn);
192
+ break;
193
+
194
+ case 0: /* float32 */
195
+ tcg_single = read_fp_sreg(s, rn);
196
if (sf) {
197
if (is_signed) {
198
gen_helper_vfp_tosqs(tcg_int, tcg_single,
199
@@ -XXX,XX +XXX,XX @@ static void handle_fpfpcvt(DisasContext *s, int rd, int rn, int opcode,
200
tcg_temp_free_i32(tcg_dest);
201
}
202
tcg_temp_free_i32(tcg_single);
203
+ break;
204
+
205
+ case 3: /* float16 */
206
+ tcg_single = read_fp_sreg(s, rn);
207
+ if (sf) {
208
+ if (is_signed) {
209
+ gen_helper_vfp_tosqh(tcg_int, tcg_single,
210
+ tcg_shift, tcg_fpstatus);
211
+ } else {
212
+ gen_helper_vfp_touqh(tcg_int, tcg_single,
213
+ tcg_shift, tcg_fpstatus);
214
+ }
215
+ } else {
216
+ TCGv_i32 tcg_dest = tcg_temp_new_i32();
217
+ if (is_signed) {
218
+ gen_helper_vfp_toslh(tcg_dest, tcg_single,
219
+ tcg_shift, tcg_fpstatus);
220
+ } else {
221
+ gen_helper_vfp_toulh(tcg_dest, tcg_single,
222
+ tcg_shift, tcg_fpstatus);
223
+ }
224
+ tcg_gen_extu_i32_i64(tcg_int, tcg_dest);
225
+ tcg_temp_free_i32(tcg_dest);
226
+ }
227
+ tcg_temp_free_i32(tcg_single);
228
+ break;
229
+
230
+ default:
231
+ g_assert_not_reached();
232
}
233
234
gen_helper_set_rmode(tcg_rmode, tcg_rmode, tcg_fpstatus);
235
tcg_temp_free_i32(tcg_rmode);
236
-
237
- if (!sf) {
238
- tcg_gen_ext32u_i64(tcg_int, tcg_int);
239
- }
240
}
241
242
tcg_temp_free_ptr(tcg_fpstatus);
243
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
244
/* actual FP conversions */
245
bool itof = extract32(opcode, 1, 1);
246
247
- if (type > 1 || (rmode != 0 && opcode > 1)) {
248
+ if (rmode != 0 && opcode > 1) {
249
+ unallocated_encoding(s);
250
+ return;
251
+ }
252
+ switch (type) {
253
+ case 0: /* float32 */
254
+ case 1: /* float64 */
255
+ break;
256
+ case 3: /* float16 */
257
+ if (arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
258
+ break;
259
+ }
260
+ /* fallthru */
261
+ default:
262
unallocated_encoding(s);
263
return;
264
}
265
--
38
--
266
2.17.0
39
2.18.0
267
40
268
41
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
No sense in emitting code after the exception.
3
This makes float16_muladd correctly use FZ16 not FZ.
4
4
5
Fixes: 6ceabaad110
6
Cc: qemu-stable@nongnu.org (3.0.1)
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Message-id: 20180512003217.9105-3-richard.henderson@linaro.org
10
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20180810193129.1556-4-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
target/arm/translate-a64.c | 2 +-
14
target/arm/sve_helper.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
13
16
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
19
--- a/target/arm/sve_helper.c
17
+++ b/target/arm/translate-a64.c
20
+++ b/target/arm/sve_helper.c
18
@@ -XXX,XX +XXX,XX @@ static void disas_fp_int_conv(DisasContext *s, uint32_t insn)
21
@@ -XXX,XX +XXX,XX @@ static void do_fmla_zpzzz_h(CPUARMState *env, void *vg, uint32_t desc,
19
default:
22
e1 = *(uint16_t *)(vn + H1_2(i)) ^ neg1;
20
/* all other sf/type/rmode combinations are invalid */
23
e2 = *(uint16_t *)(vm + H1_2(i));
21
unallocated_encoding(s);
24
e3 = *(uint16_t *)(va + H1_2(i)) ^ neg3;
22
- break;
25
- r = float16_muladd(e1, e2, e3, 0, &env->vfp.fp_status);
23
+ return;
26
+ r = float16_muladd(e1, e2, e3, 0, &env->vfp.fp_status_f16);
24
}
27
*(uint16_t *)(vd + H1_2(i)) = r;
25
28
}
26
if (!fp_access_check(s)) {
29
} while (i & 63);
27
--
30
--
28
2.17.0
31
2.18.0
29
32
30
33
diff view generated by jsdifflib
1
In float-to-integer conversion, if the floating point input
1
From: Richard Henderson <richard.henderson@linaro.org>
2
converts exactly to the largest or smallest integer that
3
fits in to the result type, this is not an overflow.
4
In this situation we were producing the correct result value,
5
but were incorrectly setting the Invalid flag.
6
For example for Arm A64, "FCVTAS w0, d0" on an input of
7
0x41dfffffffc00000 should produce 0x7fffffff and set no flags.
8
2
9
Fix the boundary case to take the right half of the if()
3
We were using the wrong flush-to-zero bit for the non-half input.
10
statements.
11
4
12
This fixes a regression from 2.11 introduced by the softfloat
5
Fixes: 46d33d1e3c9
13
refactoring.
6
Cc: qemu-stable@nongnu.org (3.0.1)
14
7
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
15
Cc: qemu-stable@nongnu.org
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Fixes: ab52f973a50
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
11
Message-id: 20180810193129.1556-5-richard.henderson@linaro.org
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20180510140141.12120-1-peter.maydell@linaro.org
20
---
13
---
21
fpu/softfloat.c | 4 ++--
14
target/arm/translate-sve.c | 4 ++--
22
1 file changed, 2 insertions(+), 2 deletions(-)
15
1 file changed, 2 insertions(+), 2 deletions(-)
23
16
24
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
17
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
25
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
26
--- a/fpu/softfloat.c
19
--- a/target/arm/translate-sve.c
27
+++ b/fpu/softfloat.c
20
+++ b/target/arm/translate-sve.c
28
@@ -XXX,XX +XXX,XX @@ static int64_t round_to_int_and_pack(FloatParts in, int rmode,
21
@@ -XXX,XX +XXX,XX @@ static bool do_zpz_ptr(DisasContext *s, int rd, int rn, int pg,
29
r = UINT64_MAX;
22
30
}
23
static bool trans_FCVT_sh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
31
if (p.sign) {
24
{
32
- if (r < -(uint64_t) min) {
25
- return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_sh);
33
+ if (r <= -(uint64_t) min) {
26
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_sh);
34
return -r;
27
}
35
} else {
28
36
s->float_exception_flags = orig_flags | float_flag_invalid;
29
static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
37
return min;
30
@@ -XXX,XX +XXX,XX @@ static bool trans_FCVT_hs(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
38
}
31
39
} else {
32
static bool trans_FCVT_dh(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
40
- if (r < max) {
33
{
41
+ if (r <= max) {
34
- return do_zpz_ptr(s, a->rd, a->rn, a->pg, true, gen_helper_sve_fcvt_dh);
42
return r;
35
+ return do_zpz_ptr(s, a->rd, a->rn, a->pg, false, gen_helper_sve_fcvt_dh);
43
} else {
36
}
44
s->float_exception_flags = orig_flags | float_flag_invalid;
37
38
static bool trans_FCVT_hd(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
45
--
39
--
46
2.17.0
40
2.18.0
47
41
48
42
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
We are meant to explicitly pass fpst, not cpu_env.
3
These insns require u=1; failed to include that in the switch
4
cases. This probably happened during one of the rebases just
5
before final commit.
4
6
5
Cc: qemu-stable@nongnu.org
7
Fixes: d17b7cdcf4e
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Alex Bennée <alex.bennee@linaro.org>
9
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20180512003217.9105-12-richard.henderson@linaro.org
10
Message-id: 20180810193129.1556-6-richard.henderson@linaro.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
12
---
13
target/arm/translate-a64.c | 3 ++-
13
target/arm/translate-a64.c | 12 ++++++------
14
1 file changed, 2 insertions(+), 1 deletion(-)
14
1 file changed, 6 insertions(+), 6 deletions(-)
15
15
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/translate-a64.c
18
--- a/target/arm/translate-a64.c
19
+++ b/target/arm/translate-a64.c
19
+++ b/target/arm/translate-a64.c
20
@@ -XXX,XX +XXX,XX @@ static void handle_fp_1src_half(DisasContext *s, int opcode, int rd, int rn)
20
@@ -XXX,XX +XXX,XX @@ static void disas_simd_three_reg_same_extra(DisasContext *s, uint32_t insn)
21
tcg_gen_xori_i32(tcg_res, tcg_op, 0x8000);
21
}
22
feature = ARM_FEATURE_V8_DOTPROD;
22
break;
23
break;
23
case 0x3: /* FSQRT */
24
- case 0x8: /* FCMLA, #0 */
24
- gen_helper_sqrt_f16(tcg_res, tcg_op, cpu_env);
25
- case 0x9: /* FCMLA, #90 */
25
+ fpst = get_fpstatus_ptr(true);
26
- case 0xa: /* FCMLA, #180 */
26
+ gen_helper_sqrt_f16(tcg_res, tcg_op, fpst);
27
- case 0xb: /* FCMLA, #270 */
27
break;
28
- case 0xc: /* FCADD, #90 */
28
case 0x8: /* FRINTN */
29
- case 0xe: /* FCADD, #270 */
29
case 0x9: /* FRINTP */
30
+ case 0x18: /* FCMLA, #0 */
31
+ case 0x19: /* FCMLA, #90 */
32
+ case 0x1a: /* FCMLA, #180 */
33
+ case 0x1b: /* FCMLA, #270 */
34
+ case 0x1c: /* FCADD, #90 */
35
+ case 0x1e: /* FCADD, #270 */
36
if (size == 0
37
|| (size == 1 && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))
38
|| (size == 3 && !is_q)) {
30
--
39
--
31
2.17.0
40
2.18.0
32
41
33
42
diff view generated by jsdifflib
1
From: Alex Bennée <alex.bennee@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Reported by Coverity (CID1390635). We ensure this for uint_to_float
3
For 0x1.0000000000003p+0 + 0x1.ffffffep+14 = 0x1.0001fffp+15
4
later on so we might as well mirror that.
4
we dropped the sticky bit and so failed to raise inexact.
5
5
6
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Laurent Desnogues <laurent.desnogues@gmail.com>
9
Tested-by: Laurent Desnogues <laurent.desnogues@gmail.com>
10
Message-id: 20180810193129.1556-7-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
fpu/softfloat.c | 2 +-
13
fpu/softfloat.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
13
15
14
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
16
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/fpu/softfloat.c
18
--- a/fpu/softfloat.c
17
+++ b/fpu/softfloat.c
19
+++ b/fpu/softfloat.c
18
@@ -XXX,XX +XXX,XX @@ FLOAT_TO_UINT(64, 64)
20
@@ -XXX,XX +XXX,XX @@ static FloatParts addsub_floats(FloatParts a, FloatParts b, bool subtract,
19
21
}
20
static FloatParts int_to_float(int64_t a, float_status *status)
22
a.frac += b.frac;
21
{
23
if (a.frac & DECOMPOSED_OVERFLOW_BIT) {
22
- FloatParts r;
24
- a.frac >>= 1;
23
+ FloatParts r = {};
25
+ shift64RightJamming(a.frac, 1, &a.frac);
24
if (a == 0) {
26
a.exp += 1;
25
r.cls = float_class_zero;
27
}
26
r.sign = false;
28
return a;
27
--
29
--
28
2.17.0
30
2.18.0
29
31
30
32
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Per the Physical Layer Simplified Spec. "4.3.10.4 Switch Function Status":
3
Now that we've got the common sysbus_init_child_obj() function, we do
4
not need the local init_sysbus_child() anymore.
4
5
5
The block length is predefined to 512 bits
6
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
7
Message-id: 1534420566-15799-1-git-send-email-thuth@redhat.com
7
and "4.10.2 SD Status":
8
9
The SD Status contains status bits that are related to the SD Memory Card
10
proprietary features and may be used for future application-specific usage.
11
The size of the SD Status is one data block of 512 bit. The content of this
12
register is transmitted to the Host over the DAT bus along with a 16-bit CRC.
13
14
Thus the 16-bit CRC goes at offset 64.
15
16
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
Message-id: 20180509060104.4458-3-f4bug@amsat.org
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
10
---
21
hw/sd/sd.c | 2 +-
11
hw/arm/mps2-tz.c | 32 +++++++++++---------------------
22
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 11 insertions(+), 21 deletions(-)
23
13
24
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
14
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
25
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
26
--- a/hw/sd/sd.c
16
--- a/hw/arm/mps2-tz.c
27
+++ b/hw/sd/sd.c
17
+++ b/hw/arm/mps2-tz.c
28
@@ -XXX,XX +XXX,XX @@ static void sd_function_switch(SDState *sd, uint32_t arg)
18
@@ -XXX,XX +XXX,XX @@ static void make_ram_alias(MemoryRegion *mr, const char *name,
29
sd->data[14 + (i >> 1)] = new_func << ((i * 4) & 4);
19
memory_region_add_subregion(get_system_memory(), base, mr);
20
}
21
22
-static void init_sysbus_child(Object *parent, const char *childname,
23
- void *child, size_t childsize,
24
- const char *childtype)
25
-{
26
- object_initialize(child, childsize, childtype);
27
- object_property_add_child(parent, childname, OBJECT(child), &error_abort);
28
- qdev_set_parent_bus(DEVICE(child), sysbus_get_default());
29
-
30
-}
31
-
32
/* Most of the devices in the AN505 FPGA image sit behind
33
* Peripheral Protection Controllers. These data structures
34
* define the layout of which devices sit behind which PPCs.
35
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_unimp_dev(MPS2TZMachineState *mms,
36
*/
37
UnimplementedDeviceState *uds = opaque;
38
39
- init_sysbus_child(OBJECT(mms), name, uds,
40
- sizeof(UnimplementedDeviceState),
41
- TYPE_UNIMPLEMENTED_DEVICE);
42
+ sysbus_init_child_obj(OBJECT(mms), name, uds,
43
+ sizeof(UnimplementedDeviceState),
44
+ TYPE_UNIMPLEMENTED_DEVICE);
45
qdev_prop_set_string(DEVICE(uds), "name", name);
46
qdev_prop_set_uint64(DEVICE(uds), "size", size);
47
object_property_set_bool(OBJECT(uds), true, "realized", &error_fatal);
48
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_uart(MPS2TZMachineState *mms, void *opaque,
49
DeviceState *iotkitdev = DEVICE(&mms->iotkit);
50
DeviceState *orgate_dev = DEVICE(&mms->uart_irq_orgate);
51
52
- init_sysbus_child(OBJECT(mms), name, uart,
53
- sizeof(mms->uart[0]), TYPE_CMSDK_APB_UART);
54
+ sysbus_init_child_obj(OBJECT(mms), name, uart, sizeof(mms->uart[0]),
55
+ TYPE_CMSDK_APB_UART);
56
qdev_prop_set_chr(DEVICE(uart), "chardev", serial_hd(i));
57
qdev_prop_set_uint32(DEVICE(uart), "pclk-frq", SYSCLK_FRQ);
58
object_property_set_bool(OBJECT(uart), true, "realized", &error_fatal);
59
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_mpc(MPS2TZMachineState *mms, void *opaque,
60
61
memory_region_init_ram(ssram, NULL, name, ramsize[i], &error_fatal);
62
63
- init_sysbus_child(OBJECT(mms), mpcname, mpc,
64
- sizeof(mms->ssram_mpc[0]), TYPE_TZ_MPC);
65
+ sysbus_init_child_obj(OBJECT(mms), mpcname, mpc, sizeof(mms->ssram_mpc[0]),
66
+ TYPE_TZ_MPC);
67
object_property_set_link(OBJECT(mpc), OBJECT(ssram),
68
"downstream", &error_fatal);
69
object_property_set_bool(OBJECT(mpc), true, "realized", &error_fatal);
70
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
71
exit(1);
30
}
72
}
31
memset(&sd->data[17], 0, 47);
73
32
- stw_be_p(sd->data + 65, sd_crc16(sd->data, 64));
74
- init_sysbus_child(OBJECT(machine), "iotkit", &mms->iotkit,
33
+ stw_be_p(sd->data + 64, sd_crc16(sd->data, 64));
75
- sizeof(mms->iotkit), TYPE_IOTKIT);
34
}
76
+ sysbus_init_child_obj(OBJECT(machine), "iotkit", &mms->iotkit,
35
77
+ sizeof(mms->iotkit), TYPE_IOTKIT);
36
static inline bool sd_wp_addr(SDState *sd, uint64_t addr)
78
iotkitdev = DEVICE(&mms->iotkit);
79
object_property_set_link(OBJECT(&mms->iotkit), OBJECT(system_memory),
80
"memory", &error_abort);
81
@@ -XXX,XX +XXX,XX @@ static void mps2tz_common_init(MachineState *machine)
82
int port;
83
char *gpioname;
84
85
- init_sysbus_child(OBJECT(machine), ppcinfo->name, ppc,
86
- sizeof(TZPPC), TYPE_TZ_PPC);
87
+ sysbus_init_child_obj(OBJECT(machine), ppcinfo->name, ppc,
88
+ sizeof(TZPPC), TYPE_TZ_PPC);
89
ppcdev = DEVICE(ppc);
90
91
for (port = 0; port < TZ_NUM_PORTS; port++) {
37
--
92
--
38
2.17.0
93
2.18.0
39
94
40
95
diff view generated by jsdifflib