1
ARM queue, various patches accumulated over the Christmas break.
1
Handful of bug fixes to sneak in before rc3.
2
2
3
thanks
3
-- PMM
4
-- PMM
4
5
5
The following changes since commit 612061b277915fadd80631eb7a6926f48a110c44:
6
The following changes since commit c985266ea5b50e46e07b3568c1346e10064205c9:
6
7
7
Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-01-10' into staging (2018-01-11 11:52:40 +0000)
8
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20190726' into staging (2019-07-26 13:52:06 +0100)
8
9
9
are available in the git repository at:
10
are available in the Git repository at:
10
11
11
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180111
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190726
12
13
13
for you to fetch changes up to 0cf09852015e47a5fbb974ff7ac320366afd21ee:
14
for you to fetch changes up to 67505c114e6acc26f3a1a2b74833c61b6a34ff95:
14
15
15
hw/intc/arm_gic: reserved register addresses are RAZ/WI (2018-01-11 13:25:40 +0000)
16
hw/arm/boot: Further improve initrd positioning code (2019-07-26 16:17:56 +0100)
16
17
17
----------------------------------------------------------------
18
----------------------------------------------------------------
18
target-arm queue:
19
target-arm queue:
19
* add aarch64_be linux-user target
20
* Fix broken migration on pl330 device
20
* Virt: ACPI: fix qemu assert due to re-assigned table data address
21
* Fix broken migration on stellaris-input device
21
* imx_fec: various bug fixes and cleanups
22
* Add type checks to vmstate varry macros to avoid this class of bugs
22
* hw/timer/pxa2xx_timer: replace hw_error() -> qemu_log_mask()
23
* hw/arm/boot: Fix some remaining cases where we would put the
23
* hw/sd/pxa2xx_mmci: add read/write() trace events
24
initrd on top of the kernel image
24
* linux-user/arm/nwfpe: Check coprocessor number for FPA emulation
25
* target/arm: Make disas_thumb2_insn() generate its own UNDEF exceptions
26
* hw/intc/arm_gicv3: Make reserved register addresses RAZ/WI
27
* hw/intc/arm_gic: reserved register addresses are RAZ/WI
28
25
29
----------------------------------------------------------------
26
----------------------------------------------------------------
30
Andrey Smirnov (11):
27
Damien Hedde (1):
31
imx_fec: Do not link to netdev
28
pl330: fix vmstate description
32
imx_fec: Refactor imx_eth_enable_rx()
33
imx_fec: Change queue flushing heuristics
34
imx_fec: Move Tx frame buffer away from the stack
35
imx_fec: Use ENET_FTRL to determine truncation length
36
imx_fec: Use MIN instead of explicit ternary operator
37
imx_fec: Emulate SHIFT16 in ENETx_RACC
38
imx_fec: Add support for multiple Tx DMA rings
39
imx_fec: Use correct length for packet size
40
imx_fec: Fix a typo in imx_enet_receive()
41
imx_fec: Reserve full FSL_IMX25_FEC_SIZE page for the register file
42
43
Michael Weiser (8):
44
linux-user: Add support for big-endian aarch64
45
linux-user: Add separate aarch64_be uname
46
linux-user: Fix endianess of aarch64 signal trampoline
47
configure: Add aarch64_be-linux-user target
48
linux-user: Add aarch64_be magic numbers to qemu-binfmt-conf.sh
49
linux-user: Separate binfmt arm CPU families
50
linux-user: Activate armeb handler registration
51
target/arm: Fix stlxp for aarch64_be
52
29
53
Peter Maydell (4):
30
Peter Maydell (4):
54
linux-user/arm/nwfpe: Check coprocessor number for FPA emulation
31
stellaris_input: Fix vmstate description of buttons field
55
target/arm: Make disas_thumb2_insn() generate its own UNDEF exceptions
32
vmstate.h: Type check VMSTATE_STRUCT_VARRAY macros
56
hw/intc/arm_gicv3: Make reserved register addresses RAZ/WI
33
hw/arm/boot: Rename elf_{low, high}_addr to image_{low, high}_addr
57
hw/intc/arm_gic: reserved register addresses are RAZ/WI
34
hw/arm/boot: Further improve initrd positioning code
58
35
59
Philippe Mathieu-Daudé (2):
36
include/migration/vmstate.h | 30 ++++++++++++++++++++++++------
60
hw/timer/pxa2xx_timer: replace hw_error() -> qemu_log_mask()
37
hw/arm/boot.c | 37 +++++++++++++++++++++++++++----------
61
hw/sd/pxa2xx_mmci: add read/write() trace events
38
hw/dma/pl330.c | 17 +++++++++--------
39
hw/input/stellaris_input.c | 10 ++++++----
40
4 files changed, 66 insertions(+), 28 deletions(-)
62
41
63
Zhaoshenglong (1):
64
Virt: ACPI: fix qemu assert due to re-assigned table data address
65
66
configure | 5 +-
67
include/hw/arm/fsl-imx25.h | 1 -
68
include/hw/net/imx_fec.h | 27 +++-
69
linux-user/aarch64/target_syscall.h | 4 +
70
hw/arm/fsl-imx6.c | 1 +
71
hw/arm/virt-acpi-build.c | 18 ++-
72
hw/intc/arm_gic.c | 5 +-
73
hw/intc/arm_gicv3_dist.c | 13 ++
74
hw/intc/arm_gicv3_its_common.c | 8 +-
75
hw/intc/arm_gicv3_redist.c | 13 ++
76
hw/net/imx_fec.c | 210 +++++++++++++++++++++++-------
77
hw/sd/pxa2xx_mmci.c | 78 +++++++----
78
hw/timer/pxa2xx_timer.c | 17 ++-
79
linux-user/arm/nwfpe/fpa11.c | 9 ++
80
linux-user/main.c | 6 +
81
linux-user/signal.c | 10 +-
82
target/arm/helper-a64.c | 7 +-
83
target/arm/translate.c | 23 ++--
84
default-configs/aarch64_be-linux-user.mak | 1 +
85
hw/sd/trace-events | 4 +
86
scripts/qemu-binfmt-conf.sh | 15 ++-
87
21 files changed, 356 insertions(+), 119 deletions(-)
88
create mode 100644 default-configs/aarch64_be-linux-user.mak
89
diff view generated by jsdifflib
Deleted patch
1
From: Michael Weiser <michael.weiser@gmx.de>
2
1
3
Enable big-endian mode for data accesses on aarch64 for big-endian linux
4
user mode. Activate it for all exception levels as documented by ARM:
5
Set the SCTLR EE bit for ELs 1 through 3. Additionally set bit E0E in
6
EL1 to enable it in EL0 as well.
7
8
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20171220212308.12614-2-michael.weiser@gmx.de
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
linux-user/main.c | 6 ++++++
14
1 file changed, 6 insertions(+)
15
16
diff --git a/linux-user/main.c b/linux-user/main.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/linux-user/main.c
19
+++ b/linux-user/main.c
20
@@ -XXX,XX +XXX,XX @@ int main(int argc, char **argv, char **envp)
21
}
22
env->pc = regs->pc;
23
env->xregs[31] = regs->sp;
24
+#ifdef TARGET_WORDS_BIGENDIAN
25
+ env->cp15.sctlr_el[1] |= SCTLR_E0E;
26
+ for (i = 1; i < 4; ++i) {
27
+ env->cp15.sctlr_el[i] |= SCTLR_EE;
28
+ }
29
+#endif
30
}
31
#elif defined(TARGET_ARM)
32
{
33
--
34
2.7.4
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Michael Weiser <michael.weiser@gmx.de>
2
1
3
Make big-endian aarch64 systems identify as aarch64_be as expected by
4
big-endian userland and toolchains.
5
6
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
9
Message-id: 20171220212308.12614-3-michael.weiser@gmx.de
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
linux-user/aarch64/target_syscall.h | 4 ++++
13
1 file changed, 4 insertions(+)
14
15
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/linux-user/aarch64/target_syscall.h
18
+++ b/linux-user/aarch64/target_syscall.h
19
@@ -XXX,XX +XXX,XX @@ struct target_pt_regs {
20
uint64_t pstate;
21
};
22
23
+#if defined(TARGET_WORDS_BIGENDIAN)
24
+#define UNAME_MACHINE "aarch64_be"
25
+#else
26
#define UNAME_MACHINE "aarch64"
27
+#endif
28
#define UNAME_MINIMUM_RELEASE "3.8.0"
29
#define TARGET_CLONE_BACKWARDS
30
#define TARGET_MINSIGSTKSZ 2048
31
--
32
2.7.4
33
34
diff view generated by jsdifflib
Deleted patch
1
From: Michael Weiser <michael.weiser@gmx.de>
2
1
3
Since for aarch64 the signal trampoline is synthesized directly into the
4
signal frame we need to make sure the instructions end up little-endian.
5
Otherwise the wrong endianness will cause a SIGILL upon return from the
6
signal handler on big-endian targets.
7
8
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20171220212308.12614-4-michael.weiser@gmx.de
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
linux-user/signal.c | 10 +++++++---
14
1 file changed, 7 insertions(+), 3 deletions(-)
15
16
diff --git a/linux-user/signal.c b/linux-user/signal.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/linux-user/signal.c
19
+++ b/linux-user/signal.c
20
@@ -XXX,XX +XXX,XX @@ static void target_setup_frame(int usig, struct target_sigaction *ka,
21
if (ka->sa_flags & TARGET_SA_RESTORER) {
22
return_addr = ka->sa_restorer;
23
} else {
24
- /* mov x8,#__NR_rt_sigreturn; svc #0 */
25
- __put_user(0xd2801168, &frame->tramp[0]);
26
- __put_user(0xd4000001, &frame->tramp[1]);
27
+ /*
28
+ * mov x8,#__NR_rt_sigreturn; svc #0
29
+ * Since these are instructions they need to be put as little-endian
30
+ * regardless of target default or current CPU endianness.
31
+ */
32
+ __put_user_e(0xd2801168, &frame->tramp[0], le);
33
+ __put_user_e(0xd4000001, &frame->tramp[1], le);
34
return_addr = frame_addr + offsetof(struct target_rt_sigframe, tramp);
35
}
36
env->xregs[0] = usig;
37
--
38
2.7.4
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Michael Weiser <michael.weiser@gmx.de>
2
1
3
Add target aarch64_be-linux-user. This allows a qemu-aarch64_be binary
4
to be built that will run big-endian aarch64 binaries.
5
6
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
9
Message-id: 20171220212308.12614-5-michael.weiser@gmx.de
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
configure | 5 +++--
13
default-configs/aarch64_be-linux-user.mak | 1 +
14
2 files changed, 4 insertions(+), 2 deletions(-)
15
create mode 100644 default-configs/aarch64_be-linux-user.mak
16
17
diff --git a/configure b/configure
18
index XXXXXXX..XXXXXXX 100755
19
--- a/configure
20
+++ b/configure
21
@@ -XXX,XX +XXX,XX @@ target_name=$(echo $target | cut -d '-' -f 1)
22
target_bigendian="no"
23
24
case "$target_name" in
25
- armeb|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
26
+ armeb|aarch64_be|hppa|lm32|m68k|microblaze|mips|mipsn32|mips64|moxie|or1k|ppc|ppcemb|ppc64|ppc64abi32|s390x|sh4eb|sparc|sparc64|sparc32plus|xtensaeb)
27
target_bigendian=yes
28
;;
29
esac
30
@@ -XXX,XX +XXX,XX @@ case "$target_name" in
31
mttcg="yes"
32
gdb_xml_files="arm-core.xml arm-vfp.xml arm-vfp3.xml arm-neon.xml"
33
;;
34
- aarch64)
35
+ aarch64|aarch64_be)
36
+ TARGET_ARCH=aarch64
37
TARGET_BASE_ARCH=arm
38
bflt="yes"
39
mttcg="yes"
40
diff --git a/default-configs/aarch64_be-linux-user.mak b/default-configs/aarch64_be-linux-user.mak
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/default-configs/aarch64_be-linux-user.mak
45
@@ -0,0 +1 @@
46
+# Default configuration for aarch64_be-linux-user
47
--
48
2.7.4
49
50
diff view generated by jsdifflib
Deleted patch
1
From: Michael Weiser <michael.weiser@gmx.de>
2
1
3
As we now have a linux-user aarch64_be target, we can add it to the list
4
of supported targets in qemu-binfmt-conf.sh
5
6
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
7
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
8
Message-id: 20171220212308.12614-6-michael.weiser@gmx.de
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
scripts/qemu-binfmt-conf.sh | 6 +++++-
12
1 file changed, 5 insertions(+), 1 deletion(-)
13
14
diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
15
index XXXXXXX..XXXXXXX 100755
16
--- a/scripts/qemu-binfmt-conf.sh
17
+++ b/scripts/qemu-binfmt-conf.sh
18
@@ -XXX,XX +XXX,XX @@
19
20
qemu_target_list="i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le m68k \
21
mips mipsel mipsn32 mipsn32el mips64 mips64el \
22
-sh4 sh4eb s390x aarch64 hppa"
23
+sh4 sh4eb s390x aarch64 aarch64_be hppa"
24
25
i386_magic='\x7fELF\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03\x00'
26
i386_mask='\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
27
@@ -XXX,XX +XXX,XX @@ aarch64_magic='\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x
28
aarch64_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff'
29
aarch64_family=arm
30
31
+aarch64_be_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7'
32
+aarch64_be_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
33
+aarch64_be_family=arm
34
+
35
hppa_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x0f'
36
hppa_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
37
hppa_family=hppa
38
--
39
2.7.4
40
41
diff view generated by jsdifflib
Deleted patch
1
From: Michael Weiser <michael.weiser@gmx.de>
2
1
3
Give big-endian arm and aarch64 CPUs their own family in
4
qemu-binfmt-conf.sh to make sure we register qemu-user for binaries of
5
the opposite endianness on arm and aarch64. Apart from the family
6
assignments of the magic values, qemu_get_family() needs to be able to
7
distinguish the two and recognise aarch64{,_be} as well.
8
9
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
10
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
11
Message-id: 20171220212308.12614-7-michael.weiser@gmx.de
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
scripts/qemu-binfmt-conf.sh | 9 ++++++---
15
1 file changed, 6 insertions(+), 3 deletions(-)
16
17
diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
18
index XXXXXXX..XXXXXXX 100755
19
--- a/scripts/qemu-binfmt-conf.sh
20
+++ b/scripts/qemu-binfmt-conf.sh
21
@@ -XXX,XX +XXX,XX @@ arm_family=arm
22
23
armeb_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x28'
24
armeb_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
25
-armeb_family=arm
26
+armeb_family=armeb
27
28
sparc_magic='\x7fELF\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02'
29
sparc_mask='\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
30
@@ -XXX,XX +XXX,XX @@ aarch64_family=arm
31
32
aarch64_be_magic='\x7fELF\x02\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7'
33
aarch64_be_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
34
-aarch64_be_family=arm
35
+aarch64_be_family=armeb
36
37
hppa_magic='\x7f\x45\x4c\x46\x01\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x0f'
38
hppa_mask='\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff'
39
@@ -XXX,XX +XXX,XX @@ qemu_get_family() {
40
ppc64el|ppc64le)
41
echo "ppcle"
42
;;
43
- arm|armel|armhf|arm64|armv[4-9]*)
44
+ arm|armel|armhf|arm64|armv[4-9]*l|aarch64)
45
echo "arm"
46
;;
47
+ armeb|armv[4-9]*b|aarch64_be)
48
+ echo "armeb"
49
+ ;;
50
sparc*)
51
echo "sparc"
52
;;
53
--
54
2.7.4
55
56
diff view generated by jsdifflib
Deleted patch
1
From: Michael Weiser <michael.weiser@gmx.de>
2
1
3
armeb is missing from the target list in qemu-binfmt-conf.sh. Add it so
4
the handler for those binaries gets registered by the script.
5
6
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
7
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
8
Message-id: 20171220212308.12614-8-michael.weiser@gmx.de
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
scripts/qemu-binfmt-conf.sh | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
13
14
diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
15
index XXXXXXX..XXXXXXX 100755
16
--- a/scripts/qemu-binfmt-conf.sh
17
+++ b/scripts/qemu-binfmt-conf.sh
18
@@ -XXX,XX +XXX,XX @@
19
# enable automatic i386/ARM/M68K/MIPS/SPARC/PPC/s390/HPPA
20
# program execution by the kernel
21
22
-qemu_target_list="i386 i486 alpha arm sparc32plus ppc ppc64 ppc64le m68k \
23
+qemu_target_list="i386 i486 alpha arm armeb sparc32plus ppc ppc64 ppc64le m68k \
24
mips mipsel mipsn32 mipsn32el mips64 mips64el \
25
sh4 sh4eb s390x aarch64 aarch64_be hppa"
26
27
--
28
2.7.4
29
30
diff view generated by jsdifflib
Deleted patch
1
From: Michael Weiser <michael.weiser@gmx.de>
2
1
3
ldxp loads two consecutive doublewords from memory regardless of CPU
4
endianness. On store, stlxp currently assumes to work with a 128bit
5
value and consequently switches order in big-endian mode. With this
6
change it packs the doublewords in reverse order in anticipation of the
7
128bit big-endian store operation interposing them so they end up in
8
memory in the right order. This makes it work for both MTTCG and !MTTCG.
9
It effectively implements the ARM ARM STLXP operation pseudo-code:
10
11
data = if BigEndian() then el1:el2 else el2:el1;
12
13
With this change an aarch64_be Linux 4.14.4 kernel succeeds to boot up
14
in system emulation mode.
15
16
Signed-off-by: Michael Weiser <michael.weiser@gmx.de>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
target/arm/helper-a64.c | 7 +++++--
21
1 file changed, 5 insertions(+), 2 deletions(-)
22
23
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper-a64.c
26
+++ b/target/arm/helper-a64.c
27
@@ -XXX,XX +XXX,XX @@ static uint64_t do_paired_cmpxchg64_be(CPUARMState *env, uint64_t addr,
28
Int128 oldv, cmpv, newv;
29
bool success;
30
31
- cmpv = int128_make128(env->exclusive_val, env->exclusive_high);
32
- newv = int128_make128(new_lo, new_hi);
33
+ /* high and low need to be switched here because this is not actually a
34
+ * 128bit store but two doublewords stored consecutively
35
+ */
36
+ cmpv = int128_make128(env->exclusive_high, env->exclusive_val);
37
+ newv = int128_make128(new_hi, new_lo);
38
39
if (parallel) {
40
#ifndef CONFIG_ATOMIC128
41
--
42
2.7.4
43
44
diff view generated by jsdifflib
1
Our copy of the nwfpe code for emulating of the old FPA11 floating
1
From: Damien Hedde <damien.hedde@greensocs.com>
2
point unit doesn't check the coprocessor number in the instruction
3
when it emulates it. This means that we might treat some
4
instructions which should really UNDEF as being FPA11 instructions by
5
accident.
6
2
7
The kernel's copy of the nwfpe code doesn't make this error; I suspect
3
Fix the pl330 main and queue vmstate description.
8
the bug was noticed and fixed as part of the process of mainlining
4
There were missing POINTER flags causing crashes during
9
the nwfpe code more than a decade ago.
5
incoming migration because:
6
+ PL330State chan field is a pointer to an array
7
+ PL330Queue queue field is a pointer to an array
10
8
11
Add a check that the coprocessor number (which is always in bits
9
Also bump corresponding vmsd version numbers.
12
[11:8] of the instruction) is either 1 or 2, which is where the
13
FPA11 lives.
14
10
15
Reported-by: Richard Henderson <richard.henderson@linaro.org>
11
Signed-off-by: Damien Hedde <damien.hedde@greensocs.com>
12
Reviewed-by: Philippe Mathieu-Daude <philmd@redhat.com>
13
Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
14
Message-id: 20190724143553.21557-1-damien.hedde@greensocs.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
16
---
18
linux-user/arm/nwfpe/fpa11.c | 9 +++++++++
17
hw/dma/pl330.c | 17 +++++++++--------
19
1 file changed, 9 insertions(+)
18
1 file changed, 9 insertions(+), 8 deletions(-)
20
19
21
diff --git a/linux-user/arm/nwfpe/fpa11.c b/linux-user/arm/nwfpe/fpa11.c
20
diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
22
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
23
--- a/linux-user/arm/nwfpe/fpa11.c
22
--- a/hw/dma/pl330.c
24
+++ b/linux-user/arm/nwfpe/fpa11.c
23
+++ b/hw/dma/pl330.c
25
@@ -XXX,XX +XXX,XX @@ unsigned int EmulateAll(unsigned int opcode, FPA11* qfpa, CPUARMState* qregs)
24
@@ -XXX,XX +XXX,XX @@ typedef struct PL330Queue {
26
unsigned int nRc = 0;
25
27
// unsigned long flags;
26
static const VMStateDescription vmstate_pl330_queue = {
28
FPA11 *fpa11;
27
.name = "pl330_queue",
29
+ unsigned int cp;
28
- .version_id = 1,
30
// save_flags(flags); sti();
29
- .minimum_version_id = 1,
31
30
+ .version_id = 2,
32
+ /* Check that this is really an FPA11 instruction: the coprocessor
31
+ .minimum_version_id = 2,
33
+ * field in bits [11:8] must be 1 or 2.
32
.fields = (VMStateField[]) {
34
+ */
33
- VMSTATE_STRUCT_VARRAY_UINT32(queue, PL330Queue, queue_size, 1,
35
+ cp = (opcode >> 8) & 0xf;
34
- vmstate_pl330_queue_entry, PL330QueueEntry),
36
+ if (cp != 1 && cp != 2) {
35
+ VMSTATE_STRUCT_VARRAY_POINTER_UINT32(queue, PL330Queue, queue_size,
37
+ return 0;
36
+ vmstate_pl330_queue_entry,
38
+ }
37
+ PL330QueueEntry),
39
+
38
VMSTATE_END_OF_LIST()
40
qemufpa=qfpa;
39
}
41
user_registers=qregs;
40
};
42
41
@@ -XXX,XX +XXX,XX @@ struct PL330State {
42
43
static const VMStateDescription vmstate_pl330 = {
44
.name = "pl330",
45
- .version_id = 1,
46
- .minimum_version_id = 1,
47
+ .version_id = 2,
48
+ .minimum_version_id = 2,
49
.fields = (VMStateField[]) {
50
VMSTATE_STRUCT(manager, PL330State, 0, vmstate_pl330_chan, PL330Chan),
51
- VMSTATE_STRUCT_VARRAY_UINT32(chan, PL330State, num_chnls, 0,
52
- vmstate_pl330_chan, PL330Chan),
53
+ VMSTATE_STRUCT_VARRAY_POINTER_UINT32(chan, PL330State, num_chnls,
54
+ vmstate_pl330_chan, PL330Chan),
55
VMSTATE_VBUFFER_UINT32(lo_seqn, PL330State, 1, NULL, num_chnls),
56
VMSTATE_VBUFFER_UINT32(hi_seqn, PL330State, 1, NULL, num_chnls),
57
VMSTATE_STRUCT(fifo, PL330State, 0, vmstate_pl330_fifo, PL330Fifo),
43
--
58
--
44
2.7.4
59
2.20.1
45
60
46
61
diff view generated by jsdifflib
1
Refactor disas_thumb2_insn() so that it generates the code for raising
1
gamepad_state::buttons is a pointer to an array of structs,
2
an UNDEF exception for invalid insns, rather than returning a flag
2
not an array of structs, so should be declared in the vmstate
3
which the caller must check to see if it needs to generate the UNDEF
3
with VMSTATE_STRUCT_VARRAY_POINTER_INT32; otherwise we
4
code. This brings the function in to line with the behaviour of
4
corrupt memory on incoming migration.
5
disas_thumb_insn() and disas_arm_insn().
5
6
We bump the vmstate version field as the easiest way to
7
deal with the migration break, since migration wouldn't have
8
worked reliably before anyway.
6
9
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
9
Message-id: 1513080506-17703-1-git-send-email-peter.maydell@linaro.org
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
13
Reviewed-by: Damien Hedde <damien.hedde@greensocs.com>
14
Message-id: 20190725163710.11703-2-peter.maydell@linaro.org
10
---
15
---
11
target/arm/translate.c | 23 ++++++++++-------------
16
hw/input/stellaris_input.c | 10 ++++++----
12
1 file changed, 10 insertions(+), 13 deletions(-)
17
1 file changed, 6 insertions(+), 4 deletions(-)
13
18
14
diff --git a/target/arm/translate.c b/target/arm/translate.c
19
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate.c
21
--- a/hw/input/stellaris_input.c
17
+++ b/target/arm/translate.c
22
+++ b/hw/input/stellaris_input.c
18
@@ -XXX,XX +XXX,XX @@ gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
23
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_stellaris_button = {
19
return 0;
24
20
}
25
static const VMStateDescription vmstate_stellaris_gamepad = {
21
26
.name = "stellaris_gamepad",
22
-/* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
27
- .version_id = 1,
23
- is not legal. */
28
- .minimum_version_id = 1,
24
-static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
29
+ .version_id = 2,
25
+/* Translate a 32-bit thumb instruction. */
30
+ .minimum_version_id = 2,
26
+static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
31
.fields = (VMStateField[]) {
27
{
32
VMSTATE_INT32(extension, gamepad_state),
28
uint32_t imm, shift, offset;
33
- VMSTATE_STRUCT_VARRAY_INT32(buttons, gamepad_state, num_buttons, 0,
29
uint32_t rd, rn, rm, rs;
34
- vmstate_stellaris_button, gamepad_button),
30
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
35
+ VMSTATE_STRUCT_VARRAY_POINTER_INT32(buttons, gamepad_state,
31
/* UNPREDICTABLE, unallocated hint or
36
+ num_buttons,
32
* PLD/PLDW/PLI (literal)
37
+ vmstate_stellaris_button,
33
*/
38
+ gamepad_button),
34
- return 0;
39
VMSTATE_END_OF_LIST()
35
+ return;
36
}
37
if (op1 & 1) {
38
- return 0; /* PLD/PLDW/PLI or unallocated hint */
39
+ return; /* PLD/PLDW/PLI or unallocated hint */
40
}
41
if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
42
- return 0; /* PLD/PLDW/PLI or unallocated hint */
43
+ return; /* PLD/PLDW/PLI or unallocated hint */
44
}
45
/* UNDEF space, or an UNPREDICTABLE */
46
- return 1;
47
+ goto illegal_op;
48
}
49
}
50
memidx = get_mem_index(s);
51
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
52
default:
53
goto illegal_op;
54
}
40
}
55
- return 0;
41
};
56
+ return;
57
illegal_op:
58
- return 1;
59
+ gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
60
+ default_exception_el(s));
61
}
62
63
static void disas_thumb_insn(DisasContext *s, uint32_t insn)
64
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
65
if (is_16bit) {
66
disas_thumb_insn(dc, insn);
67
} else {
68
- if (disas_thumb2_insn(dc, insn)) {
69
- gen_exception_insn(dc, 4, EXCP_UDEF, syn_uncategorized(),
70
- default_exception_el(dc));
71
- }
72
+ disas_thumb2_insn(dc, insn);
73
}
74
75
/* Advance the Thumb condexec condition. */
76
--
42
--
77
2.7.4
43
2.20.1
78
44
79
45
diff view generated by jsdifflib
1
From: Zhaoshenglong <zhaoshenglong@huawei.com>
1
The VMSTATE_STRUCT_VARRAY_UINT32 macro is intended to handle
2
migrating a field which is an array of structs, but where instead of
3
migrating the entire array we only migrate a variable number of
4
elements of it.
2
5
3
acpi_data_push uses g_array_set_size to resize the memory size. If there
6
The VMSTATE_STRUCT_VARRAY_POINTER_UINT32 macro is intended to handle
4
is no enough contiguous memory, the address will be changed. If we use
7
migrating a field which is of pointer type, and points to a
5
the old value, it will assert.
8
dynamically allocated array of structs of variable size.
6
qemu-kvm: hw/acpi/bios-linker-loader.c:214: bios_linker_loader_add_checksum:
7
Assertion `start_offset < file->blob->len' failed.`
8
9
9
This issue only happens in building SRAT table now but here we unify the
10
We weren't actually checking that the field passed to
10
pattern for other tables as well to avoid possible issues in the future.
11
VMSTATE_STRUCT_VARRAY_UINT32 really is an array, with the result that
12
accidentally using it where the _POINTER_ macro was intended would
13
compile but silently corrupt memory on migration.
11
14
12
Signed-off-by: Zhaoshenglong <zhaoshenglong@huawei.com>
15
Add type-checking that enforces that the field passed in is
13
Reviewed-by: Andrew Jones <drjones@redhat.com>
16
really of the right array type. This applies to all the VMSTATE
17
macros which use flags including VMS_VARRAY_* but not VMS_POINTER.
18
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
21
Reviewed-by: Damien Hedde <damien.hedde@greensocs.com>
22
Tested-by: Damien Hedde <damien.hedde@greensocs.com>
23
Message-id: 20190725163710.11703-3-peter.maydell@linaro.org
15
---
24
---
16
hw/arm/virt-acpi-build.c | 18 +++++++++++-------
25
include/migration/vmstate.h | 30 ++++++++++++++++++++++++------
17
1 file changed, 11 insertions(+), 7 deletions(-)
26
1 file changed, 24 insertions(+), 6 deletions(-)
18
27
19
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
28
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
20
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/arm/virt-acpi-build.c
30
--- a/include/migration/vmstate.h
22
+++ b/hw/arm/virt-acpi-build.c
31
+++ b/include/migration/vmstate.h
23
@@ -XXX,XX +XXX,XX @@ build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
32
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_bitmap;
24
AcpiSerialPortConsoleRedirection *spcr;
33
extern const VMStateInfo vmstate_info_qtailq;
25
const MemMapEntry *uart_memmap = &vms->memmap[VIRT_UART];
34
26
int irq = vms->irqmap[VIRT_UART] + ARM_SPI_BASE;
35
#define type_check_2darray(t1,t2,n,m) ((t1(*)[n][m])0 - (t2*)0)
27
+ int spcr_start = table_data->len;
36
+/*
28
37
+ * Check that type t2 is an array of type t1 of size n,
29
spcr = acpi_data_push(table_data, sizeof(*spcr));
38
+ * e.g. if t1 is 'foo' and n is 32 then t2 must be 'foo[32]'
30
39
+ */
31
@@ -XXX,XX +XXX,XX @@ build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
40
#define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0)
32
spcr->pci_device_id = 0xffff; /* PCI Device ID: not a PCI device */
41
#define type_check_pointer(t1,t2) ((t1**)0 - (t2*)0)
33
spcr->pci_vendor_id = 0xffff; /* PCI Vendor ID: not a PCI device */
42
+/*
34
43
+ * type of element 0 of the specified (array) field of the type.
35
- build_header(linker, table_data, (void *)spcr, "SPCR", sizeof(*spcr), 2,
44
+ * Note that if the field is a pointer then this will return the
36
- NULL, NULL);
45
+ * pointed-to type rather than complaining.
37
+ build_header(linker, table_data, (void *)(table_data->data + spcr_start),
46
+ */
38
+ "SPCR", table_data->len - spcr_start, 2, NULL, NULL);
47
+#define typeof_elt_of_field(type, field) typeof(((type *)0)->field[0])
48
+/* Check that field f in struct type t2 is an array of t1, of any size */
49
+#define type_check_varray(t1, t2, f) \
50
+ (type_check(t1, typeof_elt_of_field(t2, f)) \
51
+ + QEMU_BUILD_BUG_ON_ZERO(!QEMU_IS_ARRAY(((t2 *)0)->f)))
52
53
#define vmstate_offset_value(_state, _field, _type) \
54
(offsetof(_state, _field) + \
55
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
56
vmstate_offset_array(_state, _field, uint8_t, \
57
sizeof(typeof_field(_state, _field)))
58
59
+#define vmstate_offset_varray(_state, _field, _type) \
60
+ (offsetof(_state, _field) + \
61
+ type_check_varray(_type, _state, _field))
62
+
63
/* In the macros below, if there is a _version, that means the macro's
64
* field will be processed only if the version being received is >=
65
* the _version specified. In general, if you add a new field, you
66
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
67
.info = &(_info), \
68
.size = sizeof(_type), \
69
.flags = VMS_VARRAY_UINT32|VMS_MULTIPLY_ELEMENTS, \
70
- .offset = offsetof(_state, _field), \
71
+ .offset = vmstate_offset_varray(_state, _field, _type), \
39
}
72
}
40
73
41
static void
74
#define VMSTATE_ARRAY_TEST(_field, _state, _num, _test, _info, _type) {\
42
@@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
75
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
43
mem_base += numa_info[i].node_mem;
76
.info = &(_info), \
44
}
77
.size = sizeof(_type), \
45
78
.flags = VMS_VARRAY_INT32, \
46
- build_header(linker, table_data, (void *)srat, "SRAT",
79
- .offset = offsetof(_state, _field), \
47
- table_data->len - srat_start, 3, NULL, NULL);
80
+ .offset = vmstate_offset_varray(_state, _field, _type), \
48
+ build_header(linker, table_data, (void *)(table_data->data + srat_start),
49
+ "SRAT", table_data->len - srat_start, 3, NULL, NULL);
50
}
81
}
51
82
52
static void
83
#define VMSTATE_VARRAY_INT32(_field, _state, _field_num, _version, _info, _type) {\
53
@@ -XXX,XX +XXX,XX @@ build_mcfg(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
84
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
54
AcpiTableMcfg *mcfg;
85
.info = &(_info), \
55
const MemMapEntry *memmap = vms->memmap;
86
.size = sizeof(_type), \
56
int len = sizeof(*mcfg) + sizeof(mcfg->allocation[0]);
87
.flags = VMS_VARRAY_UINT16, \
57
+ int mcfg_start = table_data->len;
88
- .offset = offsetof(_state, _field), \
58
89
+ .offset = vmstate_offset_varray(_state, _field, _type), \
59
mcfg = acpi_data_push(table_data, len);
60
mcfg->allocation[0].address = cpu_to_le64(memmap[VIRT_PCIE_ECAM].base);
61
@@ -XXX,XX +XXX,XX @@ build_mcfg(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
62
mcfg->allocation[0].end_bus_number = (memmap[VIRT_PCIE_ECAM].size
63
/ PCIE_MMCFG_SIZE_MIN) - 1;
64
65
- build_header(linker, table_data, (void *)mcfg, "MCFG", len, 1, NULL, NULL);
66
+ build_header(linker, table_data, (void *)(table_data->data + mcfg_start),
67
+ "MCFG", table_data->len - mcfg_start, 1, NULL, NULL);
68
}
90
}
69
91
70
/* GTDT */
92
#define VMSTATE_VSTRUCT_TEST(_field, _state, _test, _version, _vmsd, _type, _struct_version) { \
71
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
93
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
72
static void build_fadt(GArray *table_data, BIOSLinker *linker,
94
.vmsd = &(_vmsd), \
73
VirtMachineState *vms, unsigned dsdt_tbl_offset)
95
.size = sizeof(_type), \
74
{
96
.flags = VMS_STRUCT|VMS_VARRAY_UINT8, \
75
+ int fadt_start = table_data->len;
97
- .offset = offsetof(_state, _field), \
76
AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));
98
+ .offset = vmstate_offset_varray(_state, _field, _type), \
77
unsigned xdsdt_entry_offset = (char *)&fadt->x_dsdt - table_data->data;
78
uint16_t bootflags;
79
@@ -XXX,XX +XXX,XX @@ static void build_fadt(GArray *table_data, BIOSLinker *linker,
80
ACPI_BUILD_TABLE_FILE, xdsdt_entry_offset, sizeof(fadt->x_dsdt),
81
ACPI_BUILD_TABLE_FILE, dsdt_tbl_offset);
82
83
- build_header(linker, table_data,
84
- (void *)fadt, "FACP", sizeof(*fadt), 5, NULL, NULL);
85
+ build_header(linker, table_data, (void *)(table_data->data + fadt_start),
86
+ "FACP", table_data->len - fadt_start, 5, NULL, NULL);
87
}
99
}
88
100
89
/* DSDT */
101
/* a variable length array (i.e. _type *_field) but we know the
102
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
103
.vmsd = &(_vmsd), \
104
.size = sizeof(_type), \
105
.flags = VMS_STRUCT|VMS_VARRAY_INT32, \
106
- .offset = offsetof(_state, _field), \
107
+ .offset = vmstate_offset_varray(_state, _field, _type), \
108
}
109
110
#define VMSTATE_STRUCT_VARRAY_UINT32(_field, _state, _field_num, _version, _vmsd, _type) { \
111
@@ -XXX,XX +XXX,XX @@ extern const VMStateInfo vmstate_info_qtailq;
112
.vmsd = &(_vmsd), \
113
.size = sizeof(_type), \
114
.flags = VMS_STRUCT|VMS_VARRAY_UINT32, \
115
- .offset = offsetof(_state, _field), \
116
+ .offset = vmstate_offset_varray(_state, _field, _type), \
117
}
118
119
#define VMSTATE_STRUCT_VARRAY_ALLOC(_field, _state, _field_num, _version, _vmsd, _type) {\
90
--
120
--
91
2.7.4
121
2.20.1
92
122
93
123
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
Binding to a particular netdev doesn't seem to belong to this layer
4
and should probably be done as a part of board or SoC specific code.
5
6
Convert all of the users of this IP block to use
7
qdev_set_nic_properties() instead.
8
9
Cc: Peter Maydell <peter.maydell@linaro.org>
10
Cc: Jason Wang <jasowang@redhat.com>
11
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Cc: qemu-devel@nongnu.org
13
Cc: qemu-arm@nongnu.org
14
Cc: yurovsky@gmail.com
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
19
hw/arm/fsl-imx6.c | 1 +
20
hw/net/imx_fec.c | 2 --
21
2 files changed, 1 insertion(+), 2 deletions(-)
22
23
diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/arm/fsl-imx6.c
26
+++ b/hw/arm/fsl-imx6.c
27
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6_realize(DeviceState *dev, Error **errp)
28
spi_table[i].irq));
29
}
30
31
+ qdev_set_nic_properties(DEVICE(&s->eth), &nd_table[0]);
32
object_property_set_bool(OBJECT(&s->eth), true, "realized", &err);
33
if (err) {
34
error_propagate(errp, err);
35
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/net/imx_fec.c
38
+++ b/hw/net/imx_fec.c
39
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
40
41
qemu_macaddr_default_if_unset(&s->conf.macaddr);
42
43
- s->conf.peers.ncs[0] = nd_table[0].netdev;
44
-
45
s->nic = qemu_new_nic(&imx_eth_net_info, &s->conf,
46
object_get_typename(OBJECT(dev)),
47
DEVICE(dev)->id, s);
48
--
49
2.7.4
50
51
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
Refactor imx_eth_enable_rx() to have more meaningfull variable name
4
than 'tmp' and to reduce number of logical negations done.
5
6
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Cc: Jason Wang <jasowang@redhat.com>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: qemu-devel@nongnu.org
10
Cc: qemu-arm@nongnu.org
11
Cc: yurovsky@gmail.com
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/net/imx_fec.c | 8 ++++----
18
1 file changed, 4 insertions(+), 4 deletions(-)
19
20
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/net/imx_fec.c
23
+++ b/hw/net/imx_fec.c
24
@@ -XXX,XX +XXX,XX @@ static void imx_eth_do_tx(IMXFECState *s)
25
static void imx_eth_enable_rx(IMXFECState *s)
26
{
27
IMXFECBufDesc bd;
28
- bool tmp;
29
+ bool rx_ring_full;
30
31
imx_fec_read_bd(&bd, s->rx_descriptor);
32
33
- tmp = ((bd.flags & ENET_BD_E) != 0);
34
+ rx_ring_full = !(bd.flags & ENET_BD_E);
35
36
- if (!tmp) {
37
+ if (rx_ring_full) {
38
FEC_PRINTF("RX buffer full\n");
39
} else if (!s->regs[ENET_RDAR]) {
40
qemu_flush_queued_packets(qemu_get_queue(s->nic));
41
}
42
43
- s->regs[ENET_RDAR] = tmp ? ENET_RDAR_RDAR : 0;
44
+ s->regs[ENET_RDAR] = rx_ring_full ? 0 : ENET_RDAR_RDAR;
45
}
46
47
static void imx_eth_reset(DeviceState *d)
48
--
49
2.7.4
50
51
diff view generated by jsdifflib
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
1
Rename the elf_low_addr and elf_high_addr variables to image_low_addr
2
and image_high_addr -- in the next commit we will extend them to
3
be set for other kinds of image file and not just ELF files.
2
4
3
In current implementation, packet queue flushing logic seem to suffer
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
from a deadlock like scenario if a packet is received by the interface
6
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
before before Rx ring is initialized by Guest's driver. Consider the
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
following sequence of events:
8
Tested-by: Mark Rutland <mark.rutland@arm.com>
9
Message-id: 20190722151804.25467-2-peter.maydell@linaro.org
10
---
11
hw/arm/boot.c | 20 +++++++++++---------
12
1 file changed, 11 insertions(+), 9 deletions(-)
7
13
8
    1. A QEMU instance is started against a TAP device on Linux
14
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
9
     host, running Linux guest, e. g., something to the effect
10
     of:
11
12
     qemu-system-arm \
13
     -net nic,model=imx.fec,netdev=lan0 \
14
     netdev tap,id=lan0,ifname=tap0,script=no,downscript=no \
15
     ... rest of the arguments ...
16
17
    2. Once QEMU starts, but before guest reaches the point where
18
     FEC deriver is done initializing the HW, Guest, via TAP
19
     interface, receives a number of multicast MDNS packets from
20
     Host (not necessarily true for every OS, but it happens at
21
     least on Fedora 25)
22
23
    3. Recieving a packet in such a state results in
24
     imx_eth_can_receive() returning '0', which in turn causes
25
     tap_send() to disable corresponding event (tap.c:203)
26
27
    4. Once Guest's driver reaches the point where it is ready to
28
     recieve packets it prepares Rx ring descriptors and writes
29
     ENET_RDAR_RDAR to ENET_RDAR register to indicate to HW that
30
     more descriptors are ready. And at this points emulation
31
     layer does this:
32
33
          s->regs[index] = ENET_RDAR_RDAR;
34
imx_eth_enable_rx(s);
35
36
     which, combined with:
37
38
          if (!s->regs[ENET_RDAR]) {
39
         qemu_flush_queued_packets(qemu_get_queue(s->nic));
40
         }
41
42
     results in Rx queue never being flushed and corresponding
43
     I/O event beign disabled.
44
45
To prevent the problem, change the code to always flush packet queue
46
when ENET_RDAR transitions 0 -> ENET_RDAR_RDAR.
47
48
Cc: Peter Maydell <peter.maydell@linaro.org>
49
Cc: Jason Wang <jasowang@redhat.com>
50
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
51
Cc: qemu-devel@nongnu.org
52
Cc: qemu-arm@nongnu.org
53
Cc: yurovsky@gmail.com
54
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
55
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
56
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
57
---
58
hw/net/imx_fec.c | 12 ++++++------
59
1 file changed, 6 insertions(+), 6 deletions(-)
60
61
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
62
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/net/imx_fec.c
16
--- a/hw/arm/boot.c
64
+++ b/hw/net/imx_fec.c
17
+++ b/hw/arm/boot.c
65
@@ -XXX,XX +XXX,XX @@ static void imx_eth_do_tx(IMXFECState *s)
18
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
66
}
19
int kernel_size;
67
}
20
int initrd_size;
68
21
int is_linux = 0;
69
-static void imx_eth_enable_rx(IMXFECState *s)
22
- uint64_t elf_entry, elf_low_addr, elf_high_addr;
70
+static void imx_eth_enable_rx(IMXFECState *s, bool flush)
23
+ uint64_t elf_entry;
71
{
24
+ /* Addresses of first byte used and first byte not used by the image */
72
IMXFECBufDesc bd;
25
+ uint64_t image_low_addr, image_high_addr;
73
bool rx_ring_full;
26
int elf_machine;
74
@@ -XXX,XX +XXX,XX @@ static void imx_eth_enable_rx(IMXFECState *s)
27
hwaddr entry;
75
28
static const ARMInsnFixup *primary_loader;
76
if (rx_ring_full) {
29
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
77
FEC_PRINTF("RX buffer full\n");
30
info->nb_cpus = 1;
78
- } else if (!s->regs[ENET_RDAR]) {
31
79
+ } else if (flush) {
32
/* Assume that raw images are linux kernels, and ELF images are not. */
80
qemu_flush_queued_packets(qemu_get_queue(s->nic));
33
- kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr,
81
}
34
- &elf_high_addr, elf_machine, as);
82
35
+ kernel_size = arm_load_elf(info, &elf_entry, &image_low_addr,
83
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
36
+ &image_high_addr, elf_machine, as);
84
if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
37
if (kernel_size > 0 && have_dtb(info)) {
85
if (!s->regs[index]) {
38
/*
86
s->regs[index] = ENET_RDAR_RDAR;
39
* If there is still some room left at the base of RAM, try and put
87
- imx_eth_enable_rx(s);
40
* the DTB there like we do for images loaded with -bios or -pflash.
88
+ imx_eth_enable_rx(s, true);
41
*/
42
- if (elf_low_addr > info->loader_start
43
- || elf_high_addr < info->loader_start) {
44
+ if (image_low_addr > info->loader_start
45
+ || image_high_addr < info->loader_start) {
46
/*
47
- * Set elf_low_addr as address limit for arm_load_dtb if it may be
48
+ * Set image_low_addr as address limit for arm_load_dtb if it may be
49
* pointing into RAM, otherwise pass '0' (no limit)
50
*/
51
- if (elf_low_addr < info->loader_start) {
52
- elf_low_addr = 0;
53
+ if (image_low_addr < info->loader_start) {
54
+ image_low_addr = 0;
89
}
55
}
90
} else {
56
info->dtb_start = info->loader_start;
91
s->regs[index] = 0;
57
- info->dtb_limit = elf_low_addr;
92
@@ -XXX,XX +XXX,XX @@ static int imx_eth_can_receive(NetClientState *nc)
58
+ info->dtb_limit = image_low_addr;
93
94
FEC_PRINTF("\n");
95
96
- return s->regs[ENET_RDAR] ? 1 : 0;
97
+ return !!s->regs[ENET_RDAR];
98
}
99
100
static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
101
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
102
}
59
}
103
}
60
}
104
s->rx_descriptor = addr;
61
entry = elf_entry;
105
- imx_eth_enable_rx(s);
106
+ imx_eth_enable_rx(s, false);
107
imx_eth_update(s);
108
return len;
109
}
110
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
111
}
112
}
113
s->rx_descriptor = addr;
114
- imx_eth_enable_rx(s);
115
+ imx_eth_enable_rx(s, false);
116
imx_eth_update(s);
117
return len;
118
}
119
--
62
--
120
2.7.4
63
2.20.1
121
64
122
65
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
Make Tx frame assembly buffer to be a paort of IMXFECState structure
4
to avoid a concern about having large data buffer on the stack.
5
6
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Cc: Jason Wang <jasowang@redhat.com>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: qemu-devel@nongnu.org
10
Cc: qemu-arm@nongnu.org
11
Cc: yurovsky@gmail.com
12
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
include/hw/net/imx_fec.h | 3 +++
17
hw/net/imx_fec.c | 22 +++++++++++-----------
18
2 files changed, 14 insertions(+), 11 deletions(-)
19
20
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/net/imx_fec.h
23
+++ b/include/hw/net/imx_fec.h
24
@@ -XXX,XX +XXX,XX @@ typedef struct IMXFECState {
25
uint32_t phy_int_mask;
26
27
bool is_fec;
28
+
29
+ /* Buffer used to assemble a Tx frame */
30
+ uint8_t frame[ENET_MAX_FRAME_SIZE];
31
} IMXFECState;
32
33
#endif
34
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/net/imx_fec.c
37
+++ b/hw/net/imx_fec.c
38
@@ -XXX,XX +XXX,XX @@ static void imx_eth_update(IMXFECState *s)
39
static void imx_fec_do_tx(IMXFECState *s)
40
{
41
int frame_size = 0, descnt = 0;
42
- uint8_t frame[ENET_MAX_FRAME_SIZE];
43
- uint8_t *ptr = frame;
44
+ uint8_t *ptr = s->frame;
45
uint32_t addr = s->tx_descriptor;
46
47
while (descnt++ < IMX_MAX_DESC) {
48
@@ -XXX,XX +XXX,XX @@ static void imx_fec_do_tx(IMXFECState *s)
49
frame_size += len;
50
if (bd.flags & ENET_BD_L) {
51
/* Last buffer in frame. */
52
- qemu_send_packet(qemu_get_queue(s->nic), frame, frame_size);
53
- ptr = frame;
54
+ qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
55
+ ptr = s->frame;
56
frame_size = 0;
57
s->regs[ENET_EIR] |= ENET_INT_TXF;
58
}
59
@@ -XXX,XX +XXX,XX @@ static void imx_fec_do_tx(IMXFECState *s)
60
static void imx_enet_do_tx(IMXFECState *s)
61
{
62
int frame_size = 0, descnt = 0;
63
- uint8_t frame[ENET_MAX_FRAME_SIZE];
64
- uint8_t *ptr = frame;
65
+ uint8_t *ptr = s->frame;
66
uint32_t addr = s->tx_descriptor;
67
68
while (descnt++ < IMX_MAX_DESC) {
69
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s)
70
frame_size += len;
71
if (bd.flags & ENET_BD_L) {
72
if (bd.option & ENET_BD_PINS) {
73
- struct ip_header *ip_hd = PKT_GET_IP_HDR(frame);
74
+ struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
75
if (IP_HEADER_VERSION(ip_hd) == 4) {
76
- net_checksum_calculate(frame, frame_size);
77
+ net_checksum_calculate(s->frame, frame_size);
78
}
79
}
80
if (bd.option & ENET_BD_IINS) {
81
- struct ip_header *ip_hd = PKT_GET_IP_HDR(frame);
82
+ struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame);
83
/* We compute checksum only for IPv4 frames */
84
if (IP_HEADER_VERSION(ip_hd) == 4) {
85
uint16_t csum;
86
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s)
87
}
88
}
89
/* Last buffer in frame. */
90
- qemu_send_packet(qemu_get_queue(s->nic), frame, len);
91
- ptr = frame;
92
+
93
+ qemu_send_packet(qemu_get_queue(s->nic), s->frame, len);
94
+ ptr = s->frame;
95
+
96
frame_size = 0;
97
if (bd.option & ENET_BD_TX_INT) {
98
s->regs[ENET_EIR] |= ENET_INT_TXF;
99
--
100
2.7.4
101
102
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
Frame truncation length, TRUNC_FL, is determined by the contents of
4
ENET_FTRL register, so convert the code to use it instead of a
5
hardcoded constant.
6
7
To avoid the case where TRUNC_FL is greater that ENET_MAX_FRAME_SIZE,
8
increase the value of the latter to its theoretical maximum of 16K.
9
10
Cc: Peter Maydell <peter.maydell@linaro.org>
11
Cc: Jason Wang <jasowang@redhat.com>
12
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
Cc: qemu-devel@nongnu.org
14
Cc: qemu-arm@nongnu.org
15
Cc: yurovsky@gmail.com
16
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
17
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
20
include/hw/net/imx_fec.h | 3 ++-
21
hw/net/imx_fec.c | 4 ++--
22
2 files changed, 4 insertions(+), 3 deletions(-)
23
24
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/net/imx_fec.h
27
+++ b/include/hw/net/imx_fec.h
28
@@ -XXX,XX +XXX,XX @@
29
#define ENET_TCCR3 393
30
#define ENET_MAX 400
31
32
-#define ENET_MAX_FRAME_SIZE 2032
33
34
/* EIR and EIMR */
35
#define ENET_INT_HB (1 << 31)
36
@@ -XXX,XX +XXX,XX @@
37
#define ENET_RCR_NLC (1 << 30)
38
#define ENET_RCR_GRS (1 << 31)
39
40
+#define ENET_MAX_FRAME_SIZE (1 << ENET_RCR_MAX_FL_LENGTH)
41
+
42
/* TCR */
43
#define ENET_TCR_GTS (1 << 0)
44
#define ENET_TCR_FDEN (1 << 2)
45
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/net/imx_fec.c
48
+++ b/hw/net/imx_fec.c
49
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
50
crc_ptr = (uint8_t *) &crc;
51
52
/* Huge frames are truncted. */
53
- if (size > ENET_MAX_FRAME_SIZE) {
54
- size = ENET_MAX_FRAME_SIZE;
55
+ if (size > s->regs[ENET_FTRL]) {
56
+ size = s->regs[ENET_FTRL];
57
flags |= ENET_BD_TR | ENET_BD_LG;
58
}
59
60
--
61
2.7.4
62
63
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
Cc: Peter Maydell <peter.maydell@linaro.org>
4
Cc: Jason Wang <jasowang@redhat.com>
5
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Cc: qemu-devel@nongnu.org
7
Cc: qemu-arm@nongnu.org
8
Cc: yurovsky@gmail.com
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/net/imx_fec.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/imx_fec.c
19
+++ b/hw/net/imx_fec.c
20
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
21
TYPE_IMX_FEC, __func__);
22
break;
23
}
24
- buf_len = (size <= s->regs[ENET_MRBR]) ? size : s->regs[ENET_MRBR];
25
+ buf_len = MIN(size, s->regs[ENET_MRBR]);
26
bd.length = buf_len;
27
size -= buf_len;
28
29
--
30
2.7.4
31
32
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
Needed to support latest Linux kernel driver which relies on that
4
functionality.
5
6
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Cc: Jason Wang <jasowang@redhat.com>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: qemu-devel@nongnu.org
10
Cc: qemu-arm@nongnu.org
11
Cc: yurovsky@gmail.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
include/hw/net/imx_fec.h | 2 ++
17
hw/net/imx_fec.c | 23 +++++++++++++++++++++++
18
2 files changed, 25 insertions(+)
19
20
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/net/imx_fec.h
23
+++ b/include/hw/net/imx_fec.h
24
@@ -XXX,XX +XXX,XX @@
25
#define ENET_TWFR_TFWR_LENGTH (6)
26
#define ENET_TWFR_STRFWD (1 << 8)
27
28
+#define ENET_RACC_SHIFT16 BIT(7)
29
+
30
/* Buffer Descriptor. */
31
typedef struct {
32
uint16_t length;
33
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/net/imx_fec.c
36
+++ b/hw/net/imx_fec.c
37
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
38
uint8_t *crc_ptr;
39
unsigned int buf_len;
40
size_t size = len;
41
+ bool shift16 = s->regs[ENET_RACC] & ENET_RACC_SHIFT16;
42
43
FEC_PRINTF("len %d\n", (int)size);
44
45
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
46
crc = cpu_to_be32(crc32(~0, buf, size));
47
crc_ptr = (uint8_t *) &crc;
48
49
+ if (shift16) {
50
+ size += 2;
51
+ }
52
+
53
/* Huge frames are truncted. */
54
if (size > s->regs[ENET_FTRL]) {
55
size = s->regs[ENET_FTRL];
56
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
57
buf_len += size - 4;
58
}
59
buf_addr = bd.data;
60
+
61
+ if (shift16) {
62
+ /*
63
+ * If SHIFT16 bit of ENETx_RACC register is set we need to
64
+ * align the payload to 4-byte boundary.
65
+ */
66
+ const uint8_t zeros[2] = { 0 };
67
+
68
+ dma_memory_write(&address_space_memory, buf_addr,
69
+ zeros, sizeof(zeros));
70
+
71
+ buf_addr += sizeof(zeros);
72
+ buf_len -= sizeof(zeros);
73
+
74
+ /* We only do this once per Ethernet frame */
75
+ shift16 = false;
76
+ }
77
+
78
dma_memory_write(&address_space_memory, buf_addr, buf, buf_len);
79
buf += buf_len;
80
if (size < 4) {
81
--
82
2.7.4
83
84
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
More recent version of the IP block support more than one Tx DMA ring,
4
so add the code implementing that feature.
5
6
Cc: Peter Maydell <peter.maydell@linaro.org>
7
Cc: Jason Wang <jasowang@redhat.com>
8
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Cc: qemu-devel@nongnu.org
10
Cc: qemu-arm@nongnu.org
11
Cc: yurovsky@gmail.com
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
include/hw/net/imx_fec.h | 18 ++++++-
17
hw/net/imx_fec.c | 133 ++++++++++++++++++++++++++++++++++++++++-------
18
2 files changed, 130 insertions(+), 21 deletions(-)
19
20
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/net/imx_fec.h
23
+++ b/include/hw/net/imx_fec.h
24
@@ -XXX,XX +XXX,XX @@
25
#define ENET_TFWR 81
26
#define ENET_FRBR 83
27
#define ENET_FRSR 84
28
+#define ENET_TDSR1 89
29
+#define ENET_TDSR2 92
30
#define ENET_RDSR 96
31
#define ENET_TDSR 97
32
#define ENET_MRBR 98
33
@@ -XXX,XX +XXX,XX @@
34
#define ENET_FTRL 108
35
#define ENET_TACC 112
36
#define ENET_RACC 113
37
+#define ENET_TDAR1 121
38
+#define ENET_TDAR2 123
39
#define ENET_MIIGSK_CFGR 192
40
#define ENET_MIIGSK_ENR 194
41
#define ENET_ATCR 256
42
@@ -XXX,XX +XXX,XX @@
43
#define ENET_INT_WAKEUP (1 << 17)
44
#define ENET_INT_TS_AVAIL (1 << 16)
45
#define ENET_INT_TS_TIMER (1 << 15)
46
+#define ENET_INT_TXF2 (1 << 7)
47
+#define ENET_INT_TXB2 (1 << 6)
48
+#define ENET_INT_TXF1 (1 << 3)
49
+#define ENET_INT_TXB1 (1 << 2)
50
51
#define ENET_INT_MAC (ENET_INT_HB | ENET_INT_BABR | ENET_INT_BABT | \
52
ENET_INT_GRA | ENET_INT_TXF | ENET_INT_TXB | \
53
ENET_INT_RXF | ENET_INT_RXB | ENET_INT_MII | \
54
ENET_INT_EBERR | ENET_INT_LC | ENET_INT_RL | \
55
ENET_INT_UN | ENET_INT_PLR | ENET_INT_WAKEUP | \
56
- ENET_INT_TS_AVAIL)
57
+ ENET_INT_TS_AVAIL | ENET_INT_TXF1 | \
58
+ ENET_INT_TXB1 | ENET_INT_TXF2 | ENET_INT_TXB2)
59
60
/* RDAR */
61
#define ENET_RDAR_RDAR (1 << 24)
62
@@ -XXX,XX +XXX,XX @@ typedef struct {
63
64
#define ENET_BD_BDU (1 << 31)
65
66
+#define ENET_TX_RING_NUM 3
67
+
68
+
69
typedef struct IMXFECState {
70
/*< private >*/
71
SysBusDevice parent_obj;
72
@@ -XXX,XX +XXX,XX @@ typedef struct IMXFECState {
73
74
uint32_t regs[ENET_MAX];
75
uint32_t rx_descriptor;
76
- uint32_t tx_descriptor;
77
+
78
+ uint32_t tx_descriptor[ENET_TX_RING_NUM];
79
+ uint32_t tx_ring_num;
80
81
uint32_t phy_status;
82
uint32_t phy_control;
83
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/hw/net/imx_fec.c
86
+++ b/hw/net/imx_fec.c
87
@@ -XXX,XX +XXX,XX @@ static const char *imx_eth_reg_name(IMXFECState *s, uint32_t index)
88
}
89
}
90
91
+/*
92
+ * Versions of this device with more than one TX descriptor save the
93
+ * 2nd and 3rd descriptors in a subsection, to maintain migration
94
+ * compatibility with previous versions of the device that only
95
+ * supported a single descriptor.
96
+ */
97
+static bool imx_eth_is_multi_tx_ring(void *opaque)
98
+{
99
+ IMXFECState *s = IMX_FEC(opaque);
100
+
101
+ return s->tx_ring_num > 1;
102
+}
103
+
104
+static const VMStateDescription vmstate_imx_eth_txdescs = {
105
+ .name = "imx.fec/txdescs",
106
+ .version_id = 1,
107
+ .minimum_version_id = 1,
108
+ .needed = imx_eth_is_multi_tx_ring,
109
+ .fields = (VMStateField[]) {
110
+ VMSTATE_UINT32(tx_descriptor[1], IMXFECState),
111
+ VMSTATE_UINT32(tx_descriptor[2], IMXFECState),
112
+ VMSTATE_END_OF_LIST()
113
+ }
114
+};
115
+
116
static const VMStateDescription vmstate_imx_eth = {
117
.name = TYPE_IMX_FEC,
118
.version_id = 2,
119
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx_eth = {
120
.fields = (VMStateField[]) {
121
VMSTATE_UINT32_ARRAY(regs, IMXFECState, ENET_MAX),
122
VMSTATE_UINT32(rx_descriptor, IMXFECState),
123
- VMSTATE_UINT32(tx_descriptor, IMXFECState),
124
-
125
+ VMSTATE_UINT32(tx_descriptor[0], IMXFECState),
126
VMSTATE_UINT32(phy_status, IMXFECState),
127
VMSTATE_UINT32(phy_control, IMXFECState),
128
VMSTATE_UINT32(phy_advertise, IMXFECState),
129
VMSTATE_UINT32(phy_int, IMXFECState),
130
VMSTATE_UINT32(phy_int_mask, IMXFECState),
131
VMSTATE_END_OF_LIST()
132
- }
133
+ },
134
+ .subsections = (const VMStateDescription * []) {
135
+ &vmstate_imx_eth_txdescs,
136
+ NULL
137
+ },
138
};
139
140
#define PHY_INT_ENERGYON (1 << 7)
141
@@ -XXX,XX +XXX,XX @@ static void imx_fec_do_tx(IMXFECState *s)
142
{
143
int frame_size = 0, descnt = 0;
144
uint8_t *ptr = s->frame;
145
- uint32_t addr = s->tx_descriptor;
146
+ uint32_t addr = s->tx_descriptor[0];
147
148
while (descnt++ < IMX_MAX_DESC) {
149
IMXFECBufDesc bd;
150
@@ -XXX,XX +XXX,XX @@ static void imx_fec_do_tx(IMXFECState *s)
151
}
152
}
153
154
- s->tx_descriptor = addr;
155
+ s->tx_descriptor[0] = addr;
156
157
imx_eth_update(s);
158
}
159
160
-static void imx_enet_do_tx(IMXFECState *s)
161
+static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
162
{
163
int frame_size = 0, descnt = 0;
164
+
165
uint8_t *ptr = s->frame;
166
- uint32_t addr = s->tx_descriptor;
167
+ uint32_t addr, int_txb, int_txf, tdsr;
168
+ size_t ring;
169
+
170
+ switch (index) {
171
+ case ENET_TDAR:
172
+ ring = 0;
173
+ int_txb = ENET_INT_TXB;
174
+ int_txf = ENET_INT_TXF;
175
+ tdsr = ENET_TDSR;
176
+ break;
177
+ case ENET_TDAR1:
178
+ ring = 1;
179
+ int_txb = ENET_INT_TXB1;
180
+ int_txf = ENET_INT_TXF1;
181
+ tdsr = ENET_TDSR1;
182
+ break;
183
+ case ENET_TDAR2:
184
+ ring = 2;
185
+ int_txb = ENET_INT_TXB2;
186
+ int_txf = ENET_INT_TXF2;
187
+ tdsr = ENET_TDSR2;
188
+ break;
189
+ default:
190
+ qemu_log_mask(LOG_GUEST_ERROR,
191
+ "%s: bogus value for index %x\n",
192
+ __func__, index);
193
+ abort();
194
+ break;
195
+ }
196
+
197
+ addr = s->tx_descriptor[ring];
198
199
while (descnt++ < IMX_MAX_DESC) {
200
IMXENETBufDesc bd;
201
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s)
202
203
frame_size = 0;
204
if (bd.option & ENET_BD_TX_INT) {
205
- s->regs[ENET_EIR] |= ENET_INT_TXF;
206
+ s->regs[ENET_EIR] |= int_txf;
207
}
208
}
209
if (bd.option & ENET_BD_TX_INT) {
210
- s->regs[ENET_EIR] |= ENET_INT_TXB;
211
+ s->regs[ENET_EIR] |= int_txb;
212
}
213
bd.flags &= ~ENET_BD_R;
214
/* Write back the modified descriptor. */
215
imx_enet_write_bd(&bd, addr);
216
/* Advance to the next descriptor. */
217
if ((bd.flags & ENET_BD_W) != 0) {
218
- addr = s->regs[ENET_TDSR];
219
+ addr = s->regs[tdsr];
220
} else {
221
addr += sizeof(bd);
222
}
223
}
224
225
- s->tx_descriptor = addr;
226
+ s->tx_descriptor[ring] = addr;
227
228
imx_eth_update(s);
229
}
230
231
-static void imx_eth_do_tx(IMXFECState *s)
232
+static void imx_eth_do_tx(IMXFECState *s, uint32_t index)
233
{
234
if (!s->is_fec && (s->regs[ENET_ECR] & ENET_ECR_EN1588)) {
235
- imx_enet_do_tx(s);
236
+ imx_enet_do_tx(s, index);
237
} else {
238
imx_fec_do_tx(s);
239
}
240
@@ -XXX,XX +XXX,XX @@ static void imx_eth_reset(DeviceState *d)
241
}
242
243
s->rx_descriptor = 0;
244
- s->tx_descriptor = 0;
245
+ memset(s->tx_descriptor, 0, sizeof(s->tx_descriptor));
246
247
/* We also reset the PHY */
248
phy_reset(s);
249
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
250
unsigned size)
251
{
252
IMXFECState *s = IMX_FEC(opaque);
253
+ const bool single_tx_ring = !imx_eth_is_multi_tx_ring(s);
254
uint32_t index = offset >> 2;
255
256
FEC_PRINTF("reg[%s] <= 0x%" PRIx32 "\n", imx_eth_reg_name(s, index),
257
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
258
s->regs[index] = 0;
259
}
260
break;
261
- case ENET_TDAR:
262
+ case ENET_TDAR1: /* FALLTHROUGH */
263
+ case ENET_TDAR2: /* FALLTHROUGH */
264
+ if (unlikely(single_tx_ring)) {
265
+ qemu_log_mask(LOG_GUEST_ERROR,
266
+ "[%s]%s: trying to access TDAR2 or TDAR1\n",
267
+ TYPE_IMX_FEC, __func__);
268
+ return;
269
+ }
270
+ case ENET_TDAR: /* FALLTHROUGH */
271
if (s->regs[ENET_ECR] & ENET_ECR_ETHEREN) {
272
s->regs[index] = ENET_TDAR_TDAR;
273
- imx_eth_do_tx(s);
274
+ imx_eth_do_tx(s, index);
275
}
276
s->regs[index] = 0;
277
break;
278
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
279
if ((s->regs[index] & ENET_ECR_ETHEREN) == 0) {
280
s->regs[ENET_RDAR] = 0;
281
s->rx_descriptor = s->regs[ENET_RDSR];
282
- s->regs[ENET_TDAR] = 0;
283
- s->tx_descriptor = s->regs[ENET_TDSR];
284
+ s->regs[ENET_TDAR] = 0;
285
+ s->regs[ENET_TDAR1] = 0;
286
+ s->regs[ENET_TDAR2] = 0;
287
+ s->tx_descriptor[0] = s->regs[ENET_TDSR];
288
+ s->tx_descriptor[1] = s->regs[ENET_TDSR1];
289
+ s->tx_descriptor[2] = s->regs[ENET_TDSR2];
290
}
291
break;
292
case ENET_MMFR:
293
@@ -XXX,XX +XXX,XX @@ static void imx_eth_write(void *opaque, hwaddr offset, uint64_t value,
294
} else {
295
s->regs[index] = value & ~7;
296
}
297
- s->tx_descriptor = s->regs[index];
298
+ s->tx_descriptor[0] = s->regs[index];
299
+ break;
300
+ case ENET_TDSR1:
301
+ if (unlikely(single_tx_ring)) {
302
+ qemu_log_mask(LOG_GUEST_ERROR,
303
+ "[%s]%s: trying to access TDSR1\n",
304
+ TYPE_IMX_FEC, __func__);
305
+ return;
306
+ }
307
+
308
+ s->regs[index] = value & ~7;
309
+ s->tx_descriptor[1] = s->regs[index];
310
+ break;
311
+ case ENET_TDSR2:
312
+ if (unlikely(single_tx_ring)) {
313
+ qemu_log_mask(LOG_GUEST_ERROR,
314
+ "[%s]%s: trying to access TDSR2\n",
315
+ TYPE_IMX_FEC, __func__);
316
+ return;
317
+ }
318
+
319
+ s->regs[index] = value & ~7;
320
+ s->tx_descriptor[2] = s->regs[index];
321
break;
322
case ENET_MRBR:
323
s->regs[index] = value & 0x00003ff0;
324
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
325
326
static Property imx_eth_properties[] = {
327
DEFINE_NIC_PROPERTIES(IMXFECState, conf),
328
+ DEFINE_PROP_UINT32("tx-ring-num", IMXFECState, tx_ring_num, 1),
329
DEFINE_PROP_END_OF_LIST(),
330
};
331
332
--
333
2.7.4
334
335
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
Use 'frame_size' instead of 'len' when calling qemu_send_packet(),
4
failing to do so results in malformed packets send in case when that
5
packed is fragmented into multiple DMA transactions.
6
7
Cc: Peter Maydell <peter.maydell@linaro.org>
8
Cc: Jason Wang <jasowang@redhat.com>
9
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Cc: qemu-devel@nongnu.org
11
Cc: qemu-arm@nongnu.org
12
Cc: yurovsky@gmail.com
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/net/imx_fec.c | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
19
20
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/net/imx_fec.c
23
+++ b/hw/net/imx_fec.c
24
@@ -XXX,XX +XXX,XX @@ static void imx_enet_do_tx(IMXFECState *s, uint32_t index)
25
}
26
/* Last buffer in frame. */
27
28
- qemu_send_packet(qemu_get_queue(s->nic), s->frame, len);
29
+ qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size);
30
ptr = s->frame;
31
32
frame_size = 0;
33
--
34
2.7.4
35
36
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
Cc: Peter Maydell <peter.maydell@linaro.org>
4
Cc: Jason Wang <jasowang@redhat.com>
5
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Cc: qemu-devel@nongnu.org
7
Cc: qemu-arm@nongnu.org
8
Cc: yurovsky@gmail.com
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/net/imx_fec.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/net/imx_fec.c
19
+++ b/hw/net/imx_fec.c
20
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
21
size += 2;
22
}
23
24
- /* Huge frames are truncted. */
25
+ /* Huge frames are truncated. */
26
if (size > s->regs[ENET_FTRL]) {
27
size = s->regs[ENET_FTRL];
28
flags |= ENET_BD_TR | ENET_BD_LG;
29
--
30
2.7.4
31
32
diff view generated by jsdifflib
Deleted patch
1
From: Andrey Smirnov <andrew.smirnov@gmail.com>
2
1
3
Some i.MX SoCs (e.g. i.MX7) have FEC registers going as far as offset
4
0x614, so to avoid getting aborts when accessing those on QEMU, extend
5
the register file to cover FSL_IMX25_FEC_SIZE(16K) of address space
6
instead of just 1K.
7
8
Cc: Peter Maydell <peter.maydell@linaro.org>
9
Cc: Jason Wang <jasowang@redhat.com>
10
Cc: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Cc: qemu-devel@nongnu.org
12
Cc: qemu-arm@nongnu.org
13
Cc: yurovsky@gmail.com
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
include/hw/arm/fsl-imx25.h | 1 -
19
include/hw/net/imx_fec.h | 1 +
20
hw/net/imx_fec.c | 2 +-
21
3 files changed, 2 insertions(+), 2 deletions(-)
22
23
diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/fsl-imx25.h
26
+++ b/include/hw/arm/fsl-imx25.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct FslIMX25State {
28
#define FSL_IMX25_UART5_ADDR 0x5002C000
29
#define FSL_IMX25_UART5_SIZE 0x4000
30
#define FSL_IMX25_FEC_ADDR 0x50038000
31
-#define FSL_IMX25_FEC_SIZE 0x4000
32
#define FSL_IMX25_CCM_ADDR 0x53F80000
33
#define FSL_IMX25_CCM_SIZE 0x4000
34
#define FSL_IMX25_GPT4_ADDR 0x53F84000
35
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/include/hw/net/imx_fec.h
38
+++ b/include/hw/net/imx_fec.h
39
@@ -XXX,XX +XXX,XX @@ typedef struct {
40
41
#define ENET_TX_RING_NUM 3
42
43
+#define FSL_IMX25_FEC_SIZE 0x4000
44
45
typedef struct IMXFECState {
46
/*< private >*/
47
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/net/imx_fec.c
50
+++ b/hw/net/imx_fec.c
51
@@ -XXX,XX +XXX,XX @@ static void imx_eth_realize(DeviceState *dev, Error **errp)
52
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
53
54
memory_region_init_io(&s->iomem, OBJECT(dev), &imx_eth_ops, s,
55
- TYPE_IMX_FEC, 0x400);
56
+ TYPE_IMX_FEC, FSL_IMX25_FEC_SIZE);
57
sysbus_init_mmio(sbd, &s->iomem);
58
sysbus_init_irq(sbd, &s->irq[0]);
59
sysbus_init_irq(sbd, &s->irq[1]);
60
--
61
2.7.4
62
63
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
5
Message-id: 20180103224208.30291-2-f4bug@amsat.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
hw/timer/pxa2xx_timer.c | 17 +++++++++++++++--
9
1 file changed, 15 insertions(+), 2 deletions(-)
10
11
diff --git a/hw/timer/pxa2xx_timer.c b/hw/timer/pxa2xx_timer.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/timer/pxa2xx_timer.c
14
+++ b/hw/timer/pxa2xx_timer.c
15
@@ -XXX,XX +XXX,XX @@
16
#include "sysemu/sysemu.h"
17
#include "hw/arm/pxa.h"
18
#include "hw/sysbus.h"
19
+#include "qemu/log.h"
20
21
#define OSMR0    0x00
22
#define OSMR1    0x04
23
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset,
24
case OSNR:
25
return s->snapshot;
26
default:
27
+ qemu_log_mask(LOG_UNIMP,
28
+ "%s: unknown register 0x%02" HWADDR_PRIx "\n",
29
+ __func__, offset);
30
+ break;
31
badreg:
32
- hw_error("pxa2xx_timer_read: Bad offset " REG_FMT "\n", offset);
33
+ qemu_log_mask(LOG_GUEST_ERROR,
34
+ "%s: incorrect register 0x%02" HWADDR_PRIx "\n",
35
+ __func__, offset);
36
}
37
38
return 0;
39
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset,
40
}
41
break;
42
default:
43
+ qemu_log_mask(LOG_UNIMP,
44
+ "%s: unknown register 0x%02" HWADDR_PRIx " "
45
+ "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
46
+ break;
47
badreg:
48
- hw_error("pxa2xx_timer_write: Bad offset " REG_FMT "\n", offset);
49
+ qemu_log_mask(LOG_GUEST_ERROR,
50
+ "%s: incorrect register 0x%02" HWADDR_PRIx " "
51
+ "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
52
}
53
}
54
55
--
56
2.7.4
57
58
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
5
Message-id: 20180104000156.30932-1-f4bug@amsat.org
6
[PMM: add missing include]
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
hw/sd/pxa2xx_mmci.c | 78 ++++++++++++++++++++++++++++++++++-------------------
10
hw/sd/trace-events | 4 +++
11
2 files changed, 54 insertions(+), 28 deletions(-)
12
13
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/sd/pxa2xx_mmci.c
16
+++ b/hw/sd/pxa2xx_mmci.c
17
@@ -XXX,XX +XXX,XX @@
18
#include "hw/qdev.h"
19
#include "hw/qdev-properties.h"
20
#include "qemu/error-report.h"
21
+#include "qemu/log.h"
22
+#include "trace.h"
23
24
#define TYPE_PXA2XX_MMCI "pxa2xx-mmci"
25
#define PXA2XX_MMCI(obj) OBJECT_CHECK(PXA2xxMMCIState, (obj), TYPE_PXA2XX_MMCI)
26
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_wakequeues(PXA2xxMMCIState *s)
27
static uint64_t pxa2xx_mmci_read(void *opaque, hwaddr offset, unsigned size)
28
{
29
PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
30
- uint32_t ret;
31
+ uint32_t ret = 0;
32
33
switch (offset) {
34
case MMC_STRPCL:
35
- return 0;
36
+ break;
37
case MMC_STAT:
38
- return s->status;
39
+ ret = s->status;
40
+ break;
41
case MMC_CLKRT:
42
- return s->clkrt;
43
+ ret = s->clkrt;
44
+ break;
45
case MMC_SPI:
46
- return s->spi;
47
+ ret = s->spi;
48
+ break;
49
case MMC_CMDAT:
50
- return s->cmdat;
51
+ ret = s->cmdat;
52
+ break;
53
case MMC_RESTO:
54
- return s->resp_tout;
55
+ ret = s->resp_tout;
56
+ break;
57
case MMC_RDTO:
58
- return s->read_tout;
59
+ ret = s->read_tout;
60
+ break;
61
case MMC_BLKLEN:
62
- return s->blklen;
63
+ ret = s->blklen;
64
+ break;
65
case MMC_NUMBLK:
66
- return s->numblk;
67
+ ret = s->numblk;
68
+ break;
69
case MMC_PRTBUF:
70
- return 0;
71
+ break;
72
case MMC_I_MASK:
73
- return s->intmask;
74
+ ret = s->intmask;
75
+ break;
76
case MMC_I_REG:
77
- return s->intreq;
78
+ ret = s->intreq;
79
+ break;
80
case MMC_CMD:
81
- return s->cmd | 0x40;
82
+ ret = s->cmd | 0x40;
83
+ break;
84
case MMC_ARGH:
85
- return s->arg >> 16;
86
+ ret = s->arg >> 16;
87
+ break;
88
case MMC_ARGL:
89
- return s->arg & 0xffff;
90
+ ret = s->arg & 0xffff;
91
+ break;
92
case MMC_RES:
93
- if (s->resp_len < 9)
94
- return s->resp_fifo[s->resp_len ++];
95
- return 0;
96
+ ret = (s->resp_len < 9) ? s->resp_fifo[s->resp_len++] : 0;
97
+ break;
98
case MMC_RXFIFO:
99
- ret = 0;
100
while (size-- && s->rx_len) {
101
ret |= s->rx_fifo[s->rx_start++] << (size << 3);
102
s->rx_start &= 0x1f;
103
@@ -XXX,XX +XXX,XX @@ static uint64_t pxa2xx_mmci_read(void *opaque, hwaddr offset, unsigned size)
104
}
105
s->intreq &= ~INT_RXFIFO_REQ;
106
pxa2xx_mmci_fifo_update(s);
107
- return ret;
108
+ break;
109
case MMC_RDWAIT:
110
- return 0;
111
+ break;
112
case MMC_BLKS_REM:
113
- return s->numblk;
114
+ ret = s->numblk;
115
+ break;
116
default:
117
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
118
+ qemu_log_mask(LOG_GUEST_ERROR,
119
+ "%s: incorrect register 0x%02" HWADDR_PRIx "\n",
120
+ __func__, offset);
121
}
122
+ trace_pxa2xx_mmci_read(size, offset, ret);
123
124
- return 0;
125
+ return ret;
126
}
127
128
static void pxa2xx_mmci_write(void *opaque,
129
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_write(void *opaque,
130
{
131
PXA2xxMMCIState *s = (PXA2xxMMCIState *) opaque;
132
133
+ trace_pxa2xx_mmci_write(size, offset, value);
134
switch (offset) {
135
case MMC_STRPCL:
136
if (value & STRPCL_STRT_CLK) {
137
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_write(void *opaque,
138
139
case MMC_SPI:
140
s->spi = value & 0xf;
141
- if (value & SPI_SPI_MODE)
142
- printf("%s: attempted to use card in SPI mode\n", __FUNCTION__);
143
+ if (value & SPI_SPI_MODE) {
144
+ qemu_log_mask(LOG_GUEST_ERROR,
145
+ "%s: attempted to use card in SPI mode\n", __func__);
146
+ }
147
break;
148
149
case MMC_CMDAT:
150
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_mmci_write(void *opaque,
151
break;
152
153
default:
154
- hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);
155
+ qemu_log_mask(LOG_GUEST_ERROR,
156
+ "%s: incorrect reg 0x%02" HWADDR_PRIx " "
157
+ "(value 0x%08" PRIx64 ")\n", __func__, offset, value);
158
}
159
}
160
161
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
162
index XXXXXXX..XXXXXXX 100644
163
--- a/hw/sd/trace-events
164
+++ b/hw/sd/trace-events
165
@@ -XXX,XX +XXX,XX @@
166
# hw/sd/milkymist-memcard.c
167
milkymist_memcard_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
168
milkymist_memcard_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
169
+
170
+# hw/sd/pxa2xx_mmci.c
171
+pxa2xx_mmci_read(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x"
172
+pxa2xx_mmci_write(uint8_t size, uint32_t addr, uint32_t value) "size %d addr 0x%02x value 0x%08x"
173
--
174
2.7.4
175
176
diff view generated by jsdifflib
Deleted patch
1
The GICv3 specification says that reserved register addresses
2
should RAZ/WI. This means we need to return MEMTX_OK, not MEMTX_ERROR,
3
because now that we support generating external aborts the
4
latter will cause an abort on new board models.
5
1
6
Cc: qemu-stable@nongnu.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1513183941-24300-2-git-send-email-peter.maydell@linaro.org
9
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
10
---
11
hw/intc/arm_gicv3_dist.c | 13 +++++++++++++
12
hw/intc/arm_gicv3_its_common.c | 8 +++-----
13
hw/intc/arm_gicv3_redist.c | 13 +++++++++++++
14
3 files changed, 29 insertions(+), 5 deletions(-)
15
16
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/arm_gicv3_dist.c
19
+++ b/hw/intc/arm_gicv3_dist.c
20
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_dist_read(void *opaque, hwaddr offset, uint64_t *data,
21
"%s: invalid guest read at offset " TARGET_FMT_plx
22
"size %u\n", __func__, offset, size);
23
trace_gicv3_dist_badread(offset, size, attrs.secure);
24
+ /* The spec requires that reserved registers are RAZ/WI;
25
+ * so use MEMTX_ERROR returns from leaf functions as a way to
26
+ * trigger the guest-error logging but don't return it to
27
+ * the caller, or we'll cause a spurious guest data abort.
28
+ */
29
+ r = MEMTX_OK;
30
+ *data = 0;
31
} else {
32
trace_gicv3_dist_read(offset, *data, size, attrs.secure);
33
}
34
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_dist_write(void *opaque, hwaddr offset, uint64_t data,
35
"%s: invalid guest write at offset " TARGET_FMT_plx
36
"size %u\n", __func__, offset, size);
37
trace_gicv3_dist_badwrite(offset, data, size, attrs.secure);
38
+ /* The spec requires that reserved registers are RAZ/WI;
39
+ * so use MEMTX_ERROR returns from leaf functions as a way to
40
+ * trigger the guest-error logging but don't return it to
41
+ * the caller, or we'll cause a spurious guest data abort.
42
+ */
43
+ r = MEMTX_OK;
44
} else {
45
trace_gicv3_dist_write(offset, data, size, attrs.secure);
46
}
47
diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/intc/arm_gicv3_its_common.c
50
+++ b/hw/intc/arm_gicv3_its_common.c
51
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_trans_read(void *opaque, hwaddr offset,
52
MemTxAttrs attrs)
53
{
54
qemu_log_mask(LOG_GUEST_ERROR, "ITS read at offset 0x%"PRIx64"\n", offset);
55
- return MEMTX_ERROR;
56
+ *data = 0;
57
+ return MEMTX_OK;
58
}
59
60
static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset,
61
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_trans_write(void *opaque, hwaddr offset,
62
if (ret <= 0) {
63
qemu_log_mask(LOG_GUEST_ERROR,
64
"ITS: Error sending MSI: %s\n", strerror(-ret));
65
- return MEMTX_DECODE_ERROR;
66
}
67
-
68
- return MEMTX_OK;
69
} else {
70
qemu_log_mask(LOG_GUEST_ERROR,
71
"ITS write at bad offset 0x%"PRIx64"\n", offset);
72
- return MEMTX_DECODE_ERROR;
73
}
74
+ return MEMTX_OK;
75
}
76
77
static const MemoryRegionOps gicv3_its_trans_ops = {
78
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
79
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/intc/arm_gicv3_redist.c
81
+++ b/hw/intc/arm_gicv3_redist.c
82
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
83
"size %u\n", __func__, offset, size);
84
trace_gicv3_redist_badread(gicv3_redist_affid(cs), offset,
85
size, attrs.secure);
86
+ /* The spec requires that reserved registers are RAZ/WI;
87
+ * so use MEMTX_ERROR returns from leaf functions as a way to
88
+ * trigger the guest-error logging but don't return it to
89
+ * the caller, or we'll cause a spurious guest data abort.
90
+ */
91
+ r = MEMTX_OK;
92
+ *data = 0;
93
} else {
94
trace_gicv3_redist_read(gicv3_redist_affid(cs), offset, *data,
95
size, attrs.secure);
96
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
97
"size %u\n", __func__, offset, size);
98
trace_gicv3_redist_badwrite(gicv3_redist_affid(cs), offset, data,
99
size, attrs.secure);
100
+ /* The spec requires that reserved registers are RAZ/WI;
101
+ * so use MEMTX_ERROR returns from leaf functions as a way to
102
+ * trigger the guest-error logging but don't return it to
103
+ * the caller, or we'll cause a spurious guest data abort.
104
+ */
105
+ r = MEMTX_OK;
106
} else {
107
trace_gicv3_redist_write(gicv3_redist_affid(cs), offset, data,
108
size, attrs.secure);
109
--
110
2.7.4
111
112
diff view generated by jsdifflib
1
The GICv2 specification says that reserved register addresses
1
In commit e6b2b20d9735d4ef we made the boot loader code try to avoid
2
must RAZ/WI; now that we implement external abort handling
2
putting the initrd on top of the kernel. However the expression used
3
for Arm CPUs this means we must return MEMTX_OK rather than
3
to calculate the start of the initrd:
4
MEMTX_ERROR, to avoid generating a spurious guest data abort.
5
4
6
Cc: qemu-stable@nongnu.org
5
info->initrd_start = info->loader_start +
6
MAX(MIN(info->ram_size / 2, 128 * 1024 * 1024), kernel_size);
7
8
incorrectly uses 'kernel_size' as the offset within RAM of the
9
highest address to avoid. This is incorrect because the kernel
10
doesn't start at address 0, but slightly higher than that. This
11
means that we can still incorrectly end up overlaying the initrd on
12
the kernel in some cases, for example:
13
14
* The kernel's image_size is 0x0a7a8000
15
* The kernel was loaded at 0x40080000
16
* The end of the kernel is 0x4A828000
17
* The DTB was loaded at 0x4a800000
18
19
To get this right we need to track the actual highest address used
20
by the kernel and use that rather than kernel_size. We already
21
set image_low_addr and image_high_addr for ELF images; set them
22
also for the various other image types we support, and then use
23
image_high_addr as the lowest allowed address for the initrd.
24
(We don't use image_low_addr, but we set it for consistency
25
with the existing code path for ELF files.)
26
27
Fixes: e6b2b20d9735d4ef
28
Reported-by: Mark Rutland <mark.rutland@arm.com>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 1513183941-24300-3-git-send-email-peter.maydell@linaro.org
30
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
31
Tested-by: Mark Rutland <mark.rutland@arm.com>
32
Message-id: 20190722151804.25467-3-peter.maydell@linaro.org
10
---
33
---
11
hw/intc/arm_gic.c | 5 +++--
34
hw/arm/boot.c | 19 +++++++++++++++++--
12
1 file changed, 3 insertions(+), 2 deletions(-)
35
1 file changed, 17 insertions(+), 2 deletions(-)
13
36
14
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
37
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
15
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/intc/arm_gic.c
39
--- a/hw/arm/boot.c
17
+++ b/hw/intc/arm_gic.c
40
+++ b/hw/arm/boot.c
18
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset,
41
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
19
default:
42
int is_linux = 0;
20
qemu_log_mask(LOG_GUEST_ERROR,
43
uint64_t elf_entry;
21
"gic_cpu_read: Bad offset %x\n", (int)offset);
44
/* Addresses of first byte used and first byte not used by the image */
22
- return MEMTX_ERROR;
45
- uint64_t image_low_addr, image_high_addr;
23
+ *data = 0;
46
+ uint64_t image_low_addr = 0, image_high_addr = 0;
24
+ break;
47
int elf_machine;
48
hwaddr entry;
49
static const ARMInsnFixup *primary_loader;
50
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
51
uint64_t loadaddr = info->loader_start + KERNEL_NOLOAD_ADDR;
52
kernel_size = load_uimage_as(info->kernel_filename, &entry, &loadaddr,
53
&is_linux, NULL, NULL, as);
54
+ if (kernel_size >= 0) {
55
+ image_low_addr = loadaddr;
56
+ image_high_addr = image_low_addr + kernel_size;
57
+ }
25
}
58
}
26
return MEMTX_OK;
59
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
27
}
60
kernel_size = load_aarch64_image(info->kernel_filename,
28
@@ -XXX,XX +XXX,XX @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset,
61
info->loader_start, &entry, as);
29
default:
62
is_linux = 1;
30
qemu_log_mask(LOG_GUEST_ERROR,
63
+ if (kernel_size >= 0) {
31
"gic_cpu_write: Bad offset %x\n", (int)offset);
64
+ image_low_addr = entry;
32
- return MEMTX_ERROR;
65
+ image_high_addr = image_low_addr + kernel_size;
33
+ return MEMTX_OK;
66
+ }
67
} else if (kernel_size < 0) {
68
/* 32-bit ARM */
69
entry = info->loader_start + KERNEL_LOAD_ADDR;
70
kernel_size = load_image_targphys_as(info->kernel_filename, entry,
71
ram_end - KERNEL_LOAD_ADDR, as);
72
is_linux = 1;
73
+ if (kernel_size >= 0) {
74
+ image_low_addr = entry;
75
+ image_high_addr = image_low_addr + kernel_size;
76
+ }
34
}
77
}
35
gic_update(s);
78
if (kernel_size < 0) {
36
return MEMTX_OK;
79
error_report("could not load kernel '%s'", info->kernel_filename);
80
@@ -XXX,XX +XXX,XX @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
81
* we might still make a bad choice here.
82
*/
83
info->initrd_start = info->loader_start +
84
- MAX(MIN(info->ram_size / 2, 128 * 1024 * 1024), kernel_size);
85
+ MIN(info->ram_size / 2, 128 * 1024 * 1024);
86
+ if (image_high_addr) {
87
+ info->initrd_start = MAX(info->initrd_start, image_high_addr);
88
+ }
89
info->initrd_start = TARGET_PAGE_ALIGN(info->initrd_start);
90
91
if (is_linux) {
37
--
92
--
38
2.7.4
93
2.20.1
39
94
40
95
diff view generated by jsdifflib