1
Small pullreq with some bug fixes to go into rc1.
1
Hi; some minor changes for 6.2, which I think can be classified
2
as bug fixes and are OK for this point in the release cycle.
3
(Wouldn't be the end of the world if they slipped to 7.0.)
2
4
3
-- PMM
5
-- PMM
4
6
5
The following changes since commit 5ca634afcf83215a9a54ca6e66032325b5ffb5f6:
7
The following changes since commit 42f6c9179be4401974dd3a75ee72defd16b5092d:
6
8
7
Merge remote-tracking branch 'remotes/philmd/tags/sdmmc-20210322' into staging (2021-03-22 18:50:25 +0000)
9
Merge tag 'pull-ppc-20211112' of https://github.com/legoater/qemu into staging (2021-11-12 12:28:25 +0100)
8
10
9
are available in the Git repository at:
11
are available in the Git repository at:
10
12
11
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210323
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20211115-1
12
14
13
for you to fetch changes up to dad90de78e9e9d47cefcbcd30115706b98e6ec87:
15
for you to fetch changes up to 1adf528ec3bdf62ea3b580b7ad562534a3676ff5:
14
16
15
target/arm: Set ARMMMUFaultInfo.level in user-only arm_cpu_tlb_fill (2021-03-23 14:07:55 +0000)
17
hw/rtc/pl031: Send RTC_CHANGE QMP event (2021-11-15 18:53:00 +0000)
16
18
17
----------------------------------------------------------------
19
----------------------------------------------------------------
18
target-arm queue:
20
target-arm queue:
19
* hw/arm/virt: Disable pl011 clock migration if needed
21
* Support multiple redistributor regions for TCG GICv3
20
* target/arm: Make M-profile VTOR loads on reset handle memory aliasing
22
* Send RTC_CHANGE QMP event from pl031
21
* target/arm: Set ARMMMUFaultInfo.level in user-only arm_cpu_tlb_fill
22
23
23
----------------------------------------------------------------
24
----------------------------------------------------------------
24
Gavin Shan (1):
25
Eric Auger (1):
25
hw/arm/virt: Disable pl011 clock migration if needed
26
hw/rtc/pl031: Send RTC_CHANGE QMP event
26
27
27
Peter Maydell (5):
28
Peter Maydell (3):
28
memory: Make flatview_cb return bool, not int
29
hw/intc/arm_gicv3: Move checking of redist-region-count to arm_gicv3_common_realize
29
memory: Document flatview_for_each_range()
30
hw/intc/arm_gicv3: Set GICR_TYPER.Last correctly when nb_redist_regions > 1
30
memory: Add offset_in_region to flatview_cb arguments
31
hw/intc/arm_gicv3: Support multiple redistributor regions
31
hw/core/loader: Add new function rom_ptr_for_as()
32
target/arm: Make M-profile VTOR loads on reset handle memory aliasing
33
32
34
Richard Henderson (1):
33
include/hw/intc/arm_gicv3_common.h | 14 ++++++++--
35
target/arm: Set ARMMMUFaultInfo.level in user-only arm_cpu_tlb_fill
34
hw/intc/arm_gicv3.c | 12 +-------
35
hw/intc/arm_gicv3_common.c | 56 ++++++++++++++++++++++++--------------
36
hw/intc/arm_gicv3_kvm.c | 10 ++-----
37
hw/intc/arm_gicv3_redist.c | 40 +++++++++++++++------------
38
hw/rtc/pl031.c | 10 ++++++-
39
hw/rtc/meson.build | 2 +-
40
7 files changed, 83 insertions(+), 61 deletions(-)
36
41
37
include/exec/memory.h | 32 +++++++++++++++---
38
include/hw/char/pl011.h | 1 +
39
include/hw/loader.h | 31 +++++++++++++++++
40
hw/char/pl011.c | 9 +++++
41
hw/core/loader.c | 75 +++++++++++++++++++++++++++++++++++++++++
42
hw/core/machine.c | 1 +
43
softmmu/memory.c | 4 ++-
44
target/arm/cpu.c | 2 +-
45
target/arm/tlb_helper.c | 1 +
46
tests/qtest/fuzz/generic_fuzz.c | 11 +++---
47
10 files changed, 157 insertions(+), 10 deletions(-)
48
diff view generated by jsdifflib
Deleted patch
1
From: Gavin Shan <gshan@redhat.com>
2
1
3
A clock is added by commit aac63e0e6ea3 ("hw/char/pl011: add a clock
4
input") since v5.2.0 which corresponds to virt-5.2 machine type. It
5
causes backwards migration failure from upstream to downstream (v5.1.0)
6
when the machine type is specified with virt-5.1.
7
8
This fixes the issue by following instructions from section "Connecting
9
subsections to properties" in docs/devel/migration.rst. With this applied,
10
the PL011 clock is migrated based on the machine type.
11
12
virt-5.2 or newer: migration
13
virt-5.1 or older: non-migration
14
15
Cc: qemu-stable@nongnu.org # v5.2.0+
16
Fixes: aac63e0e6ea3 ("hw/char/pl011: add a clock input")
17
Suggested-by: Andrew Jones <drjones@redhat.com>
18
Signed-off-by: Gavin Shan <gshan@redhat.com>
19
Reviewed-by: Andrew Jones <drjones@redhat.com>
20
Message-id: 20210318023801.18287-1-gshan@redhat.com
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
---
23
include/hw/char/pl011.h | 1 +
24
hw/char/pl011.c | 9 +++++++++
25
hw/core/machine.c | 1 +
26
3 files changed, 11 insertions(+)
27
28
diff --git a/include/hw/char/pl011.h b/include/hw/char/pl011.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/char/pl011.h
31
+++ b/include/hw/char/pl011.h
32
@@ -XXX,XX +XXX,XX @@ struct PL011State {
33
CharBackend chr;
34
qemu_irq irq[6];
35
Clock *clk;
36
+ bool migrate_clk;
37
const unsigned char *id;
38
};
39
40
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/char/pl011.c
43
+++ b/hw/char/pl011.c
44
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps pl011_ops = {
45
.endianness = DEVICE_NATIVE_ENDIAN,
46
};
47
48
+static bool pl011_clock_needed(void *opaque)
49
+{
50
+ PL011State *s = PL011(opaque);
51
+
52
+ return s->migrate_clk;
53
+}
54
+
55
static const VMStateDescription vmstate_pl011_clock = {
56
.name = "pl011/clock",
57
.version_id = 1,
58
.minimum_version_id = 1,
59
+ .needed = pl011_clock_needed,
60
.fields = (VMStateField[]) {
61
VMSTATE_CLOCK(clk, PL011State),
62
VMSTATE_END_OF_LIST()
63
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pl011 = {
64
65
static Property pl011_properties[] = {
66
DEFINE_PROP_CHR("chardev", PL011State, chr),
67
+ DEFINE_PROP_BOOL("migrate-clk", PL011State, migrate_clk, true),
68
DEFINE_PROP_END_OF_LIST(),
69
};
70
71
diff --git a/hw/core/machine.c b/hw/core/machine.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/hw/core/machine.c
74
+++ b/hw/core/machine.c
75
@@ -XXX,XX +XXX,XX @@ GlobalProperty hw_compat_5_1[] = {
76
{ "virtio-scsi-device", "num_queues", "1"},
77
{ "nvme", "use-intel-id", "on"},
78
{ "pvpanic", "events", "1"}, /* PVPANIC_PANICKED */
79
+ { "pl011", "migrate-clk", "off" },
80
};
81
const size_t hw_compat_5_1_len = G_N_ELEMENTS(hw_compat_5_1);
82
83
--
84
2.20.1
85
86
diff view generated by jsdifflib
1
The return value of the flatview_cb callback passed to the
1
The GICv3 devices have an array property redist-region-count.
2
flatview_for_each_range() function is zero if the iteration through
2
Currently we check this for errors (bad values) in
3
the ranges should continue, or non-zero to break out of it. Use a
3
gicv3_init_irqs_and_mmio(), just before we use it. Move this error
4
bool for this rather than int.
4
checking to the arm_gicv3_common_realize() function, where we
5
sanity-check all of the other base-class properties. (This will
6
always be before gicv3_init_irqs_and_mmio() is called, because
7
that function is called in the subclass realize methods, after
8
they have called the parent-class realize.)
9
10
The motivation for this refactor is:
11
* we would like to use the redist_region_count[] values in
12
arm_gicv3_common_realize() in a subsequent patch, so we need
13
to have already done the sanity-checking first
14
* this removes the only use of the Error** argument to
15
gicv3_init_irqs_and_mmio(), so we can remove some error-handling
16
boilerplate
5
17
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210318174823.18066-2-peter.maydell@linaro.org
10
---
20
---
11
include/exec/memory.h | 6 +++---
21
include/hw/intc/arm_gicv3_common.h | 2 +-
12
tests/qtest/fuzz/generic_fuzz.c | 8 ++++----
22
hw/intc/arm_gicv3.c | 6 +-----
13
2 files changed, 7 insertions(+), 7 deletions(-)
23
hw/intc/arm_gicv3_common.c | 26 +++++++++++++-------------
24
hw/intc/arm_gicv3_kvm.c | 6 +-----
25
4 files changed, 16 insertions(+), 24 deletions(-)
14
26
15
diff --git a/include/exec/memory.h b/include/exec/memory.h
27
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
16
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
17
--- a/include/exec/memory.h
29
--- a/include/hw/intc/arm_gicv3_common.h
18
+++ b/include/exec/memory.h
30
+++ b/include/hw/intc/arm_gicv3_common.h
19
@@ -XXX,XX +XXX,XX @@ static inline FlatView *address_space_to_flatview(AddressSpace *as)
31
@@ -XXX,XX +XXX,XX @@ struct ARMGICv3CommonClass {
20
return qatomic_rcu_read(&as->current_map);
32
};
33
34
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
35
- const MemoryRegionOps *ops, Error **errp);
36
+ const MemoryRegionOps *ops);
37
38
#endif
39
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/intc/arm_gicv3.c
42
+++ b/hw/intc/arm_gicv3.c
43
@@ -XXX,XX +XXX,XX @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
44
return;
45
}
46
47
- gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops, &local_err);
48
- if (local_err) {
49
- error_propagate(errp, local_err);
50
- return;
51
- }
52
+ gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops);
53
54
gicv3_init_cpuif(s);
21
}
55
}
22
56
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
23
-typedef int (*flatview_cb)(Int128 start,
24
- Int128 len,
25
- const MemoryRegion*, void*);
26
+typedef bool (*flatview_cb)(Int128 start,
27
+ Int128 len,
28
+ const MemoryRegion*, void*);
29
30
void flatview_for_each_range(FlatView *fv, flatview_cb cb , void *opaque);
31
32
diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
33
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
34
--- a/tests/qtest/fuzz/generic_fuzz.c
58
--- a/hw/intc/arm_gicv3_common.c
35
+++ b/tests/qtest/fuzz/generic_fuzz.c
59
+++ b/hw/intc/arm_gicv3_common.c
36
@@ -XXX,XX +XXX,XX @@ struct get_io_cb_info {
60
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_gicv3 = {
37
address_range result;
38
};
61
};
39
62
40
-static int get_io_address_cb(Int128 start, Int128 size,
63
void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
41
- const MemoryRegion *mr, void *opaque) {
64
- const MemoryRegionOps *ops, Error **errp)
42
+static bool get_io_address_cb(Int128 start, Int128 size,
65
+ const MemoryRegionOps *ops)
43
+ const MemoryRegion *mr, void *opaque) {
66
{
44
struct get_io_cb_info *info = opaque;
67
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
45
if (g_hash_table_lookup(fuzzable_memoryregions, mr)) {
68
- int rdist_capacity = 0;
46
if (info->index == 0) {
69
int i;
47
info->result.addr = (ram_addr_t)start;
70
48
info->result.size = (ram_addr_t)size;
71
- for (i = 0; i < s->nb_redist_regions; i++) {
49
info->found = 1;
72
- rdist_capacity += s->redist_region_count[i];
50
- return 1;
73
- }
51
+ return true;
74
- if (rdist_capacity < s->num_cpu) {
52
}
75
- error_setg(errp, "Capacity of the redist regions(%d) "
53
info->index--;
76
- "is less than number of vcpus(%d)",
77
- rdist_capacity, s->num_cpu);
78
- return;
79
- }
80
-
81
/* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
82
* GPIO array layout is thus:
83
* [0..N-1] spi
84
@@ -XXX,XX +XXX,XX @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
85
static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
86
{
87
GICv3State *s = ARM_GICV3_COMMON(dev);
88
- int i;
89
+ int i, rdist_capacity;
90
91
/* revision property is actually reserved and currently used only in order
92
* to keep the interface compatible with GICv2 code, avoiding extra
93
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
94
return;
54
}
95
}
55
- return 0;
96
56
+ return false;
97
+ rdist_capacity = 0;
57
}
98
+ for (i = 0; i < s->nb_redist_regions; i++) {
58
99
+ rdist_capacity += s->redist_region_count[i];
59
/*
100
+ }
101
+ if (rdist_capacity < s->num_cpu) {
102
+ error_setg(errp, "Capacity of the redist regions(%d) "
103
+ "is less than number of vcpus(%d)",
104
+ rdist_capacity, s->num_cpu);
105
+ return;
106
+ }
107
+
108
s->cpu = g_new0(GICv3CPUState, s->num_cpu);
109
110
for (i = 0; i < s->num_cpu; i++) {
111
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/hw/intc/arm_gicv3_kvm.c
114
+++ b/hw/intc/arm_gicv3_kvm.c
115
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
116
return;
117
}
118
119
- gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL, &local_err);
120
- if (local_err) {
121
- error_propagate(errp, local_err);
122
- return;
123
- }
124
+ gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL);
125
126
for (i = 0; i < s->num_cpu; i++) {
127
ARMCPU *cpu = ARM_CPU(qemu_get_cpu(i));
60
--
128
--
61
2.20.1
129
2.25.1
62
130
63
131
diff view generated by jsdifflib
Deleted patch
1
Add a documentation comment describing flatview_for_each_range().
2
1
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
6
Message-id: 20210318174823.18066-3-peter.maydell@linaro.org
7
---
8
include/exec/memory.h | 26 ++++++++++++++++++++++++--
9
1 file changed, 24 insertions(+), 2 deletions(-)
10
11
diff --git a/include/exec/memory.h b/include/exec/memory.h
12
index XXXXXXX..XXXXXXX 100644
13
--- a/include/exec/memory.h
14
+++ b/include/exec/memory.h
15
@@ -XXX,XX +XXX,XX @@ static inline FlatView *address_space_to_flatview(AddressSpace *as)
16
return qatomic_rcu_read(&as->current_map);
17
}
18
19
+/**
20
+ * typedef flatview_cb: callback for flatview_for_each_range()
21
+ *
22
+ * @start: start address of the range within the FlatView
23
+ * @len: length of the range in bytes
24
+ * @mr: MemoryRegion covering this range
25
+ * @opaque: data pointer passed to flatview_for_each_range()
26
+ *
27
+ * Returns: true to stop the iteration, false to keep going.
28
+ */
29
typedef bool (*flatview_cb)(Int128 start,
30
Int128 len,
31
- const MemoryRegion*, void*);
32
+ const MemoryRegion *mr,
33
+ void *opaque);
34
35
-void flatview_for_each_range(FlatView *fv, flatview_cb cb , void *opaque);
36
+/**
37
+ * flatview_for_each_range: Iterate through a FlatView
38
+ * @fv: the FlatView to iterate through
39
+ * @cb: function to call for each range
40
+ * @opaque: opaque data pointer to pass to @cb
41
+ *
42
+ * A FlatView is made up of a list of non-overlapping ranges, each of
43
+ * which is a slice of a MemoryRegion. This function iterates through
44
+ * each range in @fv, calling @cb. The callback function can terminate
45
+ * iteration early by returning 'true'.
46
+ */
47
+void flatview_for_each_range(FlatView *fv, flatview_cb cb, void *opaque);
48
49
/**
50
* struct MemoryRegionSection: describes a fragment of a #MemoryRegion
51
--
52
2.20.1
53
54
diff view generated by jsdifflib
1
For accesses to rom blob data before or during reset, we have a
1
The 'Last' bit in the GICR_TYPER GICv3 redistributor register is
2
function rom_ptr() which looks for a rom blob that would be loaded to
2
supposed to be set to 1 if this is the last redistributor in a series
3
the specified address, and returns a pointer into the rom blob data
3
of contiguous redistributor pages. Currently we set Last only for
4
corresponding to that address. This allows board or CPU code to say
4
the redistributor for CPU (num_cpu - 1). This only works if there is
5
"what is the data that is going to be loaded to this address?".
5
a single redistributor region; if there are multiple redistributor
6
regions then we need to set the Last bit for the last redistributor
7
in each region.
6
8
7
However, this function does not take account of memory region
9
This doesn't cause any problems currently because only the KVM GICv3
8
aliases. If for instance a machine model has RAM at address
10
supports multiple redistributor regions, and it ignores the value in
9
0x0000_0000 which is aliased to also appear at 0x1000_0000, a
11
GICv3State::gicr_typer. But we need to fix this before we can enable
10
rom_ptr() query for address 0x0000_0000 will only return a match if
12
support for multiple regions in the emulated GICv3.
11
the guest image provided by the user was loaded at 0x0000_0000 and
12
not if it was loaded at 0x1000_0000, even though they are the same
13
RAM and a run-time guest CPU read of 0x0000_0000 will read the data
14
loaded to 0x1000_0000.
15
16
Provide a new function rom_ptr_for_as() which takes an AddressSpace
17
argument, so that it can check whether the MemoryRegion corresponding
18
to the address is also mapped anywhere else in the AddressSpace and
19
look for rom blobs that loaded to that alias.
20
13
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20210318174823.18066-5-peter.maydell@linaro.org
24
---
16
---
25
include/hw/loader.h | 31 +++++++++++++++++++
17
hw/intc/arm_gicv3_common.c | 17 ++++++++++++-----
26
hw/core/loader.c | 75 +++++++++++++++++++++++++++++++++++++++++++++
18
1 file changed, 12 insertions(+), 5 deletions(-)
27
2 files changed, 106 insertions(+)
28
19
29
diff --git a/include/hw/loader.h b/include/hw/loader.h
20
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
30
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/loader.h
22
--- a/hw/intc/arm_gicv3_common.c
32
+++ b/include/hw/loader.h
23
+++ b/hw/intc/arm_gicv3_common.c
33
@@ -XXX,XX +XXX,XX @@ void rom_transaction_end(bool commit);
24
@@ -XXX,XX +XXX,XX @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
34
25
static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
35
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
26
{
36
void *rom_ptr(hwaddr addr, size_t size);
27
GICv3State *s = ARM_GICV3_COMMON(dev);
37
+/**
28
- int i, rdist_capacity;
38
+ * rom_ptr_for_as: Return a pointer to ROM blob data for the address
29
+ int i, rdist_capacity, cpuidx;
39
+ * @as: AddressSpace to look for the ROM blob in
30
40
+ * @addr: Address within @as
31
/* revision property is actually reserved and currently used only in order
41
+ * @size: size of data required in bytes
32
* to keep the interface compatible with GICv2 code, avoiding extra
42
+ *
33
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
43
+ * Returns: pointer into the data which backs the matching ROM blob,
34
for (i = 0; i < s->num_cpu; i++) {
44
+ * or NULL if no blob covers the address range.
35
CPUState *cpu = qemu_get_cpu(i);
45
+ *
36
uint64_t cpu_affid;
46
+ * This function looks for a ROM blob which covers the specified range
37
- int last;
47
+ * of bytes of length @size starting at @addr within the address space
38
48
+ * @as. This is useful for code which runs as part of board
39
s->cpu[i].cpu = cpu;
49
+ * initialization or CPU reset which wants to read data that is part
40
s->cpu[i].gic = s;
50
+ * of a user-supplied guest image or other guest memory contents, but
41
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
51
+ * which runs before the ROM loader's reset function has copied the
42
* PLPIS == 0 (physical LPIs not supported)
52
+ * blobs into guest memory.
43
*/
53
+ *
44
cpu_affid = object_property_get_uint(OBJECT(cpu), "mp-affinity", NULL);
54
+ * rom_ptr_for_as() will look not just for blobs loaded directly to
45
- last = (i == s->num_cpu - 1);
55
+ * the specified address, but also for blobs which were loaded to an
46
56
+ * alias of the region at a different location in the AddressSpace.
47
/* The CPU mp-affinity property is in MPIDR register format; squash
57
+ * In other words, if a machine model has RAM at address 0x0000_0000
48
* the affinity bytes into 32 bits as the GICR_TYPER has them.
58
+ * which is aliased to also appear at 0x1000_0000, rom_ptr_for_as()
49
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_common_realize(DeviceState *dev, Error **errp)
59
+ * will return the correct data whether the guest image was linked and
50
(cpu_affid & 0xFFFFFF);
60
+ * loaded at 0x0000_0000 or 0x1000_0000. Contrast rom_ptr(), which
51
s->cpu[i].gicr_typer = (cpu_affid << 32) |
61
+ * will only return data if the image load address is an exact match
52
(1 << 24) |
62
+ * with the queried address.
53
- (i << 8) |
63
+ *
54
- (last << 4);
64
+ * New code should prefer to use rom_ptr_for_as() instead of
55
+ (i << 8);
65
+ * rom_ptr().
56
66
+ */
57
if (s->lpi_enable) {
67
+void *rom_ptr_for_as(AddressSpace *as, hwaddr addr, size_t size);
58
s->cpu[i].gicr_typer |= GICR_TYPER_PLPIS;
68
void hmp_info_roms(Monitor *mon, const QDict *qdict);
59
}
69
60
}
70
#define rom_add_file_fixed(_f, _a, _i) \
61
+
71
diff --git a/hw/core/loader.c b/hw/core/loader.c
62
+ /*
72
index XXXXXXX..XXXXXXX 100644
63
+ * Now go through and set GICR_TYPER.Last for the final
73
--- a/hw/core/loader.c
64
+ * redistributor in each region.
74
+++ b/hw/core/loader.c
65
+ */
75
@@ -XXX,XX +XXX,XX @@ void *rom_ptr(hwaddr addr, size_t size)
66
+ cpuidx = 0;
76
return rom->data + (addr - rom->addr);
67
+ for (i = 0; i < s->nb_redist_regions; i++) {
68
+ cpuidx += s->redist_region_count[i];
69
+ s->cpu[cpuidx - 1].gicr_typer |= GICR_TYPER_LAST;
70
+ }
77
}
71
}
78
72
79
+typedef struct FindRomCBData {
73
static void arm_gicv3_finalize(Object *obj)
80
+ size_t size; /* Amount of data we want from ROM, in bytes */
81
+ MemoryRegion *mr; /* MR at the unaliased guest addr */
82
+ hwaddr xlat; /* Offset of addr within mr */
83
+ void *rom; /* Output: rom data pointer, if found */
84
+} FindRomCBData;
85
+
86
+static bool find_rom_cb(Int128 start, Int128 len, const MemoryRegion *mr,
87
+ hwaddr offset_in_region, void *opaque)
88
+{
89
+ FindRomCBData *cbdata = opaque;
90
+ hwaddr alias_addr;
91
+
92
+ if (mr != cbdata->mr) {
93
+ return false;
94
+ }
95
+
96
+ alias_addr = int128_get64(start) + cbdata->xlat - offset_in_region;
97
+ cbdata->rom = rom_ptr(alias_addr, cbdata->size);
98
+ if (!cbdata->rom) {
99
+ return false;
100
+ }
101
+ /* Found a match, stop iterating */
102
+ return true;
103
+}
104
+
105
+void *rom_ptr_for_as(AddressSpace *as, hwaddr addr, size_t size)
106
+{
107
+ /*
108
+ * Find any ROM data for the given guest address range. If there
109
+ * is a ROM blob then return a pointer to the host memory
110
+ * corresponding to 'addr'; otherwise return NULL.
111
+ *
112
+ * We look not only for ROM blobs that were loaded directly to
113
+ * addr, but also for ROM blobs that were loaded to aliases of
114
+ * that memory at other addresses within the AddressSpace.
115
+ *
116
+ * Note that we do not check @as against the 'as' member in the
117
+ * 'struct Rom' returned by rom_ptr(). The Rom::as is the
118
+ * AddressSpace which the rom blob should be written to, whereas
119
+ * our @as argument is the AddressSpace which we are (effectively)
120
+ * reading from, and the same underlying RAM will often be visible
121
+ * in multiple AddressSpaces. (A common example is a ROM blob
122
+ * written to the 'system' address space but then read back via a
123
+ * CPU's cpu->as pointer.) This does mean we might potentially
124
+ * return a false-positive match if a ROM blob was loaded into an
125
+ * AS which is entirely separate and distinct from the one we're
126
+ * querying, but this issue exists also for rom_ptr() and hasn't
127
+ * caused any problems in practice.
128
+ */
129
+ FlatView *fv;
130
+ void *rom;
131
+ hwaddr len_unused;
132
+ FindRomCBData cbdata = {};
133
+
134
+ /* Easy case: there's data at the actual address */
135
+ rom = rom_ptr(addr, size);
136
+ if (rom) {
137
+ return rom;
138
+ }
139
+
140
+ RCU_READ_LOCK_GUARD();
141
+
142
+ fv = address_space_to_flatview(as);
143
+ cbdata.mr = flatview_translate(fv, addr, &cbdata.xlat, &len_unused,
144
+ false, MEMTXATTRS_UNSPECIFIED);
145
+ if (!cbdata.mr) {
146
+ /* Nothing at this address, so there can't be any aliasing */
147
+ return NULL;
148
+ }
149
+ cbdata.size = size;
150
+ flatview_for_each_range(fv, find_rom_cb, &cbdata);
151
+ return cbdata.rom;
152
+}
153
+
154
void hmp_info_roms(Monitor *mon, const QDict *qdict)
155
{
156
Rom *rom;
157
--
74
--
158
2.20.1
75
2.25.1
159
76
160
77
diff view generated by jsdifflib
1
The function flatview_for_each_range() calls a callback for each
1
Our GICv3 QOM interface includes an array property
2
range in a FlatView. Currently the callback gets the start and
2
redist-region-count which allows board models to specify that the
3
length of the range and the MemoryRegion involved, but not the offset
3
registributor registers are not in a single contiguous range, but
4
within the MemoryRegion. Add this to the callback's arguments; we're
4
split into multiple pieces. We implemented this for KVM, but
5
going to want it for a new use in the next commit.
5
currently the TCG GICv3 model insists that there is only one region.
6
You can see the limit being hit with a setup like:
7
qemu-system-aarch64 -machine virt,gic-version=3 -smp 124
8
9
Add support for split regions to the TCG GICv3. To do this we switch
10
from allocating a simple array of MemoryRegions to an array of
11
GICv3RedistRegion structs so that we can use the GICv3RedistRegion as
12
the opaque pointer in the MemoryRegion read/write callbacks. Each
13
GICv3RedistRegion contains the MemoryRegion, a backpointer allowing
14
the read/write callback to get hold of the GICv3State, and an index
15
which allows us to calculate which CPU's redistributor is being
16
accessed.
17
18
Note that arm_gicv3_kvm always passes in NULL as the ops argument
19
to gicv3_init_irqs_and_mmio(), so the only MemoryRegion read/write
20
callbacks we need to update to handle this new scheme are the
21
gicv3_redist_read/write functions used by the emulated GICv3.
6
22
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Message-id: 20210318174823.18066-4-peter.maydell@linaro.org
11
---
25
---
12
include/exec/memory.h | 2 ++
26
include/hw/intc/arm_gicv3_common.h | 12 ++++++++-
13
softmmu/memory.c | 4 +++-
27
hw/intc/arm_gicv3.c | 6 -----
14
tests/qtest/fuzz/generic_fuzz.c | 5 ++++-
28
hw/intc/arm_gicv3_common.c | 15 ++++++++---
15
3 files changed, 9 insertions(+), 2 deletions(-)
29
hw/intc/arm_gicv3_kvm.c | 4 +--
16
30
hw/intc/arm_gicv3_redist.c | 40 ++++++++++++++++--------------
17
diff --git a/include/exec/memory.h b/include/exec/memory.h
31
5 files changed, 46 insertions(+), 31 deletions(-)
18
index XXXXXXX..XXXXXXX 100644
32
19
--- a/include/exec/memory.h
33
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
20
+++ b/include/exec/memory.h
34
index XXXXXXX..XXXXXXX 100644
21
@@ -XXX,XX +XXX,XX @@ static inline FlatView *address_space_to_flatview(AddressSpace *as)
35
--- a/include/hw/intc/arm_gicv3_common.h
22
* @start: start address of the range within the FlatView
36
+++ b/include/hw/intc/arm_gicv3_common.h
23
* @len: length of the range in bytes
37
@@ -XXX,XX +XXX,XX @@ struct GICv3CPUState {
24
* @mr: MemoryRegion covering this range
38
bool seenbetter;
25
+ * @offset_in_region: offset of the first byte of the range within @mr
39
};
26
* @opaque: data pointer passed to flatview_for_each_range()
40
27
*
41
+/*
28
* Returns: true to stop the iteration, false to keep going.
42
+ * The redistributor pages might be split into more than one region
29
@@ -XXX,XX +XXX,XX @@ static inline FlatView *address_space_to_flatview(AddressSpace *as)
43
+ * on some machine types if there are many CPUs.
30
typedef bool (*flatview_cb)(Int128 start,
44
+ */
31
Int128 len,
45
+typedef struct GICv3RedistRegion {
32
const MemoryRegion *mr,
46
+ GICv3State *gic;
33
+ hwaddr offset_in_region,
47
+ MemoryRegion iomem;
34
void *opaque);
48
+ uint32_t cpuidx; /* index of first CPU this region covers */
35
49
+} GICv3RedistRegion;
36
/**
50
+
37
diff --git a/softmmu/memory.c b/softmmu/memory.c
51
struct GICv3State {
38
index XXXXXXX..XXXXXXX 100644
52
/*< private >*/
39
--- a/softmmu/memory.c
53
SysBusDevice parent_obj;
40
+++ b/softmmu/memory.c
54
/*< public >*/
41
@@ -XXX,XX +XXX,XX @@ void flatview_for_each_range(FlatView *fv, flatview_cb cb , void *opaque)
55
42
assert(cb);
56
MemoryRegion iomem_dist; /* Distributor */
43
57
- MemoryRegion *iomem_redist; /* Redistributor Regions */
44
FOR_EACH_FLAT_RANGE(fr, fv) {
58
+ GICv3RedistRegion *redist_regions; /* Redistributor Regions */
45
- if (cb(fr->addr.start, fr->addr.size, fr->mr, opaque))
59
uint32_t *redist_region_count; /* redistributor count within each region */
46
+ if (cb(fr->addr.start, fr->addr.size, fr->mr,
60
uint32_t nb_redist_regions; /* number of redist regions */
47
+ fr->offset_in_region, opaque)) {
61
48
break;
62
diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c
49
+ }
63
index XXXXXXX..XXXXXXX 100644
64
--- a/hw/intc/arm_gicv3.c
65
+++ b/hw/intc/arm_gicv3.c
66
@@ -XXX,XX +XXX,XX @@ static void arm_gic_realize(DeviceState *dev, Error **errp)
67
return;
68
}
69
70
- if (s->nb_redist_regions != 1) {
71
- error_setg(errp, "VGICv3 redist region number(%d) not equal to 1",
72
- s->nb_redist_regions);
73
- return;
74
- }
75
-
76
gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops);
77
78
gicv3_init_cpuif(s);
79
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/intc/arm_gicv3_common.c
82
+++ b/hw/intc/arm_gicv3_common.c
83
@@ -XXX,XX +XXX,XX @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
84
{
85
SysBusDevice *sbd = SYS_BUS_DEVICE(s);
86
int i;
87
+ int cpuidx;
88
89
/* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
90
* GPIO array layout is thus:
91
@@ -XXX,XX +XXX,XX @@ void gicv3_init_irqs_and_mmio(GICv3State *s, qemu_irq_handler handler,
92
"gicv3_dist", 0x10000);
93
sysbus_init_mmio(sbd, &s->iomem_dist);
94
95
- s->iomem_redist = g_new0(MemoryRegion, s->nb_redist_regions);
96
+ s->redist_regions = g_new0(GICv3RedistRegion, s->nb_redist_regions);
97
+ cpuidx = 0;
98
for (i = 0; i < s->nb_redist_regions; i++) {
99
char *name = g_strdup_printf("gicv3_redist_region[%d]", i);
100
+ GICv3RedistRegion *region = &s->redist_regions[i];
101
102
- memory_region_init_io(&s->iomem_redist[i], OBJECT(s),
103
- ops ? &ops[1] : NULL, s, name,
104
+ region->gic = s;
105
+ region->cpuidx = cpuidx;
106
+ cpuidx += s->redist_region_count[i];
107
+
108
+ memory_region_init_io(&region->iomem, OBJECT(s),
109
+ ops ? &ops[1] : NULL, region, name,
110
s->redist_region_count[i] * GICV3_REDIST_SIZE);
111
- sysbus_init_mmio(sbd, &s->iomem_redist[i]);
112
+ sysbus_init_mmio(sbd, &region->iomem);
113
g_free(name);
50
}
114
}
51
}
115
}
52
116
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
53
diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
117
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
118
--- a/hw/intc/arm_gicv3_kvm.c
55
--- a/tests/qtest/fuzz/generic_fuzz.c
119
+++ b/hw/intc/arm_gicv3_kvm.c
56
+++ b/tests/qtest/fuzz/generic_fuzz.c
120
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
57
@@ -XXX,XX +XXX,XX @@ struct get_io_cb_info {
121
KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd, 0);
58
};
122
59
123
if (!multiple_redist_region_allowed) {
60
static bool get_io_address_cb(Int128 start, Int128 size,
124
- kvm_arm_register_device(&s->iomem_redist[0], -1,
61
- const MemoryRegion *mr, void *opaque) {
125
+ kvm_arm_register_device(&s->redist_regions[0].iomem, -1,
62
+ const MemoryRegion *mr,
126
KVM_DEV_ARM_VGIC_GRP_ADDR,
63
+ hwaddr offset_in_region,
127
KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd, 0);
64
+ void *opaque)
128
} else {
65
+{
129
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
66
struct get_io_cb_info *info = opaque;
130
uint64_t addr_ormask =
67
if (g_hash_table_lookup(fuzzable_memoryregions, mr)) {
131
i | ((uint64_t)s->redist_region_count[i] << 52);
68
if (info->index == 0) {
132
133
- kvm_arm_register_device(&s->iomem_redist[i], -1,
134
+ kvm_arm_register_device(&s->redist_regions[i].iomem, -1,
135
KVM_DEV_ARM_VGIC_GRP_ADDR,
136
KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION,
137
s->dev_fd, addr_ormask);
138
diff --git a/hw/intc/arm_gicv3_redist.c b/hw/intc/arm_gicv3_redist.c
139
index XXXXXXX..XXXXXXX 100644
140
--- a/hw/intc/arm_gicv3_redist.c
141
+++ b/hw/intc/arm_gicv3_redist.c
142
@@ -XXX,XX +XXX,XX @@ static MemTxResult gicr_writell(GICv3CPUState *cs, hwaddr offset,
143
MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
144
unsigned size, MemTxAttrs attrs)
145
{
146
- GICv3State *s = opaque;
147
+ GICv3RedistRegion *region = opaque;
148
+ GICv3State *s = region->gic;
149
GICv3CPUState *cs;
150
MemTxResult r;
151
int cpuidx;
152
153
assert((offset & (size - 1)) == 0);
154
155
- /* This region covers all the redistributor pages; there are
156
- * (for GICv3) two 64K pages per CPU. At the moment they are
157
- * all contiguous (ie in this one region), though we might later
158
- * want to allow splitting of redistributor pages into several
159
- * blocks so we can support more CPUs.
160
+ /*
161
+ * There are (for GICv3) two 64K redistributor pages per CPU.
162
+ * In some cases the redistributor pages for all CPUs are not
163
+ * contiguous (eg on the virt board they are split into two
164
+ * parts if there are too many CPUs to all fit in the same place
165
+ * in the memory map); if so then the GIC has multiple MemoryRegions
166
+ * for the redistributors.
167
*/
168
- cpuidx = offset / 0x20000;
169
- offset %= 0x20000;
170
- assert(cpuidx < s->num_cpu);
171
+ cpuidx = region->cpuidx + offset / GICV3_REDIST_SIZE;
172
+ offset %= GICV3_REDIST_SIZE;
173
174
cs = &s->cpu[cpuidx];
175
176
@@ -XXX,XX +XXX,XX @@ MemTxResult gicv3_redist_read(void *opaque, hwaddr offset, uint64_t *data,
177
MemTxResult gicv3_redist_write(void *opaque, hwaddr offset, uint64_t data,
178
unsigned size, MemTxAttrs attrs)
179
{
180
- GICv3State *s = opaque;
181
+ GICv3RedistRegion *region = opaque;
182
+ GICv3State *s = region->gic;
183
GICv3CPUState *cs;
184
MemTxResult r;
185
int cpuidx;
186
187
assert((offset & (size - 1)) == 0);
188
189
- /* This region covers all the redistributor pages; there are
190
- * (for GICv3) two 64K pages per CPU. At the moment they are
191
- * all contiguous (ie in this one region), though we might later
192
- * want to allow splitting of redistributor pages into several
193
- * blocks so we can support more CPUs.
194
+ /*
195
+ * There are (for GICv3) two 64K redistributor pages per CPU.
196
+ * In some cases the redistributor pages for all CPUs are not
197
+ * contiguous (eg on the virt board they are split into two
198
+ * parts if there are too many CPUs to all fit in the same place
199
+ * in the memory map); if so then the GIC has multiple MemoryRegions
200
+ * for the redistributors.
201
*/
202
- cpuidx = offset / 0x20000;
203
- offset %= 0x20000;
204
- assert(cpuidx < s->num_cpu);
205
+ cpuidx = region->cpuidx + offset / GICV3_REDIST_SIZE;
206
+ offset %= GICV3_REDIST_SIZE;
207
208
cs = &s->cpu[cpuidx];
209
69
--
210
--
70
2.20.1
211
2.25.1
71
212
72
213
diff view generated by jsdifflib
Deleted patch
1
For Arm M-profile CPUs, on reset the CPU must load its initial PC and
2
SP from a vector table in guest memory. Because we can't guarantee
3
reset ordering, we have to handle the possibility that the ROM blob
4
loader's reset function has not yet run when the CPU resets, in which
5
case the data in an ELF file specified by the user won't be in guest
6
memory to be read yet.
7
1
8
We work around the reset ordering problem by checking whether the ROM
9
blob loader has any data for the address where the vector table is,
10
using rom_ptr(). Unfortunately this does not handle the possibility
11
of memory aliasing. For many M-profile boards, memory can be
12
accessed via multiple possible physical addresses; if the board has
13
the vector table at address X but the user's ELF file loads data via
14
a different address Y which is an alias to the same underlying guest
15
RAM then rom_ptr() will not find it.
16
17
Use the new rom_ptr_for_as() function, which deals with memory
18
aliasing when locating a relevant ROM blob.
19
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Message-id: 20210318174823.18066-6-peter.maydell@linaro.org
23
---
24
target/arm/cpu.c | 2 +-
25
1 file changed, 1 insertion(+), 1 deletion(-)
26
27
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.c
30
+++ b/target/arm/cpu.c
31
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(DeviceState *dev)
32
33
/* Load the initial SP and PC from offset 0 and 4 in the vector table */
34
vecbase = env->v7m.vecbase[env->v7m.secure];
35
- rom = rom_ptr(vecbase, 8);
36
+ rom = rom_ptr_for_as(s->as, vecbase, 8);
37
if (rom) {
38
/* Address zero is covered by ROM which hasn't yet been
39
* copied into physical memory.
40
--
41
2.20.1
42
43
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Eric Auger <eric.auger@redhat.com>
2
2
3
Pretend the fault always happens at page table level 3.
3
The PL031 currently is not able to report guest RTC change to the QMP
4
monitor as opposed to mc146818 or spapr RTCs. This patch adds the call
5
to qapi_event_send_rtc_change() when the Load Register is written. The
6
value which is reported corresponds to the difference between the guest
7
reference time and the reference time kept in softmmu/rtc.c.
4
8
5
Failure to set this leaves level = 0, which is impossible for
9
For instance adding 20s to the guest RTC value will report 20. Adding
6
ARMFault_Permission, and produces an invalid syndrome, which
10
an extra 20s to the guest RTC value will report 20 + 20 = 40.
7
reaches g_assert_not_reached in cpu_loop.
8
11
9
Fixes: 8db94ab4e5db ("linux-user/aarch64: Pass syndrome to EXC_*_ABORT")
12
The inclusion of qapi/qapi-types-misc-target.h in hw/rtl/pl031.c
10
Reported-by: Laurent Vivier <laurent@vivier.eu>
13
require to compile the PL031 with specific_ss.add() to avoid
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
./qapi/qapi-types-misc-target.h:18:13: error: attempt to use poisoned
15
"TARGET_<ARCH>".
16
17
Signed-off-by: Eric Auger <eric.auger@redhat.com>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20210320000606.1788699-1-richard.henderson@linaro.org
19
Message-id: 20210920122535.269988-1-eric.auger@redhat.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
21
---
16
target/arm/tlb_helper.c | 1 +
22
hw/rtc/pl031.c | 10 +++++++++-
17
1 file changed, 1 insertion(+)
23
hw/rtc/meson.build | 2 +-
24
2 files changed, 10 insertions(+), 2 deletions(-)
18
25
19
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
26
diff --git a/hw/rtc/pl031.c b/hw/rtc/pl031.c
20
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/tlb_helper.c
28
--- a/hw/rtc/pl031.c
22
+++ b/target/arm/tlb_helper.c
29
+++ b/hw/rtc/pl031.c
23
@@ -XXX,XX +XXX,XX @@ bool arm_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
30
@@ -XXX,XX +XXX,XX @@
24
} else {
31
#include "qemu/log.h"
25
fi.type = ARMFault_Translation;
32
#include "qemu/module.h"
26
}
33
#include "trace.h"
27
+ fi.level = 3;
34
+#include "qapi/qapi-events-misc-target.h"
28
35
29
/* now we have a real cpu fault */
36
#define RTC_DR 0x00 /* Data read register */
30
cpu_restore_state(cs, retaddr, true);
37
#define RTC_MR 0x04 /* Match register */
38
@@ -XXX,XX +XXX,XX @@ static void pl031_write(void * opaque, hwaddr offset,
39
trace_pl031_write(offset, value);
40
41
switch (offset) {
42
- case RTC_LR:
43
+ case RTC_LR: {
44
+ struct tm tm;
45
+
46
s->tick_offset += value - pl031_get_count(s);
47
+
48
+ qemu_get_timedate(&tm, s->tick_offset);
49
+ qapi_event_send_rtc_change(qemu_timedate_diff(&tm));
50
+
51
pl031_set_alarm(s);
52
break;
53
+ }
54
case RTC_MR:
55
s->mr = value;
56
pl031_set_alarm(s);
57
diff --git a/hw/rtc/meson.build b/hw/rtc/meson.build
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/rtc/meson.build
60
+++ b/hw/rtc/meson.build
61
@@ -XXX,XX +XXX,XX @@
62
softmmu_ss.add(when: 'CONFIG_DS1338', if_true: files('ds1338.c'))
63
softmmu_ss.add(when: 'CONFIG_M41T80', if_true: files('m41t80.c'))
64
softmmu_ss.add(when: 'CONFIG_M48T59', if_true: files('m48t59.c'))
65
-softmmu_ss.add(when: 'CONFIG_PL031', if_true: files('pl031.c'))
66
+specific_ss.add(when: 'CONFIG_PL031', if_true: files('pl031.c'))
67
softmmu_ss.add(when: 'CONFIG_TWL92230', if_true: files('twl92230.c'))
68
softmmu_ss.add(when: ['CONFIG_ISA_BUS', 'CONFIG_M48T59'], if_true: files('m48t59-isa.c'))
69
softmmu_ss.add(when: 'CONFIG_XLNX_ZYNQMP', if_true: files('xlnx-zynqmp-rtc.c'))
31
--
70
--
32
2.20.1
71
2.25.1
33
72
34
73
diff view generated by jsdifflib