1
Target-arm queue...
1
Some more outstanding target-arm patches; nothing terribly
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.
2
8
3
thanks
9
thanks
4
-- PMM
10
-- PMM
5
11
6
The following changes since commit 735286a4f88255e1463d42ce28d8d14181fd32d4:
7
12
8
Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170613' into staging (2017-06-13 13:51:29 +0100)
13
The following changes since commit adaec191bfb31e12d40af8ab1b869f5b40d61ee9:
9
14
10
are available in the git repository at:
15
Merge remote-tracking branch 'remotes/ehabkost/tags/machine-next-pull-request' into staging (2018-08-20 09:48:03 +0100)
11
16
12
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20170613
17
are available in the Git repository at:
13
18
14
for you to fetch changes up to 252a7a6a968c279a4636a86b0559ba3a930a90b5:
19
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20180820
15
20
16
hw/intc/arm_gicv3_its: Allow save/restore (2017-06-13 14:57:01 +0100)
21
for you to fetch changes up to b85fad1588e812566f897f747e38da345a7016d6:
22
23
hw/dma/pl080: Remove hw_error() if DMA is enabled (2018-08-20 11:24:33 +0100)
17
24
18
----------------------------------------------------------------
25
----------------------------------------------------------------
19
target-arm queue:
26
target-arm queue:
20
* vITS: Support save/restore
27
* Fix crash on conditional instruction in an IT block
21
* timer/aspeed: Fix timer enablement when reload is not set
28
* docs/generic-loader: mention U-Boot and Intel HEX executable formats
22
* aspped: add temperature sensor device
29
* hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset
23
* timer.h: Provide better monotonic time on ARM hosts
30
* imx_serial: Generate interrupt on receive data ready if enabled
24
* exynos4210: various cleanups
31
* Fix various minor bugs in AArch32 Hyp related coprocessor registers
25
* exynos4210: support system poweroff
32
* Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked)
33
* Implement AArch32 ERET instruction
34
* hw/arm/virt: Add virt-3.1 machine type
35
* sdhci: add i.MX SD Stable Clock bit
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
26
41
27
----------------------------------------------------------------
42
----------------------------------------------------------------
28
Cédric Le Goater (3):
43
Andrew Jones (1):
29
hw/misc: add a TMP42{1, 2, 3} device model
44
hw/arm/virt: Add virt-3.1 machine type
30
aspeed: add a temp sensor device on I2C bus 3
31
timer/aspeed: fix timer enablement when a reload is not set
32
45
33
Eric Auger (4):
46
Hans-Erik Floryd (2):
34
kvm-all: Pass an error object to kvm_device_access
47
imx_serial: Generate interrupt on receive data ready if enabled
35
hw/intc/arm_gicv3_its: Implement state save/restore
48
sdhci: add i.MX SD Stable Clock bit
36
hw/intc/arm_gicv3_kvm: Implement pending table save
37
hw/intc/arm_gicv3_its: Allow save/restore
38
49
39
Krzysztof Kozlowski (9):
50
Jia He (1):
40
hw/intc/exynos4210_gic: Use more meaningful name for local variable
51
hw/intc/arm_gicv3_its: downgrade error_report to warn_report in kvm_arm_its_reset
41
hw/timer/exynos4210_mct: Fix checkpatch style errors
42
hw/timer/exynos4210_mct: Cleanup indentation and empty new lines
43
hw/timer/exynos4210_mct: Remove unused defines
44
hw/arm/exynos: Move DRAM initialization next boards
45
hw/arm/exynos: Declare local variables in some order
46
hw/arm/exynos: Use type define instead of hard-coded a9mpcore_priv string
47
hw/intc/exynos4210_gic: Constify array of combiner interrupts
48
hw/misc/exynos4210_pmu: Add support for system poweroff
49
52
50
Pranith Kumar (1):
53
Peter Maydell (19):
51
timer.h: Provide better monotonic time
54
target/arm: Correct typo in HAMAIR1 regdef name
55
target/arm: Add missing .cp = 15 to HMAIR1 and HAMAIR1 regdefs
56
target/arm: Implement AArch32 HVBAR
57
target/arm: Implement AArch32 Hyp FARs
58
target/arm: Implement ESR_EL2/HSR for AArch32 and no-EL2
59
target/arm: Permit accesses to ELR_Hyp from Hyp mode via MSR/MRS (banked)
60
target/arm: Implement AArch32 ERET instruction
61
hw/ssi/xilinx_spips: Remove unneeded MMIO request_ptr code
62
memory: Remove MMIO request_ptr APIs
63
hw/misc: Remove mmio_interface device
64
hw/timer/m48t59: Move away from old_mmio accessors
65
hw/watchdog/cmsdk_apb_watchdog: Implement CMSDK APB watchdog module
66
nvic: Expose NMI line
67
hw/dma/pl080: Allow use as embedded-struct device
68
hw/dma/pl080: Support all three interrupt lines
69
hw/dma/pl080: Don't use CPU address space for DMA accesses
70
hw/dma/pl080: Provide device reset function
71
hw/dma/pl080: Correct bug in register address decode logic
72
hw/dma/pl080: Remove hw_error() if DMA is enabled
52
73
53
hw/misc/Makefile.objs | 1 +
74
Roman Kapl (1):
54
include/hw/arm/exynos4210.h | 5 +-
75
target/arm: Fix crash on conditional instruction in an IT block
55
include/hw/intc/arm_gicv3_its_common.h | 8 +
56
include/migration/vmstate.h | 2 +
57
include/qemu/timer.h | 5 +-
58
include/sysemu/kvm.h | 11 +-
59
hw/arm/aspeed.c | 9 +
60
hw/arm/exynos4210.c | 27 +--
61
hw/arm/exynos4_boards.c | 50 +++-
62
hw/intc/arm_gic_kvm.c | 9 +-
63
hw/intc/arm_gicv3_common.c | 1 +
64
hw/intc/arm_gicv3_its_common.c | 12 +-
65
hw/intc/arm_gicv3_its_kvm.c | 131 +++++++++--
66
hw/intc/arm_gicv3_kvm.c | 48 +++-
67
hw/intc/exynos4210_gic.c | 14 +-
68
hw/misc/exynos4210_pmu.c | 20 +-
69
hw/misc/tmp421.c | 402 +++++++++++++++++++++++++++++++++
70
hw/timer/aspeed_timer.c | 37 ++-
71
hw/timer/exynos4210_mct.c | 50 ++--
72
kvm-all.c | 14 +-
73
default-configs/arm-softmmu.mak | 1 +
74
21 files changed, 741 insertions(+), 116 deletions(-)
75
create mode 100644 hw/misc/tmp421.c
76
76
77
Stefan Hajnoczi (1):
78
docs/generic-loader: mention U-Boot and Intel HEX executable formats
79
80
docs/generic-loader.txt | 20 +-
81
Makefile.objs | 1 +
82
hw/misc/Makefile.objs | 1 -
83
hw/watchdog/Makefile.objs | 1 +
84
hw/sd/sdhci-internal.h | 2 +
85
include/exec/memory.h | 35 ----
86
include/hw/char/imx_serial.h | 1 +
87
include/hw/dma/pl080.h | 71 +++++++
88
include/hw/misc/mmio_interface.h | 49 -----
89
include/hw/watchdog/cmsdk-apb-watchdog.h | 59 ++++++
90
hw/arm/armv7m.c | 1 +
91
hw/arm/realview.c | 8 +-
92
hw/arm/versatilepb.c | 9 +-
93
hw/arm/virt.c | 23 ++-
94
hw/char/imx_serial.c | 3 +-
95
hw/dma/pl080.c | 113 ++++++-----
96
hw/intc/arm_gicv3_its_kvm.c | 2 +-
97
hw/intc/armv7m_nvic.c | 19 ++
98
hw/misc/mmio_interface.c | 135 -------------
99
hw/sd/sdhci.c | 8 +
100
hw/ssi/xilinx_spips.c | 46 -----
101
hw/timer/m48t59.c | 59 ++----
102
hw/watchdog/cmsdk-apb-watchdog.c | 326 +++++++++++++++++++++++++++++++
103
memory.c | 110 -----------
104
target/arm/helper.c | 36 +++-
105
target/arm/op_helper.c | 22 +--
106
target/arm/translate.c | 76 +++++--
107
MAINTAINERS | 3 +
108
default-configs/arm-softmmu.mak | 1 +
109
hw/intc/trace-events | 1 +
110
hw/watchdog/trace-events | 6 +
111
31 files changed, 717 insertions(+), 530 deletions(-)
112
create mode 100644 include/hw/dma/pl080.h
113
delete mode 100644 include/hw/misc/mmio_interface.h
114
create mode 100644 include/hw/watchdog/cmsdk-apb-watchdog.h
115
delete mode 100644 hw/misc/mmio_interface.c
116
create mode 100644 hw/watchdog/cmsdk-apb-watchdog.c
117
create mode 100644 hw/watchdog/trace-events
118
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Roman Kapl <rka@sysgo.com>
2
2
3
We need to handle both registers and ITS tables. While
3
If an instruction is conditional (like CBZ) and it is executed
4
register handling is standard, ITS table handling is more
4
conditionally (using the ITx instruction), a jump to an undefined
5
challenging since the kernel API is devised so that the
5
label is generated, and QEMU crashes.
6
tables are flushed into guest RAM and not in vmstate buffers.
7
6
8
Flushing the ITS tables on device pre_save() is too late
7
CBZ in IT block is an UNPREDICTABLE behavior, but we should not
9
since the guest RAM is already saved at this point.
8
crash. Honouring the condition code is allowed by the spec in this
9
case (constrained unpredictable, ARMv8, section K1.1.7), and matches
10
what we do for other "UNPREDICTABLE inside an IT block" instructions.
10
11
11
Table flushing needs to happen when we are sure the vcpus
12
Fix the 'skip on condition' code to create a new label only if it
12
are stopped and before the last dirty page saving. The
13
does not already exist. Previously multiple labels were created, but
13
right point is RUN_STATE_FINISH_MIGRATE but sometimes the
14
only the last one of them was set.
14
VM gets stopped before migration launch so let's simply
15
flush the tables each time the VM gets stopped.
16
15
17
For regular ITS registers we just can use vmstate pre_save()
16
Signed-off-by: Roman Kapl <rka@sysgo.com>
18
and post_load() callbacks.
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
18
Message-id: 20180816120533.6587-1-rka@sysgo.com
20
Signed-off-by: Eric Auger <eric.auger@redhat.com>
19
[PMM: fixed ^ 1 being applied to wrong argument, fixed typo]
21
Message-id: 1497023553-18411-3-git-send-email-eric.auger@redhat.com
22
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
24
---
22
---
25
include/hw/intc/arm_gicv3_its_common.h | 8 +++
23
target/arm/translate.c | 35 +++++++++++++++++++++--------------
26
hw/intc/arm_gicv3_its_common.c | 10 ++++
24
1 file changed, 21 insertions(+), 14 deletions(-)
27
hw/intc/arm_gicv3_its_kvm.c | 105 +++++++++++++++++++++++++++++++++
28
3 files changed, 123 insertions(+)
29
25
30
diff --git a/include/hw/intc/arm_gicv3_its_common.h b/include/hw/intc/arm_gicv3_its_common.h
26
diff --git a/target/arm/translate.c b/target/arm/translate.c
31
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
32
--- a/include/hw/intc/arm_gicv3_its_common.h
28
--- a/target/arm/translate.c
33
+++ b/include/hw/intc/arm_gicv3_its_common.h
29
+++ b/target/arm/translate.c
34
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ static void gen_srs(DisasContext *s,
35
#define ITS_TRANS_SIZE 0x10000
31
s->base.is_jmp = DISAS_UPDATE;
36
#define ITS_SIZE (ITS_CONTROL_SIZE + ITS_TRANS_SIZE)
37
38
+#define GITS_CTLR 0x0
39
+#define GITS_IIDR 0x4
40
+#define GITS_CBASER 0x80
41
+#define GITS_CWRITER 0x88
42
+#define GITS_CREADR 0x90
43
+#define GITS_BASER 0x100
44
+
45
struct GICv3ITSState {
46
SysBusDevice parent_obj;
47
48
@@ -XXX,XX +XXX,XX @@ struct GICv3ITSState {
49
50
/* Registers */
51
uint32_t ctlr;
52
+ uint32_t iidr;
53
uint64_t cbaser;
54
uint64_t cwriter;
55
uint64_t creadr;
56
diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/intc/arm_gicv3_its_common.c
59
+++ b/hw/intc/arm_gicv3_its_common.c
60
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_its = {
61
.pre_save = gicv3_its_pre_save,
62
.post_load = gicv3_its_post_load,
63
.unmigratable = true,
64
+ .fields = (VMStateField[]) {
65
+ VMSTATE_UINT32(ctlr, GICv3ITSState),
66
+ VMSTATE_UINT32(iidr, GICv3ITSState),
67
+ VMSTATE_UINT64(cbaser, GICv3ITSState),
68
+ VMSTATE_UINT64(cwriter, GICv3ITSState),
69
+ VMSTATE_UINT64(creadr, GICv3ITSState),
70
+ VMSTATE_UINT64_ARRAY(baser, GICv3ITSState, 8),
71
+ VMSTATE_END_OF_LIST()
72
+ },
73
};
74
75
static MemTxResult gicv3_its_trans_read(void *opaque, hwaddr offset,
76
@@ -XXX,XX +XXX,XX @@ static void gicv3_its_common_reset(DeviceState *dev)
77
s->cbaser = 0;
78
s->cwriter = 0;
79
s->creadr = 0;
80
+ s->iidr = 0;
81
memset(&s->baser, 0, sizeof(s->baser));
82
83
gicv3_its_post_load(s, 0);
84
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/hw/intc/arm_gicv3_its_kvm.c
87
+++ b/hw/intc/arm_gicv3_its_kvm.c
88
@@ -XXX,XX +XXX,XX @@ static int kvm_its_send_msi(GICv3ITSState *s, uint32_t value, uint16_t devid)
89
return kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi);
90
}
32
}
91
33
92
+/**
34
+/* Generate a label used for skipping this instruction */
93
+ * vm_change_state_handler - VM change state callback aiming at flushing
35
+static void arm_gen_condlabel(DisasContext *s)
94
+ * ITS tables into guest RAM
95
+ *
96
+ * The tables get flushed to guest RAM whenever the VM gets stopped.
97
+ */
98
+static void vm_change_state_handler(void *opaque, int running,
99
+ RunState state)
100
+{
36
+{
101
+ GICv3ITSState *s = (GICv3ITSState *)opaque;
37
+ if (!s->condjmp) {
102
+ Error *err = NULL;
38
+ s->condlabel = gen_new_label();
103
+ int ret;
39
+ s->condjmp = 1;
104
+
105
+ if (running) {
106
+ return;
107
+ }
108
+
109
+ ret = kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
110
+ KVM_DEV_ARM_ITS_SAVE_TABLES, NULL, true, &err);
111
+ if (err) {
112
+ error_report_err(err);
113
+ }
114
+ if (ret < 0 && ret != -EFAULT) {
115
+ abort();
116
+ }
40
+ }
117
+}
41
+}
118
+
42
+
119
static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
43
+/* Skip this instruction if the ARM condition is false */
120
{
44
+static void arm_skip_unless(DisasContext *s, uint32_t cond)
121
GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
122
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
123
kvm_msi_use_devid = true;
124
kvm_gsi_direct_mapping = false;
125
kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
126
+
127
+ qemu_add_vm_change_state_handler(vm_change_state_handler, s);
128
}
129
130
static void kvm_arm_its_init(Object *obj)
131
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_init(Object *obj)
132
&error_abort);
133
}
134
135
+/**
136
+ * kvm_arm_its_pre_save - handles the saving of ITS registers.
137
+ * ITS tables are flushed into guest RAM separately and earlier,
138
+ * through the VM change state handler, since at the moment pre_save()
139
+ * is called, the guest RAM has already been saved.
140
+ */
141
+static void kvm_arm_its_pre_save(GICv3ITSState *s)
142
+{
45
+{
143
+ int i;
46
+ arm_gen_condlabel(s);
144
+
47
+ arm_gen_test_cc(cond ^ 1, s->condlabel);
145
+ for (i = 0; i < 8; i++) {
146
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
147
+ GITS_BASER + i * 8, &s->baser[i], false,
148
+ &error_abort);
149
+ }
150
+
151
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
152
+ GITS_CTLR, &s->ctlr, false, &error_abort);
153
+
154
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
155
+ GITS_CBASER, &s->cbaser, false, &error_abort);
156
+
157
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
158
+ GITS_CREADR, &s->creadr, false, &error_abort);
159
+
160
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
161
+ GITS_CWRITER, &s->cwriter, false, &error_abort);
162
+
163
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
164
+ GITS_IIDR, &s->iidr, false, &error_abort);
165
+}
48
+}
166
+
49
+
167
+/**
50
static void disas_arm_insn(DisasContext *s, unsigned int insn)
168
+ * kvm_arm_its_post_load - Restore both the ITS registers and tables
169
+ */
170
+static void kvm_arm_its_post_load(GICv3ITSState *s)
171
+{
172
+ int i;
173
+
174
+ if (!s->iidr) {
175
+ return;
176
+ }
177
+
178
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
179
+ GITS_IIDR, &s->iidr, true, &error_abort);
180
+
181
+ /*
182
+ * must be written before GITS_CREADR since GITS_CBASER write
183
+ * access resets GITS_CREADR.
184
+ */
185
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
186
+ GITS_CBASER, &s->cbaser, true, &error_abort);
187
+
188
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
189
+ GITS_CREADR, &s->creadr, true, &error_abort);
190
+
191
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
192
+ GITS_CWRITER, &s->cwriter, true, &error_abort);
193
+
194
+
195
+ for (i = 0; i < 8; i++) {
196
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
197
+ GITS_BASER + i * 8, &s->baser[i], true,
198
+ &error_abort);
199
+ }
200
+
201
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
202
+ KVM_DEV_ARM_ITS_RESTORE_TABLES, NULL, true,
203
+ &error_abort);
204
+
205
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
206
+ GITS_CTLR, &s->ctlr, true, &error_abort);
207
+}
208
+
209
static void kvm_arm_its_class_init(ObjectClass *klass, void *data)
210
{
51
{
211
DeviceClass *dc = DEVICE_CLASS(klass);
52
unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
212
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_class_init(ObjectClass *klass, void *data)
53
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
213
54
if (cond != 0xe) {
214
dc->realize = kvm_arm_its_realize;
55
/* if not always execute, we generate a conditional jump to
215
icc->send_msi = kvm_its_send_msi;
56
next instruction */
216
+ icc->pre_save = kvm_arm_its_pre_save;
57
- s->condlabel = gen_new_label();
217
+ icc->post_load = kvm_arm_its_post_load;
58
- arm_gen_test_cc(cond ^ 1, s->condlabel);
218
}
59
- s->condjmp = 1;
219
60
+ arm_skip_unless(s, cond);
220
static const TypeInfo kvm_arm_its_info = {
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
}
105
}
106
221
--
107
--
222
2.7.4
108
2.18.0
223
109
224
110
diff view generated by jsdifflib
1
From: Krzysztof Kozlowski <krzk@kernel.org>
1
From: Stefan Hajnoczi <stefanha@redhat.com>
2
2
3
Remove defines not used anywhere.
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.
4
7
5
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
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
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
13
---
9
hw/timer/exynos4210_mct.c | 3 ---
14
docs/generic-loader.txt | 20 ++++++++++----------
10
1 file changed, 3 deletions(-)
15
1 file changed, 10 insertions(+), 10 deletions(-)
11
16
12
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
17
diff --git a/docs/generic-loader.txt b/docs/generic-loader.txt
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/timer/exynos4210_mct.c
19
--- a/docs/generic-loader.txt
15
+++ b/hw/timer/exynos4210_mct.c
20
+++ b/docs/generic-loader.txt
16
@@ -XXX,XX +XXX,XX @@ enum LocalTimerRegCntIndexes {
21
@@ -XXX,XX +XXX,XX @@ An example of setting CPU 0's PC to 0x8000 is:
17
L_REG_CNT_AMOUNT
22
18
};
23
Loading Files
19
24
-------------
20
-#define MCT_NIRQ 6
25
-The loader device also allows files to be loaded into memory. It can load raw
21
#define MCT_SFR_SIZE 0x444
26
-files and ELF executable files. Raw files are loaded verbatim. ELF executable
22
27
-files are loaded by an ELF loader. The syntax is shown below:
23
#define MCT_GT_CMP_NUM 4
28
+The loader device also allows files to be loaded into memory. It can load ELF,
24
29
+U-Boot, and Intel HEX executable formats as well as raw images. The syntax is
25
-#define MCT_GT_MAX_VAL UINT64_MAX
30
+shown below:
26
-
31
27
#define MCT_GT_COUNTER_STEP 0x100000000ULL
32
-device loader,file=<file>[,addr=<addr>][,cpu-num=<cpu-num>][,force-raw=<raw>]
28
#define MCT_LT_COUNTER_STEP 0x100000000ULL
33
29
#define MCT_LT_CNT_LOW_LIMIT 0x100
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
30
--
57
--
31
2.7.4
58
2.18.0
32
59
33
60
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Jia He <hejianet@gmail.com>
2
2
3
We change the restoration priority of both the GICv3 and ITS. The
3
In scripts/arch-run.bash of kvm-unit-tests, it will check the qemu
4
GICv3 must be restored before the ITS and the ITS needs to be restored
4
output log with:
5
before PCIe devices since it translates their MSI transactions.
5
if [ -z "$(echo "$errors" | grep -vi warning)" ]; then
6
6
7
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Thus without the warning prefix, all of the test fail.
8
Reviewed-by: Juan Quintela <quintela@redhat.com>
8
9
Message-id: 1497023553-18411-5-git-send-email-eric.auger@redhat.com
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>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
17
---
12
include/migration/vmstate.h | 2 ++
18
hw/intc/arm_gicv3_its_kvm.c | 2 +-
13
hw/intc/arm_gicv3_common.c | 1 +
19
1 file changed, 1 insertion(+), 1 deletion(-)
14
hw/intc/arm_gicv3_its_common.c | 2 +-
15
hw/intc/arm_gicv3_its_kvm.c | 24 ++++++++++++------------
16
4 files changed, 16 insertions(+), 13 deletions(-)
17
20
18
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/migration/vmstate.h
21
+++ b/include/migration/vmstate.h
22
@@ -XXX,XX +XXX,XX @@ enum VMStateFlags {
23
typedef enum {
24
MIG_PRI_DEFAULT = 0,
25
MIG_PRI_IOMMU, /* Must happen before PCI devices */
26
+ MIG_PRI_GICV3_ITS, /* Must happen before PCI devices */
27
+ MIG_PRI_GICV3, /* Must happen before the ITS */
28
MIG_PRI_MAX,
29
} MigrationPriority;
30
31
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/intc/arm_gicv3_common.c
34
+++ b/hw/intc/arm_gicv3_common.c
35
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_gicv3 = {
36
.minimum_version_id = 1,
37
.pre_save = gicv3_pre_save,
38
.post_load = gicv3_post_load,
39
+ .priority = MIG_PRI_GICV3,
40
.fields = (VMStateField[]) {
41
VMSTATE_UINT32(gicd_ctlr, GICv3State),
42
VMSTATE_UINT32_ARRAY(gicd_statusr, GICv3State, 2),
43
diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/intc/arm_gicv3_its_common.c
46
+++ b/hw/intc/arm_gicv3_its_common.c
47
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_its = {
48
.name = "arm_gicv3_its",
49
.pre_save = gicv3_its_pre_save,
50
.post_load = gicv3_its_post_load,
51
- .unmigratable = true,
52
+ .priority = MIG_PRI_GICV3_ITS,
53
.fields = (VMStateField[]) {
54
VMSTATE_UINT32(ctlr, GICv3ITSState),
55
VMSTATE_UINT32(iidr, GICv3ITSState),
56
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
21
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
57
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/intc/arm_gicv3_its_kvm.c
23
--- a/hw/intc/arm_gicv3_its_kvm.c
59
+++ b/hw/intc/arm_gicv3_its_kvm.c
24
+++ b/hw/intc/arm_gicv3_its_kvm.c
60
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
25
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_reset(DeviceState *dev)
61
GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
26
return;
62
Error *local_err = NULL;
27
}
63
28
64
- /*
29
- error_report("ITS KVM: full reset is not supported by the host kernel");
65
- * Block migration of a KVM GICv3 ITS device: the API for saving and
30
+ warn_report("ITS KVM: full reset is not supported by the host kernel");
66
- * restoring the state in the kernel is not yet available
31
67
- */
32
if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
68
- error_setg(&s->migration_blocker, "vITS migration is not implemented");
33
GITS_CTLR)) {
69
- migrate_add_blocker(s->migration_blocker, &local_err);
70
- if (local_err) {
71
- error_propagate(errp, local_err);
72
- error_free(s->migration_blocker);
73
- return;
74
- }
75
-
76
s->dev_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_ARM_VGIC_ITS, false);
77
if (s->dev_fd < 0) {
78
error_setg_errno(errp, -s->dev_fd, "error creating in-kernel ITS");
79
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
80
81
gicv3_its_init_mmio(s, NULL);
82
83
+ if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
84
+ GITS_CTLR)) {
85
+ error_setg(&s->migration_blocker, "This operating system kernel "
86
+ "does not support vITS migration");
87
+ migrate_add_blocker(s->migration_blocker, &local_err);
88
+ if (local_err) {
89
+ error_propagate(errp, local_err);
90
+ error_free(s->migration_blocker);
91
+ return;
92
+ }
93
+ }
94
+
95
kvm_msi_use_devid = true;
96
kvm_gsi_direct_mapping = false;
97
kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled();
98
--
34
--
99
2.7.4
35
2.18.0
100
36
101
37
diff view generated by jsdifflib
1
From: Pranith Kumar <bobby.prani@gmail.com>
1
From: Hans-Erik Floryd <hans-erik.floryd@rt-labs.com>
2
2
3
Tested and confirmed that the stretch i386 debian qcow2 image on a
3
Generate an interrupt if USR2_RDR and UCR4_DREN are both set.
4
raspberry pi 2 works.
5
4
6
Fixes: LP#: 893208 <https://bugs.launchpad.net/qemu/+bug/893208/>
5
Signed-off-by: Hans-Erik Floryd <hans-erik.floryd@rt-labs.com>
7
Signed-off-by: Pranith Kumar <bobby.prani@gmail.com>
6
Message-id: 1534341354-11956-1-git-send-email-hans-erik.floryd@rt-labs.com
8
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20170418191817.10430-1-bobby.prani@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
9
---
12
include/qemu/timer.h | 5 ++---
10
include/hw/char/imx_serial.h | 1 +
13
1 file changed, 2 insertions(+), 3 deletions(-)
11
hw/char/imx_serial.c | 3 ++-
12
2 files changed, 3 insertions(+), 1 deletion(-)
14
13
15
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
14
diff --git a/include/hw/char/imx_serial.h b/include/hw/char/imx_serial.h
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/include/qemu/timer.h
16
--- a/include/hw/char/imx_serial.h
18
+++ b/include/qemu/timer.h
17
+++ b/include/hw/char/imx_serial.h
19
@@ -XXX,XX +XXX,XX @@ static inline int64_t cpu_get_host_ticks(void)
18
@@ -XXX,XX +XXX,XX @@
20
/* The host CPU doesn't have an easily accessible cycle counter.
19
#define UCR2_RXEN (1<<1) /* Receiver enable */
21
Just return a monotonically increasing value. This will be
20
#define UCR2_SRST (1<<0) /* Reset complete */
22
totally wrong, but hopefully better than nothing. */
21
23
-static inline int64_t cpu_get_host_ticks (void)
22
+#define UCR4_DREN BIT(0) /* Receive Data Ready interrupt enable */
24
+static inline int64_t cpu_get_host_ticks(void)
23
#define UCR4_TCEN BIT(3) /* TX complete interrupt enable */
25
{
24
26
- static int64_t ticks = 0;
25
#define UTS1_TXEMPTY (1<<6)
27
- return ticks++;
26
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
28
+ return get_clock();
27
index XXXXXXX..XXXXXXX 100644
29
}
28
--- a/hw/char/imx_serial.c
30
#endif
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;
31
40
32
--
41
--
33
2.7.4
42
2.18.0
34
43
35
44
diff view generated by jsdifflib
1
From: Krzysztof Kozlowski <krzk@kernel.org>
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).
2
4
3
Bring some more readability by declaring local function variables: first
4
initialized ones and then the rest (with reversed-christmas-tree order).
5
6
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
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
---
9
---
10
hw/arm/exynos4210.c | 4 ++--
10
target/arm/helper.c | 4 ++--
11
1 file changed, 2 insertions(+), 2 deletions(-)
11
1 file changed, 2 insertions(+), 2 deletions(-)
12
12
13
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/exynos4210.c
15
--- a/target/arm/helper.c
16
+++ b/hw/arm/exynos4210.c
16
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_calc_affinity(int cpu)
17
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
18
18
.opc0 = 3, .opc1 = 4, .crn = 10, .crm = 3, .opc2 = 0,
19
Exynos4210State *exynos4210_init(MemoryRegion *system_mem)
19
.access = PL2_RW, .type = ARM_CP_CONST,
20
{
20
.resetvalue = 0 },
21
- int i, n;
21
- { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
22
Exynos4210State *s = g_new(Exynos4210State, 1);
22
+ { .name = "HAMAIR1", .state = ARM_CP_STATE_AA32,
23
qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
23
.opc1 = 4, .crn = 10, .crm = 3, .opc2 = 1,
24
- DeviceState *dev;
24
.access = PL2_RW, .type = ARM_CP_CONST,
25
SysBusDevice *busdev;
25
.resetvalue = 0 },
26
ObjectClass *cpu_oc;
26
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
27
+ DeviceState *dev;
27
.access = PL2_RW, .type = ARM_CP_CONST,
28
+ int i, n;
28
.resetvalue = 0 },
29
29
/* HAMAIR1 is mapped to AMAIR_EL2[63:32] */
30
cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, "cortex-a9");
30
- { .name = "HMAIR1", .state = ARM_CP_STATE_AA32,
31
assert(cpu_oc);
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 },
32
--
35
--
33
2.7.4
36
2.18.0
34
37
35
38
diff view generated by jsdifflib
New 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.
1
7
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
1
From: Krzysztof Kozlowski <krzk@kernel.org>
1
Implement the AArch32 HVBAR register; we can do this just by
2
making the existing VBAR_EL2 regdefs be STATE_BOTH.
2
3
3
Fix checkpatch errors:
4
1. ERROR: spaces required around that '+' (ctx:VxV)
5
2. ERROR: spaces required around that '&' (ctx:VxV)
6
7
No functional changes.
8
9
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
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>
6
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
7
Message-id: 20180814124254.5229-5-peter.maydell@linaro.org
13
---
8
---
14
hw/timer/exynos4210_mct.c | 4 ++--
9
target/arm/helper.c | 4 ++--
15
1 file changed, 2 insertions(+), 2 deletions(-)
10
1 file changed, 2 insertions(+), 2 deletions(-)
16
11
17
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/timer/exynos4210_mct.c
14
--- a/target/arm/helper.c
20
+++ b/hw/timer/exynos4210_mct.c
15
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_update_freq(Exynos4210MCTState *s)
16
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
22
{
17
23
uint32_t freq = s->freq;
18
/* Used to describe the behaviour of EL2 regs when EL2 does not exist. */
24
s->freq = 24000000 /
19
static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
25
- ((MCT_CFG_GET_PRESCALER(s->reg_mct_cfg)+1) *
20
- { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
26
+ ((MCT_CFG_GET_PRESCALER(s->reg_mct_cfg) + 1) *
21
+ { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
27
MCT_CFG_GET_DIVIDER(s->reg_mct_cfg));
22
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
28
23
.access = PL2_RW,
29
if (freq != s->freq) {
24
.readfn = arm_cp_read_zero, .writefn = arm_cp_write_ignore },
30
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_write(void *opaque, hwaddr offset,
25
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
31
26
.opc0 = 3, .opc1 = 4, .crn = 4, .crm = 0, .opc2 = 0,
32
DPRINTF("comparator %d write 0x%llx val << %d\n", index, value, shift);
27
.access = PL2_RW,
33
28
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_HYP]) },
34
- if (offset&0x4) {
29
- { .name = "VBAR_EL2", .state = ARM_CP_STATE_AA64,
35
+ if (offset & 0x4) {
30
+ { .name = "VBAR_EL2", .state = ARM_CP_STATE_BOTH,
36
s->g_timer.reg.wstat |= G_WSTAT_COMP_U(index);
31
.opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 0,
37
} else {
32
.access = PL2_RW, .writefn = vbar_write,
38
s->g_timer.reg.wstat |= G_WSTAT_COMP_L(index);
33
.fieldoffset = offsetof(CPUARMState, cp15.vbar_el[2]),
39
--
34
--
40
2.7.4
35
2.18.0
41
36
42
37
diff view generated by jsdifflib
New patch
1
The AArch32 virtualization extensions support these fault address
2
registers:
3
* HDFAR: aliased with AArch64 FAR_EL2[31:0] and AArch32 DFAR(S)
4
* HIFAR: aliased with AArch64 FAR_EL2[63:32] and AArch32 IFAR(S)
1
5
6
Implement the accessors for these. This fixes in passing a bug
7
where we weren't implementing the "RES0 from EL3 if EL2 not
8
implemented" behaviour for AArch64 FAR_EL2.
9
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
13
Message-id: 20180814124254.5229-7-peter.maydell@linaro.org
14
---
15
target/arm/helper.c | 14 +++++++++++++-
16
1 file changed, 13 insertions(+), 1 deletion(-)
17
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
21
+++ b/target/arm/helper.c
22
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el3_no_el2_cp_reginfo[] = {
23
{ .name = "HSTR_EL2", .state = ARM_CP_STATE_BOTH,
24
.opc0 = 3, .opc1 = 4, .crn = 1, .crm = 1, .opc2 = 3,
25
.access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
26
+ { .name = "FAR_EL2", .state = ARM_CP_STATE_BOTH,
27
+ .opc0 = 3, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 0,
28
+ .access = PL2_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
29
+ { .name = "HIFAR", .state = ARM_CP_STATE_AA32,
30
+ .type = ARM_CP_CONST,
31
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 0, .opc2 = 2,
32
+ .access = PL2_RW, .resetvalue = 0 },
33
REGINFO_SENTINEL
34
};
35
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
--
53
2.18.0
54
55
diff view generated by jsdifflib
New 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.
1
6
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: Cédric Le Goater <clg@kaod.org>
1
The MSR (banked) and MRS (banked) instructions allow accesses to ELR_Hyp
2
from either Monitor or Hyp mode. Our translate time check
3
was overly strict and only permitted access from Monitor mode.
2
4
3
When a timer is enabled before a reload value is set, the controller
5
The runtime check we do in msr_mrs_banked_exc_checks() had the
4
waits for a reload value to be set before starting decrementing. This
6
correct code in it, but never got there because of the earlier
5
fix tries to cover that case by changing the timer expiry only when
7
"currmode == tgtmode" check. Special case ELR_Hyp.
6
a reload value is valid.
7
8
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
10
Message-id: 1496739312-32304-1-git-send-email-clg@kaod.org
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Reviewed-by: Luc Michel <luc.michel@greensocs.com>
12
Message-id: 20180814124254.5229-9-peter.maydell@linaro.org
12
---
13
---
13
hw/timer/aspeed_timer.c | 37 +++++++++++++++++++++++++++++--------
14
target/arm/op_helper.c | 22 +++++++++++-----------
14
1 file changed, 29 insertions(+), 8 deletions(-)
15
target/arm/translate.c | 10 +++++++---
16
2 files changed, 18 insertions(+), 14 deletions(-)
15
17
16
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
18
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/timer/aspeed_timer.c
20
--- a/target/arm/op_helper.c
19
+++ b/hw/timer/aspeed_timer.c
21
+++ b/target/arm/op_helper.c
20
@@ -XXX,XX +XXX,XX @@ static uint64_t calculate_next(struct AspeedTimer *t)
22
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
21
next = seq[1];
23
*/
22
} else if (now < seq[2]) {
24
int curmode = env->uncached_cpsr & CPSR_M;
23
next = seq[2];
25
24
- } else {
26
+ if (regno == 17) {
25
+ } else if (t->reload) {
27
+ /* ELR_Hyp: a special case because access from tgtmode is OK */
26
reload_ns = muldiv64(t->reload, NANOSECONDS_PER_SECOND, rate);
28
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
27
t->start = now - ((now - t->start) % reload_ns);
29
+ goto undef;
28
+ } else {
30
+ }
29
+ /* no reload value, return 0 */
31
+ return;
30
+ break;
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;
31
}
55
}
32
}
56
}
33
57
34
return next;
58
diff --git a/target/arm/translate.c b/target/arm/translate.c
35
}
59
index XXXXXXX..XXXXXXX 100644
36
60
--- a/target/arm/translate.c
37
+static void aspeed_timer_mod(AspeedTimer *t)
61
+++ b/target/arm/translate.c
38
+{
62
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
39
+ uint64_t next = calculate_next(t);
40
+ if (next) {
41
+ timer_mod(&t->timer, next);
42
+ }
43
+}
44
+
45
static void aspeed_timer_expire(void *opaque)
46
{
47
AspeedTimer *t = opaque;
48
@@ -XXX,XX +XXX,XX @@ static void aspeed_timer_expire(void *opaque)
49
qemu_set_irq(t->irq, t->level);
50
}
51
52
- timer_mod(&t->timer, calculate_next(t));
53
+ aspeed_timer_mod(t);
54
}
55
56
static uint64_t aspeed_timer_get_value(AspeedTimer *t, int reg)
57
@@ -XXX,XX +XXX,XX @@ static void aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int reg,
58
uint32_t value)
59
{
60
AspeedTimer *t;
61
+ uint32_t old_reload;
62
63
trace_aspeed_timer_set_value(timer, reg, value);
64
t = &s->timers[timer];
65
switch (reg) {
66
+ case TIMER_REG_RELOAD:
67
+ old_reload = t->reload;
68
+ t->reload = value;
69
+
70
+ /* If the reload value was not previously set, or zero, and
71
+ * the current value is valid, try to start the timer if it is
72
+ * enabled.
73
+ */
74
+ if (old_reload || !t->reload) {
75
+ break;
76
+ }
77
+
78
case TIMER_REG_STATUS:
79
if (timer_enabled(t)) {
80
uint64_t now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
81
@@ -XXX,XX +XXX,XX @@ static void aspeed_timer_set_value(AspeedTimerCtrlState *s, int timer, int reg,
82
uint32_t rate = calculate_rate(t);
83
84
t->start += muldiv64(delta, NANOSECONDS_PER_SECOND, rate);
85
- timer_mod(&t->timer, calculate_next(t));
86
+ aspeed_timer_mod(t);
87
}
63
}
88
break;
64
break;
89
- case TIMER_REG_RELOAD:
65
case ARM_CPU_MODE_HYP:
90
- t->reload = value;
66
- /* Note that we can forbid accesses from EL2 here because they
91
- break;
67
- * must be from Hyp mode itself
92
case TIMER_REG_MATCH_FIRST:
68
+ /*
93
case TIMER_REG_MATCH_SECOND:
69
+ * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
94
t->match[reg - 2] = value;
70
+ * (and so we can forbid accesses from EL2 or below). elr_hyp
95
if (timer_enabled(t)) {
71
+ * can be accessed also from Hyp mode, so forbid accesses from
96
- timer_mod(&t->timer, calculate_next(t));
72
+ * EL0 or EL1.
97
+ aspeed_timer_mod(t);
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;
98
}
78
}
99
break;
79
break;
100
default:
101
@@ -XXX,XX +XXX,XX @@ static void aspeed_timer_ctrl_enable(AspeedTimer *t, bool enable)
102
trace_aspeed_timer_ctrl_enable(t->id, enable);
103
if (enable) {
104
t->start = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
105
- timer_mod(&t->timer, calculate_next(t));
106
+ aspeed_timer_mod(t);
107
} else {
108
timer_del(&t->timer);
109
}
110
--
80
--
111
2.7.4
81
2.18.0
112
82
113
83
diff view generated by jsdifflib
New patch
1
ARMv7VE introduced the ERET instruction, which is necessary to
2
return from an exception taken to Hyp mode. Implement this.
3
In A32 encoding it is a completely new encoding; in T32 it
4
is an adjustment of the behaviour of the existing
5
"SUBS PC, LR, #<imm8>" instruction.
1
6
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-10-peter.maydell@linaro.org
11
---
12
target/arm/translate.c | 31 +++++++++++++++++++++++++++++--
13
1 file changed, 29 insertions(+), 2 deletions(-)
14
15
diff --git a/target/arm/translate.c b/target/arm/translate.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate.c
18
+++ b/target/arm/translate.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
20
tcg_temp_free_i32(tmp2);
21
store_reg(s, rd, tmp);
22
break;
23
+ case 0x6: /* ERET */
24
+ if (op1 != 3) {
25
+ goto illegal_op;
26
+ }
27
+ if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
28
+ goto illegal_op;
29
+ }
30
+ if ((insn & 0x000fff0f) != 0x0000000e) {
31
+ /* UNPREDICTABLE; we choose to UNDEF */
32
+ goto illegal_op;
33
+ }
34
+
35
+ if (s->current_el == 2) {
36
+ tmp = load_cpu_field(elr_el[2]);
37
+ } else {
38
+ tmp = load_reg(s, 14);
39
+ }
40
+ gen_exception_return(s, tmp);
41
+ break;
42
case 7:
43
{
44
int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
45
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
46
if (rn != 14 || rd != 15) {
47
goto illegal_op;
48
}
49
- tmp = load_reg(s, rn);
50
- tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
51
+ if (s->current_el == 2) {
52
+ /* ERET from Hyp uses ELR_Hyp, not LR */
53
+ if (insn & 0xff) {
54
+ goto illegal_op;
55
+ }
56
+ tmp = load_cpu_field(elr_el[2]);
57
+ } else {
58
+ tmp = load_reg(s, rn);
59
+ tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
60
+ }
61
gen_exception_return(s, tmp);
62
break;
63
case 6: /* MRS */
64
--
65
2.18.0
66
67
diff view generated by jsdifflib
1
From: Krzysztof Kozlowski <krzk@kernel.org>
1
From: Andrew Jones <drjones@redhat.com>
2
2
3
On all Exynos-based boards, the system powers down itself by driving
3
Signed-off-by: Andrew Jones <drjones@redhat.com>
4
PS_HOLD signal low - eight bit in PS_HOLD_CONTROL register of PMU.
4
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
5
Handle writing to respective PMU register to fix power off failure:
6
7
reboot: Power down
8
Unable to poweroff system
9
shutdown: 31 output lines suppressed due to ratelimiting
10
Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000000
11
12
CPU: 0 PID: 1 Comm: shutdown Not tainted 4.11.0-rc8 #846
13
Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
14
[<c031050c>] (unwind_backtrace) from [<c030ba6c>] (show_stack+0x10/0x14)
15
[<c030ba6c>] (show_stack) from [<c05b2800>] (dump_stack+0x88/0x9c)
16
[<c05b2800>] (dump_stack) from [<c03d3140>] (panic+0xdc/0x268)
17
[<c03d3140>] (panic) from [<c0343614>] (do_exit+0xa90/0xab4)
18
[<c0343614>] (do_exit) from [<c035f2dc>] (SyS_reboot+0x164/0x1d0)
19
[<c035f2dc>] (SyS_reboot) from [<c0307c80>] (ret_fast_syscall+0x0/0x3c)
20
21
Additionally the initial value of PS_HOLD has to be changed because
22
recent Linux kernel (v4.12-rc1) uses regmap cache for this access.
23
When the register is kept at reset value, the kernel will not issue a
24
write to it. Usually the bootloader sets the eight bit of PS_HOLD high
25
so mimic its existence here.
26
27
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
28
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
29
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
30
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
---
7
---
32
hw/misc/exynos4210_pmu.c | 20 +++++++++++++++++++-
8
hw/arm/virt.c | 23 +++++++++++++++++------
33
1 file changed, 19 insertions(+), 1 deletion(-)
9
1 file changed, 17 insertions(+), 6 deletions(-)
34
10
35
diff --git a/hw/misc/exynos4210_pmu.c b/hw/misc/exynos4210_pmu.c
11
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
36
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/misc/exynos4210_pmu.c
13
--- a/hw/arm/virt.c
38
+++ b/hw/misc/exynos4210_pmu.c
14
+++ b/hw/arm/virt.c
39
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void machvirt_machine_init(void)
40
16
}
41
#include "qemu/osdep.h"
17
type_init(machvirt_machine_init);
42
#include "hw/sysbus.h"
18
43
+#include "sysemu/sysemu.h"
19
-#define VIRT_COMPAT_2_12 \
44
20
- HW_COMPAT_2_12
45
#ifndef DEBUG_PMU
21
-
46
#define DEBUG_PMU 0
22
-static void virt_3_0_instance_init(Object *obj)
47
@@ -XXX,XX +XXX,XX @@ static const Exynos4210PmuReg exynos4210_pmu_regs[] = {
23
+static void virt_3_1_instance_init(Object *obj)
48
{"PAD_RETENTION_MMCB_OPTION", PAD_RETENTION_MMCB_OPTION, 0x00000000},
24
{
49
{"PAD_RETENTION_EBIA_OPTION", PAD_RETENTION_EBIA_OPTION, 0x00000000},
25
VirtMachineState *vms = VIRT_MACHINE(obj);
50
{"PAD_RETENTION_EBIB_OPTION", PAD_RETENTION_EBIB_OPTION, 0x00000000},
26
VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
51
- {"PS_HOLD_CONTROL", PS_HOLD_CONTROL, 0x00005200},
27
@@ -XXX,XX +XXX,XX @@ static void virt_3_0_instance_init(Object *obj)
52
+ /*
28
vms->irqmap = a15irqmap;
53
+ * PS_HOLD_CONTROL: reset value and manually toggle high the DATA bit.
29
}
54
+ * DATA bit high, set usually by bootloader, keeps system on.
30
55
+ */
31
-static void virt_machine_3_0_options(MachineClass *mc)
56
+ {"PS_HOLD_CONTROL", PS_HOLD_CONTROL, 0x00005200 | BIT(8)},
32
+static void virt_machine_3_1_options(MachineClass *mc)
57
{"XUSBXTI_CONFIGURATION", XUSBXTI_CONFIGURATION, 0x00000001},
33
{
58
{"XUSBXTI_STATUS", XUSBXTI_STATUS, 0x00000001},
34
}
59
{"XUSBXTI_DURATION", XUSBXTI_DURATION, 0xFFF00000},
35
-DEFINE_VIRT_MACHINE_AS_LATEST(3, 0)
60
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210PmuState {
36
+DEFINE_VIRT_MACHINE_AS_LATEST(3, 1)
61
uint32_t reg[PMU_NUM_OF_REGISTERS];
37
+
62
} Exynos4210PmuState;
38
+static void virt_3_0_instance_init(Object *obj)
63
64
+static void exynos4210_pmu_poweroff(void)
65
+{
39
+{
66
+ PRINT_DEBUG("QEMU PMU: PS_HOLD bit down, powering off\n");
40
+ virt_3_1_instance_init(obj);
67
+ qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
68
+}
41
+}
69
+
42
+
70
static uint64_t exynos4210_pmu_read(void *opaque, hwaddr offset,
43
+static void virt_machine_3_0_options(MachineClass *mc)
71
unsigned size)
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)
72
{
53
{
73
@@ -XXX,XX +XXX,XX @@ static void exynos4210_pmu_write(void *opaque, hwaddr offset,
74
PRINT_DEBUG_EXTEND("%s <0x%04x> <- 0x%04x\n", reg_p->name,
75
(uint32_t)offset, (uint32_t)val);
76
s->reg[i] = val;
77
+ if ((offset == PS_HOLD_CONTROL) && ((val & BIT(8)) == 0)) {
78
+ /*
79
+ * We are interested only in setting data bit
80
+ * of PS_HOLD_CONTROL register to indicate power off request.
81
+ */
82
+ exynos4210_pmu_poweroff();
83
+ }
84
return;
85
}
86
reg_p++;
87
--
54
--
88
2.7.4
55
2.18.0
89
56
90
57
diff view generated by jsdifflib
1
From: Krzysztof Kozlowski <krzk@kernel.org>
1
From: Hans-Erik Floryd <hans-erik.floryd@rt-labs.com>
2
2
3
Statements under 'case' were in some places wrongly indented bringing
3
Add the ESDHC PRSSTAT_SDSTB bit, using the value of SDHC_CLOCK_INT_STABLE.
4
confusion and making the code less readable. Remove also few unneeded
4
Freescale recommends checking this bit when changing clock frequency.
5
blank lines. No functional changes.
6
5
7
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
6
Signed-off-by: Hans-Erik Floryd <hans-erik.floryd@rt-labs.com>
7
Message-id: 1534507843-4251-1-git-send-email-hans-erik.floryd@rt-labs.com
8
[PMM: fixed indentation]
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/timer/exynos4210_mct.c | 45 ++++++++++++++++++++-------------------------
12
hw/sd/sdhci-internal.h | 2 ++
13
1 file changed, 20 insertions(+), 25 deletions(-)
13
hw/sd/sdhci.c | 8 ++++++++
14
2 files changed, 10 insertions(+)
14
15
15
diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c
16
diff --git a/hw/sd/sdhci-internal.h b/hw/sd/sdhci-internal.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/timer/exynos4210_mct.c
18
--- a/hw/sd/sdhci-internal.h
18
+++ b/hw/timer/exynos4210_mct.c
19
+++ b/hw/sd/sdhci-internal.h
19
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_mct_read(void *opaque, hwaddr offset,
20
@@ -XXX,XX +XXX,XX @@ extern const VMStateDescription sdhci_vmstate;
20
21
#define ESDHC_CTRL_4BITBUS (0x1 << 1)
21
case G_COMP_L(0): case G_COMP_L(1): case G_COMP_L(2): case G_COMP_L(3):
22
#define ESDHC_CTRL_8BITBUS (0x2 << 1)
22
case G_COMP_U(0): case G_COMP_U(1): case G_COMP_U(2): case G_COMP_U(3):
23
23
- index = GET_G_COMP_IDX(offset);
24
+#define ESDHC_PRNSTS_SDSTB (1 << 3)
24
- shift = 8 * (offset & 0x4);
25
+
25
- value = UINT32_MAX & (s->g_timer.reg.comp[index] >> shift);
26
#endif
26
+ index = GET_G_COMP_IDX(offset);
27
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
27
+ shift = 8 * (offset & 0x4);
28
index XXXXXXX..XXXXXXX 100644
28
+ value = UINT32_MAX & (s->g_timer.reg.comp[index] >> shift);
29
--- a/hw/sd/sdhci.c
29
break;
30
+++ b/hw/sd/sdhci.c
30
31
@@ -XXX,XX +XXX,XX @@ static uint64_t usdhc_read(void *opaque, hwaddr offset, unsigned size)
31
case G_TCON:
32
32
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_mct_read(void *opaque, hwaddr offset,
33
lt_i = GET_L_TIMER_IDX(offset);
34
35
value = exynos4210_lfrc_get_count(&s->l_timer[lt_i]);
36
-
37
break;
33
break;
38
34
39
case L0_TCON: case L1_TCON:
35
+ case SDHC_PRNSTS:
40
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_write(void *opaque, hwaddr offset,
36
+ /* Add SDSTB (SD Clock Stable) bit to PRNSTS */
41
37
+ ret = sdhci_read(opaque, offset, size) & ~ESDHC_PRNSTS_SDSTB;
42
case G_COMP_L(0): case G_COMP_L(1): case G_COMP_L(2): case G_COMP_L(3):
38
+ if (s->clkcon & SDHC_CLOCK_INT_STABLE) {
43
case G_COMP_U(0): case G_COMP_U(1): case G_COMP_U(2): case G_COMP_U(3):
39
+ ret |= ESDHC_PRNSTS_SDSTB;
44
- index = GET_G_COMP_IDX(offset);
45
- shift = 8 * (offset & 0x4);
46
- s->g_timer.reg.comp[index] =
47
- (s->g_timer.reg.comp[index] &
48
- (((uint64_t)UINT32_MAX << 32) >> shift)) +
49
- (value << shift);
50
+ index = GET_G_COMP_IDX(offset);
51
+ shift = 8 * (offset & 0x4);
52
+ s->g_timer.reg.comp[index] =
53
+ (s->g_timer.reg.comp[index] &
54
+ (((uint64_t)UINT32_MAX << 32) >> shift)) +
55
+ (value << shift);
56
57
- DPRINTF("comparator %d write 0x%llx val << %d\n", index, value, shift);
58
+ DPRINTF("comparator %d write 0x%llx val << %d\n", index, value, shift);
59
60
- if (offset & 0x4) {
61
- s->g_timer.reg.wstat |= G_WSTAT_COMP_U(index);
62
- } else {
63
- s->g_timer.reg.wstat |= G_WSTAT_COMP_L(index);
64
- }
65
+ if (offset & 0x4) {
66
+ s->g_timer.reg.wstat |= G_WSTAT_COMP_U(index);
67
+ } else {
68
+ s->g_timer.reg.wstat |= G_WSTAT_COMP_L(index);
69
+ }
40
+ }
70
71
- exynos4210_gfrc_restart(s);
72
- break;
73
+ exynos4210_gfrc_restart(s);
74
+ break;
41
+ break;
75
42
+
76
case G_TCON:
43
case ESDHC_DLL_CTRL:
77
old_val = s->g_timer.reg.tcon;
44
case ESDHC_TUNE_CTRL_STATUS:
78
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_write(void *opaque, hwaddr offset,
45
case ESDHC_UNDOCUMENTED_REG27:
79
break;
80
81
case G_INT_ENB:
82
-
83
/* Raise IRQ if transition from disabled to enabled and CSTAT pending */
84
for (i = 0; i < MCT_GT_CMP_NUM; i++) {
85
if ((value & G_INT_ENABLE(i)) > (s->g_timer.reg.tcon &
86
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_write(void *opaque, hwaddr offset,
87
break;
88
89
case L0_TCNTB: case L1_TCNTB:
90
-
91
lt_i = GET_L_TIMER_IDX(offset);
92
index = GET_L_TIMER_CNT_REG_IDX(offset, lt_i);
93
94
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_write(void *opaque, hwaddr offset,
95
break;
96
97
case L0_ICNTB: case L1_ICNTB:
98
-
99
lt_i = GET_L_TIMER_IDX(offset);
100
index = GET_L_TIMER_CNT_REG_IDX(offset, lt_i);
101
102
@@ -XXX,XX +XXX,XX @@ static void exynos4210_mct_write(void *opaque, hwaddr offset,
103
if (icntb_max[lt_i] < value) {
104
icntb_max[lt_i] = value;
105
}
106
-DPRINTF("local timer[%d] ICNTB write %llx; max=%x, min=%x\n\n",
107
- lt_i, value, icntb_max[lt_i], icntb_min[lt_i]);
108
+ DPRINTF("local timer[%d] ICNTB write %llx; max=%x, min=%x\n\n",
109
+ lt_i, value, icntb_max[lt_i], icntb_min[lt_i]);
110
#endif
111
-break;
112
+ break;
113
114
case L0_FRCNTB: case L1_FRCNTB:
115
-
116
lt_i = GET_L_TIMER_IDX(offset);
117
index = GET_L_TIMER_CNT_REG_IDX(offset, lt_i);
118
119
--
46
--
120
2.7.4
47
2.18.0
121
48
122
49
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
We now support direct execution from MMIO regions in the
2
core memory subsystem. This means that we don't need to
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.)
2
7
3
In some circumstances, we don't want to abort if the
8
This device is the only in-tree user of this API.
4
kvm_device_access fails. This will be the case during ITS
5
migration, in case the ITS table save/restore fails because
6
the guest did not program the vITS correctly. So let's pass an
7
error object to the function and return the ioctl value. New
8
callers will be able to make a decision upon this returned
9
value.
10
9
11
Existing callers pass &error_abort which will cause the
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
function to abort on failure.
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
14
Message-id: 20180817114619.22354-2-peter.maydell@linaro.org
15
---
16
hw/ssi/xilinx_spips.c | 46 -------------------------------------------
17
1 file changed, 46 deletions(-)
13
18
14
Signed-off-by: Eric Auger <eric.auger@redhat.com>
19
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
15
Reviewed-by: Juan Quintela <quintela@redhat.com>
16
Reviewed-by: Peter Xu <peterx@redhat.com>
17
Message-id: 1497023553-18411-2-git-send-email-eric.auger@redhat.com
18
[PMM: wrapped long line]
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
21
include/sysemu/kvm.h | 11 +++++++----
22
hw/intc/arm_gic_kvm.c | 9 +++++----
23
hw/intc/arm_gicv3_its_kvm.c | 2 +-
24
hw/intc/arm_gicv3_kvm.c | 14 +++++++-------
25
kvm-all.c | 14 ++++++++------
26
5 files changed, 28 insertions(+), 22 deletions(-)
27
28
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
29
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
30
--- a/include/sysemu/kvm.h
21
--- a/hw/ssi/xilinx_spips.c
31
+++ b/include/sysemu/kvm.h
22
+++ b/hw/ssi/xilinx_spips.c
32
@@ -XXX,XX +XXX,XX @@ int kvm_device_check_attr(int fd, uint32_t group, uint64_t attr);
23
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps spips_ops = {
33
* @attr: the attribute of that group to set or get
24
34
* @val: pointer to a storage area for the value
25
static void xilinx_qspips_invalidate_mmio_ptr(XilinxQSPIPS *q)
35
* @write: true for set and false for get operation
36
+ * @errp: error object handle
37
*
38
- * This function is not allowed to fail. Use kvm_device_check_attr()
39
- * in order to check for the availability of optional attributes.
40
+ * Returns: 0 on success
41
+ * < 0 on error
42
+ * Use kvm_device_check_attr() in order to check for the availability
43
+ * of optional attributes.
44
*/
45
-void kvm_device_access(int fd, int group, uint64_t attr,
46
- void *val, bool write);
47
+int kvm_device_access(int fd, int group, uint64_t attr,
48
+ void *val, bool write, Error **errp);
49
50
/**
51
* kvm_create_device - create a KVM device for the device control API
52
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/intc/arm_gic_kvm.c
55
+++ b/hw/intc/arm_gic_kvm.c
56
@@ -XXX,XX +XXX,XX @@ static void kvm_gicd_access(GICState *s, int offset, int cpu,
57
uint32_t *val, bool write)
58
{
26
{
59
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_DIST_REGS,
27
- XilinxSPIPS *s = &q->parent_obj;
60
- KVM_VGIC_ATTR(offset, cpu), val, write);
28
-
61
+ KVM_VGIC_ATTR(offset, cpu), val, write, &error_abort);
29
- if ((q->mmio_execution_enabled) && (q->lqspi_cached_addr != ~0ULL)) {
30
- /* Invalidate the current mapped mmio */
31
- memory_region_invalidate_mmio_ptr(&s->mmlqspi, q->lqspi_cached_addr,
32
- LQSPI_CACHE_SIZE);
33
- }
34
-
35
q->lqspi_cached_addr = ~0ULL;
62
}
36
}
63
37
64
static void kvm_gicc_access(GICState *s, int offset, int cpu,
38
@@ -XXX,XX +XXX,XX @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
65
uint32_t *val, bool write)
39
}
40
}
41
42
-static void *lqspi_request_mmio_ptr(void *opaque, hwaddr addr, unsigned *size,
43
- unsigned *offset)
44
-{
45
- XilinxQSPIPS *q = opaque;
46
- hwaddr offset_within_the_region;
47
-
48
- if (!q->mmio_execution_enabled) {
49
- return NULL;
50
- }
51
-
52
- offset_within_the_region = addr & ~(LQSPI_CACHE_SIZE - 1);
53
- lqspi_load_cache(opaque, offset_within_the_region);
54
- *size = LQSPI_CACHE_SIZE;
55
- *offset = offset_within_the_region;
56
- return q->lqspi_buf;
57
-}
58
-
59
static uint64_t
60
lqspi_read(void *opaque, hwaddr addr, unsigned int size)
66
{
61
{
67
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_REGS,
62
@@ -XXX,XX +XXX,XX @@ lqspi_read(void *opaque, hwaddr addr, unsigned int size)
68
- KVM_VGIC_ATTR(offset, cpu), val, write);
63
69
+ KVM_VGIC_ATTR(offset, cpu), val, write, &error_abort);
64
static const MemoryRegionOps lqspi_ops = {
65
.read = lqspi_read,
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
- }
70
}
83
}
71
84
72
#define for_each_irq_reg(_ctr, _max_irq, _field_width) \
85
static void xlnx_zynqmp_qspips_realize(DeviceState *dev, Error **errp)
73
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
86
@@ -XXX,XX +XXX,XX @@ static Property xilinx_zynqmp_qspips_properties[] = {
74
if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0)) {
87
DEFINE_PROP_END_OF_LIST(),
75
uint32_t numirqs = s->num_irq;
88
};
76
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0,
89
77
- &numirqs, true);
90
-static Property xilinx_qspips_properties[] = {
78
+ &numirqs, true, &error_abort);
91
- /* We had to turn this off for 2.10 as it is not compatible with migration.
79
}
92
- * It can be enabled but will prevent the device to be migrated.
80
/* Tell the kernel to complete VGIC initialization now */
93
- * This will go aways when a fix will be released.
81
if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
94
- */
82
KVM_DEV_ARM_VGIC_CTRL_INIT)) {
95
- DEFINE_PROP_BOOL("x-mmio-exec", XilinxQSPIPS, mmio_execution_enabled,
83
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
96
- false),
84
- KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
97
- DEFINE_PROP_END_OF_LIST(),
85
+ KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true,
98
-};
86
+ &error_abort);
99
-
87
}
100
static Property xilinx_spips_properties[] = {
88
} else if (ret != -ENODEV && ret != -ENOTSUP) {
101
DEFINE_PROP_UINT8("num-busses", XilinxSPIPS, num_busses, 1),
89
error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
102
DEFINE_PROP_UINT8("num-ss-bits", XilinxSPIPS, num_cs, 4),
90
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
103
@@ -XXX,XX +XXX,XX @@ static void xilinx_qspips_class_init(ObjectClass *klass, void * data)
91
index XXXXXXX..XXXXXXX 100644
104
XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass);
92
--- a/hw/intc/arm_gicv3_its_kvm.c
105
93
+++ b/hw/intc/arm_gicv3_its_kvm.c
106
dc->realize = xilinx_qspips_realize;
94
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_realize(DeviceState *dev, Error **errp)
107
- dc->props = xilinx_qspips_properties;
95
108
xsc->reg_ops = &qspips_ops;
96
/* explicit init of the ITS */
109
xsc->rx_fifo_size = RXFF_A_Q;
97
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
110
xsc->tx_fifo_size = TXFF_A_Q;
98
- KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
99
+ KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true, &error_abort);
100
101
/* register the base address */
102
kvm_arm_register_device(&s->iomem_its_cntrl, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
103
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/hw/intc/arm_gicv3_kvm.c
106
+++ b/hw/intc/arm_gicv3_kvm.c
107
@@ -XXX,XX +XXX,XX @@ static inline void kvm_gicd_access(GICv3State *s, int offset,
108
{
109
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_DIST_REGS,
110
KVM_VGIC_ATTR(offset, 0),
111
- val, write);
112
+ val, write, &error_abort);
113
}
114
115
static inline void kvm_gicr_access(GICv3State *s, int offset, int cpu,
116
@@ -XXX,XX +XXX,XX @@ static inline void kvm_gicr_access(GICv3State *s, int offset, int cpu,
117
{
118
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_REDIST_REGS,
119
KVM_VGIC_ATTR(offset, s->cpu[cpu].gicr_typer),
120
- val, write);
121
+ val, write, &error_abort);
122
}
123
124
static inline void kvm_gicc_access(GICv3State *s, uint64_t reg, int cpu,
125
@@ -XXX,XX +XXX,XX @@ static inline void kvm_gicc_access(GICv3State *s, uint64_t reg, int cpu,
126
{
127
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
128
KVM_VGIC_ATTR(reg, s->cpu[cpu].gicr_typer),
129
- val, write);
130
+ val, write, &error_abort);
131
}
132
133
static inline void kvm_gic_line_level_access(GICv3State *s, int irq, int cpu,
134
@@ -XXX,XX +XXX,XX @@ static inline void kvm_gic_line_level_access(GICv3State *s, int irq, int cpu,
135
KVM_VGIC_ATTR(irq, s->cpu[cpu].gicr_typer) |
136
(VGIC_LEVEL_INFO_LINE_LEVEL <<
137
KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT),
138
- val, write);
139
+ val, write, &error_abort);
140
}
141
142
/* Loop through each distributor IRQ related register; since bits
143
@@ -XXX,XX +XXX,XX @@ static void arm_gicv3_icc_reset(CPUARMState *env, const ARMCPRegInfo *ri)
144
/* Initialize to actual HW supported configuration */
145
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS,
146
KVM_VGIC_ATTR(ICC_CTLR_EL1, cpu->mp_affinity),
147
- &c->icc_ctlr_el1[GICV3_NS], false);
148
+ &c->icc_ctlr_el1[GICV3_NS], false, &error_abort);
149
150
c->icc_ctlr_el1[GICV3_S] = c->icc_ctlr_el1[GICV3_NS];
151
}
152
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
153
}
154
155
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS,
156
- 0, &s->num_irq, true);
157
+ 0, &s->num_irq, true, &error_abort);
158
159
/* Tell the kernel to complete VGIC initialization now */
160
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
161
- KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true);
162
+ KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true, &error_abort);
163
164
kvm_arm_register_device(&s->iomem_dist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR,
165
KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd);
166
diff --git a/kvm-all.c b/kvm-all.c
167
index XXXXXXX..XXXXXXX 100644
168
--- a/kvm-all.c
169
+++ b/kvm-all.c
170
@@ -XXX,XX +XXX,XX @@
171
#include "qemu/option.h"
172
#include "qemu/config-file.h"
173
#include "qemu/error-report.h"
174
+#include "qapi/error.h"
175
#include "hw/hw.h"
176
#include "hw/pci/msi.h"
177
#include "hw/pci/msix.h"
178
@@ -XXX,XX +XXX,XX @@ int kvm_device_check_attr(int dev_fd, uint32_t group, uint64_t attr)
179
return kvm_device_ioctl(dev_fd, KVM_HAS_DEVICE_ATTR, &attribute) ? 0 : 1;
180
}
181
182
-void kvm_device_access(int fd, int group, uint64_t attr,
183
- void *val, bool write)
184
+int kvm_device_access(int fd, int group, uint64_t attr,
185
+ void *val, bool write, Error **errp)
186
{
187
struct kvm_device_attr kvmattr;
188
int err;
189
@@ -XXX,XX +XXX,XX @@ void kvm_device_access(int fd, int group, uint64_t attr,
190
write ? KVM_SET_DEVICE_ATTR : KVM_GET_DEVICE_ATTR,
191
&kvmattr);
192
if (err < 0) {
193
- error_report("KVM_%s_DEVICE_ATTR failed: %s",
194
- write ? "SET" : "GET", strerror(-err));
195
- error_printf("Group %d attr 0x%016" PRIx64 "\n", group, attr);
196
- abort();
197
+ error_setg_errno(errp, -err,
198
+ "KVM_%s_DEVICE_ATTR failed: Group %d "
199
+ "attr 0x%016" PRIx64,
200
+ write ? "SET" : "GET", group, attr);
201
}
202
+ return err;
203
}
204
205
/* Return 1 on success, 0 on failure */
206
--
111
--
207
2.7.4
112
2.18.0
208
113
209
114
diff view generated by jsdifflib
New patch
1
Remove the obsolete MMIO request_ptr APIs; they have no
2
users now.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
8
Message-id: 20180817114619.22354-3-peter.maydell@linaro.org
9
---
10
include/exec/memory.h | 35 --------------
11
memory.c | 110 ------------------------------------------
12
2 files changed, 145 deletions(-)
13
14
diff --git a/include/exec/memory.h b/include/exec/memory.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/exec/memory.h
17
+++ b/include/exec/memory.h
18
@@ -XXX,XX +XXX,XX @@ struct MemoryRegionOps {
19
uint64_t data,
20
unsigned size,
21
MemTxAttrs attrs);
22
- /* Instruction execution pre-callback:
23
- * @addr is the address of the access relative to the @mr.
24
- * @size is the size of the area returned by the callback.
25
- * @offset is the location of the pointer inside @mr.
26
- *
27
- * Returns a pointer to a location which contains guest code.
28
- */
29
- void *(*request_ptr)(void *opaque, hwaddr addr, unsigned *size,
30
- unsigned *offset);
31
32
enum device_endian endianness;
33
/* Guest-visible constraints: */
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
69
--- a/memory.c
70
+++ b/memory.c
71
@@ -XXX,XX +XXX,XX @@
72
#include "exec/ram_addr.h"
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
}
82
83
-bool memory_region_request_mmio_ptr(MemoryRegion *mr, hwaddr addr)
84
-{
85
- void *host;
86
- unsigned size = 0;
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
-}
119
-
120
-typedef struct MMIOPtrInvalidate {
121
- MemoryRegion *mr;
122
- hwaddr offset;
123
- unsigned size;
124
- int busy;
125
- int allocated;
126
-} MMIOPtrInvalidate;
127
-
128
-#define MAX_MMIO_INVALIDATE 10
129
-static MMIOPtrInvalidate mmio_ptr_invalidate_list[MAX_MMIO_INVALIDATE];
130
-
131
-static void memory_region_do_invalidate_mmio_ptr(CPUState *cpu,
132
- run_on_cpu_data data)
133
-{
134
- MMIOPtrInvalidate *invalidate_data = (MMIOPtrInvalidate *)data.host_ptr;
135
- MemoryRegion *mr = invalidate_data->mr;
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
-}
165
-
166
-void memory_region_invalidate_mmio_ptr(MemoryRegion *mr, hwaddr offset,
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
{
194
memory_region_ref(root);
195
--
196
2.18.0
197
198
diff view generated by jsdifflib
New patch
1
1
The mmio_interface device was a purely internal artifact
2
of the implementation of the memory subsystem's request_ptr
3
APIs. Now that we have removed those APIs, we can remove
4
the mmio_interface device too.
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
10
Message-id: 20180817114619.22354-4-peter.maydell@linaro.org
11
---
12
hw/misc/Makefile.objs | 1 -
13
include/hw/misc/mmio_interface.h | 49 -----------
14
hw/misc/mmio_interface.c | 135 -------------------------------
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
19
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/misc/Makefile.objs
22
+++ b/hw/misc/Makefile.objs
23
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_PVPANIC) += pvpanic.o
24
obj-$(CONFIG_HYPERV_TESTDEV) += hyperv_testdev.o
25
obj-$(CONFIG_AUX) += auxbus.o
26
obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o
27
-obj-y += mmio_interface.o
28
obj-$(CONFIG_MSF2) += msf2-sysreg.o
29
diff --git a/include/hw/misc/mmio_interface.h b/include/hw/misc/mmio_interface.h
30
deleted file mode 100644
31
index XXXXXXX..XXXXXXX
32
--- a/include/hw/misc/mmio_interface.h
33
+++ /dev/null
34
@@ -XXX,XX +XXX,XX @@
35
-/*
36
- * mmio_interface.h
37
- *
38
- * Copyright (C) 2017 : GreenSocs
39
- * http://www.greensocs.com/ , email: info@greensocs.com
40
- *
41
- * Developed by :
42
- * Frederic Konrad <fred.konrad@greensocs.com>
43
- *
44
- * This program is free software; you can redistribute it and/or modify
45
- * it under the terms of the GNU General Public License as published by
46
- * the Free Software Foundation, either version 2 of the License, or
47
- * (at your option)any later version.
48
- *
49
- * This program is distributed in the hope that it will be useful,
50
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
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
--
226
2.18.0
227
228
diff view generated by jsdifflib
New patch
1
Move the m48t59 device away from using old_mmio MemoryRegionOps
2
accessors.
1
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
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
---
9
hw/timer/m48t59.c | 59 +++++++++--------------------------------------
10
1 file changed, 11 insertions(+), 48 deletions(-)
11
12
diff --git a/hw/timer/m48t59.c b/hw/timer/m48t59.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/timer/m48t59.c
15
+++ b/hw/timer/m48t59.c
16
@@ -XXX,XX +XXX,XX @@ static uint64_t NVRAM_readb(void *opaque, hwaddr addr, unsigned size)
17
return retval;
18
}
19
20
-static void nvram_writeb (void *opaque, hwaddr addr, uint32_t value)
21
-{
22
- M48t59State *NVRAM = opaque;
23
-
24
- m48t59_write(NVRAM, addr, value & 0xff);
25
-}
26
-
27
-static void nvram_writew (void *opaque, hwaddr addr, uint32_t value)
28
-{
29
- M48t59State *NVRAM = opaque;
30
-
31
- m48t59_write(NVRAM, addr, (value >> 8) & 0xff);
32
- m48t59_write(NVRAM, addr + 1, value & 0xff);
33
-}
34
-
35
-static void nvram_writel (void *opaque, hwaddr addr, uint32_t value)
36
-{
37
- M48t59State *NVRAM = opaque;
38
-
39
- m48t59_write(NVRAM, addr, (value >> 24) & 0xff);
40
- m48t59_write(NVRAM, addr + 1, (value >> 16) & 0xff);
41
- m48t59_write(NVRAM, addr + 2, (value >> 8) & 0xff);
42
- m48t59_write(NVRAM, addr + 3, value & 0xff);
43
-}
44
-
45
-static uint32_t nvram_readb (void *opaque, hwaddr addr)
46
+static uint64_t nvram_read(void *opaque, hwaddr addr, unsigned size)
47
{
48
M48t59State *NVRAM = opaque;
49
50
return m48t59_read(NVRAM, addr);
51
}
52
53
-static uint32_t nvram_readw (void *opaque, hwaddr addr)
54
+static void nvram_write(void *opaque, hwaddr addr, uint64_t value,
55
+ unsigned 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
-}
64
-
65
-static uint32_t nvram_readl (void *opaque, hwaddr addr)
66
-{
67
- M48t59State *NVRAM = opaque;
68
- uint32_t retval;
69
-
70
- retval = m48t59_read(NVRAM, addr) << 24;
71
- retval |= m48t59_read(NVRAM, addr + 1) << 16;
72
- retval |= m48t59_read(NVRAM, addr + 2) << 8;
73
- retval |= m48t59_read(NVRAM, addr + 3);
74
- return retval;
75
+ return m48t59_write(NVRAM, addr, value);
76
}
77
78
static const MemoryRegionOps nvram_ops = {
79
- .old_mmio = {
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
--
95
2.18.0
96
97
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
The Arm Cortex-M System Design Kit includes a simple watchdog module
2
based on a 32-bit down-counter. Implement this.
2
3
3
Largely inspired by the TMP105 temperature sensor, here is a model for
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
the TMP42{1,2,3} temperature sensors.
5
---
6
Makefile.objs | 1 +
7
hw/watchdog/Makefile.objs | 1 +
8
include/hw/watchdog/cmsdk-apb-watchdog.h | 59 ++++
9
hw/watchdog/cmsdk-apb-watchdog.c | 326 +++++++++++++++++++++++
10
MAINTAINERS | 2 +
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
5
17
6
Specs can be found here :
18
diff --git a/Makefile.objs b/Makefile.objs
7
8
    http://www.ti.com/lit/gpn/tmp421
9
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Message-id: 1496739230-32109-2-git-send-email-clg@kaod.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/misc/Makefile.objs | 1 +
16
hw/misc/tmp421.c | 402 ++++++++++++++++++++++++++++++++++++++++
17
default-configs/arm-softmmu.mak | 1 +
18
3 files changed, 404 insertions(+)
19
create mode 100644 hw/misc/tmp421.c
20
21
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/misc/Makefile.objs
20
--- a/Makefile.objs
24
+++ b/hw/misc/Makefile.objs
21
+++ b/Makefile.objs
22
@@ -XXX,XX +XXX,XX @@ trace-events-subdirs += hw/tpm
23
trace-events-subdirs += hw/usb
24
trace-events-subdirs += hw/vfio
25
trace-events-subdirs += hw/virtio
26
+trace-events-subdirs += hw/watchdog
27
trace-events-subdirs += hw/xen
28
trace-events-subdirs += io
29
trace-events-subdirs += linux-user
30
diff --git a/hw/watchdog/Makefile.objs b/hw/watchdog/Makefile.objs
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/watchdog/Makefile.objs
33
+++ b/hw/watchdog/Makefile.objs
25
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@
26
common-obj-$(CONFIG_APPLESMC) += applesmc.o
35
common-obj-y += watchdog.o
27
common-obj-$(CONFIG_MAX111X) += max111x.o
36
+common-obj-$(CONFIG_CMSDK_APB_WATCHDOG) += cmsdk-apb-watchdog.o
28
common-obj-$(CONFIG_TMP105) += tmp105.o
37
common-obj-$(CONFIG_WDT_IB6300ESB) += wdt_i6300esb.o
29
+common-obj-$(CONFIG_TMP421) += tmp421.o
38
common-obj-$(CONFIG_WDT_IB700) += wdt_ib700.o
30
common-obj-$(CONFIG_ISA_DEBUG) += debugexit.o
39
common-obj-$(CONFIG_WDT_DIAG288) += wdt_diag288.o
31
common-obj-$(CONFIG_SGA) += sga.o
40
diff --git a/include/hw/watchdog/cmsdk-apb-watchdog.h b/include/hw/watchdog/cmsdk-apb-watchdog.h
32
common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o
33
diff --git a/hw/misc/tmp421.c b/hw/misc/tmp421.c
34
new file mode 100644
41
new file mode 100644
35
index XXXXXXX..XXXXXXX
42
index XXXXXXX..XXXXXXX
36
--- /dev/null
43
--- /dev/null
37
+++ b/hw/misc/tmp421.c
44
+++ b/include/hw/watchdog/cmsdk-apb-watchdog.h
38
@@ -XXX,XX +XXX,XX @@
45
@@ -XXX,XX +XXX,XX @@
39
+/*
46
+/*
40
+ * Texas Instruments TMP421 temperature sensor.
47
+ * ARM CMSDK APB watchdog emulation
41
+ *
48
+ *
42
+ * Copyright (c) 2016 IBM Corporation.
49
+ * Copyright (c) 2018 Linaro Limited
43
+ *
50
+ * Written by Peter Maydell
44
+ * Largely inspired by :
51
+ *
45
+ *
52
+ * This program is free software; you can redistribute it and/or modify
46
+ * Texas Instruments TMP105 temperature sensor.
53
+ * it under the terms of the GNU General Public License version 2 or
47
+ *
54
+ * (at your option) any later version.
48
+ * Copyright (C) 2008 Nokia Corporation
49
+ * Written by Andrzej Zaborowski <andrew@openedhand.com>
50
+ *
51
+ * This program is free software; you can redistribute it and/or
52
+ * modify it under the terms of the GNU General Public License as
53
+ * published by the Free Software Foundation; either version 2 or
54
+ * (at your option) version 3 of the License.
55
+ *
56
+ * This program is distributed in the hope that it will be useful,
57
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59
+ * GNU General Public License for more details.
60
+ *
61
+ * You should have received a copy of the GNU General Public License along
62
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
63
+ */
55
+ */
64
+
56
+
57
+/*
58
+ * This is a model of the "APB watchdog" which is part of the Cortex-M
59
+ * System Design Kit (CMSDK) and documented in the Cortex-M System
60
+ * Design Kit Technical Reference Manual (ARM DDI0479C):
61
+ * https://developer.arm.com/products/system-design/system-design-kits/cortex-m-system-design-kit
62
+ *
63
+ * QEMU interface:
64
+ * + QOM property "wdogclk-frq": frequency at which the watchdog is clocked
65
+ * + sysbus MMIO region 0: the register bank
66
+ * + sysbus IRQ 0: watchdog interrupt
67
+ *
68
+ * In real hardware the watchdog's reset output is just a GPIO line
69
+ * which can then be masked by the board or treated as a simple interrupt.
70
+ * (For instance the IoTKit does this with the non-secure watchdog, so that
71
+ * secure code can control whether non-secure code can perform a system
72
+ * reset via its watchdog.) In QEMU, we just wire up the watchdog reset
73
+ * to watchdog_perform_action(), at least for the moment.
74
+ */
75
+
76
+#ifndef CMSDK_APB_WATCHDOG_H
77
+#define CMSDK_APB_WATCHDOG_H
78
+
79
+#include "hw/sysbus.h"
80
+#include "hw/ptimer.h"
81
+
82
+#define TYPE_CMSDK_APB_WATCHDOG "cmsdk-apb-watchdog"
83
+#define CMSDK_APB_WATCHDOG(obj) OBJECT_CHECK(CMSDKAPBWatchdog, (obj), \
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
+
65
+#include "qemu/osdep.h"
129
+#include "qemu/osdep.h"
66
+#include "hw/hw.h"
130
+#include "qemu/log.h"
67
+#include "hw/i2c/i2c.h"
131
+#include "trace.h"
68
+#include "qapi/error.h"
132
+#include "qapi/error.h"
69
+#include "qapi/visitor.h"
133
+#include "qemu/main-loop.h"
70
+
134
+#include "sysemu/watchdog.h"
71
+/* Manufacturer / Device ID's */
135
+#include "hw/sysbus.h"
72
+#define TMP421_MANUFACTURER_ID 0x55
136
+#include "hw/registerfields.h"
73
+#define TMP421_DEVICE_ID 0x21
137
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
74
+#define TMP422_DEVICE_ID 0x22
138
+
75
+#define TMP423_DEVICE_ID 0x23
139
+REG32(WDOGLOAD, 0x0)
76
+
140
+REG32(WDOGVALUE, 0x4)
77
+typedef struct DeviceInfo {
141
+REG32(WDOGCONTROL, 0x8)
78
+ int model;
142
+ FIELD(WDOGCONTROL, INTEN, 0, 1)
79
+ const char *name;
143
+ FIELD(WDOGCONTROL, RESEN, 1, 1)
80
+} DeviceInfo;
144
+#define R_WDOGCONTROL_VALID_MASK (R_WDOGCONTROL_INTEN_MASK | \
81
+
145
+ R_WDOGCONTROL_RESEN_MASK)
82
+static const DeviceInfo devices[] = {
146
+REG32(WDOGINTCLR, 0xc)
83
+ { TMP421_DEVICE_ID, "tmp421" },
147
+REG32(WDOGRIS, 0x10)
84
+ { TMP422_DEVICE_ID, "tmp422" },
148
+ FIELD(WDOGRIS, INT, 0, 1)
85
+ { TMP423_DEVICE_ID, "tmp423" },
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 */
86
+};
178
+};
87
+
179
+
88
+typedef struct TMP421State {
180
+static bool cmsdk_apb_watchdog_intstatus(CMSDKAPBWatchdog *s)
89
+ /*< private >*/
181
+{
90
+ I2CSlave i2c;
182
+ /* Return masked interrupt status */
91
+ /*< public >*/
183
+ return s->intstatus && (s->control & R_WDOGCONTROL_INTEN_MASK);
92
+
184
+}
93
+ int16_t temperature[4];
185
+
94
+
186
+static bool cmsdk_apb_watchdog_resetstatus(CMSDKAPBWatchdog *s)
95
+ uint8_t status;
187
+{
96
+ uint8_t config[2];
188
+ /* Return masked reset status */
97
+ uint8_t rate;
189
+ return s->resetstatus && (s->control & R_WDOGCONTROL_RESEN_MASK);
98
+
190
+}
99
+ uint8_t len;
191
+
100
+ uint8_t buf[2];
192
+static void cmsdk_apb_watchdog_update(CMSDKAPBWatchdog *s)
101
+ uint8_t pointer;
193
+{
102
+
194
+ bool wdogint;
103
+} TMP421State;
195
+ bool wdogres;
104
+
196
+
105
+typedef struct TMP421Class {
197
+ if (s->itcr) {
106
+ I2CSlaveClass parent_class;
198
+ wdogint = s->itop & R_WDOGITOP_WDOGINT_MASK;
107
+ DeviceInfo *dev;
199
+ wdogres = s->itop & R_WDOGITOP_WDOGRES_MASK;
108
+} TMP421Class;
200
+ } else {
109
+
201
+ wdogint = cmsdk_apb_watchdog_intstatus(s);
110
+#define TYPE_TMP421 "tmp421-generic"
202
+ wdogres = cmsdk_apb_watchdog_resetstatus(s);
111
+#define TMP421(obj) OBJECT_CHECK(TMP421State, (obj), TYPE_TMP421)
203
+ }
112
+
204
+
113
+#define TMP421_CLASS(klass) \
205
+ qemu_set_irq(s->wdogint, wdogint);
114
+ OBJECT_CLASS_CHECK(TMP421Class, (klass), TYPE_TMP421)
206
+ if (wdogres) {
115
+#define TMP421_GET_CLASS(obj) \
207
+ watchdog_perform_action();
116
+ OBJECT_GET_CLASS(TMP421Class, (obj), TYPE_TMP421)
208
+ }
117
+
209
+}
118
+/* the TMP421 registers */
210
+
119
+#define TMP421_STATUS_REG 0x08
211
+static uint64_t cmsdk_apb_watchdog_read(void *opaque, hwaddr offset,
120
+#define TMP421_STATUS_BUSY (1 << 7)
212
+ unsigned size)
121
+#define TMP421_CONFIG_REG_1 0x09
213
+{
122
+#define TMP421_CONFIG_RANGE (1 << 2)
214
+ CMSDKAPBWatchdog *s = CMSDK_APB_WATCHDOG(opaque);
123
+#define TMP421_CONFIG_SHUTDOWN (1 << 6)
215
+ uint64_t r;
124
+#define TMP421_CONFIG_REG_2 0x0A
216
+
125
+#define TMP421_CONFIG_RC (1 << 2)
217
+ switch (offset) {
126
+#define TMP421_CONFIG_LEN (1 << 3)
218
+ case A_WDOGLOAD:
127
+#define TMP421_CONFIG_REN (1 << 4)
219
+ r = ptimer_get_limit(s->timer);
128
+#define TMP421_CONFIG_REN2 (1 << 5)
220
+ break;
129
+#define TMP421_CONFIG_REN3 (1 << 6)
221
+ case A_WDOGVALUE:
130
+
222
+ r = ptimer_get_count(s->timer);
131
+#define TMP421_CONVERSION_RATE_REG 0x0B
223
+ break;
132
+#define TMP421_ONE_SHOT 0x0F
224
+ case A_WDOGCONTROL:
133
+
225
+ r = s->control;
134
+#define TMP421_RESET 0xFC
226
+ break;
135
+#define TMP421_MANUFACTURER_ID_REG 0xFE
227
+ case A_WDOGRIS:
136
+#define TMP421_DEVICE_ID_REG 0xFF
228
+ r = s->intstatus;
137
+
229
+ break;
138
+#define TMP421_TEMP_MSB0 0x00
230
+ case A_WDOGMIS:
139
+#define TMP421_TEMP_MSB1 0x01
231
+ r = cmsdk_apb_watchdog_intstatus(s);
140
+#define TMP421_TEMP_MSB2 0x02
232
+ break;
141
+#define TMP421_TEMP_MSB3 0x03
233
+ case A_WDOGLOCK:
142
+#define TMP421_TEMP_LSB0 0x10
234
+ r = s->lock;
143
+#define TMP421_TEMP_LSB1 0x11
235
+ break;
144
+#define TMP421_TEMP_LSB2 0x12
236
+ case A_WDOGITCR:
145
+#define TMP421_TEMP_LSB3 0x13
237
+ r = s->itcr;
146
+
238
+ break;
147
+static const int32_t mins[2] = { -40000, -55000 };
239
+ case A_PID4 ... A_CID3:
148
+static const int32_t maxs[2] = { 127000, 150000 };
240
+ r = watchdog_id[(offset - A_PID4) / 4];
149
+
241
+ break;
150
+static void tmp421_get_temperature(Object *obj, Visitor *v, const char *name,
242
+ case A_WDOGINTCLR:
151
+ void *opaque, Error **errp)
243
+ case A_WDOGITOP:
152
+{
244
+ qemu_log_mask(LOG_GUEST_ERROR,
153
+ TMP421State *s = TMP421(obj);
245
+ "CMSDK APB watchdog read: read of WO offset %x\n",
154
+ bool ext_range = (s->config[0] & TMP421_CONFIG_RANGE);
246
+ (int)offset);
155
+ int offset = ext_range * 64 * 256;
247
+ r = 0;
156
+ int64_t value;
248
+ break;
157
+ int tempid;
249
+ default:
158
+
250
+ qemu_log_mask(LOG_GUEST_ERROR,
159
+ if (sscanf(name, "temperature%d", &tempid) != 1) {
251
+ "CMSDK APB watchdog read: bad offset %x\n", (int)offset);
160
+ error_setg(errp, "error reading %s: %m", name);
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");
161
+ return;
270
+ return;
162
+ }
271
+ }
163
+
272
+
164
+ if (tempid >= 4 || tempid < 0) {
273
+ switch (offset) {
165
+ error_setg(errp, "error reading %s", name);
274
+ case A_WDOGLOAD:
275
+ /*
276
+ * Reset the load value and the current count, and make sure
277
+ * we're counting.
278
+ */
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
+}
317
+
318
+static const MemoryRegionOps cmsdk_apb_watchdog_ops = {
319
+ .read = cmsdk_apb_watchdog_read,
320
+ .write = cmsdk_apb_watchdog_write,
321
+ .endianness = DEVICE_LITTLE_ENDIAN,
322
+ /* byte/halfword accesses are just zero-padded on reads and writes */
323
+ .impl.min_access_size = 4,
324
+ .impl.max_access_size = 4,
325
+ .valid.min_access_size = 1,
326
+ .valid.max_access_size = 4,
327
+};
328
+
329
+static void cmsdk_apb_watchdog_tick(void *opaque)
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");
166
+ return;
379
+ return;
167
+ }
380
+ }
168
+
381
+
169
+ value = ((s->temperature[tempid] - offset) * 1000 + 128) / 256;
382
+ bh = qemu_bh_new(cmsdk_apb_watchdog_tick, s);
170
+
383
+ s->timer = ptimer_init(bh,
171
+ visit_type_int(v, name, &value, errp);
384
+ PTIMER_POLICY_WRAP_AFTER_ONE_PERIOD |
172
+}
385
+ PTIMER_POLICY_TRIGGER_ONLY_ON_DECREMENT |
173
+
386
+ PTIMER_POLICY_NO_IMMEDIATE_RELOAD |
174
+/* Units are 0.001 centigrades relative to 0 C. s->temperature is 8.8
387
+ PTIMER_POLICY_NO_COUNTER_ROUND_DOWN);
175
+ * fixed point, so units are 1/256 centigrades. A simple ratio will do.
388
+
176
+ */
389
+ ptimer_set_freq(s->timer, s->wdogclk_frq);
177
+static void tmp421_set_temperature(Object *obj, Visitor *v, const char *name,
390
+}
178
+ void *opaque, Error **errp)
391
+
179
+{
392
+static const VMStateDescription cmsdk_apb_watchdog_vmstate = {
180
+ TMP421State *s = TMP421(obj);
393
+ .name = "cmsdk-apb-watchdog",
181
+ Error *local_err = NULL;
394
+ .version_id = 1,
182
+ int64_t temp;
395
+ .minimum_version_id = 1,
183
+ bool ext_range = (s->config[0] & TMP421_CONFIG_RANGE);
184
+ int offset = ext_range * 64 * 256;
185
+ int tempid;
186
+
187
+ visit_type_int(v, name, &temp, &local_err);
188
+ if (local_err) {
189
+ error_propagate(errp, local_err);
190
+ return;
191
+ }
192
+
193
+ if (temp >= maxs[ext_range] || temp < mins[ext_range]) {
194
+ error_setg(errp, "value %" PRId64 ".%03" PRIu64 " °C is out of range",
195
+ temp / 1000, temp % 1000);
196
+ return;
197
+ }
198
+
199
+ if (sscanf(name, "temperature%d", &tempid) != 1) {
200
+ error_setg(errp, "error reading %s: %m", name);
201
+ return;
202
+ }
203
+
204
+ if (tempid >= 4 || tempid < 0) {
205
+ error_setg(errp, "error reading %s", name);
206
+ return;
207
+ }
208
+
209
+ s->temperature[tempid] = (int16_t) ((temp * 256 - 128) / 1000) + offset;
210
+}
211
+
212
+static void tmp421_read(TMP421State *s)
213
+{
214
+ TMP421Class *sc = TMP421_GET_CLASS(s);
215
+
216
+ s->len = 0;
217
+
218
+ switch (s->pointer) {
219
+ case TMP421_MANUFACTURER_ID_REG:
220
+ s->buf[s->len++] = TMP421_MANUFACTURER_ID;
221
+ break;
222
+ case TMP421_DEVICE_ID_REG:
223
+ s->buf[s->len++] = sc->dev->model;
224
+ break;
225
+ case TMP421_CONFIG_REG_1:
226
+ s->buf[s->len++] = s->config[0];
227
+ break;
228
+ case TMP421_CONFIG_REG_2:
229
+ s->buf[s->len++] = s->config[1];
230
+ break;
231
+ case TMP421_CONVERSION_RATE_REG:
232
+ s->buf[s->len++] = s->rate;
233
+ break;
234
+ case TMP421_STATUS_REG:
235
+ s->buf[s->len++] = s->status;
236
+ break;
237
+
238
+ /* FIXME: check for channel enablement in config registers */
239
+ case TMP421_TEMP_MSB0:
240
+ s->buf[s->len++] = (((uint16_t) s->temperature[0]) >> 8);
241
+ s->buf[s->len++] = (((uint16_t) s->temperature[0]) >> 0) & 0xf0;
242
+ break;
243
+ case TMP421_TEMP_MSB1:
244
+ s->buf[s->len++] = (((uint16_t) s->temperature[1]) >> 8);
245
+ s->buf[s->len++] = (((uint16_t) s->temperature[1]) >> 0) & 0xf0;
246
+ break;
247
+ case TMP421_TEMP_MSB2:
248
+ s->buf[s->len++] = (((uint16_t) s->temperature[2]) >> 8);
249
+ s->buf[s->len++] = (((uint16_t) s->temperature[2]) >> 0) & 0xf0;
250
+ break;
251
+ case TMP421_TEMP_MSB3:
252
+ s->buf[s->len++] = (((uint16_t) s->temperature[3]) >> 8);
253
+ s->buf[s->len++] = (((uint16_t) s->temperature[3]) >> 0) & 0xf0;
254
+ break;
255
+ case TMP421_TEMP_LSB0:
256
+ s->buf[s->len++] = (((uint16_t) s->temperature[0]) >> 0) & 0xf0;
257
+ break;
258
+ case TMP421_TEMP_LSB1:
259
+ s->buf[s->len++] = (((uint16_t) s->temperature[1]) >> 0) & 0xf0;
260
+ break;
261
+ case TMP421_TEMP_LSB2:
262
+ s->buf[s->len++] = (((uint16_t) s->temperature[2]) >> 0) & 0xf0;
263
+ break;
264
+ case TMP421_TEMP_LSB3:
265
+ s->buf[s->len++] = (((uint16_t) s->temperature[3]) >> 0) & 0xf0;
266
+ break;
267
+ }
268
+}
269
+
270
+static void tmp421_reset(I2CSlave *i2c);
271
+
272
+static void tmp421_write(TMP421State *s)
273
+{
274
+ switch (s->pointer) {
275
+ case TMP421_CONVERSION_RATE_REG:
276
+ s->rate = s->buf[0];
277
+ break;
278
+ case TMP421_CONFIG_REG_1:
279
+ s->config[0] = s->buf[0];
280
+ break;
281
+ case TMP421_CONFIG_REG_2:
282
+ s->config[1] = s->buf[0];
283
+ break;
284
+ case TMP421_RESET:
285
+ tmp421_reset(I2C_SLAVE(s));
286
+ break;
287
+ }
288
+}
289
+
290
+static int tmp421_rx(I2CSlave *i2c)
291
+{
292
+ TMP421State *s = TMP421(i2c);
293
+
294
+ if (s->len < 2) {
295
+ return s->buf[s->len++];
296
+ } else {
297
+ return 0xff;
298
+ }
299
+}
300
+
301
+static int tmp421_tx(I2CSlave *i2c, uint8_t data)
302
+{
303
+ TMP421State *s = TMP421(i2c);
304
+
305
+ if (s->len == 0) {
306
+ /* first byte is the register pointer for a read or write
307
+ * operation */
308
+ s->pointer = data;
309
+ s->len++;
310
+ } else if (s->len == 1) {
311
+ /* second byte is the data to write. The device only supports
312
+ * one byte writes */
313
+ s->buf[0] = data;
314
+ tmp421_write(s);
315
+ }
316
+
317
+ return 0;
318
+}
319
+
320
+static int tmp421_event(I2CSlave *i2c, enum i2c_event event)
321
+{
322
+ TMP421State *s = TMP421(i2c);
323
+
324
+ if (event == I2C_START_RECV) {
325
+ tmp421_read(s);
326
+ }
327
+
328
+ s->len = 0;
329
+ return 0;
330
+}
331
+
332
+static const VMStateDescription vmstate_tmp421 = {
333
+ .name = "TMP421",
334
+ .version_id = 0,
335
+ .minimum_version_id = 0,
336
+ .fields = (VMStateField[]) {
396
+ .fields = (VMStateField[]) {
337
+ VMSTATE_UINT8(len, TMP421State),
397
+ VMSTATE_PTIMER(timer, CMSDKAPBWatchdog),
338
+ VMSTATE_UINT8_ARRAY(buf, TMP421State, 2),
398
+ VMSTATE_UINT32(control, CMSDKAPBWatchdog),
339
+ VMSTATE_UINT8(pointer, TMP421State),
399
+ VMSTATE_UINT32(intstatus, CMSDKAPBWatchdog),
340
+ VMSTATE_UINT8_ARRAY(config, TMP421State, 2),
400
+ VMSTATE_UINT32(lock, CMSDKAPBWatchdog),
341
+ VMSTATE_UINT8(status, TMP421State),
401
+ VMSTATE_UINT32(itcr, CMSDKAPBWatchdog),
342
+ VMSTATE_UINT8(rate, TMP421State),
402
+ VMSTATE_UINT32(itop, CMSDKAPBWatchdog),
343
+ VMSTATE_INT16_ARRAY(temperature, TMP421State, 4),
403
+ VMSTATE_UINT32(resetstatus, CMSDKAPBWatchdog),
344
+ VMSTATE_I2C_SLAVE(i2c, TMP421State),
345
+ VMSTATE_END_OF_LIST()
404
+ VMSTATE_END_OF_LIST()
346
+ }
405
+ }
347
+};
406
+};
348
+
407
+
349
+static void tmp421_reset(I2CSlave *i2c)
408
+static Property cmsdk_apb_watchdog_properties[] = {
350
+{
409
+ DEFINE_PROP_UINT32("wdogclk-frq", CMSDKAPBWatchdog, wdogclk_frq, 0),
351
+ TMP421State *s = TMP421(i2c);
410
+ DEFINE_PROP_END_OF_LIST(),
352
+ TMP421Class *sc = TMP421_GET_CLASS(s);
411
+};
353
+
412
+
354
+ memset(s->temperature, 0, sizeof(s->temperature));
413
+static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, void *data)
355
+ s->pointer = 0;
356
+
357
+ s->config[0] = 0; /* TMP421_CONFIG_RANGE */
358
+
359
+ /* resistance correction and channel enablement */
360
+ switch (sc->dev->model) {
361
+ case TMP421_DEVICE_ID:
362
+ s->config[1] = 0x1c;
363
+ break;
364
+ case TMP422_DEVICE_ID:
365
+ s->config[1] = 0x3c;
366
+ break;
367
+ case TMP423_DEVICE_ID:
368
+ s->config[1] = 0x7c;
369
+ break;
370
+ }
371
+
372
+ s->rate = 0x7; /* 8Hz */
373
+ s->status = 0;
374
+}
375
+
376
+static int tmp421_init(I2CSlave *i2c)
377
+{
378
+ TMP421State *s = TMP421(i2c);
379
+
380
+ tmp421_reset(&s->i2c);
381
+
382
+ return 0;
383
+}
384
+
385
+static void tmp421_initfn(Object *obj)
386
+{
387
+ object_property_add(obj, "temperature0", "int",
388
+ tmp421_get_temperature,
389
+ tmp421_set_temperature, NULL, NULL, NULL);
390
+ object_property_add(obj, "temperature1", "int",
391
+ tmp421_get_temperature,
392
+ tmp421_set_temperature, NULL, NULL, NULL);
393
+ object_property_add(obj, "temperature2", "int",
394
+ tmp421_get_temperature,
395
+ tmp421_set_temperature, NULL, NULL, NULL);
396
+ object_property_add(obj, "temperature3", "int",
397
+ tmp421_get_temperature,
398
+ tmp421_set_temperature, NULL, NULL, NULL);
399
+}
400
+
401
+static void tmp421_class_init(ObjectClass *klass, void *data)
402
+{
414
+{
403
+ DeviceClass *dc = DEVICE_CLASS(klass);
415
+ DeviceClass *dc = DEVICE_CLASS(klass);
404
+ I2CSlaveClass *k = I2C_SLAVE_CLASS(klass);
416
+
405
+ TMP421Class *sc = TMP421_CLASS(klass);
417
+ dc->realize = cmsdk_apb_watchdog_realize;
406
+
418
+ dc->vmsd = &cmsdk_apb_watchdog_vmstate;
407
+ k->init = tmp421_init;
419
+ dc->reset = cmsdk_apb_watchdog_reset;
408
+ k->event = tmp421_event;
420
+ dc->props = cmsdk_apb_watchdog_properties;
409
+ k->recv = tmp421_rx;
421
+}
410
+ k->send = tmp421_tx;
422
+
411
+ dc->vmsd = &vmstate_tmp421;
423
+static const TypeInfo cmsdk_apb_watchdog_info = {
412
+ sc->dev = (DeviceInfo *) data;
424
+ .name = TYPE_CMSDK_APB_WATCHDOG,
413
+}
425
+ .parent = TYPE_SYS_BUS_DEVICE,
414
+
426
+ .instance_size = sizeof(CMSDKAPBWatchdog),
415
+static const TypeInfo tmp421_info = {
427
+ .instance_init = cmsdk_apb_watchdog_init,
416
+ .name = TYPE_TMP421,
428
+ .class_init = cmsdk_apb_watchdog_class_init,
417
+ .parent = TYPE_I2C_SLAVE,
418
+ .instance_size = sizeof(TMP421State),
419
+ .class_size = sizeof(TMP421Class),
420
+ .instance_init = tmp421_initfn,
421
+ .abstract = true,
422
+};
429
+};
423
+
430
+
424
+static void tmp421_register_types(void)
431
+static void cmsdk_apb_watchdog_register_types(void)
425
+{
432
+{
426
+ int i;
433
+ type_register_static(&cmsdk_apb_watchdog_info);
427
+
434
+}
428
+ type_register_static(&tmp421_info);
435
+
429
+ for (i = 0; i < ARRAY_SIZE(devices); ++i) {
436
+type_init(cmsdk_apb_watchdog_register_types);
430
+ TypeInfo ti = {
437
diff --git a/MAINTAINERS b/MAINTAINERS
431
+ .name = devices[i].name,
438
index XXXXXXX..XXXXXXX 100644
432
+ .parent = TYPE_TMP421,
439
--- a/MAINTAINERS
433
+ .class_init = tmp421_class_init,
440
+++ b/MAINTAINERS
434
+ .class_data = (void *) &devices[i],
441
@@ -XXX,XX +XXX,XX @@ F: hw/timer/cmsdk-apb-timer.c
435
+ };
442
F: include/hw/timer/cmsdk-apb-timer.h
436
+ type_register(&ti);
443
F: hw/char/cmsdk-apb-uart.c
437
+ }
444
F: include/hw/char/cmsdk-apb-uart.h
438
+}
445
+F: hw/watchdog/cmsdk-apb-watchdog.c
439
+
446
+F: include/hw/watchdog/cmsdk-apb-watchdog.h
440
+type_init(tmp421_register_types)
447
F: hw/misc/tz-ppc.c
448
F: include/hw/misc/tz-ppc.h
449
F: hw/misc/tz-mpc.c
441
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
450
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
442
index XXXXXXX..XXXXXXX 100644
451
index XXXXXXX..XXXXXXX 100644
443
--- a/default-configs/arm-softmmu.mak
452
--- a/default-configs/arm-softmmu.mak
444
+++ b/default-configs/arm-softmmu.mak
453
+++ b/default-configs/arm-softmmu.mak
445
@@ -XXX,XX +XXX,XX @@ CONFIG_TWL92230=y
454
@@ -XXX,XX +XXX,XX @@ CONFIG_STM32F205_SOC=y
446
CONFIG_TSC2005=y
455
447
CONFIG_LM832X=y
456
CONFIG_CMSDK_APB_TIMER=y
448
CONFIG_TMP105=y
457
CONFIG_CMSDK_APB_UART=y
449
+CONFIG_TMP421=y
458
+CONFIG_CMSDK_APB_WATCHDOG=y
450
CONFIG_STELLARIS=y
459
451
CONFIG_STELLARIS_INPUT=y
460
CONFIG_MPS2_FPGAIO=y
452
CONFIG_STELLARIS_ENET=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"
453
--
474
--
454
2.7.4
475
2.18.0
455
476
456
477
diff view generated by jsdifflib
1
From: Krzysztof Kozlowski <krzk@kernel.org>
1
On real v7M hardware, the NMI line is an externally visible signal
2
that an SoC or board can toggle to assert an NMI. Expose it in
3
our QEMU NVIC and armv7m container objects so that a board model
4
can wire it up if it needs to.
2
5
3
Before QOM-ifying the Exynos4 SoC model, move the DRAM initialization
6
In particular, the MPS2 watchdog is wired to NMI.
4
from exynos4210.c to exynos4_boards.c because DRAM is board specific,
5
not SoC.
6
7
7
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
include/hw/arm/exynos4210.h | 5 +----
11
hw/arm/armv7m.c | 1 +
12
hw/arm/exynos4210.c | 20 +-----------------
12
hw/intc/armv7m_nvic.c | 19 +++++++++++++++++++
13
hw/arm/exynos4_boards.c | 50 ++++++++++++++++++++++++++++++++++++++-------
13
hw/intc/trace-events | 1 +
14
3 files changed, 45 insertions(+), 30 deletions(-)
14
3 files changed, 21 insertions(+)
15
15
16
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
16
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/arm/exynos4210.h
18
--- a/hw/arm/armv7m.c
19
+++ b/include/hw/arm/exynos4210.h
19
+++ b/hw/arm/armv7m.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210State {
20
@@ -XXX,XX +XXX,XX @@ static void armv7m_realize(DeviceState *dev, Error **errp)
21
MemoryRegion iram_mem;
21
*/
22
MemoryRegion irom_mem;
22
qdev_pass_gpios(DEVICE(&s->nvic), dev, NULL);
23
MemoryRegion irom_alias_mem;
23
qdev_pass_gpios(DEVICE(&s->nvic), dev, "SYSRESETREQ");
24
- MemoryRegion dram0_mem;
24
+ qdev_pass_gpios(DEVICE(&s->nvic), dev, "NMI");
25
- MemoryRegion dram1_mem;
25
26
MemoryRegion boot_secondary;
26
/* Wire the NVIC up to the CPU */
27
MemoryRegion bootreg_mem;
27
sbd = SYS_BUS_DEVICE(&s->nvic);
28
I2CBus *i2c_if[EXYNOS4210_I2C_NUMBER];
28
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
29
@@ -XXX,XX +XXX,XX @@ typedef struct Exynos4210State {
30
void exynos4210_write_secondary(ARMCPU *cpu,
31
const struct arm_boot_info *info);
32
33
-Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
34
- unsigned long ram_size);
35
+Exynos4210State *exynos4210_init(MemoryRegion *system_mem);
36
37
/* Initialize exynos4210 IRQ subsystem stub */
38
qemu_irq *exynos4210_init_irq(Exynos4210Irq *env);
39
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
40
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/arm/exynos4210.c
30
--- a/hw/intc/armv7m_nvic.c
42
+++ b/hw/arm/exynos4210.c
31
+++ b/hw/intc/armv7m_nvic.c
43
@@ -XXX,XX +XXX,XX @@ static uint64_t exynos4210_calc_affinity(int cpu)
32
@@ -XXX,XX +XXX,XX @@ static void set_irq_level(void *opaque, int n, int level)
44
return mp_affinity;
45
}
46
47
-Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
48
- unsigned long ram_size)
49
+Exynos4210State *exynos4210_init(MemoryRegion *system_mem)
50
{
51
int i, n;
52
Exynos4210State *s = g_new(Exynos4210State, 1);
53
qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
54
- unsigned long mem_size;
55
DeviceState *dev;
56
SysBusDevice *busdev;
57
ObjectClass *cpu_oc;
58
@@ -XXX,XX +XXX,XX @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
59
memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
60
&s->iram_mem);
61
62
- /* DRAM */
63
- mem_size = ram_size;
64
- if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) {
65
- memory_region_init_ram(&s->dram1_mem, NULL, "exynos4210.dram1",
66
- mem_size - EXYNOS4210_DRAM_MAX_SIZE, &error_fatal);
67
- vmstate_register_ram_global(&s->dram1_mem);
68
- memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
69
- &s->dram1_mem);
70
- mem_size = EXYNOS4210_DRAM_MAX_SIZE;
71
- }
72
- memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size,
73
- &error_fatal);
74
- vmstate_register_ram_global(&s->dram0_mem);
75
- memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
76
- &s->dram0_mem);
77
-
78
/* PMU.
79
* The only reason of existence at the moment is that secondary CPU boot
80
* loader uses PMU INFORM5 register as a holding pen.
81
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/hw/arm/exynos4_boards.c
84
+++ b/hw/arm/exynos4_boards.c
85
@@ -XXX,XX +XXX,XX @@
86
*/
87
88
#include "qemu/osdep.h"
89
+#include "qapi/error.h"
90
#include "qemu/error-report.h"
91
#include "qemu-common.h"
92
#include "cpu.h"
93
@@ -XXX,XX +XXX,XX @@ typedef enum Exynos4BoardType {
94
EXYNOS4_NUM_OF_BOARDS
95
} Exynos4BoardType;
96
97
+typedef struct Exynos4BoardState {
98
+ Exynos4210State *soc;
99
+ MemoryRegion dram0_mem;
100
+ MemoryRegion dram1_mem;
101
+} Exynos4BoardState;
102
+
103
static int exynos4_board_id[EXYNOS4_NUM_OF_BOARDS] = {
104
[EXYNOS4_BOARD_NURI] = 0xD33,
105
[EXYNOS4_BOARD_SMDKC210] = 0xB16,
106
@@ -XXX,XX +XXX,XX @@ static void lan9215_init(uint32_t base, qemu_irq irq)
107
}
33
}
108
}
34
}
109
35
110
-static Exynos4210State *exynos4_boards_init_common(MachineState *machine,
36
+/* callback when external NMI line is changed */
111
- Exynos4BoardType board_type)
37
+static void nvic_nmi_trigger(void *opaque, int n, int level)
112
+static void exynos4_boards_init_ram(Exynos4BoardState *s,
113
+ MemoryRegion *system_mem,
114
+ unsigned long ram_size)
115
+{
38
+{
116
+ unsigned long mem_size = ram_size;
39
+ NVICState *s = opaque;
117
+
40
+
118
+ if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) {
41
+ trace_nvic_set_nmi_level(level);
119
+ memory_region_init_ram(&s->dram1_mem, NULL, "exynos4210.dram1",
42
+
120
+ mem_size - EXYNOS4210_DRAM_MAX_SIZE,
43
+ /*
121
+ &error_fatal);
44
+ * The architecture doesn't specify whether NMI should share
122
+ vmstate_register_ram_global(&s->dram1_mem);
45
+ * the normal-interrupt behaviour of being resampled on
123
+ memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
46
+ * exception handler return. We choose not to, so just
124
+ &s->dram1_mem);
47
+ * set NMI pending here and don't track the current level.
125
+ mem_size = EXYNOS4210_DRAM_MAX_SIZE;
48
+ */
49
+ if (level) {
50
+ armv7m_nvic_set_pending(s, ARMV7M_EXCP_NMI, false);
126
+ }
51
+ }
127
+
128
+ memory_region_init_ram(&s->dram0_mem, NULL, "exynos4210.dram0", mem_size,
129
+ &error_fatal);
130
+ vmstate_register_ram_global(&s->dram0_mem);
131
+ memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
132
+ &s->dram0_mem);
133
+}
52
+}
134
+
53
+
135
+static Exynos4BoardState *
54
static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
136
+exynos4_boards_init_common(MachineState *machine,
137
+ Exynos4BoardType board_type)
138
{
55
{
139
+ Exynos4BoardState *s = g_new(Exynos4BoardState, 1);
56
ARMCPU *cpu = s->cpu;
140
MachineClass *mc = MACHINE_GET_CLASS(machine);
57
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_instance_init(Object *obj)
141
58
qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1);
142
if (smp_cpus != EXYNOS4210_NCPUS && !qtest_enabled()) {
59
qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger",
143
@@ -XXX,XX +XXX,XX @@ static Exynos4210State *exynos4_boards_init_common(MachineState *machine,
60
M_REG_NUM_BANKS);
144
machine->kernel_cmdline,
61
+ qdev_init_gpio_in_named(dev, nvic_nmi_trigger, "NMI", 1);
145
machine->initrd_filename);
146
147
- return exynos4210_init(get_system_memory(),
148
- exynos4_board_ram_size[board_type]);
149
+ exynos4_boards_init_ram(s, get_system_memory(),
150
+ exynos4_board_ram_size[board_type]);
151
+
152
+ s->soc = exynos4210_init(get_system_memory());
153
+
154
+ return s;
155
}
62
}
156
63
157
static void nuri_init(MachineState *machine)
64
static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
158
@@ -XXX,XX +XXX,XX @@ static void nuri_init(MachineState *machine)
65
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
159
66
index XXXXXXX..XXXXXXX 100644
160
static void smdkc210_init(MachineState *machine)
67
--- a/hw/intc/trace-events
161
{
68
+++ b/hw/intc/trace-events
162
- Exynos4210State *s = exynos4_boards_init_common(machine,
69
@@ -XXX,XX +XXX,XX @@ nvic_acknowledge_irq(int irq, int prio) "NVIC acknowledge IRQ: %d now active (pr
163
- EXYNOS4_BOARD_SMDKC210);
70
nvic_get_pending_irq_info(int irq, bool secure) "NVIC next IRQ %d: targets_secure: %d"
164
+ Exynos4BoardState *s = exynos4_boards_init_common(machine,
71
nvic_complete_irq(int irq, bool secure) "NVIC complete IRQ %d (secure %d)"
165
+ EXYNOS4_BOARD_SMDKC210);
72
nvic_set_irq_level(int irq, int level) "NVIC external irq %d level set to %d"
166
73
+nvic_set_nmi_level(int level) "NVIC external NMI level set to %d"
167
lan9215_init(SMDK_LAN9118_BASE_ADDR,
74
nvic_sysreg_read(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
168
- qemu_irq_invert(s->irq_table[exynos4210_get_irq(37, 1)]));
75
nvic_sysreg_write(uint64_t addr, uint32_t value, unsigned size) "NVIC sysreg write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
169
+ qemu_irq_invert(s->soc->irq_table[exynos4210_get_irq(37, 1)]));
170
arm_load_kernel(ARM_CPU(first_cpu), &exynos4_board_binfo);
171
}
172
76
173
--
77
--
174
2.7.4
78
2.18.0
175
79
176
80
diff view generated by jsdifflib
New patch
1
Create a new include file for the pl081's device struct,
2
type macros, etc, so that it can be instantiated using
3
the "embedded struct" coding style.
1
4
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
---
8
include/hw/dma/pl080.h | 62 ++++++++++++++++++++++++++++++++++++++++++
9
hw/dma/pl080.c | 34 ++---------------------
10
MAINTAINERS | 1 +
11
3 files changed, 65 insertions(+), 32 deletions(-)
12
create mode 100644 include/hw/dma/pl080.h
13
14
diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h
15
new file mode 100644
16
index XXXXXXX..XXXXXXX
17
--- /dev/null
18
+++ b/include/hw/dma/pl080.h
19
@@ -XXX,XX +XXX,XX @@
20
+/*
21
+ * ARM PrimeCell PL080/PL081 DMA controller
22
+ *
23
+ * Copyright (c) 2006 CodeSourcery.
24
+ * Copyright (c) 2018 Linaro Limited
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
+ */
31
+
32
+/* This is a model of the Arm PrimeCell PL080/PL081 DMA controller:
33
+ * The PL080 TRM is:
34
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0196g/DDI0196.pdf
35
+ * and the PL081 TRM is:
36
+ * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0218e/DDI0218.pdf
37
+ *
38
+ * QEMU interface:
39
+ * + sysbus IRQ: DMACINTR combined interrupt line
40
+ * + sysbus MMIO region 0: MemoryRegion for the device's registers
41
+ */
42
+
43
+#ifndef HW_DMA_PL080_H
44
+#define HW_DMA_PL080_H
45
+
46
+#include "hw/sysbus.h"
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
+
81
+#endif
82
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/dma/pl080.c
85
+++ b/hw/dma/pl080.c
86
@@ -XXX,XX +XXX,XX @@
87
#include "hw/sysbus.h"
88
#include "exec/address-spaces.h"
89
#include "qemu/log.h"
90
+#include "hw/dma/pl080.h"
91
92
-#define PL080_MAX_CHANNELS 8
93
#define PL080_CONF_E 0x1
94
#define PL080_CONF_M1 0x2
95
#define PL080_CONF_M2 0x4
96
@@ -XXX,XX +XXX,XX @@
97
#define PL080_CCTRL_D 0x02000000
98
#define PL080_CCTRL_S 0x01000000
99
100
-typedef struct {
101
- uint32_t src;
102
- uint32_t dest;
103
- uint32_t lli;
104
- uint32_t ctrl;
105
- uint32_t conf;
106
-} pl080_channel;
107
-
108
-#define TYPE_PL080 "pl080"
109
-#define PL080(obj) OBJECT_CHECK(PL080State, (obj), TYPE_PL080)
110
-
111
-typedef struct PL080State {
112
- SysBusDevice parent_obj;
113
-
114
- MemoryRegion iomem;
115
- uint8_t tc_int;
116
- uint8_t tc_mask;
117
- uint8_t err_int;
118
- uint8_t err_mask;
119
- uint32_t conf;
120
- uint32_t sync;
121
- uint32_t req_single;
122
- uint32_t req_burst;
123
- pl080_channel chan[PL080_MAX_CHANNELS];
124
- int nchannels;
125
- /* Flag to avoid recursive DMA invocations. */
126
- int running;
127
- qemu_irq irq;
128
-} PL080State;
129
-
130
static const VMStateDescription vmstate_pl080_channel = {
131
.name = "pl080_channel",
132
.version_id = 1,
133
@@ -XXX,XX +XXX,XX @@ static const TypeInfo pl080_info = {
134
};
135
136
static const TypeInfo pl081_info = {
137
- .name = "pl081",
138
+ .name = TYPE_PL081,
139
.parent = TYPE_PL080,
140
.instance_init = pl081_init,
141
};
142
diff --git a/MAINTAINERS b/MAINTAINERS
143
index XXXXXXX..XXXXXXX 100644
144
--- a/MAINTAINERS
145
+++ b/MAINTAINERS
146
@@ -XXX,XX +XXX,XX @@ F: hw/char/pl011.c
147
F: include/hw/char/pl011.h
148
F: hw/display/pl110*
149
F: hw/dma/pl080.c
150
+F: include/hw/dma/pl080.h
151
F: hw/dma/pl330.c
152
F: hw/gpio/pl061.c
153
F: hw/input/pl050.c
154
--
155
2.18.0
156
157
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
The PL080 and PL081 have three outgoing interrupt lines:
2
* DMACINTERR signals DMA errors
3
* DMACINTTC is the DMA count interrupt
4
* DMACINTR is a combined interrupt, the logical OR of the other two
2
5
3
Temperatures can be changed from the monitor with :
6
We currently only implement DMACINTR, because that's all the
7
realview and versatile boards needed, but the instances of the
8
PL081 in the MPS2 firmware images use all three interrupt lines.
9
Implement the missing DMACINTERR and DMACINTTC.
4
10
5
    (qemu) qom-set /machine/unattached/device[2] temperature0 12000
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
---
14
include/hw/dma/pl080.h | 6 +++++-
15
hw/dma/pl080.c | 13 ++++++++-----
16
2 files changed, 13 insertions(+), 6 deletions(-)
6
17
7
Signed-off-by: Cédric Le Goater <clg@kaod.org>
18
diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h
8
Message-id: 1496739230-32109-3-git-send-email-clg@kaod.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/aspeed.c | 9 +++++++++
13
1 file changed, 9 insertions(+)
14
15
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/aspeed.c
20
--- a/include/hw/dma/pl080.h
18
+++ b/hw/arm/aspeed.c
21
+++ b/include/hw/dma/pl080.h
19
@@ -XXX,XX +XXX,XX @@ static void aspeed_board_init(MachineState *machine,
22
@@ -XXX,XX +XXX,XX @@
20
static void palmetto_bmc_i2c_init(AspeedBoardState *bmc)
23
* http://infocenter.arm.com/help/topic/com.arm.doc.ddi0218e/DDI0218.pdf
24
*
25
* QEMU interface:
26
- * + sysbus IRQ: DMACINTR combined interrupt line
27
+ * + sysbus IRQ 0: DMACINTR combined interrupt line
28
+ * + sysbus IRQ 1: DMACINTERR error interrupt request
29
+ * + sysbus IRQ 2: DMACINTTC count interrupt request
30
* + sysbus MMIO region 0: MemoryRegion for the device's registers
31
*/
32
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)
21
{
49
{
22
AspeedSoCState *soc = &bmc->soc;
50
- if ((s->tc_int & s->tc_mask)
23
+ DeviceState *dev;
51
- || (s->err_int & s->err_mask))
24
52
- qemu_irq_raise(s->irq);
25
/* The palmetto platform expects a ds3231 RTC but a ds1338 is
53
- else
26
* enough to provide basic RTC features. Alarms will be missing */
54
- qemu_irq_lower(s->irq);
27
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 0), "ds1338", 0x68);
55
+ bool tclevel = (s->tc_int & s->tc_mask);
56
+ bool errlevel = (s->err_int & s->err_mask);
28
+
57
+
29
+ /* add a TMP423 temperature sensor */
58
+ qemu_set_irq(s->interr, errlevel);
30
+ dev = i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 2),
59
+ qemu_set_irq(s->inttc, tclevel);
31
+ "tmp423", 0x4c);
60
+ qemu_set_irq(s->irq, errlevel || tclevel);
32
+ object_property_set_int(OBJECT(dev), 31000, "temperature0", &error_abort);
33
+ object_property_set_int(OBJECT(dev), 28000, "temperature1", &error_abort);
34
+ object_property_set_int(OBJECT(dev), 20000, "temperature2", &error_abort);
35
+ object_property_set_int(OBJECT(dev), 110000, "temperature3", &error_abort);
36
}
61
}
37
62
38
static void palmetto_bmc_init(MachineState *machine)
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
39
--
73
--
40
2.7.4
74
2.18.0
41
75
42
76
diff view generated by jsdifflib
1
From: Krzysztof Kozlowski <krzk@kernel.org>
1
Currently our PL080/PL081 model uses a combination of the CPU's
2
address space (via cpu_physical_memory_{read,write}()) and the
3
system address space for performing DMA accesses.
2
4
3
The static array of interrupt combiner mappings is not modified so it
5
For the PL081s in the MPS FPGA images, their DMA accesses
4
can be made const for code safeness.
6
must go via Master Security Controllers. Switch the
7
PL080/PL081 model to take a MemoryRegion property which
8
defines its downstream for making DMA accesses.
5
9
6
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
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
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
17
---
10
hw/intc/exynos4210_gic.c | 2 +-
18
include/hw/dma/pl080.h | 5 +++++
11
1 file changed, 1 insertion(+), 1 deletion(-)
19
hw/arm/realview.c | 8 +++++++-
20
hw/arm/versatilepb.c | 9 ++++++++-
21
hw/dma/pl080.c | 35 +++++++++++++++++++++++++++++------
22
4 files changed, 49 insertions(+), 8 deletions(-)
12
23
13
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
24
diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/exynos4210_gic.c
26
--- a/include/hw/dma/pl080.h
16
+++ b/hw/intc/exynos4210_gic.c
27
+++ b/include/hw/dma/pl080.h
17
@@ -XXX,XX +XXX,XX @@ enum ExtInt {
28
@@ -XXX,XX +XXX,XX @@
18
* which is INTG16 in Internal Interrupt Combiner.
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
19
*/
34
*/
20
35
21
-static uint32_t
36
#ifndef HW_DMA_PL080_H
22
+static const uint32_t
37
@@ -XXX,XX +XXX,XX @@ typedef struct PL080State {
23
combiner_grp_to_gic_id[64-EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ][8] = {
38
qemu_irq irq;
24
/* int combiner groups 16-19 */
39
qemu_irq interr;
25
{ }, { }, { }, { },
40
qemu_irq inttc;
41
+
42
+ MemoryRegion *downstream;
43
+ AddressSpace downstream_as;
44
} PL080State;
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
+
83
sysbus_create_simple("sp804", 0x101e2000, pic[4]);
84
sysbus_create_simple("sp804", 0x101e3000, pic[5]);
85
86
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
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
+ }
153
+
154
+ address_space_init(&s->downstream_as, s->downstream, "pl080-downstream");
155
+}
156
+
157
static void pl081_init(Object *obj)
158
{
159
PL080State *s = PL080(obj);
160
@@ -XXX,XX +XXX,XX @@ static void pl081_init(Object *obj)
161
s->nchannels = 2;
162
}
163
164
+static Property pl080_properties[] = {
165
+ DEFINE_PROP_LINK("downstream", PL080State, downstream,
166
+ TYPE_MEMORY_REGION, MemoryRegion *),
167
+ DEFINE_PROP_END_OF_LIST(),
168
+};
169
+
170
static void pl080_class_init(ObjectClass *oc, void *data)
171
{
172
DeviceClass *dc = DEVICE_CLASS(oc);
173
174
dc->vmsd = &vmstate_pl080;
175
+ dc->realize = pl080_realize;
176
+ dc->props = pl080_properties;
177
}
178
179
static const TypeInfo pl080_info = {
26
--
180
--
27
2.7.4
181
2.18.0
28
182
29
183
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
The PL080/PL081 model is missing a reset function; implement it.
2
2
3
This patch adds the flush of the LPI pending bits into the
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
redistributor pending tables. This happens on VM stop.
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
---
6
hw/dma/pl080.c | 25 +++++++++++++++++++++++++
7
1 file changed, 25 insertions(+)
5
8
6
There is no explicit restore as the tables are implicitly sync'ed
9
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
7
on ITS table restore and on LPI enable at redistributor level.
8
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Message-id: 1497023553-18411-4-git-send-email-eric.auger@redhat.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
hw/intc/arm_gicv3_kvm.c | 34 ++++++++++++++++++++++++++++++++++
15
1 file changed, 34 insertions(+)
16
17
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
18
index XXXXXXX..XXXXXXX 100644
10
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/arm_gicv3_kvm.c
11
--- a/hw/dma/pl080.c
20
+++ b/hw/intc/arm_gicv3_kvm.c
12
+++ b/hw/dma/pl080.c
21
@@ -XXX,XX +XXX,XX @@
13
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps pl080_ops = {
22
#include "hw/sysbus.h"
14
.endianness = DEVICE_NATIVE_ENDIAN,
23
#include "qemu/error-report.h"
24
#include "sysemu/kvm.h"
25
+#include "sysemu/sysemu.h"
26
#include "kvm_arm.h"
27
#include "gicv3_internal.h"
28
#include "vgic_common.h"
29
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gicv3_cpuif_reginfo[] = {
30
REGINFO_SENTINEL
31
};
15
};
32
16
33
+/**
17
+static void pl080_reset(DeviceState *dev)
34
+ * vm_change_state_handler - VM change state callback aiming at flushing
35
+ * RDIST pending tables into guest RAM
36
+ *
37
+ * The tables get flushed to guest RAM whenever the VM gets stopped.
38
+ */
39
+static void vm_change_state_handler(void *opaque, int running,
40
+ RunState state)
41
+{
18
+{
42
+ GICv3State *s = (GICv3State *)opaque;
19
+ PL080State *s = PL080(dev);
43
+ Error *err = NULL;
20
+ int i;
44
+ int ret;
45
+
21
+
46
+ if (running) {
22
+ s->tc_int = 0;
47
+ return;
23
+ s->tc_mask = 0;
48
+ }
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;
49
+
31
+
50
+ ret = kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
32
+ for (i = 0; i < s->nchannels; i++) {
51
+ KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES,
33
+ s->chan[i].src = 0;
52
+ NULL, true, &err);
34
+ s->chan[i].dest = 0;
53
+ if (err) {
35
+ s->chan[i].lli = 0;
54
+ error_report_err(err);
36
+ s->chan[i].ctrl = 0;
55
+ }
37
+ s->chan[i].conf = 0;
56
+ if (ret < 0 && ret != -EFAULT) {
57
+ abort();
58
+ }
38
+ }
59
+}
39
+}
60
+
40
+
61
+
41
static void pl080_init(Object *obj)
62
static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
63
{
42
{
64
GICv3State *s = KVM_ARM_GICV3(dev);
43
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
65
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp)
44
@@ -XXX,XX +XXX,XX @@ static void pl080_class_init(ObjectClass *oc, void *data)
66
return;
45
dc->vmsd = &vmstate_pl080;
67
}
46
dc->realize = pl080_realize;
68
}
47
dc->props = pl080_properties;
69
+ if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
48
+ dc->reset = pl080_reset;
70
+ KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES)) {
71
+ qemu_add_vm_change_state_handler(vm_change_state_handler, s);
72
+ }
73
}
49
}
74
50
75
static void kvm_arm_gicv3_class_init(ObjectClass *klass, void *data)
51
static const TypeInfo pl080_info = {
76
--
52
--
77
2.7.4
53
2.18.0
78
54
79
55
diff view generated by jsdifflib
1
From: Krzysztof Kozlowski <krzk@kernel.org>
1
A bug in the handling of the register address decode logic
2
for the PL08x meant that we were incorrectly treating
3
accesses to the DMA channel registers (DMACCxSrcAddr,
4
DMACCxDestaddr, DMACCxLLI, DMACCxControl, DMACCxConfiguration)
5
as bad offsets. Fix this long-standing bug.
2
6
3
Use a define for a9mpcore_priv device type name instead of hard-coded
7
Fixes: https://bugs.launchpad.net/qemu/+bug/1637974
4
string.
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
---
11
hw/dma/pl080.c | 5 +++--
12
1 file changed, 3 insertions(+), 2 deletions(-)
5
13
6
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
14
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/arm/exynos4210.c | 3 ++-
11
1 file changed, 2 insertions(+), 1 deletion(-)
12
13
diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/exynos4210.c
16
--- a/hw/dma/pl080.c
16
+++ b/hw/arm/exynos4210.c
17
+++ b/hw/dma/pl080.c
17
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ static uint64_t pl080_read(void *opaque, hwaddr offset,
18
#include "qemu-common.h"
19
i = (offset & 0xe0) >> 5;
19
#include "qemu/log.h"
20
if (i >= s->nchannels)
20
#include "cpu.h"
21
goto bad_offset;
21
+#include "hw/cpu/a9mpcore.h"
22
- switch (offset >> 2) {
22
#include "hw/boards.h"
23
+ switch ((offset >> 2) & 7) {
23
#include "sysemu/sysemu.h"
24
case 0: /* SrcAddr */
24
#include "hw/sysbus.h"
25
return s->chan[i].src;
25
@@ -XXX,XX +XXX,XX @@ Exynos4210State *exynos4210_init(MemoryRegion *system_mem)
26
case 1: /* DestAddr */
27
@@ -XXX,XX +XXX,XX @@ static void pl080_write(void *opaque, hwaddr offset,
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;
26
}
41
}
27
42
switch (offset >> 2) {
28
/* Private memory region and Internal GIC */
43
case 2: /* IntTCClear */
29
- dev = qdev_create(NULL, "a9mpcore_priv");
30
+ dev = qdev_create(NULL, TYPE_A9MPCORE_PRIV);
31
qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
32
qdev_init_nofail(dev);
33
busdev = SYS_BUS_DEVICE(dev);
34
--
44
--
35
2.7.4
45
2.18.0
36
46
37
47
diff view generated by jsdifflib
1
From: Krzysztof Kozlowski <krzk@kernel.org>
1
The PL08x model currently will unconditionally call hw_error()
2
if the DMA engine is enabled by the guest. This has been
3
present since the PL080 model was edded in 2006, and is
4
presumably either unintentional debug code left enabled,
5
or a guard against untested DMA engine code being used.
2
6
3
There are to SysBusDevice variables in exynos4210_gic_realize()
7
Remove the hw_error(), since we now have a guest which
4
function: one for the device itself and second for arm_gic device. Add
8
will actually try to use the DMA engine (the self-test
5
a prefix "gic" to the second one so it will be easier to understand the
9
binary for the AN505 MPS2 FPGA image).
6
code.
7
10
8
While at it, put local uninitialized 'i' variable at the end, next to
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
other uninitialized ones.
12
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
13
---
14
hw/dma/pl080.c | 1 -
15
1 file changed, 1 deletion(-)
10
16
11
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
17
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
hw/intc/exynos4210_gic.c | 12 ++++++------
17
1 file changed, 6 insertions(+), 6 deletions(-)
18
19
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/intc/exynos4210_gic.c
19
--- a/hw/dma/pl080.c
22
+++ b/hw/intc/exynos4210_gic.c
20
+++ b/hw/dma/pl080.c
23
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_init(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ static void pl080_run(PL080State *s)
24
DeviceState *dev = DEVICE(obj);
22
if ((s->conf & PL080_CONF_E) == 0)
25
Exynos4210GicState *s = EXYNOS4210_GIC(obj);
23
return;
26
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
24
27
- uint32_t i;
25
-hw_error("DMA active\n");
28
const char cpu_prefix[] = "exynos4210-gic-alias_cpu";
26
/* If we are already in the middle of a DMA operation then indicate that
29
const char dist_prefix[] = "exynos4210-gic-alias_dist";
27
there may be new DMA requests and return immediately. */
30
char cpu_alias_name[sizeof(cpu_prefix) + 3];
28
if (s->running) {
31
char dist_alias_name[sizeof(cpu_prefix) + 3];
32
- SysBusDevice *busdev;
33
+ SysBusDevice *gicbusdev;
34
+ uint32_t i;
35
36
s->gic = qdev_create(NULL, "arm_gic");
37
qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);
38
qdev_prop_set_uint32(s->gic, "num-irq", EXYNOS4210_GIC_NIRQ);
39
qdev_init_nofail(s->gic);
40
- busdev = SYS_BUS_DEVICE(s->gic);
41
+ gicbusdev = SYS_BUS_DEVICE(s->gic);
42
43
/* Pass through outbound IRQ lines from the GIC */
44
- sysbus_pass_irq(sbd, busdev);
45
+ sysbus_pass_irq(sbd, gicbusdev);
46
47
/* Pass through inbound GPIO lines to the GIC */
48
qdev_init_gpio_in(dev, exynos4210_gic_set_irq,
49
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_init(Object *obj)
50
sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);
51
memory_region_init_alias(&s->cpu_alias[i], obj,
52
cpu_alias_name,
53
- sysbus_mmio_get_region(busdev, 1),
54
+ sysbus_mmio_get_region(gicbusdev, 1),
55
0,
56
EXYNOS4210_GIC_CPU_REGION_SIZE);
57
memory_region_add_subregion(&s->cpu_container,
58
@@ -XXX,XX +XXX,XX @@ static void exynos4210_gic_init(Object *obj)
59
sprintf(dist_alias_name, "%s%x", dist_prefix, i);
60
memory_region_init_alias(&s->dist_alias[i], obj,
61
dist_alias_name,
62
- sysbus_mmio_get_region(busdev, 0),
63
+ sysbus_mmio_get_region(gicbusdev, 0),
64
0,
65
EXYNOS4210_GIC_DIST_REGION_SIZE);
66
memory_region_add_subregion(&s->dist_container,
67
--
29
--
68
2.7.4
30
2.18.0
69
31
70
32
diff view generated by jsdifflib