4 * Copyright (C) 2014 Red Hat Inc
7 * Marcel Apfelbaum <marcel.a@redhat.com>
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
13 #include "qemu/osdep.h"
14 #include "hw/boards.h"
15 #include "qapi-visit.h"
16 #include "qapi/visitor.h"
17 #include "hw/sysbus.h"
18 #include "sysemu/sysemu.h"
19 #include "qemu/error-report.h"
21 static char *machine_get_accel(Object
*obj
, Error
**errp
)
23 MachineState
*ms
= MACHINE(obj
);
25 return g_strdup(ms
->accel
);
28 static void machine_set_accel(Object
*obj
, const char *value
, Error
**errp
)
30 MachineState
*ms
= MACHINE(obj
);
33 ms
->accel
= g_strdup(value
);
36 static void machine_set_kernel_irqchip(Object
*obj
, Visitor
*v
,
37 const char *name
, void *opaque
,
41 MachineState
*ms
= MACHINE(obj
);
44 visit_type_OnOffSplit(v
, name
, &mode
, &err
);
46 error_propagate(errp
, err
);
51 ms
->kernel_irqchip_allowed
= true;
52 ms
->kernel_irqchip_required
= true;
53 ms
->kernel_irqchip_split
= false;
55 case ON_OFF_SPLIT_OFF
:
56 ms
->kernel_irqchip_allowed
= false;
57 ms
->kernel_irqchip_required
= false;
58 ms
->kernel_irqchip_split
= false;
60 case ON_OFF_SPLIT_SPLIT
:
61 ms
->kernel_irqchip_allowed
= true;
62 ms
->kernel_irqchip_required
= true;
63 ms
->kernel_irqchip_split
= true;
71 static void machine_get_kvm_shadow_mem(Object
*obj
, Visitor
*v
,
72 const char *name
, void *opaque
,
75 MachineState
*ms
= MACHINE(obj
);
76 int64_t value
= ms
->kvm_shadow_mem
;
78 visit_type_int(v
, name
, &value
, errp
);
81 static void machine_set_kvm_shadow_mem(Object
*obj
, Visitor
*v
,
82 const char *name
, void *opaque
,
85 MachineState
*ms
= MACHINE(obj
);
89 visit_type_int(v
, name
, &value
, &error
);
91 error_propagate(errp
, error
);
95 ms
->kvm_shadow_mem
= value
;
98 static char *machine_get_kernel(Object
*obj
, Error
**errp
)
100 MachineState
*ms
= MACHINE(obj
);
102 return g_strdup(ms
->kernel_filename
);
105 static void machine_set_kernel(Object
*obj
, const char *value
, Error
**errp
)
107 MachineState
*ms
= MACHINE(obj
);
109 g_free(ms
->kernel_filename
);
110 ms
->kernel_filename
= g_strdup(value
);
113 static char *machine_get_initrd(Object
*obj
, Error
**errp
)
115 MachineState
*ms
= MACHINE(obj
);
117 return g_strdup(ms
->initrd_filename
);
120 static void machine_set_initrd(Object
*obj
, const char *value
, Error
**errp
)
122 MachineState
*ms
= MACHINE(obj
);
124 g_free(ms
->initrd_filename
);
125 ms
->initrd_filename
= g_strdup(value
);
128 static char *machine_get_append(Object
*obj
, Error
**errp
)
130 MachineState
*ms
= MACHINE(obj
);
132 return g_strdup(ms
->kernel_cmdline
);
135 static void machine_set_append(Object
*obj
, const char *value
, Error
**errp
)
137 MachineState
*ms
= MACHINE(obj
);
139 g_free(ms
->kernel_cmdline
);
140 ms
->kernel_cmdline
= g_strdup(value
);
143 static char *machine_get_dtb(Object
*obj
, Error
**errp
)
145 MachineState
*ms
= MACHINE(obj
);
147 return g_strdup(ms
->dtb
);
150 static void machine_set_dtb(Object
*obj
, const char *value
, Error
**errp
)
152 MachineState
*ms
= MACHINE(obj
);
155 ms
->dtb
= g_strdup(value
);
158 static char *machine_get_dumpdtb(Object
*obj
, Error
**errp
)
160 MachineState
*ms
= MACHINE(obj
);
162 return g_strdup(ms
->dumpdtb
);
165 static void machine_set_dumpdtb(Object
*obj
, const char *value
, Error
**errp
)
167 MachineState
*ms
= MACHINE(obj
);
170 ms
->dumpdtb
= g_strdup(value
);
173 static void machine_get_phandle_start(Object
*obj
, Visitor
*v
,
174 const char *name
, void *opaque
,
177 MachineState
*ms
= MACHINE(obj
);
178 int64_t value
= ms
->phandle_start
;
180 visit_type_int(v
, name
, &value
, errp
);
183 static void machine_set_phandle_start(Object
*obj
, Visitor
*v
,
184 const char *name
, void *opaque
,
187 MachineState
*ms
= MACHINE(obj
);
191 visit_type_int(v
, name
, &value
, &error
);
193 error_propagate(errp
, error
);
197 ms
->phandle_start
= value
;
200 static char *machine_get_dt_compatible(Object
*obj
, Error
**errp
)
202 MachineState
*ms
= MACHINE(obj
);
204 return g_strdup(ms
->dt_compatible
);
207 static void machine_set_dt_compatible(Object
*obj
, const char *value
, Error
**errp
)
209 MachineState
*ms
= MACHINE(obj
);
211 g_free(ms
->dt_compatible
);
212 ms
->dt_compatible
= g_strdup(value
);
215 static bool machine_get_dump_guest_core(Object
*obj
, Error
**errp
)
217 MachineState
*ms
= MACHINE(obj
);
219 return ms
->dump_guest_core
;
222 static void machine_set_dump_guest_core(Object
*obj
, bool value
, Error
**errp
)
224 MachineState
*ms
= MACHINE(obj
);
226 ms
->dump_guest_core
= value
;
229 static bool machine_get_mem_merge(Object
*obj
, Error
**errp
)
231 MachineState
*ms
= MACHINE(obj
);
233 return ms
->mem_merge
;
236 static void machine_set_mem_merge(Object
*obj
, bool value
, Error
**errp
)
238 MachineState
*ms
= MACHINE(obj
);
240 ms
->mem_merge
= value
;
243 static bool machine_get_usb(Object
*obj
, Error
**errp
)
245 MachineState
*ms
= MACHINE(obj
);
250 static void machine_set_usb(Object
*obj
, bool value
, Error
**errp
)
252 MachineState
*ms
= MACHINE(obj
);
255 ms
->usb_disabled
= !value
;
258 static bool machine_get_igd_gfx_passthru(Object
*obj
, Error
**errp
)
260 MachineState
*ms
= MACHINE(obj
);
262 return ms
->igd_gfx_passthru
;
265 static void machine_set_igd_gfx_passthru(Object
*obj
, bool value
, Error
**errp
)
267 MachineState
*ms
= MACHINE(obj
);
269 ms
->igd_gfx_passthru
= value
;
272 static char *machine_get_firmware(Object
*obj
, Error
**errp
)
274 MachineState
*ms
= MACHINE(obj
);
276 return g_strdup(ms
->firmware
);
279 static void machine_set_firmware(Object
*obj
, const char *value
, Error
**errp
)
281 MachineState
*ms
= MACHINE(obj
);
283 g_free(ms
->firmware
);
284 ms
->firmware
= g_strdup(value
);
287 static bool machine_get_iommu(Object
*obj
, Error
**errp
)
289 MachineState
*ms
= MACHINE(obj
);
294 static void machine_set_iommu(Object
*obj
, bool value
, Error
**errp
)
296 MachineState
*ms
= MACHINE(obj
);
301 static void machine_set_suppress_vmdesc(Object
*obj
, bool value
, Error
**errp
)
303 MachineState
*ms
= MACHINE(obj
);
305 ms
->suppress_vmdesc
= value
;
308 static bool machine_get_suppress_vmdesc(Object
*obj
, Error
**errp
)
310 MachineState
*ms
= MACHINE(obj
);
312 return ms
->suppress_vmdesc
;
315 static void machine_set_enforce_config_section(Object
*obj
, bool value
,
318 MachineState
*ms
= MACHINE(obj
);
320 ms
->enforce_config_section
= value
;
323 static bool machine_get_enforce_config_section(Object
*obj
, Error
**errp
)
325 MachineState
*ms
= MACHINE(obj
);
327 return ms
->enforce_config_section
;
330 static int error_on_sysbus_device(SysBusDevice
*sbdev
, void *opaque
)
332 error_report("Option '-device %s' cannot be handled by this machine",
333 object_class_get_name(object_get_class(OBJECT(sbdev
))));
337 static void machine_init_notify(Notifier
*notifier
, void *data
)
339 Object
*machine
= qdev_get_machine();
340 ObjectClass
*oc
= object_get_class(machine
);
341 MachineClass
*mc
= MACHINE_CLASS(oc
);
343 if (mc
->has_dynamic_sysbus
) {
344 /* Our machine can handle dynamic sysbus devices, we're all good */
349 * Loop through all dynamically created devices and check whether there
350 * are sysbus devices among them. If there are, error out.
352 foreach_dynamic_sysbus_device(error_on_sysbus_device
, NULL
);
355 static void machine_class_init(ObjectClass
*oc
, void *data
)
357 MachineClass
*mc
= MACHINE_CLASS(oc
);
359 /* Default 128 MB as guest ram size */
360 mc
->default_ram_size
= 128 * M_BYTE
;
361 mc
->rom_file_has_mr
= true;
364 static void machine_class_base_init(ObjectClass
*oc
, void *data
)
366 if (!object_class_is_abstract(oc
)) {
367 MachineClass
*mc
= MACHINE_CLASS(oc
);
368 const char *cname
= object_class_get_name(oc
);
369 assert(g_str_has_suffix(cname
, TYPE_MACHINE_SUFFIX
));
370 mc
->name
= g_strndup(cname
,
371 strlen(cname
) - strlen(TYPE_MACHINE_SUFFIX
));
375 static void machine_initfn(Object
*obj
)
377 MachineState
*ms
= MACHINE(obj
);
379 ms
->kernel_irqchip_allowed
= true;
380 ms
->kvm_shadow_mem
= -1;
381 ms
->dump_guest_core
= true;
382 ms
->mem_merge
= true;
384 object_property_add_str(obj
, "accel",
385 machine_get_accel
, machine_set_accel
, NULL
);
386 object_property_set_description(obj
, "accel",
389 object_property_add(obj
, "kernel-irqchip", "OnOffSplit",
391 machine_set_kernel_irqchip
,
393 object_property_set_description(obj
, "kernel-irqchip",
394 "Configure KVM in-kernel irqchip",
396 object_property_add(obj
, "kvm-shadow-mem", "int",
397 machine_get_kvm_shadow_mem
,
398 machine_set_kvm_shadow_mem
,
400 object_property_set_description(obj
, "kvm-shadow-mem",
401 "KVM shadow MMU size",
403 object_property_add_str(obj
, "kernel",
404 machine_get_kernel
, machine_set_kernel
, NULL
);
405 object_property_set_description(obj
, "kernel",
406 "Linux kernel image file",
408 object_property_add_str(obj
, "initrd",
409 machine_get_initrd
, machine_set_initrd
, NULL
);
410 object_property_set_description(obj
, "initrd",
411 "Linux initial ramdisk file",
413 object_property_add_str(obj
, "append",
414 machine_get_append
, machine_set_append
, NULL
);
415 object_property_set_description(obj
, "append",
416 "Linux kernel command line",
418 object_property_add_str(obj
, "dtb",
419 machine_get_dtb
, machine_set_dtb
, NULL
);
420 object_property_set_description(obj
, "dtb",
421 "Linux kernel device tree file",
423 object_property_add_str(obj
, "dumpdtb",
424 machine_get_dumpdtb
, machine_set_dumpdtb
, NULL
);
425 object_property_set_description(obj
, "dumpdtb",
426 "Dump current dtb to a file and quit",
428 object_property_add(obj
, "phandle-start", "int",
429 machine_get_phandle_start
,
430 machine_set_phandle_start
,
432 object_property_set_description(obj
, "phandle-start",
433 "The first phandle ID we may generate dynamically",
435 object_property_add_str(obj
, "dt-compatible",
436 machine_get_dt_compatible
,
437 machine_set_dt_compatible
,
439 object_property_set_description(obj
, "dt-compatible",
440 "Overrides the \"compatible\" property of the dt root node",
442 object_property_add_bool(obj
, "dump-guest-core",
443 machine_get_dump_guest_core
,
444 machine_set_dump_guest_core
,
446 object_property_set_description(obj
, "dump-guest-core",
447 "Include guest memory in a core dump",
449 object_property_add_bool(obj
, "mem-merge",
450 machine_get_mem_merge
,
451 machine_set_mem_merge
, NULL
);
452 object_property_set_description(obj
, "mem-merge",
453 "Enable/disable memory merge support",
455 object_property_add_bool(obj
, "usb",
457 machine_set_usb
, NULL
);
458 object_property_set_description(obj
, "usb",
459 "Set on/off to enable/disable usb",
461 object_property_add_bool(obj
, "igd-passthru",
462 machine_get_igd_gfx_passthru
,
463 machine_set_igd_gfx_passthru
, NULL
);
464 object_property_set_description(obj
, "igd-passthru",
465 "Set on/off to enable/disable igd passthrou",
467 object_property_add_str(obj
, "firmware",
468 machine_get_firmware
,
469 machine_set_firmware
, NULL
);
470 object_property_set_description(obj
, "firmware",
473 object_property_add_bool(obj
, "iommu",
475 machine_set_iommu
, NULL
);
476 object_property_set_description(obj
, "iommu",
477 "Set on/off to enable/disable Intel IOMMU (VT-d)",
479 object_property_add_bool(obj
, "suppress-vmdesc",
480 machine_get_suppress_vmdesc
,
481 machine_set_suppress_vmdesc
, NULL
);
482 object_property_set_description(obj
, "suppress-vmdesc",
483 "Set on to disable self-describing migration",
485 object_property_add_bool(obj
, "enforce-config-section",
486 machine_get_enforce_config_section
,
487 machine_set_enforce_config_section
, NULL
);
488 object_property_set_description(obj
, "enforce-config-section",
489 "Set on to enforce configuration section migration",
492 /* Register notifier when init is done for sysbus sanity checks */
493 ms
->sysbus_notifier
.notify
= machine_init_notify
;
494 qemu_add_machine_init_done_notifier(&ms
->sysbus_notifier
);
497 static void machine_finalize(Object
*obj
)
499 MachineState
*ms
= MACHINE(obj
);
502 g_free(ms
->kernel_filename
);
503 g_free(ms
->initrd_filename
);
504 g_free(ms
->kernel_cmdline
);
507 g_free(ms
->dt_compatible
);
508 g_free(ms
->firmware
);
511 bool machine_usb(MachineState
*machine
)
516 bool machine_kernel_irqchip_allowed(MachineState
*machine
)
518 return machine
->kernel_irqchip_allowed
;
521 bool machine_kernel_irqchip_required(MachineState
*machine
)
523 return machine
->kernel_irqchip_required
;
526 bool machine_kernel_irqchip_split(MachineState
*machine
)
528 return machine
->kernel_irqchip_split
;
531 int machine_kvm_shadow_mem(MachineState
*machine
)
533 return machine
->kvm_shadow_mem
;
536 int machine_phandle_start(MachineState
*machine
)
538 return machine
->phandle_start
;
541 bool machine_dump_guest_core(MachineState
*machine
)
543 return machine
->dump_guest_core
;
546 bool machine_mem_merge(MachineState
*machine
)
548 return machine
->mem_merge
;
551 static const TypeInfo machine_info
= {
552 .name
= TYPE_MACHINE
,
553 .parent
= TYPE_OBJECT
,
555 .class_size
= sizeof(MachineClass
),
556 .class_init
= machine_class_init
,
557 .class_base_init
= machine_class_base_init
,
558 .instance_size
= sizeof(MachineState
),
559 .instance_init
= machine_initfn
,
560 .instance_finalize
= machine_finalize
,
563 static void machine_register_types(void)
565 type_register_static(&machine_info
);
568 type_init(machine_register_types
)