1
Some more outstanding target-arm patches; nothing terribly
1
Last lot of target-arm stuff: cleanups, bug fixes; nothing major here.
2
exciting. Mostly they're mine; I'm trying to reduce the
3
number of patches I still have in flight, so I've picked
4
out some of the reviewed patches from a couple of sets I've
5
sent out and will resend v2 versions of those sets with the
6
remaining patches with fixes for issues noted in review once
7
this is in master.
8
2
9
thanks
10
-- PMM
3
-- PMM
11
4
5
The following changes since commit 9d662a6b22a0838a85c5432385f35db2488a33a5:
12
6
13
The following changes since commit adaec191bfb31e12d40af8ab1b869f5b40d61ee9:
7
Merge remote-tracking branch 'remotes/legoater/tags/pull-ppc-20220305' into staging (2022-03-05 18:03:15 +0000)
14
15
Merge remote-tracking branch 'remotes/ehabkost/tags/machine-next-pull-request' into staging (2018-08-20 09:48:03 +0100)
16
8
17
are available in the Git repository at:
9
are available in the Git repository at:
18
10
19
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180820
11
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20220307
20
12
21
for you to fetch changes up to b85fad1588e812566f897f747e38da345a7016d6:
13
for you to fetch changes up to 0942820408dc788560f6968e9b5f011803b846c2:
22
14
23
hw/dma/pl080: Remove hw_error() if DMA is enabled (2018-08-20 11:24:33 +0100)
15
hw/arm/virt: Disable LPA2 for -machine virt-6.2 (2022-03-07 14:32:21 +0000)
24
16
25
----------------------------------------------------------------
17
----------------------------------------------------------------
26
target-arm queue:
18
target-arm queue:
27
* Fix crash on conditional instruction in an IT block
19
* cleanups of qemu_oom_check() and qemu_memalign()
28
* docs/generic-loader: mention U-Boot and Intel HEX executable formats
20
* target/arm/translate-neon: UNDEF if VLD1/VST1 stride bits are non-zero
29
* hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset
21
* target/arm/translate-neon: Simplify align field check for VLD3
30
* imx_serial: Generate interrupt on receive data ready if enabled
22
* GICv3 ITS: add more trace events
31
* Fix various minor bugs in AArch32 Hyp related coprocessor registers
23
* GICv3 ITS: implement 8-byte accesses properly
32
* Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked)
24
* GICv3: fix minor issues with some trace/log messages
33
* Implement AArch32 ERET instruction
25
* ui/cocoa: Use the standard about panel
34
* hw/arm/virt: Add virt-3.1 machine type
26
* target/arm: Provide cpu property for controling FEAT_LPA2
35
* sdhci: add i.MX SD Stable Clock bit
27
* hw/arm/virt: Disable LPA2 for -machine virt-6.2
36
* Remove now-obsolete MMIO request_ptr APIs
37
* hw/timer/m48t59: Move away from old_mmio accessors
38
* hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module
39
* nvic: Expose NMI line
40
* hw/dma/pl080: cleanups and new features required for use in MPS boards
41
28
42
----------------------------------------------------------------
29
----------------------------------------------------------------
43
Andrew Jones (1):
30
Akihiko Odaki (1):
44
hw/arm/virt: Add virt-3.1 machine type
31
ui/cocoa: Use the standard about panel
45
32
46
Hans-Erik Floryd (2):
33
Peter Maydell (15):
47
imx_serial: Generate interrupt on receive data ready if enabled
34
util: Make qemu_oom_check() a static function
48
sdhci: add i.MX SD Stable Clock bit
35
util: Unify implementations of qemu_memalign()
36
util: Return valid allocation for qemu_try_memalign() with zero size
37
meson.build: Don't misdetect posix_memalign() on Windows
38
util: Share qemu_try_memalign() implementation between POSIX and Windows
39
util: Use meson checks for valloc() and memalign() presence
40
util: Put qemu_vfree() in memalign.c
41
osdep: Move memalign-related functions to their own header
42
target/arm/translate-neon: UNDEF if VLD1/VST1 stride bits are non-zero
43
target/arm/translate-neon: Simplify align field check for VLD3
44
hw/intc/arm_gicv3_its: Add trace events for commands
45
hw/intc/arm_gicv3_its: Add trace events for table reads and writes
46
hw/intc/arm_gicv3: Specify valid and impl in MemoryRegionOps
47
hw/intc/arm_gicv3: Fix missing spaces in error log messages
48
hw/intc/arm_gicv3_cpuif: Fix register names in ICV_HPPIR read trace event
49
49
50
Jia He (1):
50
Richard Henderson (2):
51
hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset
51
target/arm: Provide cpu property for controling FEAT_LPA2
52
hw/arm/virt: Disable LPA2 for -machine virt-6.2
52
53
53
Peter Maydell (19):
54
meson.build | 7 ++-
54
target/arm: Correct typo in HAMAIR1 regdef name
55
include/hw/arm/virt.h | 1 +
55
target/arm: Add missing .cp = 15 to HMAIR1 and HAMAIR1 regdefs
56
include/qemu-common.h | 2 -
56
target/arm: Implement AArch32 HVBAR
57
include/qemu/memalign.h | 61 ++++++++++++++++++++++
57
target/arm: Implement AArch32 Hyp FARs
58
include/qemu/osdep.h | 18 -------
58
target/arm: Implement ESR_EL2/HSR for AArch32 and no-EL2
59
target/arm/cpu.h | 5 +-
59
target/arm: Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked)
60
block/blkverify.c | 1 +
60
target/arm: Implement AArch32 ERET instruction
61
block/block-copy.c | 1 +
61
hw/ssi/xilinx_spips: Remove unneeded MMIO request_ptr code
62
block/commit.c | 1 +
62
memory: Remove MMIO request_ptr APIs
63
block/crypto.c | 1 +
63
hw/misc: Remove mmio_interface device
64
block/dmg.c | 1 +
64
hw/timer/m48t59: Move away from old_mmio accessors
65
block/export/fuse.c | 1 +
65
hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module
66
block/file-posix.c | 1 +
66
nvic: Expose NMI line
67
block/io.c | 1 +
67
hw/dma/pl080: Allow use as embedded-struct device
68
block/mirror.c | 1 +
68
hw/dma/pl080: Support all three interrupt lines
69
block/nvme.c | 1 +
69
hw/dma/pl080: Don't use CPU address space for DMA accesses
70
block/parallels-ext.c | 1 +
70
hw/dma/pl080: Provide device reset function
71
block/parallels.c | 1 +
71
hw/dma/pl080: Correct bug in register address decode logic
72
block/qcow.c | 1 +
72
hw/dma/pl080: Remove hw_error() if DMA is enabled
73
block/qcow2-cache.c | 1 +
73
74
block/qcow2-cluster.c | 1 +
74
Roman Kapl (1):
75
block/qcow2-refcount.c | 1 +
75
target/arm: Fix crash on conditional instruction in an IT block
76
block/qcow2-snapshot.c | 1 +
76
77
block/qcow2.c | 1 +
77
Stefan Hajnoczi (1):
78
block/qed-l2-cache.c | 1 +
78
docs/generic-loader: mention U-Boot and Intel HEX executable formats
79
block/qed-table.c | 1 +
79
80
block/qed.c | 1 +
80
docs/generic-loader.txt | 20 +-
81
block/quorum.c | 1 +
81
Makefile.objs | 1 +
82
block/raw-format.c | 1 +
82
hw/misc/Makefile.objs | 1 -
83
block/vdi.c | 1 +
83
hw/watchdog/Makefile.objs | 1 +
84
block/vhdx-log.c | 1 +
84
hw/sd/sdhci-internal.h | 2 +
85
block/vhdx.c | 1 +
85
include/exec/memory.h | 35 ----
86
block/vmdk.c | 1 +
86
include/hw/char/imx_serial.h | 1 +
87
block/vpc.c | 1 +
87
include/hw/dma/pl080.h | 71 +++++++
88
block/win32-aio.c | 1 +
88
include/hw/misc/mmio_interface.h | 49 -----
89
hw/arm/virt.c | 7 +++
89
include/hw/watchdog/cmsdk-apb-watchdog.h | 59 ++++++
90
hw/block/dataplane/xen-block.c | 1 +
90
hw/arm/armv7m.c | 1 +
91
hw/block/fdc.c | 1 +
91
hw/arm/realview.c | 8 +-
92
hw/ide/core.c | 1 +
92
hw/arm/versatilepb.c | 9 +-
93
hw/intc/arm_gicv3.c | 8 +++
93
hw/arm/virt.c | 23 ++-
94
hw/intc/arm_gicv3_cpuif.c | 3 +-
94
hw/char/imx_serial.c | 3 +-
95
hw/intc/arm_gicv3_dist.c | 4 +-
95
hw/dma/pl080.c | 113 ++++++-----
96
hw/intc/arm_gicv3_its.c | 69 +++++++++++++++++++++----
96
hw/intc/arm_gicv3_its_kvm.c | 2 +-
97
hw/ppc/spapr.c | 1 +
97
hw/intc/armv7m_nvic.c | 19 ++
98
hw/ppc/spapr_softmmu.c | 1 +
98
hw/misc/mmio_interface.c | 135 -------------
99
hw/scsi/scsi-disk.c | 1 +
99
hw/sd/sdhci.c | 8 +
100
hw/tpm/tpm_ppi.c | 2 +-
100
hw/ssi/xilinx_spips.c | 46 -----
101
nbd/server.c | 1 +
101
hw/timer/m48t59.c | 59 ++----
102
net/l2tpv3.c | 2 +-
102
hw/watchdog/cmsdk-apb-watchdog.c | 326 +++++++++++++++++++++++++++++++
103
plugins/loader.c | 1 +
103
memory.c | 110 -----------
104
qemu-img.c | 1 +
104
target/arm/helper.c | 36 +++-
105
qemu-io-cmds.c | 1 +
105
target/arm/op_helper.c | 22 +--
106
qom/object.c | 1 +
106
target/arm/translate.c | 76 +++++--
107
softmmu/physmem.c | 1 +
107
MAINTAINERS | 3 +
108
target/arm/cpu.c | 6 +++
108
default-configs/arm-softmmu.mak | 1 +
109
target/arm/cpu64.c | 24 +++++++++
109
hw/intc/trace-events | 1 +
110
target/arm/translate-neon.c | 13 +++--
110
hw/watchdog/trace-events | 6 +
111
target/i386/hvf/hvf.c | 1 +
111
31 files changed, 717 insertions(+), 530 deletions(-)
112
target/i386/kvm/kvm.c | 1 +
112
create mode 100644 include/hw/dma/pl080.h
113
tcg/region.c | 1 +
113
delete mode 100644 include/hw/misc/mmio_interface.h
114
tests/bench/atomic_add-bench.c | 1 +
114
create mode 100644 include/hw/watchdog/cmsdk-apb-watchdog.h
115
tests/bench/qht-bench.c | 1 +
115
delete mode 100644 hw/misc/mmio_interface.c
116
util/atomic64.c | 1 +
116
create mode 100644 hw/watchdog/cmsdk-apb-watchdog.c
117
util/memalign.c | 92 +++++++++++++++++++++++++++++++++
117
create mode 100644 hw/watchdog/trace-events
118
util/oslib-posix.c | 46 -----------------
118
119
util/oslib-win32.c | 35 -------------
120
util/qht.c | 1 +
121
hw/intc/trace-events | 21 ++++++++
122
tests/avocado/boot_linux.py | 2 +
123
ui/cocoa.m | 112 +++++++++--------------------------------
124
util/meson.build | 1 +
125
71 files changed, 377 insertions(+), 212 deletions(-)
126
create mode 100644 include/qemu/memalign.h
127
create mode 100644 util/memalign.c
diff view generated by jsdifflib
1
The PL08x model currently will unconditionally call hw_error()
1
The qemu_oom_check() function, which we define in both oslib-posix.c
2
if the DMA engine is enabled by the guest. This has been
2
and oslib-win32.c, is now used only locally in that file; make it
3
present since the PL080 model was edded in 2006, and is
3
static.
4
presumably either unintentional debug code left enabled,
5
or a guard against untested DMA engine code being used.
6
7
Remove the hw_error(), since we now have a guest which
8
will actually try to use the DMA engine (the self-test
9
binary for the AN505 MPS2 FPGA image).
10
4
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20220226180723.1706285-3-peter.maydell@linaro.org
13
---
9
---
14
hw/dma/pl080.c | 1 -
10
include/qemu-common.h | 2 --
15
1 file changed, 1 deletion(-)
11
util/oslib-posix.c | 2 +-
12
util/oslib-win32.c | 2 +-
13
3 files changed, 2 insertions(+), 4 deletions(-)
16
14
17
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
15
diff --git a/include/qemu-common.h b/include/qemu-common.h
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/dma/pl080.c
17
--- a/include/qemu-common.h
20
+++ b/hw/dma/pl080.c
18
+++ b/include/qemu-common.h
21
@@ -XXX,XX +XXX,XX @@ static void pl080_run(PL080State *s)
19
@@ -XXX,XX +XXX,XX @@
22
if ((s->conf & PL080_CONF_E) == 0)
20
int qemu_main(int argc, char **argv, char **envp);
23
return;
21
#endif
24
22
25
-hw_error("DMA active\n");
23
-void *qemu_oom_check(void *ptr);
26
/* If we are already in the middle of a DMA operation then indicate that
24
-
27
there may be new DMA requests and return immediately. */
25
ssize_t qemu_write_full(int fd, const void *buf, size_t count)
28
if (s->running) {
26
QEMU_WARN_UNUSED_RESULT;
27
28
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/util/oslib-posix.c
31
+++ b/util/oslib-posix.c
32
@@ -XXX,XX +XXX,XX @@ fail_close:
33
return false;
34
}
35
36
-void *qemu_oom_check(void *ptr)
37
+static void *qemu_oom_check(void *ptr)
38
{
39
if (ptr == NULL) {
40
fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
41
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/util/oslib-win32.c
44
+++ b/util/oslib-win32.c
45
@@ -XXX,XX +XXX,XX @@
46
/* this must come after including "trace.h" */
47
#include <shlobj.h>
48
49
-void *qemu_oom_check(void *ptr)
50
+static void *qemu_oom_check(void *ptr)
51
{
52
if (ptr == NULL) {
53
fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
29
--
54
--
30
2.18.0
55
2.25.1
31
56
32
57
diff view generated by jsdifflib
1
Move the m48t59 device away from using old_mmio MemoryRegionOps
1
We implement qemu_memalign() in both oslib-posix.c and oslib-win32.c,
2
accessors.
2
but the two versions are essentially the same: they call
3
qemu_try_memalign(), and abort() after printing an error message if
4
it fails. The only difference is that the win32 version prints the
5
GetLastError() value whereas the POSIX version prints
6
strerror(errno). However, this is a bug in the win32 version: in
7
commit dfbd0b873a85021 in 2020 we changed the implementation of
8
qemu_try_memalign() from using VirtualAlloc() (which sets the
9
GetLastError() value) to using _aligned_malloc() (which sets errno),
10
but didn't update the error message to match.
11
12
Replace the two separate functions with a single version in a
13
new memalign.c file, which drops the unnecessary extra qemu_oom_check()
14
function and instead prints a more useful message including the
15
requested size and alignment as well as the errno string.
3
16
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20220226180723.1706285-4-peter.maydell@linaro.org
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
7
Message-id: 20180802180602.22047-1-peter.maydell@linaro.org
8
---
21
---
9
hw/timer/m48t59.c | 59 +++++++++--------------------------------------
22
util/memalign.c | 39 +++++++++++++++++++++++++++++++++++++++
10
1 file changed, 11 insertions(+), 48 deletions(-)
23
util/oslib-posix.c | 14 --------------
24
util/oslib-win32.c | 14 --------------
25
util/meson.build | 1 +
26
4 files changed, 40 insertions(+), 28 deletions(-)
27
create mode 100644 util/memalign.c
11
28
12
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
29
diff --git a/util/memalign.c b/util/memalign.c
30
new file mode 100644
31
index XXXXXXX..XXXXXXX
32
--- /dev/null
33
+++ b/util/memalign.c
34
@@ -XXX,XX +XXX,XX @@
35
+/*
36
+ * memalign.c: Allocate an aligned memory region
37
+ *
38
+ * Copyright (c) 2003-2008 Fabrice Bellard
39
+ * Copyright (c) 2010-2016 Red Hat, Inc.
40
+ * Copyright (c) 2022 Linaro Ltd
41
+ *
42
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
43
+ * of this software and associated documentation files (the "Software"), to deal
44
+ * in the Software without restriction, including without limitation the rights
45
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
46
+ * copies of the Software, and to permit persons to whom the Software is
47
+ * furnished to do so, subject to the following conditions:
48
+ *
49
+ * The above copyright notice and this permission notice shall be included in
50
+ * all copies or substantial portions of the Software.
51
+ *
52
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
53
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
54
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
55
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
57
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
58
+ * THE SOFTWARE.
59
+ */
60
+
61
+#include "qemu/osdep.h"
62
+
63
+void *qemu_memalign(size_t alignment, size_t size)
64
+{
65
+ void *p = qemu_try_memalign(alignment, size);
66
+ if (p) {
67
+ return p;
68
+ }
69
+ fprintf(stderr,
70
+ "qemu_memalign: failed to allocate %zu bytes at alignment %zu: %s\n",
71
+ size, alignment, strerror(errno));
72
+ abort();
73
+}
74
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
13
index XXXXXXX..XXXXXXX 100644
75
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/timer/m48t59.c
76
--- a/util/oslib-posix.c
15
+++ b/hw/timer/m48t59.c
77
+++ b/util/oslib-posix.c
16
@@ -XXX,XX +XXX,XX @@ static uint64_t NVRAM_readb(void *opaque, hwaddr addr, unsigned size)
78
@@ -XXX,XX +XXX,XX @@ fail_close:
17
return retval;
79
return false;
18
}
80
}
19
81
20
-static void nvram_writeb (void *opaque, hwaddr addr, uint32_t value)
82
-static void *qemu_oom_check(void *ptr)
21
-{
83
-{
22
- M48t59State *NVRAM = opaque;
84
- if (ptr == NULL) {
23
-
85
- fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
24
- m48t59_write(NVRAM, addr, value & 0xff);
86
- abort();
87
- }
88
- return ptr;
25
-}
89
-}
26
-
90
-
27
-static void nvram_writew (void *opaque, hwaddr addr, uint32_t value)
91
void *qemu_try_memalign(size_t alignment, size_t size)
92
{
93
void *ptr;
94
@@ -XXX,XX +XXX,XX @@ void *qemu_try_memalign(size_t alignment, size_t size)
95
return ptr;
96
}
97
98
-void *qemu_memalign(size_t alignment, size_t size)
28
-{
99
-{
29
- M48t59State *NVRAM = opaque;
100
- return qemu_oom_check(qemu_try_memalign(alignment, size));
30
-
31
- m48t59_write(NVRAM, addr, (value >> 8) & 0xff);
32
- m48t59_write(NVRAM, addr + 1, value & 0xff);
33
-}
101
-}
34
-
102
-
35
-static void nvram_writel (void *opaque, hwaddr addr, uint32_t value)
103
/* alloc shared memory pages */
104
void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment, bool shared,
105
bool noreserve)
106
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/util/oslib-win32.c
109
+++ b/util/oslib-win32.c
110
@@ -XXX,XX +XXX,XX @@
111
/* this must come after including "trace.h" */
112
#include <shlobj.h>
113
114
-static void *qemu_oom_check(void *ptr)
36
-{
115
-{
37
- M48t59State *NVRAM = opaque;
116
- if (ptr == NULL) {
38
-
117
- fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
39
- m48t59_write(NVRAM, addr, (value >> 24) & 0xff);
118
- abort();
40
- m48t59_write(NVRAM, addr + 1, (value >> 16) & 0xff);
119
- }
41
- m48t59_write(NVRAM, addr + 2, (value >> 8) & 0xff);
120
- return ptr;
42
- m48t59_write(NVRAM, addr + 3, value & 0xff);
43
-}
121
-}
44
-
122
-
45
-static uint32_t nvram_readb (void *opaque, hwaddr addr)
123
void *qemu_try_memalign(size_t alignment, size_t size)
46
+static uint64_t nvram_read(void *opaque, hwaddr addr, unsigned size)
47
{
124
{
48
M48t59State *NVRAM = opaque;
125
void *ptr;
49
126
@@ -XXX,XX +XXX,XX @@ void *qemu_try_memalign(size_t alignment, size_t size)
50
return m48t59_read(NVRAM, addr);
127
return ptr;
51
}
128
}
52
129
53
-static uint32_t nvram_readw (void *opaque, hwaddr addr)
130
-void *qemu_memalign(size_t alignment, size_t size)
54
+static void nvram_write(void *opaque, hwaddr addr, uint64_t value,
131
-{
55
+ unsigned size)
132
- return qemu_oom_check(qemu_try_memalign(alignment, size));
56
{
57
M48t59State *NVRAM = opaque;
58
- uint32_t retval;
59
60
- retval = m48t59_read(NVRAM, addr) << 8;
61
- retval |= m48t59_read(NVRAM, addr + 1);
62
- return retval;
63
-}
133
-}
64
-
134
-
65
-static uint32_t nvram_readl (void *opaque, hwaddr addr)
135
static int get_allocation_granularity(void)
66
-{
136
{
67
- M48t59State *NVRAM = opaque;
137
SYSTEM_INFO system_info;
68
- uint32_t retval;
138
diff --git a/util/meson.build b/util/meson.build
69
-
139
index XXXXXXX..XXXXXXX 100644
70
- retval = m48t59_read(NVRAM, addr) << 24;
140
--- a/util/meson.build
71
- retval |= m48t59_read(NVRAM, addr + 1) << 16;
141
+++ b/util/meson.build
72
- retval |= m48t59_read(NVRAM, addr + 2) << 8;
142
@@ -XXX,XX +XXX,XX @@ util_ss.add(when: 'CONFIG_POSIX', if_true: files('drm.c'))
73
- retval |= m48t59_read(NVRAM, addr + 3);
143
util_ss.add(files('guest-random.c'))
74
- return retval;
144
util_ss.add(files('yank.c'))
75
+ return m48t59_write(NVRAM, addr, value);
145
util_ss.add(files('int128.c'))
76
}
146
+util_ss.add(files('memalign.c'))
77
147
78
static const MemoryRegionOps nvram_ops = {
148
if have_user
79
- .old_mmio = {
149
util_ss.add(files('selfmap.c'))
80
- .read = { nvram_readb, nvram_readw, nvram_readl, },
81
- .write = { nvram_writeb, nvram_writew, nvram_writel, },
82
- },
83
- .endianness = DEVICE_NATIVE_ENDIAN,
84
+ .read = nvram_read,
85
+ .write = nvram_write,
86
+ .impl.min_access_size = 1,
87
+ .impl.max_access_size = 1,
88
+ .valid.min_access_size = 1,
89
+ .valid.max_access_size = 4,
90
+ .endianness = DEVICE_BIG_ENDIAN,
91
};
92
93
static const VMStateDescription vmstate_m48t59 = {
94
--
150
--
95
2.18.0
151
2.25.1
96
152
97
153
diff view generated by jsdifflib
1
The PL080/PL081 model is missing a reset function; implement it.
1
Currently qemu_try_memalign()'s behaviour if asked to allocate
2
0 bytes is rather variable:
3
* on Windows, we will assert
4
* on POSIX platforms, we get the underlying behaviour of
5
the posix_memalign() or equivalent function, which may be
6
either "return a valid non-NULL pointer" or "return NULL"
7
8
Explictly check for 0 byte allocations, so we get consistent
9
behaviour across platforms. We handle them by incrementing the size
10
so that we return a valid non-NULL pointer that can later be passed
11
to qemu_vfree(). This is permitted behaviour for the
12
posix_memalign() API and is the most usual way that underlying
13
malloc() etc implementations handle a zero-sized allocation request,
14
because it won't trip up calling code that assumes NULL means an
15
error. (This includes our own qemu_memalign(), which will abort on
16
NULL.)
17
18
This change is a preparation for sharing the qemu_try_memalign() code
19
between Windows and POSIX.
2
20
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
23
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
---
24
---
6
hw/dma/pl080.c | 25 +++++++++++++++++++++++++
25
util/oslib-posix.c | 3 +++
7
1 file changed, 25 insertions(+)
26
util/oslib-win32.c | 4 +++-
27
2 files changed, 6 insertions(+), 1 deletion(-)
8
28
9
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
29
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
10
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
11
--- a/hw/dma/pl080.c
31
--- a/util/oslib-posix.c
12
+++ b/hw/dma/pl080.c
32
+++ b/util/oslib-posix.c
13
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps pl080_ops = {
33
@@ -XXX,XX +XXX,XX @@ void *qemu_try_memalign(size_t alignment, size_t size)
14
.endianness = DEVICE_NATIVE_ENDIAN,
34
g_assert(is_power_of_2(alignment));
15
};
35
}
16
36
17
+static void pl080_reset(DeviceState *dev)
37
+ if (size == 0) {
18
+{
38
+ size++;
19
+ PL080State *s = PL080(dev);
20
+ int i;
21
+
22
+ s->tc_int = 0;
23
+ s->tc_mask = 0;
24
+ s->err_int = 0;
25
+ s->err_mask = 0;
26
+ s->conf = 0;
27
+ s->sync = 0;
28
+ s->req_single = 0;
29
+ s->req_burst = 0;
30
+ s->running = 0;
31
+
32
+ for (i = 0; i < s->nchannels; i++) {
33
+ s->chan[i].src = 0;
34
+ s->chan[i].dest = 0;
35
+ s->chan[i].lli = 0;
36
+ s->chan[i].ctrl = 0;
37
+ s->chan[i].conf = 0;
38
+ }
39
+ }
39
+}
40
#if defined(CONFIG_POSIX_MEMALIGN)
40
+
41
int ret;
41
static void pl080_init(Object *obj)
42
ret = posix_memalign(&ptr, alignment, size);
43
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/util/oslib-win32.c
46
+++ b/util/oslib-win32.c
47
@@ -XXX,XX +XXX,XX @@ void *qemu_try_memalign(size_t alignment, size_t size)
42
{
48
{
43
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
49
void *ptr;
44
@@ -XXX,XX +XXX,XX @@ static void pl080_class_init(ObjectClass *oc, void *data)
50
45
dc->vmsd = &vmstate_pl080;
51
- g_assert(size != 0);
46
dc->realize = pl080_realize;
52
if (alignment < sizeof(void *)) {
47
dc->props = pl080_properties;
53
alignment = sizeof(void *);
48
+ dc->reset = pl080_reset;
54
} else {
49
}
55
g_assert(is_power_of_2(alignment));
50
56
}
51
static const TypeInfo pl080_info = {
57
+ if (size == 0) {
58
+ size++;
59
+ }
60
ptr = _aligned_malloc(size, alignment);
61
trace_qemu_memalign(alignment, size, ptr);
62
return ptr;
52
--
63
--
53
2.18.0
64
2.25.1
54
65
55
66
diff view generated by jsdifflib
1
The PL080 and PL081 have three outgoing interrupt lines:
1
Currently we incorrectly think that posix_memalign() exists on
2
* DMACINTERR signals DMA errors
2
Windows. This is because of a combination of:
3
* DMACINTTC is the DMA count interrupt
4
* DMACINTR is a combined interrupt, the logical OR of the other two
5
3
6
We currently only implement DMACINTR, because that's all the
4
* the msys2/mingw toolchain/libc claim to have a
7
realview and versatile boards needed, but the instances of the
5
__builtin_posix_memalign when there isn't a builtin of that name
8
PL081 in the MPS2 firmware images use all three interrupt lines.
6
* meson will assume that if you have a __builtin_foo that
9
Implement the missing DMACINTERR and DMACINTTC.
7
counts for has_function('foo')
8
9
Specifying a specific include file via prefix: causes meson to not
10
treat builtins as sufficient and actually look for the function
11
itself; see this meson pull request which added that as the official
12
way to get the right answer:
13
https://github.com/mesonbuild/meson/pull/1150
14
15
Currently this misdectection doesn't cause problems because we only
16
use CONFIG_POSIX_MEMALIGN in oslib-posix.c; however that will change
17
in a following commit.
10
18
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20220226180723.1706285-6-peter.maydell@linaro.org
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
22
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
---
23
---
14
include/hw/dma/pl080.h | 6 +++++-
24
meson.build | 4 +++-
15
hw/dma/pl080.c | 13 ++++++++-----
25
1 file changed, 3 insertions(+), 1 deletion(-)
16
2 files changed, 13 insertions(+), 6 deletions(-)
17
26
18
diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h
27
diff --git a/meson.build b/meson.build
19
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/dma/pl080.h
29
--- a/meson.build
21
+++ b/include/hw/dma/pl080.h
30
+++ b/meson.build
22
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@ config_host_data.set('CONFIG_CLOCK_ADJTIME', cc.has_function('clock_adjtime'))
23
* http://infocenter.arm.com/help/topic/com.arm.doc.ddi0218e/DDI0218.pdf
32
config_host_data.set('CONFIG_DUP3', cc.has_function('dup3'))
24
*
33
config_host_data.set('CONFIG_FALLOCATE', cc.has_function('fallocate'))
25
* QEMU interface:
34
config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'))
26
- * + sysbus IRQ: DMACINTR combined interrupt line
35
-config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign'))
27
+ * + sysbus IRQ 0: DMACINTR combined interrupt line
36
+# Note that we need to specify prefix: here to avoid incorrectly
28
+ * + sysbus IRQ 1: DMACINTERR error interrupt request
37
+# thinking that Windows has posix_memalign()
29
+ * + sysbus IRQ 2: DMACINTTC count interrupt request
38
+config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
30
* + sysbus MMIO region 0: MemoryRegion for the device's registers
39
config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
31
*/
40
config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
32
41
config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
33
@@ -XXX,XX +XXX,XX @@ typedef struct PL080State {
34
/* Flag to avoid recursive DMA invocations. */
35
int running;
36
qemu_irq irq;
37
+ qemu_irq interr;
38
+ qemu_irq inttc;
39
} PL080State;
40
41
#endif
42
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/dma/pl080.c
45
+++ b/hw/dma/pl080.c
46
@@ -XXX,XX +XXX,XX @@ static const unsigned char pl081_id[] =
47
48
static void pl080_update(PL080State *s)
49
{
50
- if ((s->tc_int & s->tc_mask)
51
- || (s->err_int & s->err_mask))
52
- qemu_irq_raise(s->irq);
53
- else
54
- qemu_irq_lower(s->irq);
55
+ bool tclevel = (s->tc_int & s->tc_mask);
56
+ bool errlevel = (s->err_int & s->err_mask);
57
+
58
+ qemu_set_irq(s->interr, errlevel);
59
+ qemu_set_irq(s->inttc, tclevel);
60
+ qemu_set_irq(s->irq, errlevel || tclevel);
61
}
62
63
static void pl080_run(PL080State *s)
64
@@ -XXX,XX +XXX,XX @@ static void pl080_init(Object *obj)
65
memory_region_init_io(&s->iomem, OBJECT(s), &pl080_ops, s, "pl080", 0x1000);
66
sysbus_init_mmio(sbd, &s->iomem);
67
sysbus_init_irq(sbd, &s->irq);
68
+ sysbus_init_irq(sbd, &s->interr);
69
+ sysbus_init_irq(sbd, &s->inttc);
70
s->nchannels = 8;
71
}
72
73
--
42
--
74
2.18.0
43
2.25.1
75
44
76
45
diff view generated by jsdifflib
1
Currently our PL080/PL081 model uses a combination of the CPU's
1
The qemu_try_memalign() functions for POSIX and Windows used to be
2
address space (via cpu_physical_memory_{read,write}()) and the
2
significantly different, but these days they are identical except for
3
system address space for performing DMA accesses.
3
the actual allocation function called, and the POSIX version already
4
has to have ifdeffery for different allocation functions.
4
5
5
For the PL081s in the MPS FPGA images, their DMA accesses
6
Move to a single implementation in memalign.c, which uses the Windows
6
must go via Master Security Controllers. Switch the
7
_aligned_malloc if we detect that function in meson.
7
PL080/PL081 model to take a MemoryRegion property which
8
defines its downstream for making DMA accesses.
9
10
Since the PL08x are only used in two board models, we
11
make provision of the 'downstream' link mandatory and convert
12
both users at once, rather than having it be optional with
13
a default to the system address space.
14
8
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20220226180723.1706285-7-peter.maydell@linaro.org
16
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
17
---
13
---
18
include/hw/dma/pl080.h | 5 +++++
14
meson.build | 1 +
19
hw/arm/realview.c | 8 +++++++-
15
util/memalign.c | 39 +++++++++++++++++++++++++++++++++++++++
20
hw/arm/versatilepb.c | 9 ++++++++-
16
util/oslib-posix.c | 29 -----------------------------
21
hw/dma/pl080.c | 35 +++++++++++++++++++++++++++++------
17
util/oslib-win32.c | 17 -----------------
22
4 files changed, 49 insertions(+), 8 deletions(-)
18
4 files changed, 40 insertions(+), 46 deletions(-)
23
19
24
diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h
20
diff --git a/meson.build b/meson.build
25
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/dma/pl080.h
22
--- a/meson.build
27
+++ b/include/hw/dma/pl080.h
23
+++ b/meson.build
24
@@ -XXX,XX +XXX,XX @@ config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'
25
# Note that we need to specify prefix: here to avoid incorrectly
26
# thinking that Windows has posix_memalign()
27
config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
28
+config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
29
config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
30
config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
31
config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
32
diff --git a/util/memalign.c b/util/memalign.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/util/memalign.c
35
+++ b/util/memalign.c
28
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@
29
* + sysbus IRQ 1: DMACINTERR error interrupt request
30
* + sysbus IRQ 2: DMACINTTC count interrupt request
31
* + sysbus MMIO region 0: MemoryRegion for the device's registers
32
+ * + QOM property "downstream": MemoryRegion defining where DMA
33
+ * bus master transactions are made
34
*/
37
*/
35
38
36
#ifndef HW_DMA_PL080_H
39
#include "qemu/osdep.h"
37
@@ -XXX,XX +XXX,XX @@ typedef struct PL080State {
40
+#include "qemu/host-utils.h"
38
qemu_irq irq;
41
+#include "trace.h"
39
qemu_irq interr;
40
qemu_irq inttc;
41
+
42
+
42
+ MemoryRegion *downstream;
43
+void *qemu_try_memalign(size_t alignment, size_t size)
43
+ AddressSpace downstream_as;
44
+{
44
} PL080State;
45
+ void *ptr;
45
46
#endif
47
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/arm/realview.c
50
+++ b/hw/arm/realview.c
51
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
52
pl011_create(0x1000c000, pic[15], serial_hd(3));
53
54
/* DMA controller is optional, apparently. */
55
- sysbus_create_simple("pl081", 0x10030000, pic[24]);
56
+ dev = qdev_create(NULL, "pl081");
57
+ object_property_set_link(OBJECT(dev), OBJECT(sysmem), "downstream",
58
+ &error_fatal);
59
+ qdev_init_nofail(dev);
60
+ busdev = SYS_BUS_DEVICE(dev);
61
+ sysbus_mmio_map(busdev, 0, 0x10030000);
62
+ sysbus_connect_irq(busdev, 0, pic[24]);
63
64
sysbus_create_simple("sp804", 0x10011000, pic[4]);
65
sysbus_create_simple("sp804", 0x10012000, pic[5]);
66
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/hw/arm/versatilepb.c
69
+++ b/hw/arm/versatilepb.c
70
@@ -XXX,XX +XXX,XX @@ static void versatile_init(MachineState *machine, int board_id)
71
pl011_create(0x101f3000, pic[14], serial_hd(2));
72
pl011_create(0x10009000, sic[6], serial_hd(3));
73
74
- sysbus_create_simple("pl080", 0x10130000, pic[17]);
75
+ dev = qdev_create(NULL, "pl080");
76
+ object_property_set_link(OBJECT(dev), OBJECT(sysmem), "downstream",
77
+ &error_fatal);
78
+ qdev_init_nofail(dev);
79
+ busdev = SYS_BUS_DEVICE(dev);
80
+ sysbus_mmio_map(busdev, 0, 0x10130000);
81
+ sysbus_connect_irq(busdev, 0, pic[17]);
82
+
46
+
83
sysbus_create_simple("sp804", 0x101e2000, pic[4]);
47
+ if (alignment < sizeof(void*)) {
84
sysbus_create_simple("sp804", 0x101e3000, pic[5]);
48
+ alignment = sizeof(void*);
85
49
+ } else {
86
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
50
+ g_assert(is_power_of_2(alignment));
87
index XXXXXXX..XXXXXXX 100644
88
--- a/hw/dma/pl080.c
89
+++ b/hw/dma/pl080.c
90
@@ -XXX,XX +XXX,XX @@
91
#include "exec/address-spaces.h"
92
#include "qemu/log.h"
93
#include "hw/dma/pl080.h"
94
+#include "qapi/error.h"
95
96
#define PL080_CONF_E 0x1
97
#define PL080_CONF_M1 0x2
98
@@ -XXX,XX +XXX,XX @@ again:
99
swidth = 1 << ((ch->ctrl >> 18) & 7);
100
dwidth = 1 << ((ch->ctrl >> 21) & 7);
101
for (n = 0; n < dwidth; n+= swidth) {
102
- cpu_physical_memory_read(ch->src, buff + n, swidth);
103
+ address_space_read(&s->downstream_as, ch->src,
104
+ MEMTXATTRS_UNSPECIFIED, buff + n, swidth);
105
if (ch->ctrl & PL080_CCTRL_SI)
106
ch->src += swidth;
107
}
108
xsize = (dwidth < swidth) ? swidth : dwidth;
109
/* ??? This may pad the value incorrectly for dwidth < 32. */
110
for (n = 0; n < xsize; n += dwidth) {
111
- cpu_physical_memory_write(ch->dest + n, buff + n, dwidth);
112
+ address_space_write(&s->downstream_as, ch->dest + n,
113
+ MEMTXATTRS_UNSPECIFIED, buff + n, dwidth);
114
if (ch->ctrl & PL080_CCTRL_DI)
115
ch->dest += swidth;
116
}
117
@@ -XXX,XX +XXX,XX @@ again:
118
if (size == 0) {
119
/* Transfer complete. */
120
if (ch->lli) {
121
- ch->src = address_space_ldl_le(&address_space_memory,
122
+ ch->src = address_space_ldl_le(&s->downstream_as,
123
ch->lli,
124
MEMTXATTRS_UNSPECIFIED,
125
NULL);
126
- ch->dest = address_space_ldl_le(&address_space_memory,
127
+ ch->dest = address_space_ldl_le(&s->downstream_as,
128
ch->lli + 4,
129
MEMTXATTRS_UNSPECIFIED,
130
NULL);
131
- ch->ctrl = address_space_ldl_le(&address_space_memory,
132
+ ch->ctrl = address_space_ldl_le(&s->downstream_as,
133
ch->lli + 12,
134
MEMTXATTRS_UNSPECIFIED,
135
NULL);
136
- ch->lli = address_space_ldl_le(&address_space_memory,
137
+ ch->lli = address_space_ldl_le(&s->downstream_as,
138
ch->lli + 8,
139
MEMTXATTRS_UNSPECIFIED,
140
NULL);
141
@@ -XXX,XX +XXX,XX @@ static void pl080_init(Object *obj)
142
s->nchannels = 8;
143
}
144
145
+static void pl080_realize(DeviceState *dev, Error **errp)
146
+{
147
+ PL080State *s = PL080(dev);
148
+
149
+ if (!s->downstream) {
150
+ error_setg(errp, "PL080 'downstream' link not set");
151
+ return;
152
+ }
51
+ }
153
+
52
+
154
+ address_space_init(&s->downstream_as, s->downstream, "pl080-downstream");
53
+ /*
54
+ * Handling of 0 allocations varies among the different
55
+ * platform APIs (for instance _aligned_malloc() will
56
+ * fail) -- ensure that we always return a valid non-NULL
57
+ * pointer that can be freed by qemu_vfree().
58
+ */
59
+ if (size == 0) {
60
+ size++;
61
+ }
62
+#if defined(CONFIG_POSIX_MEMALIGN)
63
+ int ret;
64
+ ret = posix_memalign(&ptr, alignment, size);
65
+ if (ret != 0) {
66
+ errno = ret;
67
+ ptr = NULL;
68
+ }
69
+#elif defined(CONFIG_ALIGNED_MALLOC)
70
+ ptr = _aligned_malloc(size, alignment);
71
+#elif defined(CONFIG_BSD)
72
+ ptr = valloc(size);
73
+#else
74
+ ptr = memalign(alignment, size);
75
+#endif
76
+ trace_qemu_memalign(alignment, size, ptr);
77
+ return ptr;
155
+}
78
+}
156
+
79
157
static void pl081_init(Object *obj)
80
void *qemu_memalign(size_t alignment, size_t size)
158
{
81
{
159
PL080State *s = PL080(obj);
82
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
160
@@ -XXX,XX +XXX,XX @@ static void pl081_init(Object *obj)
83
index XXXXXXX..XXXXXXX 100644
161
s->nchannels = 2;
84
--- a/util/oslib-posix.c
85
+++ b/util/oslib-posix.c
86
@@ -XXX,XX +XXX,XX @@ fail_close:
87
return false;
162
}
88
}
163
89
164
+static Property pl080_properties[] = {
90
-void *qemu_try_memalign(size_t alignment, size_t size)
165
+ DEFINE_PROP_LINK("downstream", PL080State, downstream,
91
-{
166
+ TYPE_MEMORY_REGION, MemoryRegion *),
92
- void *ptr;
167
+ DEFINE_PROP_END_OF_LIST(),
93
-
168
+};
94
- if (alignment < sizeof(void*)) {
169
+
95
- alignment = sizeof(void*);
170
static void pl080_class_init(ObjectClass *oc, void *data)
96
- } else {
97
- g_assert(is_power_of_2(alignment));
98
- }
99
-
100
- if (size == 0) {
101
- size++;
102
- }
103
-#if defined(CONFIG_POSIX_MEMALIGN)
104
- int ret;
105
- ret = posix_memalign(&ptr, alignment, size);
106
- if (ret != 0) {
107
- errno = ret;
108
- ptr = NULL;
109
- }
110
-#elif defined(CONFIG_BSD)
111
- ptr = valloc(size);
112
-#else
113
- ptr = memalign(alignment, size);
114
-#endif
115
- trace_qemu_memalign(alignment, size, ptr);
116
- return ptr;
117
-}
118
-
119
/* alloc shared memory pages */
120
void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment, bool shared,
121
bool noreserve)
122
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
123
index XXXXXXX..XXXXXXX 100644
124
--- a/util/oslib-win32.c
125
+++ b/util/oslib-win32.c
126
@@ -XXX,XX +XXX,XX @@
127
/* this must come after including "trace.h" */
128
#include <shlobj.h>
129
130
-void *qemu_try_memalign(size_t alignment, size_t size)
131
-{
132
- void *ptr;
133
-
134
- if (alignment < sizeof(void *)) {
135
- alignment = sizeof(void *);
136
- } else {
137
- g_assert(is_power_of_2(alignment));
138
- }
139
- if (size == 0) {
140
- size++;
141
- }
142
- ptr = _aligned_malloc(size, alignment);
143
- trace_qemu_memalign(alignment, size, ptr);
144
- return ptr;
145
-}
146
-
147
static int get_allocation_granularity(void)
171
{
148
{
172
DeviceClass *dc = DEVICE_CLASS(oc);
149
SYSTEM_INFO system_info;
173
174
dc->vmsd = &vmstate_pl080;
175
+ dc->realize = pl080_realize;
176
+ dc->props = pl080_properties;
177
}
178
179
static const TypeInfo pl080_info = {
180
--
150
--
181
2.18.0
151
2.25.1
182
152
183
153
diff view generated by jsdifflib
1
The mmio_interface device was a purely internal artifact
1
Instead of assuming that all CONFIG_BSD have valloc() and anything
2
of the implementation of the memory subsystem's request_ptr
2
else is memalign(), explicitly check for those functions in
3
APIs. Now that we have removed those APIs, we can remove
3
meson.build and use the "is the function present" define. Tests for
4
the mmio_interface device too.
4
specific functionality are better than which-OS checks; this also
5
lets us give a helpful error message if somehow there's no usable
6
function present.
5
7
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
11
Message-id: 20220226180723.1706285-8-peter.maydell@linaro.org
10
Message-id: 20180817114619.22354-4-peter.maydell@linaro.org
11
---
12
---
12
hw/misc/Makefile.objs | 1 -
13
meson.build | 2 ++
13
include/hw/misc/mmio_interface.h | 49 -----------
14
util/memalign.c | 6 ++++--
14
hw/misc/mmio_interface.c | 135 -------------------------------
15
2 files changed, 6 insertions(+), 2 deletions(-)
15
3 files changed, 185 deletions(-)
16
delete mode 100644 include/hw/misc/mmio_interface.h
17
delete mode 100644 hw/misc/mmio_interface.c
18
16
19
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
17
diff --git a/meson.build b/meson.build
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/misc/Makefile.objs
19
--- a/meson.build
22
+++ b/hw/misc/Makefile.objs
20
+++ b/meson.build
23
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
21
@@ -XXX,XX +XXX,XX @@ config_host_data.set('CONFIG_POSIX_FALLOCATE', cc.has_function('posix_fallocate'
24
obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
22
# thinking that Windows has posix_memalign()
25
obj-$(CONFIG_AUX) += auxbus.o
23
config_host_data.set('CONFIG_POSIX_MEMALIGN', cc.has_function('posix_memalign', prefix: '#include <stdlib.h>'))
26
obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
24
config_host_data.set('CONFIG_ALIGNED_MALLOC', cc.has_function('_aligned_malloc'))
27
-obj-y += mmio_interface.o
25
+config_host_data.set('CONFIG_VALLOC', cc.has_function('valloc'))
28
obj-$(CONFIG_MSF2) += msf2-sysreg.o
26
+config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign'))
29
diff --git a/include/hw/misc/mmio_interface.h b/include/hw/misc/mmio_interface.h
27
config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll'))
30
deleted file mode 100644
28
config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#include <sys/uio.h>'))
31
index XXXXXXX..XXXXXXX
29
config_host_data.set('CONFIG_SEM_TIMEDWAIT', cc.has_function('sem_timedwait', dependencies: threads))
32
--- a/include/hw/misc/mmio_interface.h
30
diff --git a/util/memalign.c b/util/memalign.c
33
+++ /dev/null
31
index XXXXXXX..XXXXXXX 100644
34
@@ -XXX,XX +XXX,XX @@
32
--- a/util/memalign.c
35
-/*
33
+++ b/util/memalign.c
36
- * mmio_interface.h
34
@@ -XXX,XX +XXX,XX @@ void *qemu_try_memalign(size_t alignment, size_t size)
37
- *
35
}
38
- * Copyright (C) 2017 : GreenSocs
36
#elif defined(CONFIG_ALIGNED_MALLOC)
39
- * http://www.greensocs.com/ , email: info@greensocs.com
37
ptr = _aligned_malloc(size, alignment);
40
- *
38
-#elif defined(CONFIG_BSD)
41
- * Developed by :
39
+#elif defined(CONFIG_VALLOC)
42
- * Frederic Konrad <fred.konrad@greensocs.com>
40
ptr = valloc(size);
43
- *
41
-#else
44
- * This program is free software; you can redistribute it and/or modify
42
+#elif defined(CONFIG_MEMALIGN)
45
- * it under the terms of the GNU General Public License as published by
43
ptr = memalign(alignment, size);
46
- * the Free Software Foundation, either version 2 of the License, or
44
+#else
47
- * (at your option)any later version.
45
+ #error No function to allocate aligned memory available
48
- *
46
#endif
49
- * This program is distributed in the hope that it will be useful,
47
trace_qemu_memalign(alignment, size, ptr);
50
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
48
return ptr;
51
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52
- * GNU General Public License for more details.
53
- *
54
- * You should have received a copy of the GNU General Public License along
55
- * with this program; if not, see <http://www.gnu.org/licenses/>.
56
- *
57
- */
58
-
59
-#ifndef MMIO_INTERFACE_H
60
-#define MMIO_INTERFACE_H
61
-
62
-#include "exec/memory.h"
63
-
64
-#define TYPE_MMIO_INTERFACE "mmio_interface"
65
-#define MMIO_INTERFACE(obj) OBJECT_CHECK(MMIOInterface, (obj), \
66
- TYPE_MMIO_INTERFACE)
67
-
68
-typedef struct MMIOInterface {
69
- DeviceState parent_obj;
70
-
71
- MemoryRegion *subregion;
72
- MemoryRegion ram_mem;
73
- uint64_t start;
74
- uint64_t end;
75
- bool ro;
76
- uint64_t id;
77
- void *host_ptr;
78
-} MMIOInterface;
79
-
80
-void mmio_interface_map(MMIOInterface *s);
81
-void mmio_interface_unmap(MMIOInterface *s);
82
-
83
-#endif /* MMIO_INTERFACE_H */
84
diff --git a/hw/misc/mmio_interface.c b/hw/misc/mmio_interface.c
85
deleted file mode 100644
86
index XXXXXXX..XXXXXXX
87
--- a/hw/misc/mmio_interface.c
88
+++ /dev/null
89
@@ -XXX,XX +XXX,XX @@
90
-/*
91
- * mmio_interface.c
92
- *
93
- * Copyright (C) 2017 : GreenSocs
94
- * http://www.greensocs.com/ , email: info@greensocs.com
95
- *
96
- * Developed by :
97
- * Frederic Konrad <fred.konrad@greensocs.com>
98
- *
99
- * This program is free software; you can redistribute it and/or modify
100
- * it under the terms of the GNU General Public License as published by
101
- * the Free Software Foundation, either version 2 of the License, or
102
- * (at your option)any later version.
103
- *
104
- * This program is distributed in the hope that it will be useful,
105
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
106
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
107
- * GNU General Public License for more details.
108
- *
109
- * You should have received a copy of the GNU General Public License along
110
- * with this program; if not, see <http://www.gnu.org/licenses/>.
111
- *
112
- */
113
-
114
-#include "qemu/osdep.h"
115
-#include "qemu/log.h"
116
-#include "trace.h"
117
-#include "hw/qdev-properties.h"
118
-#include "hw/misc/mmio_interface.h"
119
-#include "qapi/error.h"
120
-
121
-#ifndef DEBUG_MMIO_INTERFACE
122
-#define DEBUG_MMIO_INTERFACE 0
123
-#endif
124
-
125
-static uint64_t mmio_interface_counter;
126
-
127
-#define DPRINTF(fmt, ...) do { \
128
- if (DEBUG_MMIO_INTERFACE) { \
129
- qemu_log("mmio_interface: 0x%" PRIX64 ": " fmt, s->id, ## __VA_ARGS__);\
130
- } \
131
-} while (0)
132
-
133
-static void mmio_interface_init(Object *obj)
134
-{
135
- MMIOInterface *s = MMIO_INTERFACE(obj);
136
-
137
- if (DEBUG_MMIO_INTERFACE) {
138
- s->id = mmio_interface_counter++;
139
- }
140
-
141
- DPRINTF("interface created\n");
142
- s->host_ptr = 0;
143
- s->subregion = 0;
144
-}
145
-
146
-static void mmio_interface_realize(DeviceState *dev, Error **errp)
147
-{
148
- MMIOInterface *s = MMIO_INTERFACE(dev);
149
-
150
- DPRINTF("realize from 0x%" PRIX64 " to 0x%" PRIX64 " map host pointer"
151
- " %p\n", s->start, s->end, s->host_ptr);
152
-
153
- if (!s->host_ptr) {
154
- error_setg(errp, "host_ptr property must be set");
155
- return;
156
- }
157
-
158
- if (!s->subregion) {
159
- error_setg(errp, "subregion property must be set");
160
- return;
161
- }
162
-
163
- memory_region_init_ram_ptr(&s->ram_mem, OBJECT(s), "ram",
164
- s->end - s->start + 1, s->host_ptr);
165
- memory_region_set_readonly(&s->ram_mem, s->ro);
166
- memory_region_add_subregion(s->subregion, s->start, &s->ram_mem);
167
-}
168
-
169
-static void mmio_interface_unrealize(DeviceState *dev, Error **errp)
170
-{
171
- MMIOInterface *s = MMIO_INTERFACE(dev);
172
-
173
- DPRINTF("unrealize from 0x%" PRIX64 " to 0x%" PRIX64 " map host pointer"
174
- " %p\n", s->start, s->end, s->host_ptr);
175
- memory_region_del_subregion(s->subregion, &s->ram_mem);
176
-}
177
-
178
-static void mmio_interface_finalize(Object *obj)
179
-{
180
- MMIOInterface *s = MMIO_INTERFACE(obj);
181
-
182
- DPRINTF("finalize from 0x%" PRIX64 " to 0x%" PRIX64 " map host pointer"
183
- " %p\n", s->start, s->end, s->host_ptr);
184
- object_unparent(OBJECT(&s->ram_mem));
185
-}
186
-
187
-static Property mmio_interface_properties[] = {
188
- DEFINE_PROP_UINT64("start", MMIOInterface, start, 0),
189
- DEFINE_PROP_UINT64("end", MMIOInterface, end, 0),
190
- DEFINE_PROP_PTR("host_ptr", MMIOInterface, host_ptr),
191
- DEFINE_PROP_BOOL("ro", MMIOInterface, ro, false),
192
- DEFINE_PROP_MEMORY_REGION("subregion", MMIOInterface, subregion),
193
- DEFINE_PROP_END_OF_LIST(),
194
-};
195
-
196
-static void mmio_interface_class_init(ObjectClass *oc, void *data)
197
-{
198
- DeviceClass *dc = DEVICE_CLASS(oc);
199
-
200
- dc->realize = mmio_interface_realize;
201
- dc->unrealize = mmio_interface_unrealize;
202
- dc->props = mmio_interface_properties;
203
- /* Reason: pointer property "host_ptr", and this device
204
- * is an implementation detail of the memory subsystem,
205
- * not intended to be created directly by the user.
206
- */
207
- dc->user_creatable = false;
208
-}
209
-
210
-static const TypeInfo mmio_interface_info = {
211
- .name = TYPE_MMIO_INTERFACE,
212
- .parent = TYPE_DEVICE,
213
- .instance_size = sizeof(MMIOInterface),
214
- .instance_init = mmio_interface_init,
215
- .instance_finalize = mmio_interface_finalize,
216
- .class_init = mmio_interface_class_init,
217
-};
218
-
219
-static void mmio_interface_register_types(void)
220
-{
221
- type_register_static(&mmio_interface_info);
222
-}
223
-
224
-type_init(mmio_interface_register_types)
225
--
49
--
226
2.18.0
50
2.25.1
227
51
228
52
diff view generated by jsdifflib
1
Remove the obsolete MMIO request_ptr APIs; they have no
1
qemu_vfree() is the companion free function to qemu_memalign(); put
2
users now.
2
it in memalign.c so the allocation and free functions are together.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-id: 20220226180723.1706285-9-peter.maydell@linaro.org
7
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20180817114619.22354-3-peter.maydell@linaro.org
9
---
8
---
10
include/exec/memory.h | 35 --------------
9
util/memalign.c | 11 +++++++++++
11
memory.c | 110 ------------------------------------------
10
util/oslib-posix.c | 6 ------
12
2 files changed, 145 deletions(-)
11
util/oslib-win32.c | 6 ------
12
3 files changed, 11 insertions(+), 12 deletions(-)
13
13
14
diff --git a/include/exec/memory.h b/include/exec/memory.h
14
diff --git a/util/memalign.c b/util/memalign.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/memory.h
16
--- a/util/memalign.c
17
+++ b/include/exec/memory.h
17
+++ b/util/memalign.c
18
@@ -XXX,XX +XXX,XX @@ struct MemoryRegionOps {
18
@@ -XXX,XX +XXX,XX @@ void *qemu_memalign(size_t alignment, size_t size)
19
uint64_t data,
19
size, alignment, strerror(errno));
20
unsigned size,
20
abort();
21
MemTxAttrs attrs);
21
}
22
- /* Instruction execution pre-callback:
22
+
23
- * @addr is the address of the access relative to the @mr.
23
+void qemu_vfree(void *ptr)
24
- * @size is the size of the area returned by the callback.
24
+{
25
- * @offset is the location of the pointer inside @mr.
25
+ trace_qemu_vfree(ptr);
26
- *
26
+#if !defined(CONFIG_POSIX_MEMALIGN) && defined(CONFIG_ALIGNED_MALLOC)
27
- * Returns a pointer to a location which contains guest code.
27
+ /* Only Windows _aligned_malloc needs a special free function */
28
- */
28
+ _aligned_free(ptr);
29
- void *(*request_ptr)(void *opaque, hwaddr addr, unsigned *size,
29
+#else
30
- unsigned *offset);
30
+ free(ptr);
31
31
+#endif
32
enum device_endian endianness;
32
+}
33
/* Guest-visible constraints: */
33
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
34
@@ -XXX,XX +XXX,XX @@ void memory_global_dirty_log_stop(void);
35
void mtree_info(fprintf_function mon_printf, void *f, bool flatview,
36
bool dispatch_tree, bool owner);
37
38
-/**
39
- * memory_region_request_mmio_ptr: request a pointer to an mmio
40
- * MemoryRegion. If it is possible map a RAM MemoryRegion with this pointer.
41
- * When the device wants to invalidate the pointer it will call
42
- * memory_region_invalidate_mmio_ptr.
43
- *
44
- * @mr: #MemoryRegion to check
45
- * @addr: address within that region
46
- *
47
- * Returns true on success, false otherwise.
48
- */
49
-bool memory_region_request_mmio_ptr(MemoryRegion *mr, hwaddr addr);
50
-
51
-/**
52
- * memory_region_invalidate_mmio_ptr: invalidate the pointer to an mmio
53
- * previously requested.
54
- * In the end that means that if something wants to execute from this area it
55
- * will need to request the pointer again.
56
- *
57
- * @mr: #MemoryRegion associated to the pointer.
58
- * @offset: offset within the memory region
59
- * @size: size of that area.
60
- */
61
-void memory_region_invalidate_mmio_ptr(MemoryRegion *mr, hwaddr offset,
62
- unsigned size);
63
-
64
/**
65
* memory_region_dispatch_read: perform a read directly to the specified
66
* MemoryRegion.
67
diff --git a/memory.c b/memory.c
68
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
69
--- a/memory.c
35
--- a/util/oslib-posix.c
70
+++ b/memory.c
36
+++ b/util/oslib-posix.c
71
@@ -XXX,XX +XXX,XX @@
37
@@ -XXX,XX +XXX,XX @@ void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment, bool shared,
72
#include "exec/ram_addr.h"
38
return ptr;
73
#include "sysemu/kvm.h"
74
#include "sysemu/sysemu.h"
75
-#include "hw/misc/mmio_interface.h"
76
#include "hw/qdev-properties.h"
77
#include "migration/vmstate.h"
78
79
@@ -XXX,XX +XXX,XX @@ void memory_listener_unregister(MemoryListener *listener)
80
listener->address_space = NULL;
81
}
39
}
82
40
83
-bool memory_region_request_mmio_ptr(MemoryRegion *mr, hwaddr addr)
41
-void qemu_vfree(void *ptr)
84
-{
42
-{
85
- void *host;
43
- trace_qemu_vfree(ptr);
86
- unsigned size = 0;
44
- free(ptr);
87
- unsigned offset = 0;
88
- Object *new_interface;
89
-
90
- if (!mr || !mr->ops->request_ptr) {
91
- return false;
92
- }
93
-
94
- /*
95
- * Avoid an update if the request_ptr call
96
- * memory_region_invalidate_mmio_ptr which seems to be likely when we use
97
- * a cache.
98
- */
99
- memory_region_transaction_begin();
100
-
101
- host = mr->ops->request_ptr(mr->opaque, addr - mr->addr, &size, &offset);
102
-
103
- if (!host || !size) {
104
- memory_region_transaction_commit();
105
- return false;
106
- }
107
-
108
- new_interface = object_new("mmio_interface");
109
- qdev_prop_set_uint64(DEVICE(new_interface), "start", offset);
110
- qdev_prop_set_uint64(DEVICE(new_interface), "end", offset + size - 1);
111
- qdev_prop_set_bit(DEVICE(new_interface), "ro", true);
112
- qdev_prop_set_ptr(DEVICE(new_interface), "host_ptr", host);
113
- qdev_prop_set_ptr(DEVICE(new_interface), "subregion", mr);
114
- object_property_set_bool(OBJECT(new_interface), true, "realized", NULL);
115
-
116
- memory_region_transaction_commit();
117
- return true;
118
-}
45
-}
119
-
46
-
120
-typedef struct MMIOPtrInvalidate {
47
void qemu_anon_ram_free(void *ptr, size_t size)
121
- MemoryRegion *mr;
48
{
122
- hwaddr offset;
49
trace_qemu_anon_ram_free(ptr, size);
123
- unsigned size;
50
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
124
- int busy;
51
index XXXXXXX..XXXXXXX 100644
125
- int allocated;
52
--- a/util/oslib-win32.c
126
-} MMIOPtrInvalidate;
53
+++ b/util/oslib-win32.c
127
-
54
@@ -XXX,XX +XXX,XX @@ void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared,
128
-#define MAX_MMIO_INVALIDATE 10
55
return ptr;
129
-static MMIOPtrInvalidate mmio_ptr_invalidate_list[MAX_MMIO_INVALIDATE];
56
}
130
-
57
131
-static void memory_region_do_invalidate_mmio_ptr(CPUState *cpu,
58
-void qemu_vfree(void *ptr)
132
- run_on_cpu_data data)
133
-{
59
-{
134
- MMIOPtrInvalidate *invalidate_data = (MMIOPtrInvalidate *)data.host_ptr;
60
- trace_qemu_vfree(ptr);
135
- MemoryRegion *mr = invalidate_data->mr;
61
- _aligned_free(ptr);
136
- hwaddr offset = invalidate_data->offset;
137
- unsigned size = invalidate_data->size;
138
- MemoryRegionSection section = memory_region_find(mr, offset, size);
139
-
140
- qemu_mutex_lock_iothread();
141
-
142
- /* Reset dirty so this doesn't happen later. */
143
- cpu_physical_memory_test_and_clear_dirty(offset, size, 1);
144
-
145
- if (section.mr != mr) {
146
- /* memory_region_find add a ref on section.mr */
147
- memory_region_unref(section.mr);
148
- if (MMIO_INTERFACE(section.mr->owner)) {
149
- /* We found the interface just drop it. */
150
- object_property_set_bool(section.mr->owner, false, "realized",
151
- NULL);
152
- object_unref(section.mr->owner);
153
- object_unparent(section.mr->owner);
154
- }
155
- }
156
-
157
- qemu_mutex_unlock_iothread();
158
-
159
- if (invalidate_data->allocated) {
160
- g_free(invalidate_data);
161
- } else {
162
- invalidate_data->busy = 0;
163
- }
164
-}
62
-}
165
-
63
-
166
-void memory_region_invalidate_mmio_ptr(MemoryRegion *mr, hwaddr offset,
64
void qemu_anon_ram_free(void *ptr, size_t size)
167
- unsigned size)
168
-{
169
- size_t i;
170
- MMIOPtrInvalidate *invalidate_data = NULL;
171
-
172
- for (i = 0; i < MAX_MMIO_INVALIDATE; i++) {
173
- if (atomic_cmpxchg(&(mmio_ptr_invalidate_list[i].busy), 0, 1) == 0) {
174
- invalidate_data = &mmio_ptr_invalidate_list[i];
175
- break;
176
- }
177
- }
178
-
179
- if (!invalidate_data) {
180
- invalidate_data = g_malloc0(sizeof(MMIOPtrInvalidate));
181
- invalidate_data->allocated = 1;
182
- }
183
-
184
- invalidate_data->mr = mr;
185
- invalidate_data->offset = offset;
186
- invalidate_data->size = size;
187
-
188
- async_safe_run_on_cpu(first_cpu, memory_region_do_invalidate_mmio_ptr,
189
- RUN_ON_CPU_HOST_PTR(invalidate_data));
190
-}
191
-
192
void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name)
193
{
65
{
194
memory_region_ref(root);
66
trace_qemu_anon_ram_free(ptr, size);
195
--
67
--
196
2.18.0
68
2.25.1
197
69
198
70
diff view generated by jsdifflib
1
Create a new include file for the pl081's device struct,
1
Move the various memalign-related functions out of osdep.h and into
2
type macros, etc, so that it can be instantiated using
2
their own header, which we include only where they are used.
3
the "embedded struct" coding style.
3
While we're doing this, add some brief documentation comments.
4
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20220226180723.1706285-10-peter.maydell@linaro.org
7
---
9
---
8
include/hw/dma/pl080.h | 62 ++++++++++++++++++++++++++++++++++++++++++
10
include/qemu/memalign.h | 61 ++++++++++++++++++++++++++++++++++
9
hw/dma/pl080.c | 34 ++---------------------
11
include/qemu/osdep.h | 18 ----------
10
MAINTAINERS | 1 +
12
block/blkverify.c | 1 +
11
3 files changed, 65 insertions(+), 32 deletions(-)
13
block/block-copy.c | 1 +
12
create mode 100644 include/hw/dma/pl080.h
14
block/commit.c | 1 +
15
block/crypto.c | 1 +
16
block/dmg.c | 1 +
17
block/export/fuse.c | 1 +
18
block/file-posix.c | 1 +
19
block/io.c | 1 +
20
block/mirror.c | 1 +
21
block/nvme.c | 1 +
22
block/parallels-ext.c | 1 +
23
block/parallels.c | 1 +
24
block/qcow.c | 1 +
25
block/qcow2-cache.c | 1 +
26
block/qcow2-cluster.c | 1 +
27
block/qcow2-refcount.c | 1 +
28
block/qcow2-snapshot.c | 1 +
29
block/qcow2.c | 1 +
30
block/qed-l2-cache.c | 1 +
31
block/qed-table.c | 1 +
32
block/qed.c | 1 +
33
block/quorum.c | 1 +
34
block/raw-format.c | 1 +
35
block/vdi.c | 1 +
36
block/vhdx-log.c | 1 +
37
block/vhdx.c | 1 +
38
block/vmdk.c | 1 +
39
block/vpc.c | 1 +
40
block/win32-aio.c | 1 +
41
hw/block/dataplane/xen-block.c | 1 +
42
hw/block/fdc.c | 1 +
43
hw/ide/core.c | 1 +
44
hw/ppc/spapr.c | 1 +
45
hw/ppc/spapr_softmmu.c | 1 +
46
hw/scsi/scsi-disk.c | 1 +
47
hw/tpm/tpm_ppi.c | 2 +-
48
nbd/server.c | 1 +
49
net/l2tpv3.c | 2 +-
50
plugins/loader.c | 1 +
51
qemu-img.c | 1 +
52
qemu-io-cmds.c | 1 +
53
qom/object.c | 1 +
54
softmmu/physmem.c | 1 +
55
target/i386/hvf/hvf.c | 1 +
56
target/i386/kvm/kvm.c | 1 +
57
tcg/region.c | 1 +
58
tests/bench/atomic_add-bench.c | 1 +
59
tests/bench/qht-bench.c | 1 +
60
util/atomic64.c | 1 +
61
util/memalign.c | 1 +
62
util/qht.c | 1 +
63
53 files changed, 112 insertions(+), 20 deletions(-)
64
create mode 100644 include/qemu/memalign.h
13
65
14
diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h
66
diff --git a/include/qemu/memalign.h b/include/qemu/memalign.h
15
new file mode 100644
67
new file mode 100644
16
index XXXXXXX..XXXXXXX
68
index XXXXXXX..XXXXXXX
17
--- /dev/null
69
--- /dev/null
18
+++ b/include/hw/dma/pl080.h
70
+++ b/include/qemu/memalign.h
19
@@ -XXX,XX +XXX,XX @@
71
@@ -XXX,XX +XXX,XX @@
20
+/*
72
+/*
21
+ * ARM PrimeCell PL080/PL081 DMA controller
73
+ * Allocation and free functions for aligned memory
22
+ *
74
+ *
23
+ * Copyright (c) 2006 CodeSourcery.
75
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
24
+ * Copyright (c) 2018 Linaro Limited
76
+ * See the COPYING file in the top-level directory.
25
+ * Written by Paul Brook, Peter Maydell
26
+ *
27
+ * This program is free software; you can redistribute it and/or modify
28
+ * it under the terms of the GNU General Public License version 2 or
29
+ * (at your option) any later version.
30
+ */
77
+ */
31
+
78
+
32
+/* This is a model of the Arm PrimeCell PL080/PL081 DMA controller:
79
+#ifndef QEMU_MEMALIGN_H
33
+ * The PL080 TRM is:
80
+#define QEMU_MEMALIGN_H
34
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0196g/DDI0196.pdf
81
+
35
+ * and the PL081 TRM is:
82
+/**
36
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0218e/DDI0218.pdf
83
+ * qemu_try_memalign: Allocate aligned memory
84
+ * @alignment: required alignment, in bytes
85
+ * @size: size of allocation, in bytes
37
+ *
86
+ *
38
+ * QEMU interface:
87
+ * Allocate memory on an aligned boundary (i.e. the returned
39
+ * + sysbus IRQ: DMACINTR combined interrupt line
88
+ * address will be an exact multiple of @alignment).
40
+ * + sysbus MMIO region 0: MemoryRegion for the device's registers
89
+ * @alignment must be a power of 2, or the function will assert().
90
+ * On success, returns allocated memory; on failure, returns NULL.
91
+ *
92
+ * The memory allocated through this function must be freed via
93
+ * qemu_vfree() (and not via free()).
41
+ */
94
+ */
95
+void *qemu_try_memalign(size_t alignment, size_t size);
96
+/**
97
+ * qemu_memalign: Allocate aligned memory, without failing
98
+ * @alignment: required alignment, in bytes
99
+ * @size: size of allocation, in bytes
100
+ *
101
+ * Allocate memory in the same way as qemu_try_memalign(), but
102
+ * abort() with an error message if the memory allocation fails.
103
+ *
104
+ * The memory allocated through this function must be freed via
105
+ * qemu_vfree() (and not via free()).
106
+ */
107
+void *qemu_memalign(size_t alignment, size_t size);
108
+/**
109
+ * qemu_vfree: Free memory allocated through qemu_memalign
110
+ * @ptr: memory to free
111
+ *
112
+ * This function must be used to free memory allocated via qemu_memalign()
113
+ * or qemu_try_memalign(). (Using the wrong free function will cause
114
+ * subtle bugs on Windows hosts.)
115
+ */
116
+void qemu_vfree(void *ptr);
117
+/*
118
+ * It's an analog of GLIB's g_autoptr_cleanup_generic_gfree(), used to define
119
+ * g_autofree macro.
120
+ */
121
+static inline void qemu_cleanup_generic_vfree(void *p)
122
+{
123
+ void **pp = (void **)p;
124
+ qemu_vfree(*pp);
125
+}
42
+
126
+
43
+#ifndef HW_DMA_PL080_H
127
+/*
44
+#define HW_DMA_PL080_H
128
+ * Analog of g_autofree, but qemu_vfree is called on cleanup instead of g_free.
45
+
129
+ */
46
+#include "hw/sysbus.h"
130
+#define QEMU_AUTO_VFREE __attribute__((cleanup(qemu_cleanup_generic_vfree)))
47
+
48
+#define PL080_MAX_CHANNELS 8
49
+
50
+typedef struct {
51
+ uint32_t src;
52
+ uint32_t dest;
53
+ uint32_t lli;
54
+ uint32_t ctrl;
55
+ uint32_t conf;
56
+} pl080_channel;
57
+
58
+#define TYPE_PL080 "pl080"
59
+#define TYPE_PL081 "pl081"
60
+#define PL080(obj) OBJECT_CHECK(PL080State, (obj), TYPE_PL080)
61
+
62
+typedef struct PL080State {
63
+ SysBusDevice parent_obj;
64
+
65
+ MemoryRegion iomem;
66
+ uint8_t tc_int;
67
+ uint8_t tc_mask;
68
+ uint8_t err_int;
69
+ uint8_t err_mask;
70
+ uint32_t conf;
71
+ uint32_t sync;
72
+ uint32_t req_single;
73
+ uint32_t req_burst;
74
+ pl080_channel chan[PL080_MAX_CHANNELS];
75
+ int nchannels;
76
+ /* Flag to avoid recursive DMA invocations. */
77
+ int running;
78
+ qemu_irq irq;
79
+} PL080State;
80
+
131
+
81
+#endif
132
+#endif
82
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
133
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
83
index XXXXXXX..XXXXXXX 100644
134
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/dma/pl080.c
135
--- a/include/qemu/osdep.h
85
+++ b/hw/dma/pl080.c
136
+++ b/include/qemu/osdep.h
86
@@ -XXX,XX +XXX,XX @@
137
@@ -XXX,XX +XXX,XX @@ extern "C" {
87
#include "hw/sysbus.h"
138
#endif
88
#include "exec/address-spaces.h"
139
89
#include "qemu/log.h"
140
int qemu_daemon(int nochdir, int noclose);
90
+#include "hw/dma/pl080.h"
141
-void *qemu_try_memalign(size_t alignment, size_t size);
91
142
-void *qemu_memalign(size_t alignment, size_t size);
92
-#define PL080_MAX_CHANNELS 8
143
void *qemu_anon_ram_alloc(size_t size, uint64_t *align, bool shared,
93
#define PL080_CONF_E 0x1
144
bool noreserve);
94
#define PL080_CONF_M1 0x2
145
-void qemu_vfree(void *ptr);
95
#define PL080_CONF_M2 0x4
146
void qemu_anon_ram_free(void *ptr, size_t size);
96
@@ -XXX,XX +XXX,XX @@
147
97
#define PL080_CCTRL_D 0x02000000
148
-/*
98
#define PL080_CCTRL_S 0x01000000
149
- * It's an analog of GLIB's g_autoptr_cleanup_generic_gfree(), used to define
99
150
- * g_autofree macro.
100
-typedef struct {
151
- */
101
- uint32_t src;
152
-static inline void qemu_cleanup_generic_vfree(void *p)
102
- uint32_t dest;
153
-{
103
- uint32_t lli;
154
- void **pp = (void **)p;
104
- uint32_t ctrl;
155
- qemu_vfree(*pp);
105
- uint32_t conf;
156
-}
106
-} pl080_channel;
107
-
157
-
108
-#define TYPE_PL080 "pl080"
158
-/*
109
-#define PL080(obj) OBJECT_CHECK(PL080State, (obj), TYPE_PL080)
159
- * Analog of g_autofree, but qemu_vfree is called on cleanup instead of g_free.
160
- */
161
-#define QEMU_AUTO_VFREE __attribute__((cleanup(qemu_cleanup_generic_vfree)))
110
-
162
-
111
-typedef struct PL080State {
163
#ifdef _WIN32
112
- SysBusDevice parent_obj;
164
#define HAVE_CHARDEV_SERIAL 1
165
#elif defined(__linux__) || defined(__sun__) || defined(__FreeBSD__) \
166
diff --git a/block/blkverify.c b/block/blkverify.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/block/blkverify.c
169
+++ b/block/blkverify.c
170
@@ -XXX,XX +XXX,XX @@
171
#include "qemu/cutils.h"
172
#include "qemu/module.h"
173
#include "qemu/option.h"
174
+#include "qemu/memalign.h"
175
176
typedef struct {
177
BdrvChild *test_file;
178
diff --git a/block/block-copy.c b/block/block-copy.c
179
index XXXXXXX..XXXXXXX 100644
180
--- a/block/block-copy.c
181
+++ b/block/block-copy.c
182
@@ -XXX,XX +XXX,XX @@
183
#include "qemu/coroutine.h"
184
#include "block/aio_task.h"
185
#include "qemu/error-report.h"
186
+#include "qemu/memalign.h"
187
188
#define BLOCK_COPY_MAX_COPY_RANGE (16 * MiB)
189
#define BLOCK_COPY_MAX_BUFFER (1 * MiB)
190
diff --git a/block/commit.c b/block/commit.c
191
index XXXXXXX..XXXXXXX 100644
192
--- a/block/commit.c
193
+++ b/block/commit.c
194
@@ -XXX,XX +XXX,XX @@
195
#include "qapi/error.h"
196
#include "qapi/qmp/qerror.h"
197
#include "qemu/ratelimit.h"
198
+#include "qemu/memalign.h"
199
#include "sysemu/block-backend.h"
200
201
enum {
202
diff --git a/block/crypto.c b/block/crypto.c
203
index XXXXXXX..XXXXXXX 100644
204
--- a/block/crypto.c
205
+++ b/block/crypto.c
206
@@ -XXX,XX +XXX,XX @@
207
#include "qemu/module.h"
208
#include "qemu/option.h"
209
#include "qemu/cutils.h"
210
+#include "qemu/memalign.h"
211
#include "crypto.h"
212
213
typedef struct BlockCrypto BlockCrypto;
214
diff --git a/block/dmg.c b/block/dmg.c
215
index XXXXXXX..XXXXXXX 100644
216
--- a/block/dmg.c
217
+++ b/block/dmg.c
218
@@ -XXX,XX +XXX,XX @@
219
#include "qemu/bswap.h"
220
#include "qemu/error-report.h"
221
#include "qemu/module.h"
222
+#include "qemu/memalign.h"
223
#include "dmg.h"
224
225
int (*dmg_uncompress_bz2)(char *next_in, unsigned int avail_in,
226
diff --git a/block/export/fuse.c b/block/export/fuse.c
227
index XXXXXXX..XXXXXXX 100644
228
--- a/block/export/fuse.c
229
+++ b/block/export/fuse.c
230
@@ -XXX,XX +XXX,XX @@
231
#define FUSE_USE_VERSION 31
232
233
#include "qemu/osdep.h"
234
+#include "qemu/memalign.h"
235
#include "block/aio.h"
236
#include "block/block.h"
237
#include "block/export.h"
238
diff --git a/block/file-posix.c b/block/file-posix.c
239
index XXXXXXX..XXXXXXX 100644
240
--- a/block/file-posix.c
241
+++ b/block/file-posix.c
242
@@ -XXX,XX +XXX,XX @@
243
#include "qemu/module.h"
244
#include "qemu/option.h"
245
#include "qemu/units.h"
246
+#include "qemu/memalign.h"
247
#include "trace.h"
248
#include "block/thread-pool.h"
249
#include "qemu/iov.h"
250
diff --git a/block/io.c b/block/io.c
251
index XXXXXXX..XXXXXXX 100644
252
--- a/block/io.c
253
+++ b/block/io.c
254
@@ -XXX,XX +XXX,XX @@
255
#include "block/coroutines.h"
256
#include "block/write-threshold.h"
257
#include "qemu/cutils.h"
258
+#include "qemu/memalign.h"
259
#include "qapi/error.h"
260
#include "qemu/error-report.h"
261
#include "qemu/main-loop.h"
262
diff --git a/block/mirror.c b/block/mirror.c
263
index XXXXXXX..XXXXXXX 100644
264
--- a/block/mirror.c
265
+++ b/block/mirror.c
266
@@ -XXX,XX +XXX,XX @@
267
#include "qapi/qmp/qerror.h"
268
#include "qemu/ratelimit.h"
269
#include "qemu/bitmap.h"
270
+#include "qemu/memalign.h"
271
272
#define MAX_IN_FLIGHT 16
273
#define MAX_IO_BYTES (1 << 20) /* 1 Mb */
274
diff --git a/block/nvme.c b/block/nvme.c
275
index XXXXXXX..XXXXXXX 100644
276
--- a/block/nvme.c
277
+++ b/block/nvme.c
278
@@ -XXX,XX +XXX,XX @@
279
#include "qemu/module.h"
280
#include "qemu/cutils.h"
281
#include "qemu/option.h"
282
+#include "qemu/memalign.h"
283
#include "qemu/vfio-helpers.h"
284
#include "block/block_int.h"
285
#include "sysemu/replay.h"
286
diff --git a/block/parallels-ext.c b/block/parallels-ext.c
287
index XXXXXXX..XXXXXXX 100644
288
--- a/block/parallels-ext.c
289
+++ b/block/parallels-ext.c
290
@@ -XXX,XX +XXX,XX @@
291
#include "parallels.h"
292
#include "crypto/hash.h"
293
#include "qemu/uuid.h"
294
+#include "qemu/memalign.h"
295
296
#define PARALLELS_FORMAT_EXTENSION_MAGIC 0xAB234CEF23DCEA87ULL
297
298
diff --git a/block/parallels.c b/block/parallels.c
299
index XXXXXXX..XXXXXXX 100644
300
--- a/block/parallels.c
301
+++ b/block/parallels.c
302
@@ -XXX,XX +XXX,XX @@
303
#include "qapi/qapi-visit-block-core.h"
304
#include "qemu/bswap.h"
305
#include "qemu/bitmap.h"
306
+#include "qemu/memalign.h"
307
#include "migration/blocker.h"
308
#include "parallels.h"
309
310
diff --git a/block/qcow.c b/block/qcow.c
311
index XXXXXXX..XXXXXXX 100644
312
--- a/block/qcow.c
313
+++ b/block/qcow.c
314
@@ -XXX,XX +XXX,XX @@
315
#include "qemu/option.h"
316
#include "qemu/bswap.h"
317
#include "qemu/cutils.h"
318
+#include "qemu/memalign.h"
319
#include <zlib.h>
320
#include "qapi/qmp/qdict.h"
321
#include "qapi/qmp/qstring.h"
322
diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
323
index XXXXXXX..XXXXXXX 100644
324
--- a/block/qcow2-cache.c
325
+++ b/block/qcow2-cache.c
326
@@ -XXX,XX +XXX,XX @@
327
*/
328
329
#include "qemu/osdep.h"
330
+#include "qemu/memalign.h"
331
#include "qcow2.h"
332
#include "trace.h"
333
334
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
335
index XXXXXXX..XXXXXXX 100644
336
--- a/block/qcow2-cluster.c
337
+++ b/block/qcow2-cluster.c
338
@@ -XXX,XX +XXX,XX @@
339
#include "qapi/error.h"
340
#include "qcow2.h"
341
#include "qemu/bswap.h"
342
+#include "qemu/memalign.h"
343
#include "trace.h"
344
345
int qcow2_shrink_l1_table(BlockDriverState *bs, uint64_t exact_size)
346
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
347
index XXXXXXX..XXXXXXX 100644
348
--- a/block/qcow2-refcount.c
349
+++ b/block/qcow2-refcount.c
350
@@ -XXX,XX +XXX,XX @@
351
#include "qemu/range.h"
352
#include "qemu/bswap.h"
353
#include "qemu/cutils.h"
354
+#include "qemu/memalign.h"
355
#include "trace.h"
356
357
static int64_t alloc_clusters_noref(BlockDriverState *bs, uint64_t size,
358
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
359
index XXXXXXX..XXXXXXX 100644
360
--- a/block/qcow2-snapshot.c
361
+++ b/block/qcow2-snapshot.c
362
@@ -XXX,XX +XXX,XX @@
363
#include "qemu/bswap.h"
364
#include "qemu/error-report.h"
365
#include "qemu/cutils.h"
366
+#include "qemu/memalign.h"
367
368
static void qcow2_free_single_snapshot(BlockDriverState *bs, int i)
369
{
370
diff --git a/block/qcow2.c b/block/qcow2.c
371
index XXXXXXX..XXXXXXX 100644
372
--- a/block/qcow2.c
373
+++ b/block/qcow2.c
374
@@ -XXX,XX +XXX,XX @@
375
#include "qemu/option_int.h"
376
#include "qemu/cutils.h"
377
#include "qemu/bswap.h"
378
+#include "qemu/memalign.h"
379
#include "qapi/qobject-input-visitor.h"
380
#include "qapi/qapi-visit-block-core.h"
381
#include "crypto.h"
382
diff --git a/block/qed-l2-cache.c b/block/qed-l2-cache.c
383
index XXXXXXX..XXXXXXX 100644
384
--- a/block/qed-l2-cache.c
385
+++ b/block/qed-l2-cache.c
386
@@ -XXX,XX +XXX,XX @@
387
*/
388
389
#include "qemu/osdep.h"
390
+#include "qemu/memalign.h"
391
#include "trace.h"
392
#include "qed.h"
393
394
diff --git a/block/qed-table.c b/block/qed-table.c
395
index XXXXXXX..XXXXXXX 100644
396
--- a/block/qed-table.c
397
+++ b/block/qed-table.c
398
@@ -XXX,XX +XXX,XX @@
399
#include "qemu/sockets.h" /* for EINPROGRESS on Windows */
400
#include "qed.h"
401
#include "qemu/bswap.h"
402
+#include "qemu/memalign.h"
403
404
/* Called with table_lock held. */
405
static int coroutine_fn qed_read_table(BDRVQEDState *s, uint64_t offset,
406
diff --git a/block/qed.c b/block/qed.c
407
index XXXXXXX..XXXXXXX 100644
408
--- a/block/qed.c
409
+++ b/block/qed.c
410
@@ -XXX,XX +XXX,XX @@
411
#include "qemu/main-loop.h"
412
#include "qemu/module.h"
413
#include "qemu/option.h"
414
+#include "qemu/memalign.h"
415
#include "trace.h"
416
#include "qed.h"
417
#include "sysemu/block-backend.h"
418
diff --git a/block/quorum.c b/block/quorum.c
419
index XXXXXXX..XXXXXXX 100644
420
--- a/block/quorum.c
421
+++ b/block/quorum.c
422
@@ -XXX,XX +XXX,XX @@
423
#include "qemu/cutils.h"
424
#include "qemu/module.h"
425
#include "qemu/option.h"
426
+#include "qemu/memalign.h"
427
#include "block/block_int.h"
428
#include "block/coroutines.h"
429
#include "block/qdict.h"
430
diff --git a/block/raw-format.c b/block/raw-format.c
431
index XXXXXXX..XXXXXXX 100644
432
--- a/block/raw-format.c
433
+++ b/block/raw-format.c
434
@@ -XXX,XX +XXX,XX @@
435
#include "qapi/error.h"
436
#include "qemu/module.h"
437
#include "qemu/option.h"
438
+#include "qemu/memalign.h"
439
440
typedef struct BDRVRawState {
441
uint64_t offset;
442
diff --git a/block/vdi.c b/block/vdi.c
443
index XXXXXXX..XXXXXXX 100644
444
--- a/block/vdi.c
445
+++ b/block/vdi.c
446
@@ -XXX,XX +XXX,XX @@
447
#include "qemu/coroutine.h"
448
#include "qemu/cutils.h"
449
#include "qemu/uuid.h"
450
+#include "qemu/memalign.h"
451
452
/* Code configuration options. */
453
454
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
455
index XXXXXXX..XXXXXXX 100644
456
--- a/block/vhdx-log.c
457
+++ b/block/vhdx-log.c
458
@@ -XXX,XX +XXX,XX @@
459
#include "block/block_int.h"
460
#include "qemu/error-report.h"
461
#include "qemu/bswap.h"
462
+#include "qemu/memalign.h"
463
#include "vhdx.h"
464
465
466
diff --git a/block/vhdx.c b/block/vhdx.c
467
index XXXXXXX..XXXXXXX 100644
468
--- a/block/vhdx.c
469
+++ b/block/vhdx.c
470
@@ -XXX,XX +XXX,XX @@
471
#include "qemu/crc32c.h"
472
#include "qemu/bswap.h"
473
#include "qemu/error-report.h"
474
+#include "qemu/memalign.h"
475
#include "vhdx.h"
476
#include "migration/blocker.h"
477
#include "qemu/uuid.h"
478
diff --git a/block/vmdk.c b/block/vmdk.c
479
index XXXXXXX..XXXXXXX 100644
480
--- a/block/vmdk.c
481
+++ b/block/vmdk.c
482
@@ -XXX,XX +XXX,XX @@
483
#include "qemu/module.h"
484
#include "qemu/option.h"
485
#include "qemu/bswap.h"
486
+#include "qemu/memalign.h"
487
#include "migration/blocker.h"
488
#include "qemu/cutils.h"
489
#include <zlib.h>
490
diff --git a/block/vpc.c b/block/vpc.c
491
index XXXXXXX..XXXXXXX 100644
492
--- a/block/vpc.c
493
+++ b/block/vpc.c
494
@@ -XXX,XX +XXX,XX @@
495
#include "migration/blocker.h"
496
#include "qemu/bswap.h"
497
#include "qemu/uuid.h"
498
+#include "qemu/memalign.h"
499
#include "qapi/qmp/qdict.h"
500
#include "qapi/qobject-input-visitor.h"
501
#include "qapi/qapi-visit-block-core.h"
502
diff --git a/block/win32-aio.c b/block/win32-aio.c
503
index XXXXXXX..XXXXXXX 100644
504
--- a/block/win32-aio.c
505
+++ b/block/win32-aio.c
506
@@ -XXX,XX +XXX,XX @@
507
#include "block/raw-aio.h"
508
#include "qemu/event_notifier.h"
509
#include "qemu/iov.h"
510
+#include "qemu/memalign.h"
511
#include <windows.h>
512
#include <winioctl.h>
513
514
diff --git a/hw/block/dataplane/xen-block.c b/hw/block/dataplane/xen-block.c
515
index XXXXXXX..XXXXXXX 100644
516
--- a/hw/block/dataplane/xen-block.c
517
+++ b/hw/block/dataplane/xen-block.c
518
@@ -XXX,XX +XXX,XX @@
519
#include "qemu/osdep.h"
520
#include "qemu/error-report.h"
521
#include "qemu/main-loop.h"
522
+#include "qemu/memalign.h"
523
#include "qapi/error.h"
524
#include "hw/xen/xen_common.h"
525
#include "hw/block/xen_blkif.h"
526
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
527
index XXXXXXX..XXXXXXX 100644
528
--- a/hw/block/fdc.c
529
+++ b/hw/block/fdc.c
530
@@ -XXX,XX +XXX,XX @@
531
#include "qapi/error.h"
532
#include "qemu/error-report.h"
533
#include "qemu/timer.h"
534
+#include "qemu/memalign.h"
535
#include "hw/irq.h"
536
#include "hw/isa/isa.h"
537
#include "hw/qdev-properties.h"
538
diff --git a/hw/ide/core.c b/hw/ide/core.c
539
index XXXXXXX..XXXXXXX 100644
540
--- a/hw/ide/core.c
541
+++ b/hw/ide/core.c
542
@@ -XXX,XX +XXX,XX @@
543
#include "qemu/main-loop.h"
544
#include "qemu/timer.h"
545
#include "qemu/hw-version.h"
546
+#include "qemu/memalign.h"
547
#include "sysemu/sysemu.h"
548
#include "sysemu/blockdev.h"
549
#include "sysemu/dma.h"
550
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
551
index XXXXXXX..XXXXXXX 100644
552
--- a/hw/ppc/spapr.c
553
+++ b/hw/ppc/spapr.c
554
@@ -XXX,XX +XXX,XX @@
555
#include "qemu/osdep.h"
556
#include "qemu-common.h"
557
#include "qemu/datadir.h"
558
+#include "qemu/memalign.h"
559
#include "qapi/error.h"
560
#include "qapi/qapi-events-machine.h"
561
#include "qapi/qapi-events-qdev.h"
562
diff --git a/hw/ppc/spapr_softmmu.c b/hw/ppc/spapr_softmmu.c
563
index XXXXXXX..XXXXXXX 100644
564
--- a/hw/ppc/spapr_softmmu.c
565
+++ b/hw/ppc/spapr_softmmu.c
566
@@ -XXX,XX +XXX,XX @@
567
#include "qemu/osdep.h"
568
#include "qemu/cutils.h"
569
+#include "qemu/memalign.h"
570
#include "cpu.h"
571
#include "helper_regs.h"
572
#include "hw/ppc/spapr.h"
573
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
574
index XXXXXXX..XXXXXXX 100644
575
--- a/hw/scsi/scsi-disk.c
576
+++ b/hw/scsi/scsi-disk.c
577
@@ -XXX,XX +XXX,XX @@
578
#include "qemu/main-loop.h"
579
#include "qemu/module.h"
580
#include "qemu/hw-version.h"
581
+#include "qemu/memalign.h"
582
#include "hw/scsi/scsi.h"
583
#include "migration/qemu-file-types.h"
584
#include "migration/vmstate.h"
585
diff --git a/hw/tpm/tpm_ppi.c b/hw/tpm/tpm_ppi.c
586
index XXXXXXX..XXXXXXX 100644
587
--- a/hw/tpm/tpm_ppi.c
588
+++ b/hw/tpm/tpm_ppi.c
589
@@ -XXX,XX +XXX,XX @@
590
*/
591
592
#include "qemu/osdep.h"
113
-
593
-
114
- MemoryRegion iomem;
594
+#include "qemu/memalign.h"
115
- uint8_t tc_int;
595
#include "qapi/error.h"
116
- uint8_t tc_mask;
596
#include "sysemu/memory_mapping.h"
117
- uint8_t err_int;
597
#include "migration/vmstate.h"
118
- uint8_t err_mask;
598
diff --git a/nbd/server.c b/nbd/server.c
119
- uint32_t conf;
599
index XXXXXXX..XXXXXXX 100644
120
- uint32_t sync;
600
--- a/nbd/server.c
121
- uint32_t req_single;
601
+++ b/nbd/server.c
122
- uint32_t req_burst;
602
@@ -XXX,XX +XXX,XX @@
123
- pl080_channel chan[PL080_MAX_CHANNELS];
603
#include "trace.h"
124
- int nchannels;
604
#include "nbd-internal.h"
125
- /* Flag to avoid recursive DMA invocations. */
605
#include "qemu/units.h"
126
- int running;
606
+#include "qemu/memalign.h"
127
- qemu_irq irq;
607
128
-} PL080State;
608
#define NBD_META_ID_BASE_ALLOCATION 0
609
#define NBD_META_ID_ALLOCATION_DEPTH 1
610
diff --git a/net/l2tpv3.c b/net/l2tpv3.c
611
index XXXXXXX..XXXXXXX 100644
612
--- a/net/l2tpv3.c
613
+++ b/net/l2tpv3.c
614
@@ -XXX,XX +XXX,XX @@
615
#include "qemu/sockets.h"
616
#include "qemu/iov.h"
617
#include "qemu/main-loop.h"
129
-
618
-
130
static const VMStateDescription vmstate_pl080_channel = {
619
+#include "qemu/memalign.h"
131
.name = "pl080_channel",
620
132
.version_id = 1,
621
/* The buffer size needs to be investigated for optimum numbers and
133
@@ -XXX,XX +XXX,XX @@ static const TypeInfo pl080_info = {
622
* optimum means of paging in on different systems. This size is
134
};
623
diff --git a/plugins/loader.c b/plugins/loader.c
135
624
index XXXXXXX..XXXXXXX 100644
136
static const TypeInfo pl081_info = {
625
--- a/plugins/loader.c
137
- .name = "pl081",
626
+++ b/plugins/loader.c
138
+ .name = TYPE_PL081,
627
@@ -XXX,XX +XXX,XX @@
139
.parent = TYPE_PL080,
628
#include "qemu/cacheinfo.h"
140
.instance_init = pl081_init,
629
#include "qemu/xxhash.h"
141
};
630
#include "qemu/plugin.h"
142
diff --git a/MAINTAINERS b/MAINTAINERS
631
+#include "qemu/memalign.h"
143
index XXXXXXX..XXXXXXX 100644
632
#include "hw/core/cpu.h"
144
--- a/MAINTAINERS
633
#include "exec/exec-all.h"
145
+++ b/MAINTAINERS
634
#ifndef CONFIG_USER_ONLY
146
@@ -XXX,XX +XXX,XX @@ F: hw/char/pl011.c
635
diff --git a/qemu-img.c b/qemu-img.c
147
F: include/hw/char/pl011.h
636
index XXXXXXX..XXXXXXX 100644
148
F: hw/display/pl110*
637
--- a/qemu-img.c
149
F: hw/dma/pl080.c
638
+++ b/qemu-img.c
150
+F: include/hw/dma/pl080.h
639
@@ -XXX,XX +XXX,XX @@
151
F: hw/dma/pl330.c
640
#include "qemu/module.h"
152
F: hw/gpio/pl061.c
641
#include "qemu/sockets.h"
153
F: hw/input/pl050.c
642
#include "qemu/units.h"
643
+#include "qemu/memalign.h"
644
#include "qom/object_interfaces.h"
645
#include "sysemu/block-backend.h"
646
#include "block/block_int.h"
647
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
648
index XXXXXXX..XXXXXXX 100644
649
--- a/qemu-io-cmds.c
650
+++ b/qemu-io-cmds.c
651
@@ -XXX,XX +XXX,XX @@
652
#include "qemu/option.h"
653
#include "qemu/timer.h"
654
#include "qemu/cutils.h"
655
+#include "qemu/memalign.h"
656
657
#define CMD_NOFILE_OK 0x01
658
659
diff --git a/qom/object.c b/qom/object.c
660
index XXXXXXX..XXXXXXX 100644
661
--- a/qom/object.c
662
+++ b/qom/object.c
663
@@ -XXX,XX +XXX,XX @@
664
#include "qom/object.h"
665
#include "qom/object_interfaces.h"
666
#include "qemu/cutils.h"
667
+#include "qemu/memalign.h"
668
#include "qapi/visitor.h"
669
#include "qapi/string-input-visitor.h"
670
#include "qapi/string-output-visitor.h"
671
diff --git a/softmmu/physmem.c b/softmmu/physmem.c
672
index XXXXXXX..XXXXXXX 100644
673
--- a/softmmu/physmem.c
674
+++ b/softmmu/physmem.c
675
@@ -XXX,XX +XXX,XX @@
676
#include "qemu/config-file.h"
677
#include "qemu/error-report.h"
678
#include "qemu/qemu-print.h"
679
+#include "qemu/memalign.h"
680
#include "exec/memory.h"
681
#include "exec/ioport.h"
682
#include "sysemu/dma.h"
683
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
684
index XXXXXXX..XXXXXXX 100644
685
--- a/target/i386/hvf/hvf.c
686
+++ b/target/i386/hvf/hvf.c
687
@@ -XXX,XX +XXX,XX @@
688
#include "qemu/osdep.h"
689
#include "qemu-common.h"
690
#include "qemu/error-report.h"
691
+#include "qemu/memalign.h"
692
693
#include "sysemu/hvf.h"
694
#include "sysemu/hvf_int.h"
695
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
696
index XXXXXXX..XXXXXXX 100644
697
--- a/target/i386/kvm/kvm.c
698
+++ b/target/i386/kvm/kvm.c
699
@@ -XXX,XX +XXX,XX @@
700
#include "qemu/main-loop.h"
701
#include "qemu/config-file.h"
702
#include "qemu/error-report.h"
703
+#include "qemu/memalign.h"
704
#include "hw/i386/x86.h"
705
#include "hw/i386/apic.h"
706
#include "hw/i386/apic_internal.h"
707
diff --git a/tcg/region.c b/tcg/region.c
708
index XXXXXXX..XXXXXXX 100644
709
--- a/tcg/region.c
710
+++ b/tcg/region.c
711
@@ -XXX,XX +XXX,XX @@
712
#include "qemu/units.h"
713
#include "qemu/madvise.h"
714
#include "qemu/mprotect.h"
715
+#include "qemu/memalign.h"
716
#include "qemu/cacheinfo.h"
717
#include "qapi/error.h"
718
#include "exec/exec-all.h"
719
diff --git a/tests/bench/atomic_add-bench.c b/tests/bench/atomic_add-bench.c
720
index XXXXXXX..XXXXXXX 100644
721
--- a/tests/bench/atomic_add-bench.c
722
+++ b/tests/bench/atomic_add-bench.c
723
@@ -XXX,XX +XXX,XX @@
724
#include "qemu/thread.h"
725
#include "qemu/host-utils.h"
726
#include "qemu/processor.h"
727
+#include "qemu/memalign.h"
728
729
struct thread_info {
730
uint64_t r;
731
diff --git a/tests/bench/qht-bench.c b/tests/bench/qht-bench.c
732
index XXXXXXX..XXXXXXX 100644
733
--- a/tests/bench/qht-bench.c
734
+++ b/tests/bench/qht-bench.c
735
@@ -XXX,XX +XXX,XX @@
736
#include "qemu/qht.h"
737
#include "qemu/rcu.h"
738
#include "qemu/xxhash.h"
739
+#include "qemu/memalign.h"
740
741
struct thread_stats {
742
size_t rd;
743
diff --git a/util/atomic64.c b/util/atomic64.c
744
index XXXXXXX..XXXXXXX 100644
745
--- a/util/atomic64.c
746
+++ b/util/atomic64.c
747
@@ -XXX,XX +XXX,XX @@
748
#include "qemu/atomic.h"
749
#include "qemu/thread.h"
750
#include "qemu/cacheinfo.h"
751
+#include "qemu/memalign.h"
752
753
#ifdef CONFIG_ATOMIC64
754
#error This file must only be compiled if !CONFIG_ATOMIC64
755
diff --git a/util/memalign.c b/util/memalign.c
756
index XXXXXXX..XXXXXXX 100644
757
--- a/util/memalign.c
758
+++ b/util/memalign.c
759
@@ -XXX,XX +XXX,XX @@
760
761
#include "qemu/osdep.h"
762
#include "qemu/host-utils.h"
763
+#include "qemu/memalign.h"
764
#include "trace.h"
765
766
void *qemu_try_memalign(size_t alignment, size_t size)
767
diff --git a/util/qht.c b/util/qht.c
768
index XXXXXXX..XXXXXXX 100644
769
--- a/util/qht.c
770
+++ b/util/qht.c
771
@@ -XXX,XX +XXX,XX @@
772
#include "qemu/qht.h"
773
#include "qemu/atomic.h"
774
#include "qemu/rcu.h"
775
+#include "qemu/memalign.h"
776
777
//#define QHT_DEBUG
778
154
--
779
--
155
2.18.0
780
2.25.1
156
781
157
782
diff view generated by jsdifflib
1
A bug in the handling of the register address decode logic
1
For VLD1/VST1 (single element to one lane) we are only accessing one
2
for the PL08x meant that we were incorrectly treating
2
register, and so the 'stride' is meaningless. The bits that would
3
accesses to the DMA channel registers (DMACCxSrcAddr,
3
specify stride (insn bit [4] for size=1, bit [6] for size=2) are
4
DMACCxDestaddr, DMACCxLLI, DMACCxControl, DMACCxConfiguration)
4
specified to be zero in the encoding (which would correspond to a
5
as bad offsets. Fix this long-standing bug.
5
stride of 1 for VLD2/VLD3/VLD4 etc), and we must UNDEF if they are
6
not.
6
7
7
Fixes: https://bugs.launchpad.net/qemu/+bug/1637974
8
We failed to make this check, which meant that we would incorrectly
9
handle some instruction patterns as loads or stores instead of
10
UNDEFing them. Enforce that stride == 1 for the nregs == 1 case.
11
12
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/890
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Tested-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20220303113741.2156877-2-peter.maydell@linaro.org
10
---
17
---
11
hw/dma/pl080.c | 5 +++--
18
target/arm/translate-neon.c | 3 +++
12
1 file changed, 3 insertions(+), 2 deletions(-)
19
1 file changed, 3 insertions(+)
13
20
14
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
21
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/dma/pl080.c
23
--- a/target/arm/translate-neon.c
17
+++ b/hw/dma/pl080.c
24
+++ b/target/arm/translate-neon.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t pl080_read(void *opaque, hwaddr offset,
25
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
19
i = (offset & 0xe0) >> 5;
26
/* Catch the UNDEF cases. This is unavoidably a bit messy. */
20
if (i >= s->nchannels)
27
switch (nregs) {
21
goto bad_offset;
28
case 1:
22
- switch (offset >> 2) {
29
+ if (a->stride != 1) {
23
+ switch ((offset >> 2) & 7) {
30
+ return false;
24
case 0: /* SrcAddr */
31
+ }
25
return s->chan[i].src;
32
if (((a->align & (1 << a->size)) != 0) ||
26
case 1: /* DestAddr */
33
(a->size == 2 && (a->align == 1 || a->align == 2))) {
27
@@ -XXX,XX +XXX,XX @@ static void pl080_write(void *opaque, hwaddr offset,
34
return false;
28
i = (offset & 0xe0) >> 5;
29
if (i >= s->nchannels)
30
goto bad_offset;
31
- switch (offset >> 2) {
32
+ switch ((offset >> 2) & 7) {
33
case 0: /* SrcAddr */
34
s->chan[i].src = value;
35
break;
36
@@ -XXX,XX +XXX,XX @@ static void pl080_write(void *opaque, hwaddr offset,
37
pl080_run(s);
38
break;
39
}
40
+ return;
41
}
42
switch (offset >> 2) {
43
case 2: /* IntTCClear */
44
--
35
--
45
2.18.0
36
2.25.1
46
47
diff view generated by jsdifflib
1
The MSR (banked) and MRS (banked) instructions allow accesses to ELR_Hyp
1
For VLD3 (single 3-element structure to one lane), there is no
2
from either Monitor or Hyp mode. Our translate time check
2
alignment specification and the alignment bits in the instruction
3
was overly strict and only permitted access from Monitor mode.
3
must be zero. This is bit [4] for the size=0 and size=1 cases, and
4
4
bits [5:4] for the size=2 case. We do this check correctly in
5
The runtime check we do in msr_mrs_banked_exc_checks() had the
5
VLDST_single(), but we write it a bit oddly: in the 'case 3' code we
6
correct code in it, but never got there because of the earlier
6
check for bit 0 of a->align (bit [4] of the insn), and then we fall
7
"currmode == tgtmode" check. Special case ELR_Hyp.
7
through to the 'case 2' code which checks bit 1 of a->align (bit [5]
8
of the insn) in the size 2 case. Replace this with just checking "is
9
a->align non-zero" for VLD3, which lets us drop the fall-through and
10
put the cases in this switch in numerical order.
8
11
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
14
Tested-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20180814124254.5229-9-peter.maydell@linaro.org
15
Message-id: 20220303113741.2156877-3-peter.maydell@linaro.org
13
---
16
---
14
target/arm/op_helper.c | 22 +++++++++++-----------
17
target/arm/translate-neon.c | 10 +++++-----
15
target/arm/translate.c | 10 +++++++---
18
1 file changed, 5 insertions(+), 5 deletions(-)
16
2 files changed, 18 insertions(+), 14 deletions(-)
17
19
18
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
20
diff --git a/target/arm/translate-neon.c b/target/arm/translate-neon.c
19
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/op_helper.c
22
--- a/target/arm/translate-neon.c
21
+++ b/target/arm/op_helper.c
23
+++ b/target/arm/translate-neon.c
22
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
24
@@ -XXX,XX +XXX,XX @@ static bool trans_VLDST_single(DisasContext *s, arg_VLDST_single *a)
23
*/
25
return false;
24
int curmode = env->uncached_cpsr & CPSR_M;
25
26
+ if (regno == 17) {
27
+ /* ELR_Hyp: a special case because access from tgtmode is OK */
28
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
29
+ goto undef;
30
+ }
31
+ return;
32
+ }
33
+
34
if (curmode == tgtmode) {
35
goto undef;
36
}
37
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
38
}
39
40
if (tgtmode == ARM_CPU_MODE_HYP) {
41
- switch (regno) {
42
- case 17: /* ELR_Hyp */
43
- if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
44
- goto undef;
45
- }
46
- break;
47
- default:
48
- if (curmode != ARM_CPU_MODE_MON) {
49
- goto undef;
50
- }
51
- break;
52
+ /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
53
+ if (curmode != ARM_CPU_MODE_MON) {
54
+ goto undef;
55
}
56
}
57
58
diff --git a/target/arm/translate.c b/target/arm/translate.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/arm/translate.c
61
+++ b/target/arm/translate.c
62
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
63
}
26
}
64
break;
27
break;
65
case ARM_CPU_MODE_HYP:
28
- case 3:
66
- /* Note that we can forbid accesses from EL2 here because they
29
- if ((a->align & 1) != 0) {
67
- * must be from Hyp mode itself
30
- return false;
68
+ /*
31
- }
69
+ * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
32
- /* fall through */
70
+ * (and so we can forbid accesses from EL2 or below). elr_hyp
33
case 2:
71
+ * can be accessed also from Hyp mode, so forbid accesses from
34
if (a->size == 2 && (a->align & 2) != 0) {
72
+ * EL0 or EL1.
35
return false;
73
*/
74
- if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
75
+ if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
76
+ (s->current_el < 3 && *regno != 17)) {
77
goto undef;
78
}
36
}
79
break;
37
break;
38
+ case 3:
39
+ if (a->align != 0) {
40
+ return false;
41
+ }
42
+ break;
43
case 4:
44
if (a->size == 2 && a->align == 3) {
45
return false;
80
--
46
--
81
2.18.0
47
2.25.1
82
83
diff view generated by jsdifflib
1
On real v7M hardware, the NMI line is an externally visible signal
1
When debugging code that's using the ITS, it's helpful to
2
that an SoC or board can toggle to assert an NMI. Expose it in
2
see tracing of the ITS commands that the guest executes. Add
3
our QEMU NVIC and armv7m container objects so that a board model
3
suitable trace events.
4
can wire it up if it needs to.
5
6
In particular, the MPS2 watchdog is wired to NMI.
7
4
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20220303202341.2232284-2-peter.maydell@linaro.org
10
---
8
---
11
hw/arm/armv7m.c | 1 +
9
hw/intc/arm_gicv3_its.c | 28 ++++++++++++++++++++++++++--
12
hw/intc/armv7m_nvic.c | 19 +++++++++++++++++++
10
hw/intc/trace-events | 12 ++++++++++++
13
hw/intc/trace-events | 1 +
11
2 files changed, 38 insertions(+), 2 deletions(-)
14
3 files changed, 21 insertions(+)
15
12
16
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
13
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/armv7m.c
15
--- a/hw/intc/arm_gicv3_its.c
19
+++ b/hw/arm/armv7m.c
16
+++ b/hw/intc/arm_gicv3_its.c
20
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
17
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_its_cmd(GICv3ITSState *s, const uint64_t *cmdpkt,
21
*/
18
22
qdev_pass_gpios(DEVICE(&s->nvic), dev, NULL);
19
devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT;
23
qdev_pass_gpios(DEVICE(&s->nvic), dev, "SYSRESETREQ");
20
eventid = cmdpkt[1] & EVENTID_MASK;
24
+ qdev_pass_gpios(DEVICE(&s->nvic), dev, "NMI");
21
+ switch (cmd) {
25
22
+ case INTERRUPT:
26
/* Wire the NVIC up to the CPU */
23
+ trace_gicv3_its_cmd_int(devid, eventid);
27
sbd = SYS_BUS_DEVICE(&s->nvic);
24
+ break;
28
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
25
+ case CLEAR:
29
index XXXXXXX..XXXXXXX 100644
26
+ trace_gicv3_its_cmd_clear(devid, eventid);
30
--- a/hw/intc/armv7m_nvic.c
27
+ break;
31
+++ b/hw/intc/armv7m_nvic.c
28
+ case DISCARD:
32
@@ -XXX,XX +XXX,XX @@ static void set_irq_level(void *opaque, int n, int level)
29
+ trace_gicv3_its_cmd_discard(devid, eventid);
30
+ break;
31
+ default:
32
+ g_assert_not_reached();
33
+ }
34
return do_process_its_cmd(s, devid, eventid, cmd);
35
}
36
37
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapti(GICv3ITSState *s, const uint64_t *cmdpkt,
38
39
devid = (cmdpkt[0] & DEVID_MASK) >> DEVID_SHIFT;
40
eventid = cmdpkt[1] & EVENTID_MASK;
41
+ icid = cmdpkt[2] & ICID_MASK;
42
43
if (ignore_pInt) {
44
pIntid = eventid;
45
+ trace_gicv3_its_cmd_mapi(devid, eventid, icid);
46
} else {
47
pIntid = (cmdpkt[1] & pINTID_MASK) >> pINTID_SHIFT;
48
+ trace_gicv3_its_cmd_mapti(devid, eventid, icid, pIntid);
33
}
49
}
34
}
50
35
51
- icid = cmdpkt[2] & ICID_MASK;
36
+/* callback when external NMI line is changed */
52
-
37
+static void nvic_nmi_trigger(void *opaque, int n, int level)
53
if (devid >= s->dt.num_entries) {
38
+{
54
qemu_log_mask(LOG_GUEST_ERROR,
39
+ NVICState *s = opaque;
55
"%s: invalid command attributes: devid %d>=%d",
56
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapc(GICv3ITSState *s, const uint64_t *cmdpkt)
57
} else {
58
cte.rdbase = 0;
59
}
60
+ trace_gicv3_its_cmd_mapc(icid, cte.rdbase, cte.valid);
61
62
if (icid >= s->ct.num_entries) {
63
qemu_log_mask(LOG_GUEST_ERROR, "ITS MAPC: invalid ICID 0x%d", icid);
64
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_mapd(GICv3ITSState *s, const uint64_t *cmdpkt)
65
dte.ittaddr = (cmdpkt[2] & ITTADDR_MASK) >> ITTADDR_SHIFT;
66
dte.valid = cmdpkt[2] & CMD_FIELD_VALID_MASK;
67
68
+ trace_gicv3_its_cmd_mapd(devid, dte.size, dte.ittaddr, dte.valid);
40
+
69
+
41
+ trace_nvic_set_nmi_level(level);
70
if (devid >= s->dt.num_entries) {
71
qemu_log_mask(LOG_GUEST_ERROR,
72
"ITS MAPD: invalid device ID field 0x%x >= 0x%x\n",
73
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_movall(GICv3ITSState *s, const uint64_t *cmdpkt)
74
rd1 = FIELD_EX64(cmdpkt[2], MOVALL_2, RDBASE1);
75
rd2 = FIELD_EX64(cmdpkt[3], MOVALL_3, RDBASE2);
76
77
+ trace_gicv3_its_cmd_movall(rd1, rd2);
42
+
78
+
43
+ /*
79
if (rd1 >= s->gicv3->num_cpu) {
44
+ * The architecture doesn't specify whether NMI should share
80
qemu_log_mask(LOG_GUEST_ERROR,
45
+ * the normal-interrupt behaviour of being resampled on
81
"%s: RDBASE1 %" PRId64
46
+ * exception handler return. We choose not to, so just
82
@@ -XXX,XX +XXX,XX @@ static ItsCmdResult process_movi(GICv3ITSState *s, const uint64_t *cmdpkt)
47
+ * set NMI pending here and don't track the current level.
83
eventid = FIELD_EX64(cmdpkt[1], MOVI_1, EVENTID);
48
+ */
84
new_icid = FIELD_EX64(cmdpkt[2], MOVI_2, ICID);
49
+ if (level) {
85
50
+ armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
86
+ trace_gicv3_its_cmd_movi(devid, eventid, new_icid);
51
+ }
52
+}
53
+
87
+
54
static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
88
if (devid >= s->dt.num_entries) {
55
{
89
qemu_log_mask(LOG_GUEST_ERROR,
56
ARMCPU *cpu = s->cpu;
90
"%s: invalid command attributes: devid %d>=%d",
57
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_instance_init(Object *obj)
91
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
58
qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1);
92
* is already consistent by the time SYNC command is executed.
59
qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger",
93
* Hence no further processing is required for SYNC command.
60
M_REG_NUM_BANKS);
94
*/
61
+ qdev_init_gpio_in_named(dev, nvic_nmi_trigger, "NMI", 1);
95
+ trace_gicv3_its_cmd_sync();
62
}
96
break;
63
97
case GITS_CMD_MAPD:
64
static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
98
result = process_mapd(s, cmdpkt);
99
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
100
* need to trigger lpi priority re-calculation to be in
101
* sync with LPI config table or pending table changes.
102
*/
103
+ trace_gicv3_its_cmd_inv();
104
for (i = 0; i < s->gicv3->num_cpu; i++) {
105
gicv3_redist_update_lpi(&s->gicv3->cpu[i]);
106
}
107
@@ -XXX,XX +XXX,XX @@ static void process_cmdq(GICv3ITSState *s)
108
result = process_movall(s, cmdpkt);
109
break;
110
default:
111
+ trace_gicv3_its_cmd_unknown(cmd);
112
break;
113
}
114
if (result == CMD_CONTINUE) {
65
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
115
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
66
index XXXXXXX..XXXXXXX 100644
116
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/intc/trace-events
117
--- a/hw/intc/trace-events
68
+++ b/hw/intc/trace-events
118
+++ b/hw/intc/trace-events
69
@@ -XXX,XX +XXX,XX @@ nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (pr
119
@@ -XXX,XX +XXX,XX @@ gicv3_its_write(uint64_t offset, uint64_t data, unsigned size) "GICv3 ITS write:
70
nvic_get_pending_irq_info(int irq, bool secure) "NVIC next IRQ %d: targets_secure: %d"
120
gicv3_its_badwrite(uint64_t offset, uint64_t data, unsigned size) "GICv3 ITS write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u: error"
71
nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)"
121
gicv3_its_translation_write(uint64_t offset, uint64_t data, unsigned size, uint32_t requester_id) "GICv3 ITS TRANSLATER write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u requester_id 0x%x"
72
nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to %d"
122
gicv3_its_process_command(uint32_t rd_offset, uint8_t cmd) "GICv3 ITS: processing command at offset 0x%x: 0x%x"
73
+nvic_set_nmi_level(int level) "NVIC external NMI level set to %d"
123
+gicv3_its_cmd_int(uint32_t devid, uint32_t eventid) "GICv3 ITS: command INT DeviceID 0x%x EventID 0x%x"
74
nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
124
+gicv3_its_cmd_clear(uint32_t devid, uint32_t eventid) "GICv3 ITS: command CLEAR DeviceID 0x%x EventID 0x%x"
75
nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
125
+gicv3_its_cmd_discard(uint32_t devid, uint32_t eventid) "GICv3 ITS: command DISCARD DeviceID 0x%x EventID 0x%x"
76
126
+gicv3_its_cmd_sync(void) "GICv3 ITS: command SYNC"
127
+gicv3_its_cmd_mapd(uint32_t devid, uint32_t size, uint64_t ittaddr, int valid) "GICv3 ITS: command MAPD DeviceID 0x%x Size 0x%x ITT_addr 0x%" PRIx64 " V %d"
128
+gicv3_its_cmd_mapc(uint32_t icid, uint64_t rdbase, int valid) "GICv3 ITS: command MAPC ICID 0x%x RDbase 0x%" PRIx64 " V %d"
129
+gicv3_its_cmd_mapi(uint32_t devid, uint32_t eventid, uint32_t icid) "GICv3 ITS: command MAPI DeviceID 0x%x EventID 0x%x ICID 0x%x"
130
+gicv3_its_cmd_mapti(uint32_t devid, uint32_t eventid, uint32_t icid, uint32_t intid) "GICv3 ITS: command MAPTI DeviceID 0x%x EventID 0x%x ICID 0x%x pINTID 0x%x"
131
+gicv3_its_cmd_inv(void) "GICv3 ITS: command INV or INVALL"
132
+gicv3_its_cmd_movall(uint64_t rd1, uint64_t rd2) "GICv3 ITS: command MOVALL RDbase1 0x%" PRIx64 " RDbase2 0x%" PRIx64
133
+gicv3_its_cmd_movi(uint32_t devid, uint32_t eventid, uint32_t icid) "GICv3 ITS: command MOVI DeviceID 0x%x EventID 0x%x ICID 0x%x"
134
+gicv3_its_cmd_unknown(unsigned cmd) "GICv3 ITS: unknown command 0x%x"
135
136
# armv7m_nvic.c
137
nvic_recompute_state(int vectpending, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_prio %d"
77
--
138
--
78
2.18.0
139
2.25.1
79
80
diff view generated by jsdifflib
1
We now support direct execution from MMIO regions in the
1
For debugging guest use of the ITS, it can be helpful to trace
2
core memory subsystem. This means that we don't need to
2
when the ITS reads and writes the in-memory tables.
3
have device-specific support for it, and we can remove
4
the request_ptr handling from the Xilinx SPIPS device.
5
(It was broken anyway due to race conditions, and disabled
6
by default.)
7
8
This device is the only in-tree user of this API.
9
3
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-id: 20220303202341.2232284-3-peter.maydell@linaro.org
13
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
14
Message-id: 20180817114619.22354-2-peter.maydell@linaro.org
15
---
7
---
16
hw/ssi/xilinx_spips.c | 46 -------------------------------------------
8
hw/intc/arm_gicv3_its.c | 37 +++++++++++++++++++++++++++++++------
17
1 file changed, 46 deletions(-)
9
hw/intc/trace-events | 9 +++++++++
10
2 files changed, 40 insertions(+), 6 deletions(-)
18
11
19
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
12
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/ssi/xilinx_spips.c
14
--- a/hw/intc/arm_gicv3_its.c
22
+++ b/hw/ssi/xilinx_spips.c
15
+++ b/hw/intc/arm_gicv3_its.c
23
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps spips_ops = {
16
@@ -XXX,XX +XXX,XX @@ static MemTxResult get_cte(GICv3ITSState *s, uint16_t icid, CTEntry *cte)
24
17
if (entry_addr == -1) {
25
static void xilinx_qspips_invalidate_mmio_ptr(XilinxQSPIPS *q)
18
/* No L2 table entry, i.e. no valid CTE, or a memory error */
26
{
19
cte->valid = false;
27
- XilinxSPIPS *s = &q->parent_obj;
20
- return res;
28
-
21
+ goto out;
29
- if ((q->mmio_execution_enabled) && (q->lqspi_cached_addr != ~0ULL)) {
22
}
30
- /* Invalidate the current mapped mmio */
23
31
- memory_region_invalidate_mmio_ptr(&s->mmlqspi, q->lqspi_cached_addr,
24
cteval = address_space_ldq_le(as, entry_addr, MEMTXATTRS_UNSPECIFIED, &res);
32
- LQSPI_CACHE_SIZE);
25
if (res != MEMTX_OK) {
33
- }
26
- return res;
34
-
27
+ goto out;
35
q->lqspi_cached_addr = ~0ULL;
28
}
29
cte->valid = FIELD_EX64(cteval, CTE, VALID);
30
cte->rdbase = FIELD_EX64(cteval, CTE, RDBASE);
31
- return MEMTX_OK;
32
+out:
33
+ if (res != MEMTX_OK) {
34
+ trace_gicv3_its_cte_read_fault(icid);
35
+ } else {
36
+ trace_gicv3_its_cte_read(icid, cte->valid, cte->rdbase);
37
+ }
38
+ return res;
36
}
39
}
37
40
38
@@ -XXX,XX +XXX,XX @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
41
/*
42
@@ -XXX,XX +XXX,XX @@ static bool update_ite(GICv3ITSState *s, uint32_t eventid, const DTEntry *dte,
43
uint64_t itel = 0;
44
uint32_t iteh = 0;
45
46
+ trace_gicv3_its_ite_write(dte->ittaddr, eventid, ite->valid,
47
+ ite->inttype, ite->intid, ite->icid,
48
+ ite->vpeid, ite->doorbell);
49
+
50
if (ite->valid) {
51
itel = FIELD_DP64(itel, ITE_L, VALID, 1);
52
itel = FIELD_DP64(itel, ITE_L, INTTYPE, ite->inttype);
53
@@ -XXX,XX +XXX,XX @@ static MemTxResult get_ite(GICv3ITSState *s, uint32_t eventid,
54
55
itel = address_space_ldq_le(as, iteaddr, MEMTXATTRS_UNSPECIFIED, &res);
56
if (res != MEMTX_OK) {
57
+ trace_gicv3_its_ite_read_fault(dte->ittaddr, eventid);
58
return res;
39
}
59
}
60
61
iteh = address_space_ldl_le(as, iteaddr + 8, MEMTXATTRS_UNSPECIFIED, &res);
62
if (res != MEMTX_OK) {
63
+ trace_gicv3_its_ite_read_fault(dte->ittaddr, eventid);
64
return res;
65
}
66
67
@@ -XXX,XX +XXX,XX @@ static MemTxResult get_ite(GICv3ITSState *s, uint32_t eventid,
68
ite->icid = FIELD_EX64(itel, ITE_L, ICID);
69
ite->vpeid = FIELD_EX64(itel, ITE_L, VPEID);
70
ite->doorbell = FIELD_EX64(iteh, ITE_H, DOORBELL);
71
+ trace_gicv3_its_ite_read(dte->ittaddr, eventid, ite->valid,
72
+ ite->inttype, ite->intid, ite->icid,
73
+ ite->vpeid, ite->doorbell);
74
return MEMTX_OK;
40
}
75
}
41
76
42
-static void *lqspi_request_mmio_ptr(void *opaque, hwaddr addr, unsigned *size,
77
@@ -XXX,XX +XXX,XX @@ static MemTxResult get_dte(GICv3ITSState *s, uint32_t devid, DTEntry *dte)
43
- unsigned *offset)
78
if (entry_addr == -1) {
44
-{
79
/* No L2 table entry, i.e. no valid DTE, or a memory error */
45
- XilinxQSPIPS *q = opaque;
80
dte->valid = false;
46
- hwaddr offset_within_the_region;
81
- return res;
47
-
82
+ goto out;
48
- if (!q->mmio_execution_enabled) {
83
}
49
- return NULL;
84
dteval = address_space_ldq_le(as, entry_addr, MEMTXATTRS_UNSPECIFIED, &res);
50
- }
85
if (res != MEMTX_OK) {
51
-
86
- return res;
52
- offset_within_the_region = addr & ~(LQSPI_CACHE_SIZE - 1);
87
+ goto out;
53
- lqspi_load_cache(opaque, offset_within_the_region);
88
}
54
- *size = LQSPI_CACHE_SIZE;
89
dte->valid = FIELD_EX64(dteval, DTE, VALID);
55
- *offset = offset_within_the_region;
90
dte->size = FIELD_EX64(dteval, DTE, SIZE);
56
- return q->lqspi_buf;
91
/* DTE word field stores bits [51:8] of the ITT address */
57
-}
92
dte->ittaddr = FIELD_EX64(dteval, DTE, ITTADDR) << ITTADDR_SHIFT;
58
-
93
- return MEMTX_OK;
59
static uint64_t
94
+out:
60
lqspi_read(void *opaque, hwaddr addr, unsigned int size)
95
+ if (res != MEMTX_OK) {
61
{
96
+ trace_gicv3_its_dte_read_fault(devid);
62
@@ -XXX,XX +XXX,XX @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
97
+ } else {
63
98
+ trace_gicv3_its_dte_read(devid, dte->valid, dte->size, dte->ittaddr);
64
static const MemoryRegionOps lqspi_ops = {
99
+ }
65
.read = lqspi_read,
100
+ return res;
66
- .request_ptr = lqspi_request_mmio_ptr,
67
.endianness = DEVICE_NATIVE_ENDIAN,
68
.valid = {
69
.min_access_size = 1,
70
@@ -XXX,XX +XXX,XX @@ static void xilinx_qspips_realize(DeviceState *dev, Error **errp)
71
sysbus_init_mmio(sbd, &s->mmlqspi);
72
73
q->lqspi_cached_addr = ~0ULL;
74
-
75
- /* mmio_execution breaks migration better aborting than having strange
76
- * bugs.
77
- */
78
- if (q->mmio_execution_enabled) {
79
- error_setg(&q->migration_blocker,
80
- "enabling mmio_execution breaks migration");
81
- migrate_add_blocker(q->migration_blocker, &error_fatal);
82
- }
83
}
101
}
84
102
85
static void xlnx_zynqmp_qspips_realize(DeviceState *dev, Error **errp)
103
/*
86
@@ -XXX,XX +XXX,XX @@ static Property xilinx_zynqmp_qspips_properties[] = {
104
@@ -XXX,XX +XXX,XX @@ static bool update_cte(GICv3ITSState *s, uint16_t icid, const CTEntry *cte)
87
DEFINE_PROP_END_OF_LIST(),
105
uint64_t cteval = 0;
88
};
106
MemTxResult res = MEMTX_OK;
89
107
90
-static Property xilinx_qspips_properties[] = {
108
+ trace_gicv3_its_cte_write(icid, cte->valid, cte->rdbase);
91
- /* We had to turn this off for 2.10 as it is not compatible with migration.
109
+
92
- * It can be enabled but will prevent the device to be migrated.
110
if (cte->valid) {
93
- * This will go aways when a fix will be released.
111
/* add mapping entry to collection table */
94
- */
112
cteval = FIELD_DP64(cteval, CTE, VALID, 1);
95
- DEFINE_PROP_BOOL("x-mmio-exec", XilinxQSPIPS, mmio_execution_enabled,
113
@@ -XXX,XX +XXX,XX @@ static bool update_dte(GICv3ITSState *s, uint32_t devid, const DTEntry *dte)
96
- false),
114
uint64_t dteval = 0;
97
- DEFINE_PROP_END_OF_LIST(),
115
MemTxResult res = MEMTX_OK;
98
-};
116
99
-
117
+ trace_gicv3_its_dte_write(devid, dte->valid, dte->size, dte->ittaddr);
100
static Property xilinx_spips_properties[] = {
118
+
101
DEFINE_PROP_UINT8("num-busses", XilinxSPIPS, num_busses, 1),
119
if (dte->valid) {
102
DEFINE_PROP_UINT8("num-ss-bits", XilinxSPIPS, num_cs, 4),
120
/* add mapping entry to device table */
103
@@ -XXX,XX +XXX,XX @@ static void xilinx_qspips_class_init(ObjectClass *klass, void * data)
121
dteval = FIELD_DP64(dteval, DTE, VALID, 1);
104
XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass);
122
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
105
123
index XXXXXXX..XXXXXXX 100644
106
dc->realize = xilinx_qspips_realize;
124
--- a/hw/intc/trace-events
107
- dc->props = xilinx_qspips_properties;
125
+++ b/hw/intc/trace-events
108
xsc->reg_ops = &qspips_ops;
126
@@ -XXX,XX +XXX,XX @@ gicv3_its_cmd_inv(void) "GICv3 ITS: command INV or INVALL"
109
xsc->rx_fifo_size = RXFF_A_Q;
127
gicv3_its_cmd_movall(uint64_t rd1, uint64_t rd2) "GICv3 ITS: command MOVALL RDbase1 0x%" PRIx64 " RDbase2 0x%" PRIx64
110
xsc->tx_fifo_size = TXFF_A_Q;
128
gicv3_its_cmd_movi(uint32_t devid, uint32_t eventid, uint32_t icid) "GICv3 ITS: command MOVI DeviceID 0x%x EventID 0x%x ICID 0x%x"
129
gicv3_its_cmd_unknown(unsigned cmd) "GICv3 ITS: unknown command 0x%x"
130
+gicv3_its_cte_read(uint32_t icid, int valid, uint32_t rdbase) "GICv3 ITS: Collection Table read for ICID 0x%x: valid %d RDBase 0x%x"
131
+gicv3_its_cte_write(uint32_t icid, int valid, uint32_t rdbase) "GICv3 ITS: Collection Table write for ICID 0x%x: valid %d RDBase 0x%x"
132
+gicv3_its_cte_read_fault(uint32_t icid) "GICv3 ITS: Collection Table read for ICID 0x%x: faulted"
133
+gicv3_its_ite_read(uint64_t ittaddr, uint32_t eventid, int valid, int inttype, uint32_t intid, uint32_t icid, uint32_t vpeid, uint32_t doorbell) "GICv3 ITS: Interrupt Table read for ITTaddr 0x%" PRIx64 " EventID 0x%x: valid %d inttype %d intid 0x%x ICID 0x%x vPEID 0x%x doorbell 0x%x"
134
+gicv3_its_ite_read_fault(uint64_t ittaddr, uint32_t eventid) "GICv3 ITS: Interrupt Table read for ITTaddr 0x%" PRIx64 " EventID 0x%x: faulted"
135
+gicv3_its_ite_write(uint64_t ittaddr, uint32_t eventid, int valid, int inttype, uint32_t intid, uint32_t icid, uint32_t vpeid, uint32_t doorbell) "GICv3 ITS: Interrupt Table write for ITTaddr 0x%" PRIx64 " EventID 0x%x: valid %d inttype %d intid 0x%x ICID 0x%x vPEID 0x%x doorbell 0x%x"
136
+gicv3_its_dte_read(uint32_t devid, int valid, uint32_t size, uint64_t ittaddr) "GICv3 ITS: Device Table read for DeviceID 0x%x: valid %d size 0x%x ITTaddr 0x%" PRIx64
137
+gicv3_its_dte_write(uint32_t devid, int valid, uint32_t size, uint64_t ittaddr) "GICv3 ITS: Device Table write for DeviceID 0x%x: valid %d size 0x%x ITTaddr 0x%" PRIx64
138
+gicv3_its_dte_read_fault(uint32_t devid) "GICv3 ITS: Device Table read for DeviceID 0x%x: faulted"
139
140
# armv7m_nvic.c
141
nvic_recompute_state(int vectpending, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_prio %d"
111
--
142
--
112
2.18.0
143
2.25.1
113
114
diff view generated by jsdifflib
1
The AArch32 virtualization extensions support these fault address
1
The GICv3 has some registers that support byte accesses, and some
2
registers:
2
that support 8-byte accesses. Our TCG implementation implements all
3
* HDFAR: aliased with AArch64 FAR_EL2[31:0] and AArch32 DFAR(S)
3
of this, switching on the 'size' argument and handling the registers
4
* HIFAR: aliased with AArch64 FAR_EL2[63:32] and AArch32 IFAR(S)
4
that must support reads of that size while logging an error for
5
attempted accesses to registers that do not support that size access.
6
However we forgot to tell the core memory subsystem about this by
7
specifying the .impl and .valid fields in the MemoryRegionOps struct,
8
so the core was happily simulating 8 byte accesses by combining two 4
9
byte accesses. This doesn't have much guest-visible effect, since
10
there aren't many 8 byte registers and they all support being written
11
in two 4 byte parts.
5
12
6
Implement the accessors for these. This fixes in passing a bug
13
Set the .impl and .valid fields to say that all sizes from 1 to 8
7
where we weren't implementing the "RES0 from EL3 if EL2 not
14
bytes are both valid and implemented by the device.
8
implemented" behaviour for AArch64 FAR_EL2.
9
15
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
18
Message-id: 20220303202341.2232284-4-peter.maydell@linaro.org
13
Message-id: 20180814124254.5229-7-peter.maydell@linaro.org
14
---
19
---
15
target/arm/helper.c | 14 +++++++++++++-
20
hw/intc/arm_gicv3.c | 8 ++++++++
16
1 file changed, 13 insertions(+), 1 deletion(-)
21
1 file changed, 8 insertions(+)
17
22
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
23
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
19
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
25
--- a/hw/intc/arm_gicv3.c
21
+++ b/target/arm/helper.c
26
+++ b/hw/intc/arm_gicv3.c
22
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
27
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps gic_ops[] = {
23
{ .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
28
.read_with_attrs = gicv3_dist_read,
24
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
29
.write_with_attrs = gicv3_dist_write,
25
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
30
.endianness = DEVICE_NATIVE_ENDIAN,
26
+ { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
31
+ .valid.min_access_size = 1,
27
+ .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
32
+ .valid.max_access_size = 8,
28
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
33
+ .impl.min_access_size = 1,
29
+ { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
34
+ .impl.max_access_size = 8,
30
+ .type = ARM_CP_CONST,
35
},
31
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
36
{
32
+ .access = PL2_RW, .resetvalue = 0 },
37
.read_with_attrs = gicv3_redist_read,
33
REGINFO_SENTINEL
38
.write_with_attrs = gicv3_redist_write,
39
.endianness = DEVICE_NATIVE_ENDIAN,
40
+ .valid.min_access_size = 1,
41
+ .valid.max_access_size = 8,
42
+ .impl.min_access_size = 1,
43
+ .impl.max_access_size = 8,
44
}
34
};
45
};
35
46
36
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
37
{ .name = "ESR_EL2", .state = ARM_CP_STATE_AA64,
38
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
39
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) },
40
- { .name = "FAR_EL2", .state = ARM_CP_STATE_AA64,
41
+ { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
42
.opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
43
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.far_el[2]) },
44
+ { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
45
+ .type = ARM_CP_ALIAS,
46
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
47
+ .access = PL2_RW,
48
+ .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[2]) },
49
{ .name = "SPSR_EL2", .state = ARM_CP_STATE_AA64,
50
.type = ARM_CP_ALIAS,
51
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
52
--
47
--
53
2.18.0
48
2.25.1
54
55
diff view generated by jsdifflib
1
ARMv7VE introduced the ERET instruction, which is necessary to
1
We forgot a space in some log messages, so the output ended
2
return from an exception taken to Hyp mode. Implement this.
2
up looking like
3
In A32 encoding it is a completely new encoding; in T32 it
3
gicv3_dist_write: invalid guest write at offset 0000000000008000size 8
4
is an adjustment of the behaviour of the existing
4
5
"SUBS PC, LR, #<imm8>" instruction.
5
with a missing space before "size". Add the missing spaces.
6
6
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
9
Message-id: 20220303202341.2232284-5-peter.maydell@linaro.org
10
Message-id: 20180814124254.5229-10-peter.maydell@linaro.org
11
---
10
---
12
target/arm/translate.c | 31 +++++++++++++++++++++++++++++--
11
hw/intc/arm_gicv3_dist.c | 4 ++--
13
1 file changed, 29 insertions(+), 2 deletions(-)
12
hw/intc/arm_gicv3_its.c | 4 ++--
13
2 files changed, 4 insertions(+), 4 deletions(-)
14
14
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
15
diff --git a/hw/intc/arm_gicv3_dist.c b/hw/intc/arm_gicv3_dist.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
17
--- a/hw/intc/arm_gicv3_dist.c
18
+++ b/target/arm/translate.c
18
+++ b/hw/intc/arm_gicv3_dist.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
19
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_dist_read(void *opaque, hwaddr offset, uint64_t *data,
20
tcg_temp_free_i32(tmp2);
20
if (!r) {
21
store_reg(s, rd, tmp);
21
qemu_log_mask(LOG_GUEST_ERROR,
22
break;
22
"%s: invalid guest read at offset " TARGET_FMT_plx
23
+ case 0x6: /* ERET */
23
- "size %u\n", __func__, offset, size);
24
+ if (op1 != 3) {
24
+ " size %u\n", __func__, offset, size);
25
+ goto illegal_op;
25
trace_gicv3_dist_badread(offset, size, attrs.secure);
26
+ }
26
/* The spec requires that reserved registers are RAZ/WI;
27
+ if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
27
* so use MEMTX_ERROR returns from leaf functions as a way to
28
+ goto illegal_op;
28
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_dist_write(void *opaque, hwaddr offset, uint64_t data,
29
+ }
29
if (!r) {
30
+ if ((insn & 0x000fff0f) != 0x0000000e) {
30
qemu_log_mask(LOG_GUEST_ERROR,
31
+ /* UNPREDICTABLE; we choose to UNDEF */
31
"%s: invalid guest write at offset " TARGET_FMT_plx
32
+ goto illegal_op;
32
- "size %u\n", __func__, offset, size);
33
+ }
33
+ " size %u\n", __func__, offset, size);
34
+
34
trace_gicv3_dist_badwrite(offset, data, size, attrs.secure);
35
+ if (s->current_el == 2) {
35
/* The spec requires that reserved registers are RAZ/WI;
36
+ tmp = load_cpu_field(elr_el[2]);
36
* so use MEMTX_ERROR returns from leaf functions as a way to
37
+ } else {
37
diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c
38
+ tmp = load_reg(s, 14);
38
index XXXXXXX..XXXXXXX 100644
39
+ }
39
--- a/hw/intc/arm_gicv3_its.c
40
+ gen_exception_return(s, tmp);
40
+++ b/hw/intc/arm_gicv3_its.c
41
+ break;
41
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_read(void *opaque, hwaddr offset, uint64_t *data,
42
case 7:
42
if (!result) {
43
{
43
qemu_log_mask(LOG_GUEST_ERROR,
44
int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
44
"%s: invalid guest read at offset " TARGET_FMT_plx
45
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
45
- "size %u\n", __func__, offset, size);
46
if (rn != 14 || rd != 15) {
46
+ " size %u\n", __func__, offset, size);
47
goto illegal_op;
47
trace_gicv3_its_badread(offset, size);
48
}
48
/*
49
- tmp = load_reg(s, rn);
49
* The spec requires that reserved registers are RAZ/WI;
50
- tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
50
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicv3_its_write(void *opaque, hwaddr offset, uint64_t data,
51
+ if (s->current_el == 2) {
51
if (!result) {
52
+ /* ERET from Hyp uses ELR_Hyp, not LR */
52
qemu_log_mask(LOG_GUEST_ERROR,
53
+ if (insn & 0xff) {
53
"%s: invalid guest write at offset " TARGET_FMT_plx
54
+ goto illegal_op;
54
- "size %u\n", __func__, offset, size);
55
+ }
55
+ " size %u\n", __func__, offset, size);
56
+ tmp = load_cpu_field(elr_el[2]);
56
trace_gicv3_its_badwrite(offset, data, size);
57
+ } else {
57
/*
58
+ tmp = load_reg(s, rn);
58
* The spec requires that reserved registers are RAZ/WI;
59
+ tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
60
+ }
61
gen_exception_return(s, tmp);
62
break;
63
case 6: /* MRS */
64
--
59
--
65
2.18.0
60
2.25.1
66
67
diff view generated by jsdifflib
1
From: Roman Kapl <rka@sysgo.com>
1
The trace_gicv3_icv_hppir_read trace event takes an integer value
2
which it uses to form the register name, which should be either
3
ICV_HPPIR0 or ICV_HPPIR1. We were passing in the 'grp' variable for
4
this, but that is either GICV3_G0 or GICV3_G1NS, which happen to be 0
5
and 2, which meant that tracing for the ICV_HPPIR1 register was
6
incorrectly printed as ICV_HPPIR2.
2
7
3
If an instruction is conditional (like CBZ) and it is executed
8
Use the same approach we do for all the other similar trace events,
4
conditionally (using the ITx instruction), a jump to an undefined
9
and pass in 'ri->crm == 8 ? 0 : 1', deriving the index value
5
label is generated, and QEMU crashes.
10
directly from the ARMCPRegInfo struct.
6
11
7
CBZ in IT block is an UNPREDICTABLE behavior, but we should not
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
crash. Honouring the condition code is allowed by the spec in this
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
case (constrained unpredictable, ARMv8, section K1.1.7), and matches
14
Message-id: 20220303202341.2232284-6-peter.maydell@linaro.org
10
what we do for other "UNPREDICTABLE inside an IT block" instructions.
15
---
16
hw/intc/arm_gicv3_cpuif.c | 3 ++-
17
1 file changed, 2 insertions(+), 1 deletion(-)
11
18
12
Fix the 'skip on condition' code to create a new label only if it
19
diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c
13
does not already exist. Previously multiple labels were created, but
14
only the last one of them was set.
15
16
Signed-off-by: Roman Kapl <rka@sysgo.com>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
18
Message-id: 20180816120533.6587-1-rka@sysgo.com
19
[PMM: fixed ^ 1 being applied to wrong argument, fixed typo]
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
target/arm/translate.c | 35 +++++++++++++++++++++--------------
24
1 file changed, 21 insertions(+), 14 deletions(-)
25
26
diff --git a/target/arm/translate.c b/target/arm/translate.c
27
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/translate.c
21
--- a/hw/intc/arm_gicv3_cpuif.c
29
+++ b/target/arm/translate.c
22
+++ b/hw/intc/arm_gicv3_cpuif.c
30
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
23
@@ -XXX,XX +XXX,XX @@ static uint64_t icv_hppir_read(CPUARMState *env, const ARMCPRegInfo *ri)
31
s->base.is_jmp = DISAS_UPDATE;
32
}
33
34
+/* Generate a label used for skipping this instruction */
35
+static void arm_gen_condlabel(DisasContext *s)
36
+{
37
+ if (!s->condjmp) {
38
+ s->condlabel = gen_new_label();
39
+ s->condjmp = 1;
40
+ }
41
+}
42
+
43
+/* Skip this instruction if the ARM condition is false */
44
+static void arm_skip_unless(DisasContext *s, uint32_t cond)
45
+{
46
+ arm_gen_condlabel(s);
47
+ arm_gen_test_cc(cond ^ 1, s->condlabel);
48
+}
49
+
50
static void disas_arm_insn(DisasContext *s, unsigned int insn)
51
{
52
unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
53
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
54
if (cond != 0xe) {
55
/* if not always execute, we generate a conditional jump to
56
next instruction */
57
- s->condlabel = gen_new_label();
58
- arm_gen_test_cc(cond ^ 1, s->condlabel);
59
- s->condjmp = 1;
60
+ arm_skip_unless(s, cond);
61
}
62
if ((insn & 0x0f900000) == 0x03000000) {
63
if ((insn & (1 << 21)) == 0) {
64
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
65
/* Conditional branch. */
66
op = (insn >> 22) & 0xf;
67
/* Generate a conditional jump to next instruction. */
68
- s->condlabel = gen_new_label();
69
- arm_gen_test_cc(op ^ 1, s->condlabel);
70
- s->condjmp = 1;
71
+ arm_skip_unless(s, op);
72
73
/* offset[11:1] = insn[10:0] */
74
offset = (insn & 0x7ff) << 1;
75
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
76
case 1: case 3: case 9: case 11: /* czb */
77
rm = insn & 7;
78
tmp = load_reg(s, rm);
79
- s->condlabel = gen_new_label();
80
- s->condjmp = 1;
81
+ arm_gen_condlabel(s);
82
if (insn & (1 << 11))
83
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
84
else
85
@@ -XXX,XX +XXX,XX @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
86
break;
87
}
88
/* generate a conditional jump to next instruction */
89
- s->condlabel = gen_new_label();
90
- arm_gen_test_cc(cond ^ 1, s->condlabel);
91
- s->condjmp = 1;
92
+ arm_skip_unless(s, cond);
93
94
/* jump to the offset */
95
val = (uint32_t)s->pc + 2;
96
@@ -XXX,XX +XXX,XX @@ static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
97
uint32_t cond = dc->condexec_cond;
98
99
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
100
- dc->condlabel = gen_new_label();
101
- arm_gen_test_cc(cond ^ 1, dc->condlabel);
102
- dc->condjmp = 1;
103
+ arm_skip_unless(dc, cond);
104
}
24
}
105
}
25
}
106
26
27
- trace_gicv3_icv_hppir_read(grp, gicv3_redist_affid(cs), value);
28
+ trace_gicv3_icv_hppir_read(ri->crm == 8 ? 0 : 1,
29
+ gicv3_redist_affid(cs), value);
30
return value;
31
}
32
107
--
33
--
108
2.18.0
34
2.25.1
109
110
diff view generated by jsdifflib
Deleted patch
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
1
3
The generic loader device supports the U-Boot and Intel HEX executable
4
formats in addition to the document raw and ELF formats. Reword the
5
documentation to include these formats and explain how various options
6
depend on the executable format.
7
8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20180816145554.9814-1-stefanha@redhat.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
docs/generic-loader.txt | 20 ++++++++++----------
15
1 file changed, 10 insertions(+), 10 deletions(-)
16
17
diff --git a/docs/generic-loader.txt b/docs/generic-loader.txt
18
index XXXXXXX..XXXXXXX 100644
19
--- a/docs/generic-loader.txt
20
+++ b/docs/generic-loader.txt
21
@@ -XXX,XX +XXX,XX @@ An example of setting CPU 0's PC to 0x8000 is:
22
23
Loading Files
24
-------------
25
-The loader device also allows files to be loaded into memory. It can load raw
26
-files and ELF executable files. Raw files are loaded verbatim. ELF executable
27
-files are loaded by an ELF loader. The syntax is shown below:
28
+The loader device also allows files to be loaded into memory. It can load ELF,
29
+U-Boot, and Intel HEX executable formats as well as raw images. The syntax is
30
+shown below:
31
32
-device loader,file=<file>[,addr=<addr>][,cpu-num=<cpu-num>][,force-raw=<raw>]
33
34
<file> - A file to be loaded into memory
35
- <addr> - The addr in memory that the file should be loaded. This is
36
- ignored if you are using an ELF (unless force-raw is true).
37
- This is required if you aren't loading an ELF.
38
+ <addr> - The memory address where the file should be loaded. This is
39
+ required for raw images and ignored for non-raw files.
40
<cpu-num> - This specifies the CPU that should be used. This is an
41
optional argument and will cause the CPU's PC to be set to
42
- where the image is stored or in the case of an ELF file to
43
- the value in the header. This option should only be used
44
- for the boot image.
45
+ the memory address where the raw file is loaded or the entry
46
+ point specified in the executable format header. This option
47
+ should only be used for the boot image.
48
This will also cause the image to be written to the specified
49
CPU's address space. If not specified, the default is CPU 0.
50
<force-raw> - Setting force-raw=on forces the file to be treated as a raw
51
- image. This can be used to load ELF files as if they were raw.
52
+ image. This can be used to load supported executable formats
53
+ as if they were raw.
54
55
All values are parsed using the standard QemuOps parsing. This allows the user
56
to specify any values in any format supported. By default the values
57
--
58
2.18.0
59
60
diff view generated by jsdifflib
Deleted patch
1
From: Jia He <hejianet@gmail.com>
2
1
3
In scripts/arch-run.bash of kvm-unit-tests, it will check the qemu
4
output log with:
5
if [ -z "$(echo "$errors" | grep -vi warning)" ]; then
6
7
Thus without the warning prefix, all of the test fail.
8
9
Since it is not unrecoverable error in kvm_arm_its_reset for
10
current implementation, downgrading the report from error to
11
warn makes sense.
12
13
Signed-off-by: Jia He <jia.he@hxt-semitech.com>
14
Message-id: 1531969910-32843-1-git-send-email-jia.he@hxt-semitech.com
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
18
hw/intc/arm_gicv3_its_kvm.c | 2 +-
19
1 file changed, 1 insertion(+), 1 deletion(-)
20
21
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/intc/arm_gicv3_its_kvm.c
24
+++ b/hw/intc/arm_gicv3_its_kvm.c
25
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_reset(DeviceState *dev)
26
return;
27
}
28
29
- error_report("ITS KVM: full reset is not supported by the host kernel");
30
+ warn_report("ITS KVM: full reset is not supported by the host kernel");
31
32
if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
33
GITS_CTLR)) {
34
--
35
2.18.0
36
37
diff view generated by jsdifflib
Deleted patch
1
From: Hans-Erik Floryd <hans-erik.floryd@rt-labs.com>
2
1
3
Generate an interrupt if USR2_RDR and UCR4_DREN are both set.
4
5
Signed-off-by: Hans-Erik Floryd <hans-erik.floryd@rt-labs.com>
6
Message-id: 1534341354-11956-1-git-send-email-hans-erik.floryd@rt-labs.com
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
include/hw/char/imx_serial.h | 1 +
11
hw/char/imx_serial.c | 3 ++-
12
2 files changed, 3 insertions(+), 1 deletion(-)
13
14
diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/char/imx_serial.h
17
+++ b/include/hw/char/imx_serial.h
18
@@ -XXX,XX +XXX,XX @@
19
#define UCR2_RXEN (1<<1) /* Receiver enable */
20
#define UCR2_SRST (1<<0) /* Reset complete */
21
22
+#define UCR4_DREN BIT(0) /* Receive Data Ready interrupt enable */
23
#define UCR4_TCEN BIT(3) /* TX complete interrupt enable */
24
25
#define UTS1_TXEMPTY (1<<6)
26
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/hw/char/imx_serial.c
29
+++ b/hw/char/imx_serial.c
30
@@ -XXX,XX +XXX,XX @@ static void imx_update(IMXSerialState *s)
31
mask = (s->ucr1 & UCR1_TXMPTYEN) ? USR2_TXFE : 0;
32
/*
33
* TCEN and TXDC are both bit 3
34
+ * RDR and DREN are both bit 0
35
*/
36
- mask |= s->ucr4 & UCR4_TCEN;
37
+ mask |= s->ucr4 & (UCR4_TCEN | UCR4_DREN);
38
39
usr2 = s->usr2 & mask;
40
41
--
42
2.18.0
43
44
diff view generated by jsdifflib
Deleted patch
1
We implement the HAMAIR1 register as RAZ/WI; we had a typo in the
2
regdef, though, and were incorrectly naming it HMAIR1 (which is
3
a different register which we also implement as RAZ/WI).
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
8
Message-id: 20180814124254.5229-2-peter.maydell@linaro.org
9
---
10
target/arm/helper.c | 4 ++--
11
1 file changed, 2 insertions(+), 2 deletions(-)
12
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
18
.opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
19
.access = PL2_RW, .type = ARM_CP_CONST,
20
.resetvalue = 0 },
21
- { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
22
+ { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
23
.opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
24
.access = PL2_RW, .type = ARM_CP_CONST,
25
.resetvalue = 0 },
26
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
27
.access = PL2_RW, .type = ARM_CP_CONST,
28
.resetvalue = 0 },
29
/* HAMAIR1 is mapped to AMAIR_EL2[63:32] */
30
- { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
31
+ { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
32
.opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
33
.access = PL2_RW, .type = ARM_CP_CONST,
34
.resetvalue = 0 },
35
--
36
2.18.0
37
38
diff view generated by jsdifflib
Deleted patch
1
ARMCPRegInfo structs will default to .cp = 15 if they
2
are ARM_CP_STATE_BOTH, but not if they are ARM_CP_STATE_AA32
3
(because a coprocessor number of 0 is valid for AArch32).
4
We forgot to explicitly set .cp = 15 for the HMAIR1 and
5
HAMAIR1 regdefs, which meant they would UNDEF when the guest
6
tried to access them under cp15.
7
1
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
11
Message-id: 20180814124254.5229-3-peter.maydell@linaro.org
12
---
13
target/arm/helper.c | 8 ++++----
14
1 file changed, 4 insertions(+), 4 deletions(-)
15
16
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper.c
19
+++ b/target/arm/helper.c
20
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
21
.access = PL2_RW, .type = ARM_CP_CONST,
22
.resetvalue = 0 },
23
{ .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
24
- .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
25
+ .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
26
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
27
{ .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH,
28
.opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
29
.access = PL2_RW, .type = ARM_CP_CONST,
30
.resetvalue = 0 },
31
{ .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
32
- .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
33
+ .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
34
.access = PL2_RW, .type = ARM_CP_CONST,
35
.resetvalue = 0 },
36
{ .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH,
37
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
38
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[2]),
39
.resetvalue = 0 },
40
{ .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
41
- .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
42
+ .cp = 15, .opc1 = 4, .crn = 10, .crm = 2, .opc2 = 1,
43
.access = PL2_RW, .type = ARM_CP_ALIAS,
44
.fieldoffset = offsetofhigh32(CPUARMState, cp15.mair_el[2]) },
45
{ .name = "AMAIR_EL2", .state = ARM_CP_STATE_BOTH,
46
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
47
.resetvalue = 0 },
48
/* HAMAIR1 is mapped to AMAIR_EL2[63:32] */
49
{ .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
50
- .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
51
+ .cp = 15, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
52
.access = PL2_RW, .type = ARM_CP_CONST,
53
.resetvalue = 0 },
54
{ .name = "AFSR0_EL2", .state = ARM_CP_STATE_BOTH,
55
--
56
2.18.0
57
58
diff view generated by jsdifflib
Deleted patch
1
Implement the AArch32 HVBAR register; we can do this just by
2
making the existing VBAR_EL2 regdefs be STATE_BOTH.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
7
Message-id: 20180814124254.5229-5-peter.maydell@linaro.org
8
---
9
target/arm/helper.c | 4 ++--
10
1 file changed, 2 insertions(+), 2 deletions(-)
11
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
17
18
/* Used to describe the behaviour of EL2 regs when EL2 does not exist. */
19
static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
20
- { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
21
+ { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
22
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
23
.access = PL2_RW,
24
.readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
25
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
26
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
27
.access = PL2_RW,
28
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) },
29
- { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
30
+ { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
31
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
32
.access = PL2_RW, .writefn = vbar_write,
33
.fieldoffset = offsetof(CPUARMState, cp15.vbar_el[2]),
34
--
35
2.18.0
36
37
diff view generated by jsdifflib
Deleted patch
1
The AArch32 HSR is the equivalent of AArch64 ESR_EL2;
2
we can implement it by marking our existing ESR_EL2 regdef
3
as STATE_BOTH. It also needs to be "RES0 from EL3 if
4
EL2 not implemented", so add the missing stanza to
5
el3_no_el2_cp_reginfo.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
10
Message-id: 20180814124254.5229-8-peter.maydell@linaro.org
11
---
12
target/arm/helper.c | 6 +++++-
13
1 file changed, 5 insertions(+), 1 deletion(-)
14
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
20
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 0,
21
.access = PL2_RW,
22
.readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
23
+ { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
24
+ .opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
25
+ .access = PL2_RW,
26
+ .type = ARM_CP_CONST, .resetvalue = 0 },
27
{ .name = "CPTR_EL2", .state = ARM_CP_STATE_BOTH,
28
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 2,
29
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
30
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
31
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 1,
32
.access = PL2_RW,
33
.fieldoffset = offsetof(CPUARMState, elr_el[2]) },
34
- { .name = "ESR_EL2", .state = ARM_CP_STATE_AA64,
35
+ { .name = "ESR_EL2", .state = ARM_CP_STATE_BOTH,
36
.opc0 = 3, .opc1 = 4, .crn = 5, .crm = 2, .opc2 = 0,
37
.access = PL2_RW, .fieldoffset = offsetof(CPUARMState, cp15.esr_el[2]) },
38
{ .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
39
--
40
2.18.0
41
42
diff view generated by jsdifflib
1
From: Hans-Erik Floryd <hans-erik.floryd@rt-labs.com>
1
From: Akihiko Odaki <akihiko.odaki@gmail.com>
2
2
3
Add the ESDHC PRSSTAT_SDSTB bit, using the value of SDHC_CLOCK_INT_STABLE.
3
This provides standard look and feel for the about panel and reduces
4
Freescale recommends checking this bit when changing clock frequency.
4
code.
5
5
6
Signed-off-by: Hans-Erik Floryd <hans-erik.floryd@rt-labs.com>
6
Signed-off-by: Akihiko Odaki <akihiko.odaki@gmail.com>
7
Message-id: 1534507843-4251-1-git-send-email-hans-erik.floryd@rt-labs.com
7
Message-id: 20220227042241.1543-1-akihiko.odaki@gmail.com
8
[PMM: fixed indentation]
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@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
hw/sd/sdhci-internal.h | 2 ++
11
ui/cocoa.m | 112 +++++++++++------------------------------------------
13
hw/sd/sdhci.c | 8 ++++++++
12
1 file changed, 23 insertions(+), 89 deletions(-)
14
2 files changed, 10 insertions(+)
15
13
16
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
14
diff --git a/ui/cocoa.m b/ui/cocoa.m
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/sd/sdhci-internal.h
16
--- a/ui/cocoa.m
19
+++ b/hw/sd/sdhci-internal.h
17
+++ b/ui/cocoa.m
20
@@ -XXX,XX +XXX,XX @@ extern const VMStateDescription sdhci_vmstate;
18
@@ -XXX,XX +XXX,XX @@ static void cocoa_switch(DisplayChangeListener *dcl,
21
#define ESDHC_CTRL_4BITBUS (0x1 << 1)
19
22
#define ESDHC_CTRL_8BITBUS (0x2 << 1)
20
static void cocoa_refresh(DisplayChangeListener *dcl);
23
21
24
+#define ESDHC_PRNSTS_SDSTB (1 << 3)
22
-static NSWindow *normalWindow, *about_window;
25
+
23
+static NSWindow *normalWindow;
26
#endif
24
static const DisplayChangeListenerOps dcl_ops = {
27
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
25
.dpy_name = "cocoa",
28
index XXXXXXX..XXXXXXX 100644
26
.dpy_gfx_update = cocoa_update,
29
--- a/hw/sd/sdhci.c
27
@@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView;
30
+++ b/hw/sd/sdhci.c
28
- (BOOL)verifyQuit;
31
@@ -XXX,XX +XXX,XX @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
29
- (void)openDocumentation:(NSString *)filename;
32
30
- (IBAction) do_about_menu_item: (id) sender;
33
break;
31
-- (void)make_about_window;
34
32
- (void)adjustSpeed:(id)sender;
35
+ case SDHC_PRNSTS:
33
@end
36
+ /* Add SDSTB (SD Clock Stable) bit to PRNSTS */
34
37
+ ret = sdhci_read(opaque, offset, size) & ~ESDHC_PRNSTS_SDSTB;
35
@@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView;
38
+ if (s->clkcon & SDHC_CLOCK_INT_STABLE) {
36
[pauseLabel setFont: [NSFont fontWithName: @"Helvetica" size: 90]];
39
+ ret |= ESDHC_PRNSTS_SDSTB;
37
[pauseLabel setTextColor: [NSColor blackColor]];
40
+ }
38
[pauseLabel sizeToFit];
41
+ break;
39
-
42
+
40
- [self make_about_window];
43
case ESDHC_DLL_CTRL:
41
}
44
case ESDHC_TUNE_CTRL_STATUS:
42
return self;
45
case ESDHC_UNDOCUMENTED_REG27:
43
}
44
@@ -XXX,XX +XXX,XX @@ QemuCocoaView *cocoaView;
45
/* The action method for the About menu item */
46
- (IBAction) do_about_menu_item: (id) sender
47
{
48
- [about_window makeKeyAndOrderFront: nil];
49
-}
50
-
51
-/* Create and display the about dialog */
52
-- (void)make_about_window
53
-{
54
- /* Make the window */
55
- int x = 0, y = 0, about_width = 400, about_height = 200;
56
- NSRect window_rect = NSMakeRect(x, y, about_width, about_height);
57
- about_window = [[NSWindow alloc] initWithContentRect:window_rect
58
- styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
59
- NSWindowStyleMaskMiniaturizable
60
- backing:NSBackingStoreBuffered
61
- defer:NO];
62
- [about_window setTitle: @"About"];
63
- [about_window setReleasedWhenClosed: NO];
64
- [about_window center];
65
- NSView *superView = [about_window contentView];
66
-
67
- /* Create the dimensions of the picture */
68
- int picture_width = 80, picture_height = 80;
69
- x = (about_width - picture_width)/2;
70
- y = about_height - picture_height - 10;
71
- NSRect picture_rect = NSMakeRect(x, y, picture_width, picture_height);
72
-
73
- /* Make the picture of QEMU */
74
- NSImageView *picture_view = [[NSImageView alloc] initWithFrame:
75
- picture_rect];
76
- char *qemu_image_path_c = get_relocated_path(CONFIG_QEMU_ICONDIR "/hicolor/512x512/apps/qemu.png");
77
- NSString *qemu_image_path = [NSString stringWithUTF8String:qemu_image_path_c];
78
- g_free(qemu_image_path_c);
79
- NSImage *qemu_image = [[NSImage alloc] initWithContentsOfFile:qemu_image_path];
80
- [picture_view setImage: qemu_image];
81
- [picture_view setImageScaling: NSImageScaleProportionallyUpOrDown];
82
- [superView addSubview: picture_view];
83
-
84
- /* Make the name label */
85
- NSBundle *bundle = [NSBundle mainBundle];
86
- if (bundle) {
87
- x = 0;
88
- y = y - 25;
89
- int name_width = about_width, name_height = 20;
90
- NSRect name_rect = NSMakeRect(x, y, name_width, name_height);
91
- NSTextField *name_label = [[NSTextField alloc] initWithFrame: name_rect];
92
- [name_label setEditable: NO];
93
- [name_label setBezeled: NO];
94
- [name_label setDrawsBackground: NO];
95
- [name_label setAlignment: NSTextAlignmentCenter];
96
- NSString *qemu_name = [[bundle executablePath] lastPathComponent];
97
- [name_label setStringValue: qemu_name];
98
- [superView addSubview: name_label];
99
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
100
+ char *icon_path_c = get_relocated_path(CONFIG_QEMU_ICONDIR "/hicolor/512x512/apps/qemu.png");
101
+ NSString *icon_path = [NSString stringWithUTF8String:icon_path_c];
102
+ g_free(icon_path_c);
103
+ NSImage *icon = [[NSImage alloc] initWithContentsOfFile:icon_path];
104
+ NSString *version = @"QEMU emulator version " QEMU_FULL_VERSION;
105
+ NSString *copyright = @QEMU_COPYRIGHT;
106
+ NSDictionary *options;
107
+ if (icon) {
108
+ options = @{
109
+ NSAboutPanelOptionApplicationIcon : icon,
110
+ NSAboutPanelOptionApplicationVersion : version,
111
+ @"Copyright" : copyright,
112
+ };
113
+ [icon release];
114
+ } else {
115
+ options = @{
116
+ NSAboutPanelOptionApplicationVersion : version,
117
+ @"Copyright" : copyright,
118
+ };
119
}
120
-
121
- /* Set the version label's attributes */
122
- x = 0;
123
- y = 50;
124
- int version_width = about_width, version_height = 20;
125
- NSRect version_rect = NSMakeRect(x, y, version_width, version_height);
126
- NSTextField *version_label = [[NSTextField alloc] initWithFrame:
127
- version_rect];
128
- [version_label setEditable: NO];
129
- [version_label setBezeled: NO];
130
- [version_label setAlignment: NSTextAlignmentCenter];
131
- [version_label setDrawsBackground: NO];
132
-
133
- /* Create the version string*/
134
- NSString *version_string;
135
- version_string = [[NSString alloc] initWithFormat:
136
- @"QEMU emulator version %s", QEMU_FULL_VERSION];
137
- [version_label setStringValue: version_string];
138
- [superView addSubview: version_label];
139
-
140
- /* Make copyright label */
141
- x = 0;
142
- y = 35;
143
- int copyright_width = about_width, copyright_height = 20;
144
- NSRect copyright_rect = NSMakeRect(x, y, copyright_width, copyright_height);
145
- NSTextField *copyright_label = [[NSTextField alloc] initWithFrame:
146
- copyright_rect];
147
- [copyright_label setEditable: NO];
148
- [copyright_label setBezeled: NO];
149
- [copyright_label setDrawsBackground: NO];
150
- [copyright_label setAlignment: NSTextAlignmentCenter];
151
- [copyright_label setStringValue: [NSString stringWithFormat: @"%s",
152
- QEMU_COPYRIGHT]];
153
- [superView addSubview: copyright_label];
154
+ [NSApp orderFrontStandardAboutPanelWithOptions:options];
155
+ [pool release];
156
}
157
158
/* Used by the Speed menu items */
46
--
159
--
47
2.18.0
160
2.25.1
48
49
diff view generated by jsdifflib
1
The Arm Cortex-M System Design Kit includes a simple watchdog module
1
From: Richard Henderson <richard.henderson@linaro.org>
2
based on a 32-bit down-counter. Implement this.
3
2
3
There is a Linux kernel bug present until v5.12 that prevents
4
booting with FEAT_LPA2 enabled. As a workaround for TCG, allow
5
the feature to be disabled from -cpu max.
6
7
Since this kernel bug is present in the Fedora 31 image that
8
we test in avocado, disable lpa2 on the command-line.
9
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
---
13
---
6
Makefile.objs | 1 +
14
target/arm/cpu.h | 5 ++++-
7
hw/watchdog/Makefile.objs | 1 +
15
target/arm/cpu.c | 6 ++++++
8
include/hw/watchdog/cmsdk-apb-watchdog.h | 59 ++++
16
target/arm/cpu64.c | 24 ++++++++++++++++++++++++
9
hw/watchdog/cmsdk-apb-watchdog.c | 326 +++++++++++++++++++++++
17
tests/avocado/boot_linux.py | 2 ++
10
MAINTAINERS | 2 +
18
4 files changed, 36 insertions(+), 1 deletion(-)
11
default-configs/arm-softmmu.mak | 1 +
12
hw/watchdog/trace-events | 6 +
13
7 files changed, 396 insertions(+)
14
create mode 100644 include/hw/watchdog/cmsdk-apb-watchdog.h
15
create mode 100644 hw/watchdog/cmsdk-apb-watchdog.c
16
create mode 100644 hw/watchdog/trace-events
17
19
18
diff --git a/Makefile.objs b/Makefile.objs
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
20
--- a/Makefile.objs
22
--- a/target/arm/cpu.h
21
+++ b/Makefile.objs
23
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ trace-events-subdirs += hw/tpm
24
@@ -XXX,XX +XXX,XX @@ typedef struct {
23
trace-events-subdirs += hw/usb
25
# define ARM_MAX_VQ 16
24
trace-events-subdirs += hw/vfio
26
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp);
25
trace-events-subdirs += hw/virtio
27
void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp);
26
+trace-events-subdirs += hw/watchdog
28
+void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp);
27
trace-events-subdirs += hw/xen
29
#else
28
trace-events-subdirs += io
30
# define ARM_MAX_VQ 1
29
trace-events-subdirs += linux-user
31
static inline void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp) { }
30
diff --git a/hw/watchdog/Makefile.objs b/hw/watchdog/Makefile.objs
32
static inline void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp) { }
33
+static inline void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp) { }
34
#endif
35
36
typedef struct ARMVectorReg {
37
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
38
39
/*
40
* Intermediate values used during property parsing.
41
- * Once finalized, the values should be read from ID_AA64ISAR1.
42
+ * Once finalized, the values should be read from ID_AA64*.
43
*/
44
bool prop_pauth;
45
bool prop_pauth_impdef;
46
+ bool prop_lpa2;
47
48
/* DCZ blocksize, in log_2(words), ie low 4 bits of DCZID_EL0 */
49
uint32_t dcz_blocksize;
50
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
31
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/watchdog/Makefile.objs
52
--- a/target/arm/cpu.c
33
+++ b/hw/watchdog/Makefile.objs
53
+++ b/target/arm/cpu.c
34
@@ -XXX,XX +XXX,XX @@
54
@@ -XXX,XX +XXX,XX @@ void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
35
common-obj-y += watchdog.o
55
error_propagate(errp, local_err);
36
+common-obj-$(CONFIG_CMSDK_APB_WATCHDOG) += cmsdk-apb-watchdog.o
56
return;
37
common-obj-$(CONFIG_WDT_IB6300ESB) += wdt_i6300esb.o
57
}
38
common-obj-$(CONFIG_WDT_IB700) += wdt_ib700.o
39
common-obj-$(CONFIG_WDT_DIAG288) += wdt_diag288.o
40
diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/include/hw/watchdog/cmsdk-apb-watchdog.h
45
@@ -XXX,XX +XXX,XX @@
46
+/*
47
+ * ARM CMSDK APB watchdog emulation
48
+ *
49
+ * Copyright (c) 2018 Linaro Limited
50
+ * Written by Peter Maydell
51
+ *
52
+ * This program is free software; you can redistribute it and/or modify
53
+ * it under the terms of the GNU General Public License version 2 or
54
+ * (at your option) any later version.
55
+ */
56
+
58
+
57
+/*
59
+ arm_cpu_lpa2_finalize(cpu, &local_err);
58
+ * This is a model of the "APB watchdog" which is part of the Cortex-M
60
+ if (local_err != NULL) {
59
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
61
+ error_propagate(errp, local_err);
60
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
62
+ return;
61
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
63
+ }
62
+ *
64
}
63
+ * QEMU interface:
65
64
+ * + QOM property "wdogclk-frq": frequency at which the watchdog is clocked
66
if (kvm_enabled()) {
65
+ * + sysbus MMIO region 0: the register bank
67
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
66
+ * + sysbus IRQ 0: watchdog interrupt
68
index XXXXXXX..XXXXXXX 100644
67
+ *
69
--- a/target/arm/cpu64.c
68
+ * In real hardware the watchdog's reset output is just a GPIO line
70
+++ b/target/arm/cpu64.c
69
+ * which can then be masked by the board or treated as a simple interrupt.
71
@@ -XXX,XX +XXX,XX @@ void aarch64_add_pauth_properties(Object *obj)
70
+ * (For instance the IoTKit does this with the non-secure watchdog, so that
72
}
71
+ * secure code can control whether non-secure code can perform a system
73
}
72
+ * reset via its watchdog.) In QEMU, we just wire up the watchdog reset
74
73
+ * to watchdog_perform_action(), at least for the moment.
75
+static Property arm_cpu_lpa2_property =
74
+ */
76
+ DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
75
+
77
+
76
+#ifndef CMSDK_APB_WATCHDOG_H
78
+void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp)
77
+#define CMSDK_APB_WATCHDOG_H
79
+{
80
+ uint64_t t;
78
+
81
+
79
+#include "hw/sysbus.h"
82
+ /*
80
+#include "hw/ptimer.h"
83
+ * We only install the property for tcg -cpu max; this is the
81
+
84
+ * only situation in which the cpu field can be true.
82
+#define TYPE_CMSDK_APB_WATCHDOG "cmsdk-apb-watchdog"
85
+ */
83
+#define CMSDK_APB_WATCHDOG(obj) OBJECT_CHECK(CMSDKAPBWatchdog, (obj), \
86
+ if (!cpu->prop_lpa2) {
84
+ TYPE_CMSDK_APB_WATCHDOG)
85
+
86
+typedef struct CMSDKAPBWatchdog {
87
+ /*< private >*/
88
+ SysBusDevice parent_obj;
89
+
90
+ /*< public >*/
91
+ MemoryRegion iomem;
92
+ qemu_irq wdogint;
93
+ uint32_t wdogclk_frq;
94
+ struct ptimer_state *timer;
95
+
96
+ uint32_t control;
97
+ uint32_t intstatus;
98
+ uint32_t lock;
99
+ uint32_t itcr;
100
+ uint32_t itop;
101
+ uint32_t resetstatus;
102
+} CMSDKAPBWatchdog;
103
+
104
+#endif
105
diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c
106
new file mode 100644
107
index XXXXXXX..XXXXXXX
108
--- /dev/null
109
+++ b/hw/watchdog/cmsdk-apb-watchdog.c
110
@@ -XXX,XX +XXX,XX @@
111
+/*
112
+ * ARM CMSDK APB watchdog emulation
113
+ *
114
+ * Copyright (c) 2018 Linaro Limited
115
+ * Written by Peter Maydell
116
+ *
117
+ * This program is free software; you can redistribute it and/or modify
118
+ * it under the terms of the GNU General Public License version 2 or
119
+ * (at your option) any later version.
120
+ */
121
+
122
+/*
123
+ * This is a model of the "APB watchdog" which is part of the Cortex-M
124
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
125
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
126
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
127
+ */
128
+
129
+#include "qemu/osdep.h"
130
+#include "qemu/log.h"
131
+#include "trace.h"
132
+#include "qapi/error.h"
133
+#include "qemu/main-loop.h"
134
+#include "sysemu/watchdog.h"
135
+#include "hw/sysbus.h"
136
+#include "hw/registerfields.h"
137
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
138
+
139
+REG32(WDOGLOAD, 0x0)
140
+REG32(WDOGVALUE, 0x4)
141
+REG32(WDOGCONTROL, 0x8)
142
+ FIELD(WDOGCONTROL, INTEN, 0, 1)
143
+ FIELD(WDOGCONTROL, RESEN, 1, 1)
144
+#define R_WDOGCONTROL_VALID_MASK (R_WDOGCONTROL_INTEN_MASK | \
145
+ R_WDOGCONTROL_RESEN_MASK)
146
+REG32(WDOGINTCLR, 0xc)
147
+REG32(WDOGRIS, 0x10)
148
+ FIELD(WDOGRIS, INT, 0, 1)
149
+REG32(WDOGMIS, 0x14)
150
+REG32(WDOGLOCK, 0xc00)
151
+#define WDOG_UNLOCK_VALUE 0x1ACCE551
152
+REG32(WDOGITCR, 0xf00)
153
+ FIELD(WDOGITCR, ENABLE, 0, 1)
154
+#define R_WDOGITCR_VALID_MASK R_WDOGITCR_ENABLE_MASK
155
+REG32(WDOGITOP, 0xf04)
156
+ FIELD(WDOGITOP, WDOGRES, 0, 1)
157
+ FIELD(WDOGITOP, WDOGINT, 1, 1)
158
+#define R_WDOGITOP_VALID_MASK (R_WDOGITOP_WDOGRES_MASK | \
159
+ R_WDOGITOP_WDOGINT_MASK)
160
+REG32(PID4, 0xfd0)
161
+REG32(PID5, 0xfd4)
162
+REG32(PID6, 0xfd8)
163
+REG32(PID7, 0xfdc)
164
+REG32(PID0, 0xfe0)
165
+REG32(PID1, 0xfe4)
166
+REG32(PID2, 0xfe8)
167
+REG32(PID3, 0xfec)
168
+REG32(CID0, 0xff0)
169
+REG32(CID1, 0xff4)
170
+REG32(CID2, 0xff8)
171
+REG32(CID3, 0xffc)
172
+
173
+/* PID/CID values */
174
+static const int watchdog_id[] = {
175
+ 0x04, 0x00, 0x00, 0x00, /* PID4..PID7 */
176
+ 0x24, 0xb8, 0x1b, 0x00, /* PID0..PID3 */
177
+ 0x0d, 0xf0, 0x05, 0xb1, /* CID0..CID3 */
178
+};
179
+
180
+static bool cmsdk_apb_watchdog_intstatus(CMSDKAPBWatchdog *s)
181
+{
182
+ /* Return masked interrupt status */
183
+ return s->intstatus && (s->control & R_WDOGCONTROL_INTEN_MASK);
184
+}
185
+
186
+static bool cmsdk_apb_watchdog_resetstatus(CMSDKAPBWatchdog *s)
187
+{
188
+ /* Return masked reset status */
189
+ return s->resetstatus && (s->control & R_WDOGCONTROL_RESEN_MASK);
190
+}
191
+
192
+static void cmsdk_apb_watchdog_update(CMSDKAPBWatchdog *s)
193
+{
194
+ bool wdogint;
195
+ bool wdogres;
196
+
197
+ if (s->itcr) {
198
+ wdogint = s->itop & R_WDOGITOP_WDOGINT_MASK;
199
+ wdogres = s->itop & R_WDOGITOP_WDOGRES_MASK;
200
+ } else {
201
+ wdogint = cmsdk_apb_watchdog_intstatus(s);
202
+ wdogres = cmsdk_apb_watchdog_resetstatus(s);
203
+ }
204
+
205
+ qemu_set_irq(s->wdogint, wdogint);
206
+ if (wdogres) {
207
+ watchdog_perform_action();
208
+ }
209
+}
210
+
211
+static uint64_t cmsdk_apb_watchdog_read(void *opaque, hwaddr offset,
212
+ unsigned size)
213
+{
214
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
215
+ uint64_t r;
216
+
217
+ switch (offset) {
218
+ case A_WDOGLOAD:
219
+ r = ptimer_get_limit(s->timer);
220
+ break;
221
+ case A_WDOGVALUE:
222
+ r = ptimer_get_count(s->timer);
223
+ break;
224
+ case A_WDOGCONTROL:
225
+ r = s->control;
226
+ break;
227
+ case A_WDOGRIS:
228
+ r = s->intstatus;
229
+ break;
230
+ case A_WDOGMIS:
231
+ r = cmsdk_apb_watchdog_intstatus(s);
232
+ break;
233
+ case A_WDOGLOCK:
234
+ r = s->lock;
235
+ break;
236
+ case A_WDOGITCR:
237
+ r = s->itcr;
238
+ break;
239
+ case A_PID4 ... A_CID3:
240
+ r = watchdog_id[(offset - A_PID4) / 4];
241
+ break;
242
+ case A_WDOGINTCLR:
243
+ case A_WDOGITOP:
244
+ qemu_log_mask(LOG_GUEST_ERROR,
245
+ "CMSDK APB watchdog read: read of WO offset %x\n",
246
+ (int)offset);
247
+ r = 0;
248
+ break;
249
+ default:
250
+ qemu_log_mask(LOG_GUEST_ERROR,
251
+ "CMSDK APB watchdog read: bad offset %x\n", (int)offset);
252
+ r = 0;
253
+ break;
254
+ }
255
+ trace_cmsdk_apb_watchdog_read(offset, r, size);
256
+ return r;
257
+}
258
+
259
+static void cmsdk_apb_watchdog_write(void *opaque, hwaddr offset,
260
+ uint64_t value, unsigned size)
261
+{
262
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
263
+
264
+ trace_cmsdk_apb_watchdog_write(offset, value, size);
265
+
266
+ if (s->lock && offset != A_WDOGLOCK) {
267
+ /* Write access is disabled via WDOGLOCK */
268
+ qemu_log_mask(LOG_GUEST_ERROR,
269
+ "CMSDK APB watchdog write: write to locked watchdog\n");
270
+ return;
87
+ return;
271
+ }
88
+ }
272
+
89
+
273
+ switch (offset) {
90
+ t = cpu->isar.id_aa64mmfr0;
274
+ case A_WDOGLOAD:
91
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 2); /* 16k pages w/ LPA2 */
275
+ /*
92
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4, 1); /* 4k pages w/ LPA2 */
276
+ * Reset the load value and the current count, and make sure
93
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 3); /* 16k stage2 w/ LPA2 */
277
+ * we're counting.
94
+ t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 3); /* 4k stage2 w/ LPA2 */
278
+ */
95
+ cpu->isar.id_aa64mmfr0 = t;
279
+ ptimer_set_limit(s->timer, value, 1);
280
+ ptimer_run(s->timer, 0);
281
+ break;
282
+ case A_WDOGCONTROL:
283
+ s->control = value & R_WDOGCONTROL_VALID_MASK;
284
+ cmsdk_apb_watchdog_update(s);
285
+ break;
286
+ case A_WDOGINTCLR:
287
+ s->intstatus = 0;
288
+ ptimer_set_count(s->timer, ptimer_get_limit(s->timer));
289
+ cmsdk_apb_watchdog_update(s);
290
+ break;
291
+ case A_WDOGLOCK:
292
+ s->lock = (value != WDOG_UNLOCK_VALUE);
293
+ break;
294
+ case A_WDOGITCR:
295
+ s->itcr = value & R_WDOGITCR_VALID_MASK;
296
+ cmsdk_apb_watchdog_update(s);
297
+ break;
298
+ case A_WDOGITOP:
299
+ s->itop = value & R_WDOGITOP_VALID_MASK;
300
+ cmsdk_apb_watchdog_update(s);
301
+ break;
302
+ case A_WDOGVALUE:
303
+ case A_WDOGRIS:
304
+ case A_WDOGMIS:
305
+ case A_PID4 ... A_CID3:
306
+ qemu_log_mask(LOG_GUEST_ERROR,
307
+ "CMSDK APB watchdog write: write to RO offset 0x%x\n",
308
+ (int)offset);
309
+ break;
310
+ default:
311
+ qemu_log_mask(LOG_GUEST_ERROR,
312
+ "CMSDK APB watchdog write: bad offset 0x%x\n",
313
+ (int)offset);
314
+ break;
315
+ }
316
+}
96
+}
317
+
97
+
318
+static const MemoryRegionOps cmsdk_apb_watchdog_ops = {
98
static void aarch64_host_initfn(Object *obj)
319
+ .read = cmsdk_apb_watchdog_read,
99
{
320
+ .write = cmsdk_apb_watchdog_write,
100
#if defined(CONFIG_KVM)
321
+ .endianness = DEVICE_LITTLE_ENDIAN,
101
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
322
+ /* byte/halfword accesses are just zero-padded on reads and writes */
102
aarch64_add_sve_properties(obj);
323
+ .impl.min_access_size = 4,
103
object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
324
+ .impl.max_access_size = 4,
104
cpu_max_set_sve_max_vq, NULL, NULL);
325
+ .valid.min_access_size = 1,
105
+ qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
326
+ .valid.max_access_size = 4,
106
}
327
+};
107
328
+
108
static void aarch64_a64fx_initfn(Object *obj)
329
+static void cmsdk_apb_watchdog_tick(void *opaque)
109
diff --git a/tests/avocado/boot_linux.py b/tests/avocado/boot_linux.py
330
+{
331
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
332
+
333
+ if (!s->intstatus) {
334
+ /* Count expired for the first time: raise interrupt */
335
+ s->intstatus = R_WDOGRIS_INT_MASK;
336
+ } else {
337
+ /* Count expired for the second time: raise reset and stop clock */
338
+ s->resetstatus = 1;
339
+ ptimer_stop(s->timer);
340
+ }
341
+ cmsdk_apb_watchdog_update(s);
342
+}
343
+
344
+static void cmsdk_apb_watchdog_reset(DeviceState *dev)
345
+{
346
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev);
347
+
348
+ trace_cmsdk_apb_watchdog_reset();
349
+ s->control = 0;
350
+ s->intstatus = 0;
351
+ s->lock = 0;
352
+ s->itcr = 0;
353
+ s->itop = 0;
354
+ s->resetstatus = 0;
355
+ /* Set the limit and the count */
356
+ ptimer_set_limit(s->timer, 0xffffffff, 1);
357
+ ptimer_run(s->timer, 0);
358
+}
359
+
360
+static void cmsdk_apb_watchdog_init(Object *obj)
361
+{
362
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
363
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(obj);
364
+
365
+ memory_region_init_io(&s->iomem, obj, &cmsdk_apb_watchdog_ops,
366
+ s, "cmsdk-apb-watchdog", 0x1000);
367
+ sysbus_init_mmio(sbd, &s->iomem);
368
+ sysbus_init_irq(sbd, &s->wdogint);
369
+}
370
+
371
+static void cmsdk_apb_watchdog_realize(DeviceState *dev, Error **errp)
372
+{
373
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(dev);
374
+ QEMUBH *bh;
375
+
376
+ if (s->wdogclk_frq == 0) {
377
+ error_setg(errp,
378
+ "CMSDK APB watchdog: wdogclk-frq property must be set");
379
+ return;
380
+ }
381
+
382
+ bh = qemu_bh_new(cmsdk_apb_watchdog_tick, s);
383
+ s->timer = ptimer_init(bh,
384
+ PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD |
385
+ PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT |
386
+ PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
387
+ PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
388
+
389
+ ptimer_set_freq(s->timer, s->wdogclk_frq);
390
+}
391
+
392
+static const VMStateDescription cmsdk_apb_watchdog_vmstate = {
393
+ .name = "cmsdk-apb-watchdog",
394
+ .version_id = 1,
395
+ .minimum_version_id = 1,
396
+ .fields = (VMStateField[]) {
397
+ VMSTATE_PTIMER(timer, CMSDKAPBWatchdog),
398
+ VMSTATE_UINT32(control, CMSDKAPBWatchdog),
399
+ VMSTATE_UINT32(intstatus, CMSDKAPBWatchdog),
400
+ VMSTATE_UINT32(lock, CMSDKAPBWatchdog),
401
+ VMSTATE_UINT32(itcr, CMSDKAPBWatchdog),
402
+ VMSTATE_UINT32(itop, CMSDKAPBWatchdog),
403
+ VMSTATE_UINT32(resetstatus, CMSDKAPBWatchdog),
404
+ VMSTATE_END_OF_LIST()
405
+ }
406
+};
407
+
408
+static Property cmsdk_apb_watchdog_properties[] = {
409
+ DEFINE_PROP_UINT32("wdogclk-frq", CMSDKAPBWatchdog, wdogclk_frq, 0),
410
+ DEFINE_PROP_END_OF_LIST(),
411
+};
412
+
413
+static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, void *data)
414
+{
415
+ DeviceClass *dc = DEVICE_CLASS(klass);
416
+
417
+ dc->realize = cmsdk_apb_watchdog_realize;
418
+ dc->vmsd = &cmsdk_apb_watchdog_vmstate;
419
+ dc->reset = cmsdk_apb_watchdog_reset;
420
+ dc->props = cmsdk_apb_watchdog_properties;
421
+}
422
+
423
+static const TypeInfo cmsdk_apb_watchdog_info = {
424
+ .name = TYPE_CMSDK_APB_WATCHDOG,
425
+ .parent = TYPE_SYS_BUS_DEVICE,
426
+ .instance_size = sizeof(CMSDKAPBWatchdog),
427
+ .instance_init = cmsdk_apb_watchdog_init,
428
+ .class_init = cmsdk_apb_watchdog_class_init,
429
+};
430
+
431
+static void cmsdk_apb_watchdog_register_types(void)
432
+{
433
+ type_register_static(&cmsdk_apb_watchdog_info);
434
+}
435
+
436
+type_init(cmsdk_apb_watchdog_register_types);
437
diff --git a/MAINTAINERS b/MAINTAINERS
438
index XXXXXXX..XXXXXXX 100644
110
index XXXXXXX..XXXXXXX 100644
439
--- a/MAINTAINERS
111
--- a/tests/avocado/boot_linux.py
440
+++ b/MAINTAINERS
112
+++ b/tests/avocado/boot_linux.py
441
@@ -XXX,XX +XXX,XX @@ F: hw/timer/cmsdk-apb-timer.c
113
@@ -XXX,XX +XXX,XX @@ def test_virt_tcg_gicv2(self):
442
F: include/hw/timer/cmsdk-apb-timer.h
114
"""
443
F: hw/char/cmsdk-apb-uart.c
115
self.require_accelerator("tcg")
444
F: include/hw/char/cmsdk-apb-uart.h
116
self.vm.add_args("-accel", "tcg")
445
+F: hw/watchdog/cmsdk-apb-watchdog.c
117
+ self.vm.add_args("-cpu", "max,lpa2=off")
446
+F: include/hw/watchdog/cmsdk-apb-watchdog.h
118
self.vm.add_args("-machine", "virt,gic-version=2")
447
F: hw/misc/tz-ppc.c
119
self.add_common_args()
448
F: include/hw/misc/tz-ppc.h
120
self.launch_and_wait(set_up_ssh_connection=False)
449
F: hw/misc/tz-mpc.c
121
@@ -XXX,XX +XXX,XX @@ def test_virt_tcg_gicv3(self):
450
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
122
"""
451
index XXXXXXX..XXXXXXX 100644
123
self.require_accelerator("tcg")
452
--- a/default-configs/arm-softmmu.mak
124
self.vm.add_args("-accel", "tcg")
453
+++ b/default-configs/arm-softmmu.mak
125
+ self.vm.add_args("-cpu", "max,lpa2=off")
454
@@ -XXX,XX +XXX,XX @@ CONFIG_STM32F205_SOC=y
126
self.vm.add_args("-machine", "virt,gic-version=3")
455
127
self.add_common_args()
456
CONFIG_CMSDK_APB_TIMER=y
128
self.launch_and_wait(set_up_ssh_connection=False)
457
CONFIG_CMSDK_APB_UART=y
458
+CONFIG_CMSDK_APB_WATCHDOG=y
459
460
CONFIG_MPS2_FPGAIO=y
461
CONFIG_MPS2_SCC=y
462
diff --git a/hw/watchdog/trace-events b/hw/watchdog/trace-events
463
new file mode 100644
464
index XXXXXXX..XXXXXXX
465
--- /dev/null
466
+++ b/hw/watchdog/trace-events
467
@@ -XXX,XX +XXX,XX @@
468
+# See docs/devel/tracing.txt for syntax documentation.
469
+
470
+# hw/char/cmsdk_apb_watchdog.c
471
+cmsdk_apb_watchdog_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
472
+cmsdk_apb_watchdog_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB watchdog write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
473
+cmsdk_apb_watchdog_reset(void) "CMSDK APB watchdog: reset"
474
--
129
--
475
2.18.0
130
2.25.1
476
477
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Andrew Jones <drjones@redhat.com>
3
There is a Linux kernel bug present until v5.12 that prevents
4
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
4
booting with FEAT_LPA2 enabled. As a workaround for TCG,
5
disable this feature for machine versions prior to 7.0.
6
7
Cc: Daniel P. Berrangé <berrange@redhat.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
hw/arm/virt.c | 23 +++++++++++++++++------
12
include/hw/arm/virt.h | 1 +
9
1 file changed, 17 insertions(+), 6 deletions(-)
13
hw/arm/virt.c | 7 +++++++
14
2 files changed, 8 insertions(+)
10
15
16
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/virt.h
19
+++ b/include/hw/arm/virt.h
20
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
21
bool no_secure_gpio;
22
/* Machines < 6.2 have no support for describing cpu topology to guest */
23
bool no_cpu_topology;
24
+ bool no_tcg_lpa2;
25
};
26
27
struct VirtMachineState {
11
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
28
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
12
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/arm/virt.c
30
--- a/hw/arm/virt.c
14
+++ b/hw/arm/virt.c
31
+++ b/hw/arm/virt.c
15
@@ -XXX,XX +XXX,XX @@ static void machvirt_machine_init(void)
32
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
33
object_property_set_bool(cpuobj, "pmu", false, NULL);
34
}
35
36
+ if (vmc->no_tcg_lpa2 && object_property_find(cpuobj, "lpa2")) {
37
+ object_property_set_bool(cpuobj, "lpa2", false, NULL);
38
+ }
39
+
40
if (object_property_find(cpuobj, "reset-cbar")) {
41
object_property_set_int(cpuobj, "reset-cbar",
42
vms->memmap[VIRT_CPUPERIPHS].base,
43
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(7, 0)
44
45
static void virt_machine_6_2_options(MachineClass *mc)
46
{
47
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
48
+
49
virt_machine_7_0_options(mc);
50
compat_props_add(mc->compat_props, hw_compat_6_2, hw_compat_6_2_len);
51
+ vmc->no_tcg_lpa2 = true;
16
}
52
}
17
type_init(machvirt_machine_init);
53
DEFINE_VIRT_MACHINE(6, 2)
18
54
19
-#define VIRT_COMPAT_2_12 \
20
- HW_COMPAT_2_12
21
-
22
-static void virt_3_0_instance_init(Object *obj)
23
+static void virt_3_1_instance_init(Object *obj)
24
{
25
VirtMachineState *vms = VIRT_MACHINE(obj);
26
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
27
@@ -XXX,XX +XXX,XX @@ static void virt_3_0_instance_init(Object *obj)
28
vms->irqmap = a15irqmap;
29
}
30
31
-static void virt_machine_3_0_options(MachineClass *mc)
32
+static void virt_machine_3_1_options(MachineClass *mc)
33
{
34
}
35
-DEFINE_VIRT_MACHINE_AS_LATEST(3, 0)
36
+DEFINE_VIRT_MACHINE_AS_LATEST(3, 1)
37
+
38
+static void virt_3_0_instance_init(Object *obj)
39
+{
40
+ virt_3_1_instance_init(obj);
41
+}
42
+
43
+static void virt_machine_3_0_options(MachineClass *mc)
44
+{
45
+ virt_machine_3_1_options(mc);
46
+}
47
+DEFINE_VIRT_MACHINE(3, 0)
48
+
49
+#define VIRT_COMPAT_2_12 \
50
+ HW_COMPAT_2_12
51
52
static void virt_2_12_instance_init(Object *obj)
53
{
54
--
55
--
55
2.18.0
56
2.25.1
56
57
57
58
diff view generated by jsdifflib