ivshmem: Require master to have ID zero
[qemu/ar7.git] / hw / s390x / s390-virtio-ccw.c
blob4361c8a5dc691ec529ca69aaeb88eaa5cd5ca76b
1 /*
2 * virtio ccw machine
4 * Copyright 2012 IBM Corp.
5 * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com>
7 * This work is licensed under the terms of the GNU GPL, version 2 or (at
8 * your option) any later version. See the COPYING file in the top-level
9 * directory.
12 #include "qemu/osdep.h"
13 #include "hw/boards.h"
14 #include "exec/address-spaces.h"
15 #include "s390-virtio.h"
16 #include "hw/s390x/sclp.h"
17 #include "hw/s390x/s390_flic.h"
18 #include "ioinst.h"
19 #include "css.h"
20 #include "virtio-ccw.h"
21 #include "qemu/config-file.h"
22 #include "s390-pci-bus.h"
23 #include "hw/s390x/storage-keys.h"
24 #include "hw/compat.h"
25 #include "hw/s390x/s390-virtio-ccw.h"
27 static const char *const reset_dev_types[] = {
28 "virtual-css-bridge",
29 "s390-sclp-event-facility",
30 "s390-flic",
31 "diag288",
34 void subsystem_reset(void)
36 DeviceState *dev;
37 int i;
39 for (i = 0; i < ARRAY_SIZE(reset_dev_types); i++) {
40 dev = DEVICE(object_resolve_path_type("", reset_dev_types[i], NULL));
41 if (dev) {
42 qdev_reset_all(dev);
47 static int virtio_ccw_hcall_notify(const uint64_t *args)
49 uint64_t subch_id = args[0];
50 uint64_t queue = args[1];
51 SubchDev *sch;
52 int cssid, ssid, schid, m;
54 if (ioinst_disassemble_sch_ident(subch_id, &m, &cssid, &ssid, &schid)) {
55 return -EINVAL;
57 sch = css_find_subch(m, cssid, ssid, schid);
58 if (!sch || !css_subch_visible(sch)) {
59 return -EINVAL;
61 if (queue >= VIRTIO_CCW_QUEUE_MAX) {
62 return -EINVAL;
64 virtio_queue_notify(virtio_ccw_get_vdev(sch), queue);
65 return 0;
69 static int virtio_ccw_hcall_early_printk(const uint64_t *args)
71 uint64_t mem = args[0];
73 if (mem < ram_size) {
74 /* Early printk */
75 return 0;
77 return -EINVAL;
80 static void virtio_ccw_register_hcalls(void)
82 s390_register_virtio_hypercall(KVM_S390_VIRTIO_CCW_NOTIFY,
83 virtio_ccw_hcall_notify);
84 /* Tolerate early printk. */
85 s390_register_virtio_hypercall(KVM_S390_VIRTIO_NOTIFY,
86 virtio_ccw_hcall_early_printk);
89 void s390_memory_init(ram_addr_t mem_size)
91 MemoryRegion *sysmem = get_system_memory();
92 MemoryRegion *ram = g_new(MemoryRegion, 1);
94 /* allocate RAM for core */
95 memory_region_allocate_system_memory(ram, NULL, "s390.ram", mem_size);
96 memory_region_add_subregion(sysmem, 0, ram);
98 /* Initialize storage key device */
99 s390_skeys_init();
102 static void ccw_init(MachineState *machine)
104 int ret;
105 VirtualCssBus *css_bus;
106 DeviceState *dev;
108 s390_sclp_init();
109 s390_memory_init(machine->ram_size);
111 /* get a BUS */
112 css_bus = virtual_css_bus_init();
113 s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline,
114 machine->initrd_filename, "s390-ccw.img", true);
115 s390_flic_init();
117 dev = qdev_create(NULL, TYPE_S390_PCI_HOST_BRIDGE);
118 object_property_add_child(qdev_get_machine(), TYPE_S390_PCI_HOST_BRIDGE,
119 OBJECT(dev), NULL);
120 qdev_init_nofail(dev);
122 /* register hypercalls */
123 virtio_ccw_register_hcalls();
125 /* init CPUs */
126 s390_init_cpus(machine);
128 if (kvm_enabled()) {
129 kvm_s390_enable_css_support(s390_cpu_addr2state(0));
132 * Create virtual css and set it as default so that non mcss-e
133 * enabled guests only see virtio devices.
135 ret = css_create_css_image(VIRTUAL_CSSID, true);
136 assert(ret == 0);
138 /* Create VirtIO network adapters */
139 s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw");
141 /* Register savevm handler for guest TOD clock */
142 register_savevm(NULL, "todclock", 0, 1,
143 gtod_save, gtod_load, kvm_state);
146 static void s390_cpu_plug(HotplugHandler *hotplug_dev,
147 DeviceState *dev, Error **errp)
149 gchar *name;
150 S390CPU *cpu = S390_CPU(dev);
151 CPUState *cs = CPU(dev);
153 name = g_strdup_printf("cpu[%i]", cpu->env.cpu_num);
154 object_property_set_link(OBJECT(hotplug_dev), OBJECT(cs), name,
155 errp);
156 g_free(name);
159 static void s390_machine_device_plug(HotplugHandler *hotplug_dev,
160 DeviceState *dev, Error **errp)
162 if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
163 s390_cpu_plug(hotplug_dev, dev, errp);
167 static HotplugHandler *s390_get_hotplug_handler(MachineState *machine,
168 DeviceState *dev)
170 if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
171 return HOTPLUG_HANDLER(machine);
173 return NULL;
176 static void s390_hot_add_cpu(const int64_t id, Error **errp)
178 MachineState *machine = MACHINE(qdev_get_machine());
179 Error *err = NULL;
181 s390x_new_cpu(machine->cpu_model, id, &err);
182 error_propagate(errp, err);
185 static void ccw_machine_class_init(ObjectClass *oc, void *data)
187 MachineClass *mc = MACHINE_CLASS(oc);
188 NMIClass *nc = NMI_CLASS(oc);
189 HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
191 mc->init = ccw_init;
192 mc->reset = s390_machine_reset;
193 mc->hot_add_cpu = s390_hot_add_cpu;
194 mc->block_default_type = IF_VIRTIO;
195 mc->no_cdrom = 1;
196 mc->no_floppy = 1;
197 mc->no_serial = 1;
198 mc->no_parallel = 1;
199 mc->no_sdcard = 1;
200 mc->use_sclp = 1;
201 mc->max_cpus = 255;
202 mc->get_hotplug_handler = s390_get_hotplug_handler;
203 hc->plug = s390_machine_device_plug;
204 nc->nmi_monitor_handler = s390_nmi;
207 static inline bool machine_get_aes_key_wrap(Object *obj, Error **errp)
209 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
211 return ms->aes_key_wrap;
214 static inline void machine_set_aes_key_wrap(Object *obj, bool value,
215 Error **errp)
217 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
219 ms->aes_key_wrap = value;
222 static inline bool machine_get_dea_key_wrap(Object *obj, Error **errp)
224 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
226 return ms->dea_key_wrap;
229 static inline void machine_set_dea_key_wrap(Object *obj, bool value,
230 Error **errp)
232 S390CcwMachineState *ms = S390_CCW_MACHINE(obj);
234 ms->dea_key_wrap = value;
237 static inline void s390_machine_initfn(Object *obj)
239 object_property_add_bool(obj, "aes-key-wrap",
240 machine_get_aes_key_wrap,
241 machine_set_aes_key_wrap, NULL);
242 object_property_set_description(obj, "aes-key-wrap",
243 "enable/disable AES key wrapping using the CPACF wrapping key",
244 NULL);
245 object_property_set_bool(obj, true, "aes-key-wrap", NULL);
247 object_property_add_bool(obj, "dea-key-wrap",
248 machine_get_dea_key_wrap,
249 machine_set_dea_key_wrap, NULL);
250 object_property_set_description(obj, "dea-key-wrap",
251 "enable/disable DEA key wrapping using the CPACF wrapping key",
252 NULL);
253 object_property_set_bool(obj, true, "dea-key-wrap", NULL);
256 static const TypeInfo ccw_machine_info = {
257 .name = TYPE_S390_CCW_MACHINE,
258 .parent = TYPE_MACHINE,
259 .abstract = true,
260 .instance_size = sizeof(S390CcwMachineState),
261 .instance_init = s390_machine_initfn,
262 .class_init = ccw_machine_class_init,
263 .interfaces = (InterfaceInfo[]) {
264 { TYPE_NMI },
265 { TYPE_HOTPLUG_HANDLER},
270 #define DEFINE_CCW_MACHINE(suffix, verstr, latest) \
271 static void ccw_machine_##suffix##_class_init(ObjectClass *oc, \
272 void *data) \
274 MachineClass *mc = MACHINE_CLASS(oc); \
275 ccw_machine_##suffix##_class_options(mc); \
276 mc->desc = "VirtIO-ccw based S390 machine v" verstr; \
277 if (latest) { \
278 mc->alias = "s390-ccw-virtio"; \
279 mc->is_default = 1; \
282 static void ccw_machine_##suffix##_instance_init(Object *obj) \
284 MachineState *machine = MACHINE(obj); \
285 ccw_machine_##suffix##_instance_options(machine); \
287 static const TypeInfo ccw_machine_##suffix##_info = { \
288 .name = MACHINE_TYPE_NAME("s390-ccw-virtio-" verstr), \
289 .parent = TYPE_S390_CCW_MACHINE, \
290 .class_init = ccw_machine_##suffix##_class_init, \
291 .instance_init = ccw_machine_##suffix##_instance_init, \
292 }; \
293 static void ccw_machine_register_##suffix(void) \
295 type_register_static(&ccw_machine_##suffix##_info); \
297 type_init(ccw_machine_register_##suffix)
299 #define CCW_COMPAT_2_5 \
300 HW_COMPAT_2_5
302 #define CCW_COMPAT_2_4 \
303 CCW_COMPAT_2_5 \
304 HW_COMPAT_2_4 \
306 .driver = TYPE_S390_SKEYS,\
307 .property = "migration-enabled",\
308 .value = "off",\
309 },{\
310 .driver = "virtio-blk-ccw",\
311 .property = "max_revision",\
312 .value = "0",\
313 },{\
314 .driver = "virtio-balloon-ccw",\
315 .property = "max_revision",\
316 .value = "0",\
317 },{\
318 .driver = "virtio-serial-ccw",\
319 .property = "max_revision",\
320 .value = "0",\
321 },{\
322 .driver = "virtio-9p-ccw",\
323 .property = "max_revision",\
324 .value = "0",\
325 },{\
326 .driver = "virtio-rng-ccw",\
327 .property = "max_revision",\
328 .value = "0",\
329 },{\
330 .driver = "virtio-net-ccw",\
331 .property = "max_revision",\
332 .value = "0",\
333 },{\
334 .driver = "virtio-scsi-ccw",\
335 .property = "max_revision",\
336 .value = "0",\
337 },{\
338 .driver = "vhost-scsi-ccw",\
339 .property = "max_revision",\
340 .value = "0",\
343 static void ccw_machine_2_6_instance_options(MachineState *machine)
347 static void ccw_machine_2_6_class_options(MachineClass *mc)
350 DEFINE_CCW_MACHINE(2_6, "2.6", true);
352 static void ccw_machine_2_5_instance_options(MachineState *machine)
356 static void ccw_machine_2_5_class_options(MachineClass *mc)
358 SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_5);
360 DEFINE_CCW_MACHINE(2_5, "2.5", false);
362 static void ccw_machine_2_4_instance_options(MachineState *machine)
364 ccw_machine_2_5_instance_options(machine);
367 static void ccw_machine_2_4_class_options(MachineClass *mc)
369 SET_MACHINE_COMPAT(mc, CCW_COMPAT_2_4);
371 DEFINE_CCW_MACHINE(2_4, "2.4", false);
373 static void ccw_machine_register_types(void)
375 type_register_static(&ccw_machine_info);
378 type_init(ccw_machine_register_types)