]> Git Repo - qemu.git/blame - hw/intc/s390_flic.c
s390x/flic: simplify flic initialization
[qemu.git] / hw / intc / s390_flic.c
CommitLineData
3a553fc6 1/*
7b35d0c4 2 * QEMU S390x floating interrupt controller (flic)
3a553fc6
JF
3 *
4 * Copyright 2014 IBM Corp.
5 * Author(s): Jens Freimann <[email protected]>
7b35d0c4 6 * Cornelia Huck <[email protected]>
3a553fc6
JF
7 *
8 * This work is licensed under the terms of the GNU GPL, version 2 or (at
9 * your option) any later version. See the COPYING file in the top-level
10 * directory.
11 */
12
90191d07 13#include "qemu/osdep.h"
3a553fc6
JF
14#include "qemu/error-report.h"
15#include "hw/sysbus.h"
1622ffd5 16#include "hw/s390x/ioinst.h"
3a553fc6 17#include "hw/s390x/s390_flic.h"
1622ffd5 18#include "hw/s390x/css.h"
3a553fc6 19#include "trace.h"
1622ffd5 20#include "cpu.h"
e61cc6b5
HP
21#include "hw/qdev.h"
22#include "qapi/error.h"
517ff12c 23#include "hw/s390x/s390-virtio-ccw.h"
3a553fc6 24
7b35d0c4 25S390FLICState *s390_get_flic(void)
819bd309 26{
bc66d6cb 27 static S390FLICState *fs;
819bd309 28
7b35d0c4 29 if (!fs) {
bc66d6cb
FL
30 fs = S390_FLIC_COMMON(object_resolve_path(TYPE_KVM_S390_FLIC, NULL));
31 if (!fs) {
32 fs = S390_FLIC_COMMON(object_resolve_path(TYPE_QEMU_S390_FLIC,
33 NULL));
34 }
819bd309 35 }
7b35d0c4 36 return fs;
819bd309
DD
37}
38
7b35d0c4 39void s390_flic_init(void)
3a553fc6 40{
7b35d0c4 41 DeviceState *dev;
3a553fc6 42
e2ac12f0
DH
43 if (kvm_enabled()) {
44 dev = qdev_create(NULL, TYPE_KVM_S390_FLIC);
45 object_property_add_child(qdev_get_machine(), TYPE_KVM_S390_FLIC,
46 OBJECT(dev), NULL);
47 } else {
7b35d0c4
CH
48 dev = qdev_create(NULL, TYPE_QEMU_S390_FLIC);
49 object_property_add_child(qdev_get_machine(), TYPE_QEMU_S390_FLIC,
50 OBJECT(dev), NULL);
3a553fc6 51 }
ae4a2bd7 52 qdev_init_nofail(dev);
3a553fc6
JF
53}
54
03cf077a
CH
55static int qemu_s390_register_io_adapter(S390FLICState *fs, uint32_t id,
56 uint8_t isc, bool swap,
1497c160 57 bool is_maskable, uint8_t flags)
03cf077a
CH
58{
59 /* nothing to do */
60 return 0;
61}
62
d426d9fb
CH
63static int qemu_s390_io_adapter_map(S390FLICState *fs, uint32_t id,
64 uint64_t map_addr, bool do_map)
65{
66 /* nothing to do */
67 return 0;
68}
69
70static int qemu_s390_add_adapter_routes(S390FLICState *fs,
71 AdapterRoutes *routes)
72{
73 return -ENOSYS;
74}
75
76static void qemu_s390_release_adapter_routes(S390FLICState *fs,
77 AdapterRoutes *routes)
78{
79}
80
9eccb862
HP
81static int qemu_s390_clear_io_flic(S390FLICState *fs, uint16_t subchannel_id,
82 uint16_t subchannel_nr)
83{
84 /* Fixme TCG */
85 return -ENOSYS;
86}
87
6c1dd652
FL
88static int qemu_s390_modify_ais_mode(S390FLICState *fs, uint8_t isc,
89 uint16_t mode)
90{
91 QEMUS390FLICState *flic = QEMU_S390_FLIC(fs);
92
93 switch (mode) {
94 case SIC_IRQ_MODE_ALL:
95 flic->simm &= ~AIS_MODE_MASK(isc);
96 flic->nimm &= ~AIS_MODE_MASK(isc);
97 break;
98 case SIC_IRQ_MODE_SINGLE:
99 flic->simm |= AIS_MODE_MASK(isc);
100 flic->nimm &= ~AIS_MODE_MASK(isc);
101 break;
102 default:
103 return -EINVAL;
104 }
105
106 return 0;
107}
108
1622ffd5
YMZ
109static int qemu_s390_inject_airq(S390FLICState *fs, uint8_t type,
110 uint8_t isc, uint8_t flags)
111{
112 QEMUS390FLICState *flic = QEMU_S390_FLIC(fs);
113 bool flag = flags & S390_ADAPTER_SUPPRESSIBLE;
114 uint32_t io_int_word = (isc << 27) | IO_INT_WORD_AI;
115
116 if (flag && (flic->nimm & AIS_MODE_MASK(isc))) {
117 trace_qemu_s390_airq_suppressed(type, isc);
118 return 0;
119 }
120
121 s390_io_interrupt(0, 0, 0, io_int_word);
122
123 if (flag && (flic->simm & AIS_MODE_MASK(isc))) {
124 flic->nimm |= AIS_MODE_MASK(isc);
125 trace_qemu_s390_suppress_airq(isc, "Single-Interruption Mode",
126 "NO-Interruptions Mode");
127 }
128
129 return 0;
130}
131
6c1dd652
FL
132static void qemu_s390_flic_reset(DeviceState *dev)
133{
134 QEMUS390FLICState *flic = QEMU_S390_FLIC(dev);
135
136 flic->simm = 0;
137 flic->nimm = 0;
138}
139
e7be8d49
YMZ
140bool ais_needed(void *opaque)
141{
142 S390FLICState *s = opaque;
143
144 return s->ais_supported;
145}
146
147static const VMStateDescription qemu_s390_flic_vmstate = {
148 .name = "qemu-s390-flic",
149 .version_id = 1,
150 .minimum_version_id = 1,
151 .needed = ais_needed,
152 .fields = (VMStateField[]) {
153 VMSTATE_UINT8(simm, QEMUS390FLICState),
154 VMSTATE_UINT8(nimm, QEMUS390FLICState),
155 VMSTATE_END_OF_LIST()
156 }
157};
158
03cf077a
CH
159static void qemu_s390_flic_class_init(ObjectClass *oc, void *data)
160{
6c1dd652 161 DeviceClass *dc = DEVICE_CLASS(oc);
03cf077a
CH
162 S390FLICStateClass *fsc = S390_FLIC_COMMON_CLASS(oc);
163
6c1dd652 164 dc->reset = qemu_s390_flic_reset;
e7be8d49 165 dc->vmsd = &qemu_s390_flic_vmstate;
03cf077a 166 fsc->register_io_adapter = qemu_s390_register_io_adapter;
d426d9fb
CH
167 fsc->io_adapter_map = qemu_s390_io_adapter_map;
168 fsc->add_adapter_routes = qemu_s390_add_adapter_routes;
169 fsc->release_adapter_routes = qemu_s390_release_adapter_routes;
9eccb862 170 fsc->clear_io_irq = qemu_s390_clear_io_flic;
6c1dd652 171 fsc->modify_ais_mode = qemu_s390_modify_ais_mode;
1622ffd5 172 fsc->inject_airq = qemu_s390_inject_airq;
03cf077a
CH
173}
174
e61cc6b5
HP
175static Property s390_flic_common_properties[] = {
176 DEFINE_PROP_UINT32("adapter_routes_max_batch", S390FLICState,
177 adapter_routes_max_batch, ADAPTER_ROUTES_MAX_GSI),
178 DEFINE_PROP_END_OF_LIST(),
179};
180
181static void s390_flic_common_realize(DeviceState *dev, Error **errp)
182{
6c1dd652
FL
183 S390FLICState *fs = S390_FLIC_COMMON(dev);
184 uint32_t max_batch = fs->adapter_routes_max_batch;
e61cc6b5
HP
185
186 if (max_batch > ADAPTER_ROUTES_MAX_GSI) {
5cbab1bf
HP
187 error_setg(errp, "flic property adapter_routes_max_batch too big"
188 " (%d > %d)", max_batch, ADAPTER_ROUTES_MAX_GSI);
3b00f702 189 return;
e61cc6b5 190 }
6c1dd652 191
3b00f702 192 fs->ais_supported = s390_has_feat(S390_FEAT_ADAPTER_INT_SUPPRESSION);
e61cc6b5
HP
193}
194
195static void s390_flic_class_init(ObjectClass *oc, void *data)
196{
197 DeviceClass *dc = DEVICE_CLASS(oc);
198
199 dc->props = s390_flic_common_properties;
200 dc->realize = s390_flic_common_realize;
201}
202
7b35d0c4
CH
203static const TypeInfo qemu_s390_flic_info = {
204 .name = TYPE_QEMU_S390_FLIC,
205 .parent = TYPE_S390_FLIC_COMMON,
206 .instance_size = sizeof(QEMUS390FLICState),
03cf077a 207 .class_init = qemu_s390_flic_class_init,
7b35d0c4 208};
3a553fc6 209
e61cc6b5 210
7b35d0c4
CH
211static const TypeInfo s390_flic_common_info = {
212 .name = TYPE_S390_FLIC_COMMON,
3a553fc6 213 .parent = TYPE_SYS_BUS_DEVICE,
7b35d0c4 214 .instance_size = sizeof(S390FLICState),
e61cc6b5 215 .class_init = s390_flic_class_init,
7b35d0c4 216 .class_size = sizeof(S390FLICStateClass),
3a553fc6
JF
217};
218
7b35d0c4 219static void qemu_s390_flic_register_types(void)
3a553fc6 220{
7b35d0c4
CH
221 type_register_static(&s390_flic_common_info);
222 type_register_static(&qemu_s390_flic_info);
3a553fc6
JF
223}
224
7b35d0c4 225type_init(qemu_s390_flic_register_types)
517ff12c 226
457af626
HP
227static bool adapter_info_so_needed(void *opaque)
228{
229 return css_migration_enabled();
230}
231
232const VMStateDescription vmstate_adapter_info_so = {
233 .name = "s390_adapter_info/summary_offset",
234 .version_id = 1,
235 .minimum_version_id = 1,
236 .needed = adapter_info_so_needed,
237 .fields = (VMStateField[]) {
238 VMSTATE_UINT32(summary_offset, AdapterInfo),
239 VMSTATE_END_OF_LIST()
240 }
241};
242
517ff12c
HP
243const VMStateDescription vmstate_adapter_info = {
244 .name = "s390_adapter_info",
245 .version_id = 1,
246 .minimum_version_id = 1,
247 .fields = (VMStateField[]) {
248 VMSTATE_UINT64(ind_offset, AdapterInfo),
249 /*
250 * We do not have to migrate neither the id nor the addresses.
251 * The id is set by css_register_io_adapter and the addresses
252 * are set based on the IndAddr objects after those get mapped.
253 */
254 VMSTATE_END_OF_LIST()
255 },
457af626
HP
256 .subsections = (const VMStateDescription * []) {
257 &vmstate_adapter_info_so,
258 NULL
259 }
517ff12c
HP
260};
261
262const VMStateDescription vmstate_adapter_routes = {
263
264 .name = "s390_adapter_routes",
265 .version_id = 1,
266 .minimum_version_id = 1,
267 .fields = (VMStateField[]) {
268 VMSTATE_STRUCT(adapter, AdapterRoutes, 1, vmstate_adapter_info,
269 AdapterInfo),
270 VMSTATE_END_OF_LIST()
271 }
272};
This page took 0.247946 seconds and 4 git commands to generate.