]> Git Repo - qemu.git/blame - hw/s390x/s390-virtio-ccw.c
target/arm: Handle banking in negative-execution-priority check in cpu_mmu_index()
[qemu.git] / hw / s390x / s390-virtio-ccw.c
CommitLineData
a5c95808
CH
1/*
2 * virtio ccw machine
3 *
4 * Copyright 2012 IBM Corp.
6286b419 5 * Copyright (c) 2009 Alexander Graf <[email protected]>
a5c95808
CH
6 * Author(s): Cornelia Huck <[email protected]>
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
9615495a 13#include "qemu/osdep.h"
da34e65c 14#include "qapi/error.h"
4771d756
PB
15#include "qemu-common.h"
16#include "cpu.h"
a5c95808
CH
17#include "hw/boards.h"
18#include "exec/address-spaces.h"
7d577546 19#include "hw/s390x/s390-virtio-hcall.h"
83c9f4ca 20#include "hw/s390x/sclp.h"
3a553fc6 21#include "hw/s390x/s390_flic.h"
bd3f16ac
PB
22#include "hw/s390x/ioinst.h"
23#include "hw/s390x/css.h"
a5c95808 24#include "virtio-ccw.h"
b6fe0124 25#include "qemu/config-file.h"
b5684cd8 26#include "qemu/error-report.h"
8cba80c3 27#include "s390-pci-bus.h"
0f5f6691 28#include "hw/s390x/storage-keys.h"
903fd80b 29#include "hw/s390x/storage-attributes.h"
54d8ec84 30#include "hw/compat.h"
04ca4b92 31#include "ipl.h"
8b8a61ad 32#include "hw/s390x/s390-virtio-ccw.h"
dd70bd0d 33#include "hw/s390x/css-bridge.h"
f2a8f0a6 34#include "migration/register.h"
7223bcce 35#include "cpu_models.h"
6286b419
DH
36#include "qapi/qmp/qerror.h"
37#include "hw/nmi.h"
38
6286b419
DH
39S390CPU *s390_cpu_addr2state(uint16_t cpu_addr)
40{
2b44178d
DH
41 static MachineState *ms;
42
43 if (!ms) {
44 ms = MACHINE(qdev_get_machine());
45 g_assert(ms->possible_cpus);
6286b419
DH
46 }
47
2b44178d
DH
48 /* CPU address corresponds to the core_id and the index */
49 if (cpu_addr >= ms->possible_cpus->len) {
50 return NULL;
51 }
52 return S390_CPU(ms->possible_cpus->cpus[cpu_addr].cpu);
6286b419
DH
53}
54
55static void s390_init_cpus(MachineState *machine)
56{
4dc3b151 57 MachineClass *mc = MACHINE_GET_CLASS(machine);
524d18d8
DH
58 const char *typename;
59 gchar **model_pieces;
60 ObjectClass *oc;
61 CPUClass *cc;
6286b419 62 int i;
6286b419
DH
63
64 if (machine->cpu_model == NULL) {
65 machine->cpu_model = s390_default_cpu_model_name();
66 }
b5684cd8
DH
67 if (tcg_enabled() && max_cpus > 1) {
68 error_report("Number of SMP CPUs requested (%d) exceeds max CPUs "
69 "supported by TCG (1) on s390x", max_cpus);
70 exit(1);
71 }
6286b419 72
4dc3b151
DH
73 /* initialize possible_cpus */
74 mc->possible_cpu_arch_ids(machine);
75
524d18d8
DH
76 model_pieces = g_strsplit(machine->cpu_model, ",", 2);
77 if (!model_pieces[0]) {
78 error_report("Invalid/empty CPU model name");
79 exit(1);
80 }
81
82 oc = cpu_class_by_name(TYPE_S390_CPU, model_pieces[0]);
83 if (!oc) {
84 error_report("Unable to find CPU definition: %s", model_pieces[0]);
85 exit(1);
86 }
87 typename = object_class_get_name(oc);
88 cc = CPU_CLASS(oc);
89 /* after parsing, properties will be applied to all *typename* instances */
90 cc->parse_features(typename, model_pieces[1], &error_fatal);
91 g_strfreev(model_pieces);
92
6286b419 93 for (i = 0; i < smp_cpus; i++) {
524d18d8 94 s390x_new_cpu(typename, i, &error_fatal);
6286b419
DH
95 }
96}
2eb1cd07 97
09c7f58c 98static const char *const reset_dev_types[] = {
3f9e4859 99 TYPE_VIRTUAL_CSS_BRIDGE,
09c7f58c
DH
100 "s390-sclp-event-facility",
101 "s390-flic",
102 "diag288",
103};
104
d9f090ec 105void subsystem_reset(void)
4e872a3f 106{
09c7f58c
DH
107 DeviceState *dev;
108 int i;
4e872a3f 109
09c7f58c
DH
110 for (i = 0; i < ARRAY_SIZE(reset_dev_types); i++) {
111 dev = DEVICE(object_resolve_path_type("", reset_dev_types[i], NULL));
112 if (dev) {
113 qdev_reset_all(dev);
114 }
0c7322cf 115 }
4e872a3f
CB
116}
117
a5c95808
CH
118static int virtio_ccw_hcall_notify(const uint64_t *args)
119{
120 uint64_t subch_id = args[0];
121 uint64_t queue = args[1];
122 SubchDev *sch;
123 int cssid, ssid, schid, m;
124
125 if (ioinst_disassemble_sch_ident(subch_id, &m, &cssid, &ssid, &schid)) {
126 return -EINVAL;
127 }
128 sch = css_find_subch(m, cssid, ssid, schid);
129 if (!sch || !css_subch_visible(sch)) {
130 return -EINVAL;
131 }
b1914b82 132 if (queue >= VIRTIO_QUEUE_MAX) {
b57ed9bf
CH
133 return -EINVAL;
134 }
a5c95808
CH
135 virtio_queue_notify(virtio_ccw_get_vdev(sch), queue);
136 return 0;
137
138}
139
140static int virtio_ccw_hcall_early_printk(const uint64_t *args)
141{
142 uint64_t mem = args[0];
143
144 if (mem < ram_size) {
145 /* Early printk */
146 return 0;
147 }
148 return -EINVAL;
149}
150
151static void virtio_ccw_register_hcalls(void)
152{
153 s390_register_virtio_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY,
154 virtio_ccw_hcall_notify);
155 /* Tolerate early printk. */
156 s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY,
157 virtio_ccw_hcall_early_printk);
158}
159
6286b419 160static void s390_memory_init(ram_addr_t mem_size)
a5c95808 161{
a5c95808
CH
162 MemoryRegion *sysmem = get_system_memory();
163 MemoryRegion *ram = g_new(MemoryRegion, 1);
80d23275
DH
164
165 /* allocate RAM for core */
ae23a335 166 memory_region_allocate_system_memory(ram, NULL, "s390.ram", mem_size);
80d23275
DH
167 memory_region_add_subregion(sysmem, 0, ram);
168
169 /* Initialize storage key device */
170 s390_skeys_init();
903fd80b
CI
171 /* Initialize storage attributes device */
172 s390_stattrib_init();
80d23275
DH
173}
174
6286b419
DH
175#define S390_TOD_CLOCK_VALUE_MISSING 0x00
176#define S390_TOD_CLOCK_VALUE_PRESENT 0x01
177
178static void gtod_save(QEMUFile *f, void *opaque)
179{
180 uint64_t tod_low;
181 uint8_t tod_high;
182 int r;
183
184 r = s390_get_clock(&tod_high, &tod_low);
185 if (r) {
186 warn_report("Unable to get guest clock for migration: %s",
187 strerror(-r));
188 error_printf("Guest clock will not be migrated "
189 "which could cause the guest to hang.");
190 qemu_put_byte(f, S390_TOD_CLOCK_VALUE_MISSING);
191 return;
192 }
193
194 qemu_put_byte(f, S390_TOD_CLOCK_VALUE_PRESENT);
195 qemu_put_byte(f, tod_high);
196 qemu_put_be64(f, tod_low);
197}
198
199static int gtod_load(QEMUFile *f, void *opaque, int version_id)
200{
201 uint64_t tod_low;
202 uint8_t tod_high;
203 int r;
204
205 if (qemu_get_byte(f) == S390_TOD_CLOCK_VALUE_MISSING) {
206 warn_report("Guest clock was not migrated. This could "
207 "cause the guest to hang.");
208 return 0;
209 }
210
211 tod_high = qemu_get_byte(f);
212 tod_low = qemu_get_be64(f);
213
214 r = s390_set_clock(&tod_high, &tod_low);
215 if (r) {
216 warn_report("Unable to set guest clock for migration: %s",
217 strerror(-r));
218 error_printf("Guest clock will not be restored "
219 "which could cause the guest to hang.");
220 }
221
222 return 0;
223}
224
1b6e7482
LV
225static SaveVMHandlers savevm_gtod = {
226 .save_state = gtod_save,
227 .load_state = gtod_load,
228};
229
6286b419
DH
230static void s390_init_ipl_dev(const char *kernel_filename,
231 const char *kernel_cmdline,
232 const char *initrd_filename, const char *firmware,
233 const char *netboot_fw, bool enforce_bios)
234{
235 Object *new = object_new(TYPE_S390_IPL);
236 DeviceState *dev = DEVICE(new);
237
238 if (kernel_filename) {
239 qdev_prop_set_string(dev, "kernel", kernel_filename);
240 }
241 if (initrd_filename) {
242 qdev_prop_set_string(dev, "initrd", initrd_filename);
243 }
244 qdev_prop_set_string(dev, "cmdline", kernel_cmdline);
245 qdev_prop_set_string(dev, "firmware", firmware);
246 qdev_prop_set_string(dev, "netboot_fw", netboot_fw);
247 qdev_prop_set_bit(dev, "enforce_bios", enforce_bios);
248 object_property_add_child(qdev_get_machine(), TYPE_S390_IPL,
249 new, NULL);
250 object_unref(new);
251 qdev_init_nofail(dev);
252}
253
254static void s390_create_virtio_net(BusState *bus, const char *name)
255{
256 int i;
257
258 for (i = 0; i < nb_nics; i++) {
259 NICInfo *nd = &nd_table[i];
260 DeviceState *dev;
261
262 if (!nd->model) {
263 nd->model = g_strdup("virtio");
264 }
265
266 qemu_check_nic_model(nd, "virtio");
267
268 dev = qdev_create(bus, name);
269 qdev_set_nic_properties(dev, nd);
270 qdev_init_nofail(dev);
271 }
272}
273
80d23275
DH
274static void ccw_init(MachineState *machine)
275{
a5c95808
CH
276 int ret;
277 VirtualCssBus *css_bus;
b6fe0124 278
1cf065fb 279 s390_sclp_init();
80d23275 280 s390_memory_init(machine->ram_size);
a5c95808 281
d32bd032 282 /* init CPUs (incl. CPU model) early so s390_has_feature() works */
3720d335
YMZ
283 s390_init_cpus(machine);
284
c572d3f3
FL
285 s390_flic_init();
286
a5c95808
CH
287 /* get a BUS */
288 css_bus = virtual_css_bus_init();
3ef96221 289 s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline,
5f31ade0
FA
290 machine->initrd_filename, "s390-ccw.img",
291 "s390-netboot.img", true);
a5c95808 292
d32bd032
CH
293 if (s390_has_feat(S390_FEAT_ZPCI)) {
294 DeviceState *dev = qdev_create(NULL, TYPE_S390_PCI_HOST_BRIDGE);
295 object_property_add_child(qdev_get_machine(),
296 TYPE_S390_PCI_HOST_BRIDGE,
297 OBJECT(dev), NULL);
298 qdev_init_nofail(dev);
299 }
8cba80c3 300
a5c95808
CH
301 /* register hypercalls */
302 virtio_ccw_register_hcalls();
303
5e7164c5 304 s390_enable_css_support(s390_cpu_addr2state(0));
a5c95808 305 /*
817d4a6b
DJS
306 * Non mcss-e enabled guests only see the devices from the default
307 * css, which is determined by the value of the squash_mcss property.
308 * Note: we must not squash non virtual devices to css 0xFE.
a5c95808 309 */
817d4a6b
DJS
310 if (css_bus->squash_mcss) {
311 ret = css_create_css_image(0, true);
312 } else {
313 ret = css_create_css_image(VIRTUAL_CSSID, true);
314 }
a5c95808
CH
315 assert(ret == 0);
316
317 /* Create VirtIO network adapters */
318 s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw");
3f9e59bb
JH
319
320 /* Register savevm handler for guest TOD clock */
fe7cb8ea 321 register_savevm_live(NULL, "todclock", 0, 1, &savevm_gtod, NULL);
a5c95808
CH
322}
323
502edbf8
MR
324static void s390_cpu_plug(HotplugHandler *hotplug_dev,
325 DeviceState *dev, Error **errp)
326{
4dc3b151 327 MachineState *ms = MACHINE(hotplug_dev);
502edbf8 328 S390CPU *cpu = S390_CPU(dev);
4dc3b151
DH
329
330 g_assert(!ms->possible_cpus->cpus[cpu->env.core_id].cpu);
331 ms->possible_cpus->cpus[cpu->env.core_id].cpu = OBJECT(dev);
502edbf8
MR
332}
333
6286b419
DH
334static void s390_machine_reset(void)
335{
336 S390CPU *ipl_cpu = S390_CPU(qemu_get_cpu(0));
337
338 s390_cmma_reset();
339 qemu_devices_reset();
340 s390_crypto_reset();
341
342 /* all cpus are stopped - configure and start the ipl cpu only */
343 s390_ipl_prepare_cpu(ipl_cpu);
344 s390_cpu_set_state(CPU_STATE_OPERATING, ipl_cpu);
345}
346
502edbf8
MR
347static void s390_machine_device_plug(HotplugHandler *hotplug_dev,
348 DeviceState *dev, Error **errp)
349{
350 if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
351 s390_cpu_plug(hotplug_dev, dev, errp);
352 }
353}
354
f2f3beb0
DH
355static void s390_machine_device_unplug_request(HotplugHandler *hotplug_dev,
356 DeviceState *dev, Error **errp)
357{
358 if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
359 error_setg(errp, "CPU hot unplug not supported on this machine");
360 return;
361 }
362}
363
4dc3b151
DH
364static CpuInstanceProperties s390_cpu_index_to_props(MachineState *machine,
365 unsigned cpu_index)
366{
367 g_assert(machine->possible_cpus && cpu_index < machine->possible_cpus->len);
368
369 return machine->possible_cpus->cpus[cpu_index].props;
370}
371
372static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms)
373{
374 int i;
375
376 if (ms->possible_cpus) {
377 g_assert(ms->possible_cpus && ms->possible_cpus->len == max_cpus);
378 return ms->possible_cpus;
379 }
380
381 ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
382 sizeof(CPUArchId) * max_cpus);
383 ms->possible_cpus->len = max_cpus;
384 for (i = 0; i < ms->possible_cpus->len; i++) {
385 ms->possible_cpus->cpus[i].vcpus_count = 1;
386 ms->possible_cpus->cpus[i].arch_id = i;
387 ms->possible_cpus->cpus[i].props.has_core_id = true;
388 ms->possible_cpus->cpus[i].props.core_id = i;
389 }
390
391 return ms->possible_cpus;
392}
393
502edbf8
MR
394static HotplugHandler *s390_get_hotplug_handler(MachineState *machine,
395 DeviceState *dev)
396{
397 if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
398 return HOTPLUG_HANDLER(machine);
399 }
400 return NULL;
401}
402
a006b67f
MR
403static void s390_hot_add_cpu(const int64_t id, Error **errp)
404{
405 MachineState *machine = MACHINE(qdev_get_machine());
524d18d8
DH
406 ObjectClass *oc;
407
408 g_assert(machine->possible_cpus->cpus[0].cpu);
409 oc = OBJECT_CLASS(CPU_GET_CLASS(machine->possible_cpus->cpus[0].cpu));
a006b67f 410
524d18d8 411 s390x_new_cpu(object_class_get_name(oc), id, errp);
a006b67f
MR
412}
413
6286b419
DH
414static void s390_nmi(NMIState *n, int cpu_index, Error **errp)
415{
416 CPUState *cs = qemu_get_cpu(cpu_index);
417
418 if (s390_cpu_restart(S390_CPU(cs))) {
419 error_setg(errp, QERR_UNSUPPORTED);
420 }
421}
422
d07aa7c7
AK
423static void ccw_machine_class_init(ObjectClass *oc, void *data)
424{
425 MachineClass *mc = MACHINE_CLASS(oc);
3dd7852f 426 NMIClass *nc = NMI_CLASS(oc);
502edbf8 427 HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
9700230b 428 S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
d07aa7c7 429
9700230b 430 s390mc->ri_allowed = true;
e73316d5 431 s390mc->cpu_model_allowed = true;
e996583e 432 s390mc->css_migration_enabled = true;
62deb62d 433 s390mc->gs_allowed = true;
d07aa7c7 434 mc->init = ccw_init;
db3b2566 435 mc->reset = s390_machine_reset;
a006b67f 436 mc->hot_add_cpu = s390_hot_add_cpu;
d07aa7c7
AK
437 mc->block_default_type = IF_VIRTIO;
438 mc->no_cdrom = 1;
439 mc->no_floppy = 1;
440 mc->no_serial = 1;
441 mc->no_parallel = 1;
442 mc->no_sdcard = 1;
fb85b34d 443 mc->use_sclp = 1;
dcddc75e 444 mc->max_cpus = 248;
4dc3b151 445 mc->has_hotpluggable_cpus = true;
502edbf8 446 mc->get_hotplug_handler = s390_get_hotplug_handler;
4dc3b151
DH
447 mc->cpu_index_to_instance_props = s390_cpu_index_to_props;
448 mc->possible_cpu_arch_ids = s390_possible_cpu_arch_ids;
502edbf8 449 hc->plug = s390_machine_device_plug;
f2f3beb0 450 hc->unplug_request = s390_machine_device_unplug_request;
3dd7852f 451 nc->nmi_monitor_handler = s390_nmi;
d07aa7c7
AK
452}
453
2eb1cd07
TK
454static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
455{
456 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
457
458 return ms->aes_key_wrap;
459}
460
461static inline void machine_set_aes_key_wrap(Object *obj, bool value,
462 Error **errp)
463{
464 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
465
466 ms->aes_key_wrap = value;
467}
468
469static inline bool machine_get_dea_key_wrap(Object *obj, Error **errp)
470{
471 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
472
473 return ms->dea_key_wrap;
474}
475
476static inline void machine_set_dea_key_wrap(Object *obj, bool value,
477 Error **errp)
478{
479 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
480
481 ms->dea_key_wrap = value;
482}
483
cec8bbf7 484static S390CcwMachineClass *current_mc;
9700230b 485
cec8bbf7
HP
486static S390CcwMachineClass *get_machine_class(void)
487{
488 if (unlikely(!current_mc)) {
392529cb 489 /*
cec8bbf7
HP
490 * No s390 ccw machine was instantiated, we are likely to
491 * be called for the 'none' machine. The properties will
492 * have their after-initialization values.
493 */
494 current_mc = S390_MACHINE_CLASS(
495 object_class_by_name(TYPE_S390_CCW_MACHINE));
9700230b 496 }
cec8bbf7 497 return current_mc;
9700230b
FZ
498}
499
cec8bbf7 500bool ri_allowed(void)
e73316d5 501{
cec8bbf7
HP
502 /* for "none" machine this results in true */
503 return get_machine_class()->ri_allowed;
504}
505
506bool cpu_model_allowed(void)
507{
508 /* for "none" machine this results in true */
509 return get_machine_class()->cpu_model_allowed;
e73316d5
CB
510}
511
62deb62d
FZ
512bool gs_allowed(void)
513{
c50f6511
DH
514 /* for "none" machine this results in true */
515 return get_machine_class()->gs_allowed;
62deb62d
FZ
516}
517
7104bae9
FA
518static char *machine_get_loadparm(Object *obj, Error **errp)
519{
520 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
521
522 return g_memdup(ms->loadparm, sizeof(ms->loadparm));
523}
524
525static void machine_set_loadparm(Object *obj, const char *val, Error **errp)
526{
527 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
528 int i;
529
530 for (i = 0; i < sizeof(ms->loadparm) && val[i]; i++) {
95a5befc 531 uint8_t c = qemu_toupper(val[i]); /* mimic HMC */
7104bae9
FA
532
533 if (('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || (c == '.') ||
534 (c == ' ')) {
535 ms->loadparm[i] = c;
536 } else {
537 error_setg(errp, "LOADPARM: invalid character '%c' (ASCII 0x%02x)",
538 c, c);
539 return;
540 }
541 }
542
543 for (; i < sizeof(ms->loadparm); i++) {
544 ms->loadparm[i] = ' '; /* pad right with spaces */
545 }
546}
274250c3
XFR
547static inline bool machine_get_squash_mcss(Object *obj, Error **errp)
548{
549 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
550
551 return ms->s390_squash_mcss;
552}
553
554static inline void machine_set_squash_mcss(Object *obj, bool value,
555 Error **errp)
556{
557 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
558
559 ms->s390_squash_mcss = value;
560}
7104bae9 561
2eb1cd07
TK
562static inline void s390_machine_initfn(Object *obj)
563{
564 object_property_add_bool(obj, "aes-key-wrap",
565 machine_get_aes_key_wrap,
566 machine_set_aes_key_wrap, NULL);
567 object_property_set_description(obj, "aes-key-wrap",
568 "enable/disable AES key wrapping using the CPACF wrapping key",
569 NULL);
570 object_property_set_bool(obj, true, "aes-key-wrap", NULL);
571
572 object_property_add_bool(obj, "dea-key-wrap",
573 machine_get_dea_key_wrap,
574 machine_set_dea_key_wrap, NULL);
575 object_property_set_description(obj, "dea-key-wrap",
576 "enable/disable DEA key wrapping using the CPACF wrapping key",
577 NULL);
578 object_property_set_bool(obj, true, "dea-key-wrap", NULL);
7104bae9
FA
579 object_property_add_str(obj, "loadparm",
580 machine_get_loadparm, machine_set_loadparm, NULL);
581 object_property_set_description(obj, "loadparm",
582 "Up to 8 chars in set of [A-Za-z0-9. ] (lower case chars converted"
583 " to upper case) to pass to machine loader, boot manager,"
584 " and guest kernel",
585 NULL);
274250c3
XFR
586 object_property_add_bool(obj, "s390-squash-mcss",
587 machine_get_squash_mcss,
588 machine_set_squash_mcss, NULL);
589 object_property_set_description(obj, "s390-squash-mcss",
590 "enable/disable squashing subchannels into the default css",
591 NULL);
592 object_property_set_bool(obj, false, "s390-squash-mcss", NULL);
2eb1cd07
TK
593}
594
d07aa7c7
AK
595static const TypeInfo ccw_machine_info = {
596 .name = TYPE_S390_CCW_MACHINE,
597 .parent = TYPE_MACHINE,
c4d3c0a2 598 .abstract = true,
2eb1cd07
TK
599 .instance_size = sizeof(S390CcwMachineState),
600 .instance_init = s390_machine_initfn,
9700230b 601 .class_size = sizeof(S390CcwMachineClass),
d07aa7c7 602 .class_init = ccw_machine_class_init,
3dd7852f
AK
603 .interfaces = (InterfaceInfo[]) {
604 { TYPE_NMI },
502edbf8 605 { TYPE_HOTPLUG_HANDLER},
3dd7852f
AK
606 { }
607 },
a5c95808
CH
608};
609
52629b3b
HP
610bool css_migration_enabled(void)
611{
612 return get_machine_class()->css_migration_enabled;
613}
614
4fca6548
JF
615#define DEFINE_CCW_MACHINE(suffix, verstr, latest) \
616 static void ccw_machine_##suffix##_class_init(ObjectClass *oc, \
617 void *data) \
618 { \
619 MachineClass *mc = MACHINE_CLASS(oc); \
620 ccw_machine_##suffix##_class_options(mc); \
621 mc->desc = "VirtIO-ccw based S390 machine v" verstr; \
622 if (latest) { \
623 mc->alias = "s390-ccw-virtio"; \
624 mc->is_default = 1; \
625 } \
626 } \
627 static void ccw_machine_##suffix##_instance_init(Object *obj) \
628 { \
629 MachineState *machine = MACHINE(obj); \
cec8bbf7 630 current_mc = S390_MACHINE_CLASS(MACHINE_GET_CLASS(machine)); \
4fca6548
JF
631 ccw_machine_##suffix##_instance_options(machine); \
632 } \
633 static const TypeInfo ccw_machine_##suffix##_info = { \
634 .name = MACHINE_TYPE_NAME("s390-ccw-virtio-" verstr), \
635 .parent = TYPE_S390_CCW_MACHINE, \
636 .class_init = ccw_machine_##suffix##_class_init, \
637 .instance_init = ccw_machine_##suffix##_instance_init, \
638 }; \
639 static void ccw_machine_register_##suffix(void) \
640 { \
641 type_register_static(&ccw_machine_##suffix##_info); \
642 } \
0e6aac87 643 type_init(ccw_machine_register_##suffix)
4fca6548 644
70d8d9a0
CH
645#define CCW_COMPAT_2_10 \
646 HW_COMPAT_2_10
647
10890873 648#define CCW_COMPAT_2_9 \
903fd80b
CI
649 HW_COMPAT_2_9 \
650 {\
651 .driver = TYPE_S390_STATTRIB,\
652 .property = "migration-enabled",\
653 .value = "off",\
654 },
10890873 655
113725a6 656#define CCW_COMPAT_2_8 \
069097da
HP
657 HW_COMPAT_2_8 \
658 {\
659 .driver = TYPE_S390_FLIC_COMMON,\
660 .property = "adapter_routes_max_batch",\
661 .value = "64",\
662 },
113725a6 663
61823988
CH
664#define CCW_COMPAT_2_7 \
665 HW_COMPAT_2_7
666
946e55f3 667#define CCW_COMPAT_2_6 \
04ca4b92
AY
668 HW_COMPAT_2_6 \
669 {\
670 .driver = TYPE_S390_IPL,\
671 .property = "iplbext_migration",\
672 .value = "off",\
2a79eb1a
CH
673 }, {\
674 .driver = TYPE_VIRTUAL_CSS_BRIDGE,\
675 .property = "css_dev_path",\
676 .value = "off",\
04ca4b92 677 },
946e55f3 678
cf87e0a3
SL
679#define CCW_COMPAT_2_5 \
680 HW_COMPAT_2_5
681
9ef40173 682#define CCW_COMPAT_2_4 \
54d8ec84 683 HW_COMPAT_2_4 \
9ef40173
JH
684 {\
685 .driver = TYPE_S390_SKEYS,\
686 .property = "migration-enabled",\
687 .value = "off",\
542571d5
CH
688 },{\
689 .driver = "virtio-blk-ccw",\
690 .property = "max_revision",\
691 .value = "0",\
692 },{\
693 .driver = "virtio-balloon-ccw",\
694 .property = "max_revision",\
695 .value = "0",\
696 },{\
697 .driver = "virtio-serial-ccw",\
698 .property = "max_revision",\
699 .value = "0",\
700 },{\
701 .driver = "virtio-9p-ccw",\
702 .property = "max_revision",\
703 .value = "0",\
704 },{\
705 .driver = "virtio-rng-ccw",\
706 .property = "max_revision",\
707 .value = "0",\
085b0b05
CH
708 },{\
709 .driver = "virtio-net-ccw",\
710 .property = "max_revision",\
711 .value = "0",\
712 },{\
713 .driver = "virtio-scsi-ccw",\
714 .property = "max_revision",\
715 .value = "0",\
716 },{\
717 .driver = "vhost-scsi-ccw",\
718 .property = "max_revision",\
719 .value = "0",\
9ef40173
JH
720 },
721
70d8d9a0
CH
722static void ccw_machine_2_11_instance_options(MachineState *machine)
723{
724}
725
726static void ccw_machine_2_11_class_options(MachineClass *mc)
727{
728}
729DEFINE_CCW_MACHINE(2_11, "2.11", true);
730
10890873
CH
731static void ccw_machine_2_10_instance_options(MachineState *machine)
732{
70d8d9a0 733 ccw_machine_2_11_instance_options(machine);
e996583e
HP
734 if (css_migration_enabled()) {
735 css_register_vmstate();
736 }
10890873
CH
737}
738
739static void ccw_machine_2_10_class_options(MachineClass *mc)
740{
70d8d9a0
CH
741 ccw_machine_2_11_class_options(mc);
742 SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_10);
10890873 743}
70d8d9a0 744DEFINE_CCW_MACHINE(2_10, "2.10", false);
10890873 745
113725a6
CH
746static void ccw_machine_2_9_instance_options(MachineState *machine)
747{
10890873 748 ccw_machine_2_10_instance_options(machine);
7223bcce
JH
749 s390_cpudef_featoff_greater(12, 1, S390_FEAT_ESOP);
750 s390_cpudef_featoff_greater(12, 1, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2);
3b00f702
YMZ
751 s390_cpudef_featoff_greater(12, 1, S390_FEAT_ZPCI);
752 s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_INT_SUPPRESSION);
753 s390_cpudef_featoff_greater(12, 1, S390_FEAT_ADAPTER_EVENT_NOTIFICATION);
113725a6
CH
754}
755
756static void ccw_machine_2_9_class_options(MachineClass *mc)
757{
52629b3b
HP
758 S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
759
62deb62d 760 s390mc->gs_allowed = false;
10890873
CH
761 ccw_machine_2_10_class_options(mc);
762 SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_9);
52629b3b 763 s390mc->css_migration_enabled = false;
113725a6 764}
10890873 765DEFINE_CCW_MACHINE(2_9, "2.9", false);
113725a6 766
61823988
CH
767static void ccw_machine_2_8_instance_options(MachineState *machine)
768{
113725a6 769 ccw_machine_2_9_instance_options(machine);
61823988
CH
770}
771
772static void ccw_machine_2_8_class_options(MachineClass *mc)
773{
113725a6
CH
774 ccw_machine_2_9_class_options(mc);
775 SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_8);
61823988 776}
113725a6 777DEFINE_CCW_MACHINE(2_8, "2.8", false);
61823988 778
946e55f3
CH
779static void ccw_machine_2_7_instance_options(MachineState *machine)
780{
61823988 781 ccw_machine_2_8_instance_options(machine);
946e55f3
CH
782}
783
784static void ccw_machine_2_7_class_options(MachineClass *mc)
785{
e73316d5
CB
786 S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
787
788 s390mc->cpu_model_allowed = false;
61823988
CH
789 ccw_machine_2_8_class_options(mc);
790 SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_7);
946e55f3 791}
61823988 792DEFINE_CCW_MACHINE(2_7, "2.7", false);
946e55f3 793
4fca6548 794static void ccw_machine_2_6_instance_options(MachineState *machine)
c4d3c0a2 795{
946e55f3 796 ccw_machine_2_7_instance_options(machine);
c4d3c0a2
CB
797}
798
4fca6548 799static void ccw_machine_2_6_class_options(MachineClass *mc)
84b48ad6 800{
9700230b
FZ
801 S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc);
802
803 s390mc->ri_allowed = false;
946e55f3
CH
804 ccw_machine_2_7_class_options(mc);
805 SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_6);
84b48ad6 806}
946e55f3 807DEFINE_CCW_MACHINE(2_6, "2.6", false);
84b48ad6 808
4fca6548
JF
809static void ccw_machine_2_5_instance_options(MachineState *machine)
810{
946e55f3 811 ccw_machine_2_6_instance_options(machine);
4fca6548 812}
84b48ad6 813
4fca6548 814static void ccw_machine_2_5_class_options(MachineClass *mc)
b21b7598 815{
946e55f3 816 ccw_machine_2_6_class_options(mc);
4fca6548
JF
817 SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_5);
818}
819DEFINE_CCW_MACHINE(2_5, "2.5", false);
b21b7598 820
4fca6548
JF
821static void ccw_machine_2_4_instance_options(MachineState *machine)
822{
823 ccw_machine_2_5_instance_options(machine);
b21b7598
CH
824}
825
4fca6548
JF
826static void ccw_machine_2_4_class_options(MachineClass *mc)
827{
946e55f3 828 ccw_machine_2_5_class_options(mc);
4fca6548
JF
829 SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_4);
830}
831DEFINE_CCW_MACHINE(2_4, "2.4", false);
b21b7598 832
d07aa7c7 833static void ccw_machine_register_types(void)
a5c95808 834{
d07aa7c7 835 type_register_static(&ccw_machine_info);
a5c95808
CH
836}
837
d07aa7c7 838type_init(ccw_machine_register_types)
This page took 0.356474 seconds and 4 git commands to generate.