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 "hw/boards.h"
14 #include "qapi/visitor.h"
15 #include "hw/sysbus.h"
16 #include "sysemu/sysemu.h"
17 #include "qemu/error-report.h"
19 static char *machine_get_accel(Object
*obj
, Error
**errp
)
21 MachineState
*ms
= MACHINE(obj
);
23 return g_strdup(ms
->accel
);
26 static void machine_set_accel(Object
*obj
, const char *value
, Error
**errp
)
28 MachineState
*ms
= MACHINE(obj
);
31 ms
->accel
= g_strdup(value
);
34 static void machine_set_kernel_irqchip(Object
*obj
, bool value
, Error
**errp
)
36 MachineState
*ms
= MACHINE(obj
);
38 ms
->kernel_irqchip_allowed
= value
;
39 ms
->kernel_irqchip_required
= value
;
42 static void machine_get_kvm_shadow_mem(Object
*obj
, Visitor
*v
,
43 void *opaque
, const char *name
,
46 MachineState
*ms
= MACHINE(obj
);
47 int64_t value
= ms
->kvm_shadow_mem
;
49 visit_type_int(v
, &value
, name
, errp
);
52 static void machine_set_kvm_shadow_mem(Object
*obj
, Visitor
*v
,
53 void *opaque
, const char *name
,
56 MachineState
*ms
= MACHINE(obj
);
60 visit_type_int(v
, &value
, name
, &error
);
62 error_propagate(errp
, error
);
66 ms
->kvm_shadow_mem
= value
;
69 static char *machine_get_kernel(Object
*obj
, Error
**errp
)
71 MachineState
*ms
= MACHINE(obj
);
73 return g_strdup(ms
->kernel_filename
);
76 static void machine_set_kernel(Object
*obj
, const char *value
, Error
**errp
)
78 MachineState
*ms
= MACHINE(obj
);
80 g_free(ms
->kernel_filename
);
81 ms
->kernel_filename
= g_strdup(value
);
84 static char *machine_get_initrd(Object
*obj
, Error
**errp
)
86 MachineState
*ms
= MACHINE(obj
);
88 return g_strdup(ms
->initrd_filename
);
91 static void machine_set_initrd(Object
*obj
, const char *value
, Error
**errp
)
93 MachineState
*ms
= MACHINE(obj
);
95 g_free(ms
->initrd_filename
);
96 ms
->initrd_filename
= g_strdup(value
);
99 static char *machine_get_append(Object
*obj
, Error
**errp
)
101 MachineState
*ms
= MACHINE(obj
);
103 return g_strdup(ms
->kernel_cmdline
);
106 static void machine_set_append(Object
*obj
, const char *value
, Error
**errp
)
108 MachineState
*ms
= MACHINE(obj
);
110 g_free(ms
->kernel_cmdline
);
111 ms
->kernel_cmdline
= g_strdup(value
);
114 static char *machine_get_dtb(Object
*obj
, Error
**errp
)
116 MachineState
*ms
= MACHINE(obj
);
118 return g_strdup(ms
->dtb
);
121 static void machine_set_dtb(Object
*obj
, const char *value
, Error
**errp
)
123 MachineState
*ms
= MACHINE(obj
);
126 ms
->dtb
= g_strdup(value
);
129 static char *machine_get_dumpdtb(Object
*obj
, Error
**errp
)
131 MachineState
*ms
= MACHINE(obj
);
133 return g_strdup(ms
->dumpdtb
);
136 static void machine_set_dumpdtb(Object
*obj
, const char *value
, Error
**errp
)
138 MachineState
*ms
= MACHINE(obj
);
141 ms
->dumpdtb
= g_strdup(value
);
144 static void machine_get_phandle_start(Object
*obj
, Visitor
*v
,
145 void *opaque
, const char *name
,
148 MachineState
*ms
= MACHINE(obj
);
149 int64_t value
= ms
->phandle_start
;
151 visit_type_int(v
, &value
, name
, errp
);
154 static void machine_set_phandle_start(Object
*obj
, Visitor
*v
,
155 void *opaque
, const char *name
,
158 MachineState
*ms
= MACHINE(obj
);
162 visit_type_int(v
, &value
, name
, &error
);
164 error_propagate(errp
, error
);
168 ms
->phandle_start
= value
;
171 static char *machine_get_dt_compatible(Object
*obj
, Error
**errp
)
173 MachineState
*ms
= MACHINE(obj
);
175 return g_strdup(ms
->dt_compatible
);
178 static void machine_set_dt_compatible(Object
*obj
, const char *value
, Error
**errp
)
180 MachineState
*ms
= MACHINE(obj
);
182 g_free(ms
->dt_compatible
);
183 ms
->dt_compatible
= g_strdup(value
);
186 static bool machine_get_dump_guest_core(Object
*obj
, Error
**errp
)
188 MachineState
*ms
= MACHINE(obj
);
190 return ms
->dump_guest_core
;
193 static void machine_set_dump_guest_core(Object
*obj
, bool value
, Error
**errp
)
195 MachineState
*ms
= MACHINE(obj
);
197 ms
->dump_guest_core
= value
;
200 static bool machine_get_mem_merge(Object
*obj
, Error
**errp
)
202 MachineState
*ms
= MACHINE(obj
);
204 return ms
->mem_merge
;
207 static void machine_set_mem_merge(Object
*obj
, bool value
, Error
**errp
)
209 MachineState
*ms
= MACHINE(obj
);
211 ms
->mem_merge
= value
;
214 static bool machine_get_usb(Object
*obj
, Error
**errp
)
216 MachineState
*ms
= MACHINE(obj
);
221 static void machine_set_usb(Object
*obj
, bool value
, Error
**errp
)
223 MachineState
*ms
= MACHINE(obj
);
226 ms
->usb_disabled
= !value
;
229 static bool machine_get_igd_gfx_passthru(Object
*obj
, Error
**errp
)
231 MachineState
*ms
= MACHINE(obj
);
233 return ms
->igd_gfx_passthru
;
236 static void machine_set_igd_gfx_passthru(Object
*obj
, bool value
, Error
**errp
)
238 MachineState
*ms
= MACHINE(obj
);
240 ms
->igd_gfx_passthru
= value
;
243 static char *machine_get_firmware(Object
*obj
, Error
**errp
)
245 MachineState
*ms
= MACHINE(obj
);
247 return g_strdup(ms
->firmware
);
250 static void machine_set_firmware(Object
*obj
, const char *value
, Error
**errp
)
252 MachineState
*ms
= MACHINE(obj
);
254 g_free(ms
->firmware
);
255 ms
->firmware
= g_strdup(value
);
258 static bool machine_get_iommu(Object
*obj
, Error
**errp
)
260 MachineState
*ms
= MACHINE(obj
);
265 static void machine_set_iommu(Object
*obj
, bool value
, Error
**errp
)
267 MachineState
*ms
= MACHINE(obj
);
272 static void machine_set_suppress_vmdesc(Object
*obj
, bool value
, Error
**errp
)
274 MachineState
*ms
= MACHINE(obj
);
276 ms
->suppress_vmdesc
= value
;
279 static bool machine_get_suppress_vmdesc(Object
*obj
, Error
**errp
)
281 MachineState
*ms
= MACHINE(obj
);
283 return ms
->suppress_vmdesc
;
286 static int error_on_sysbus_device(SysBusDevice
*sbdev
, void *opaque
)
288 error_report("Option '-device %s' cannot be handled by this machine",
289 object_class_get_name(object_get_class(OBJECT(sbdev
))));
293 static void machine_init_notify(Notifier
*notifier
, void *data
)
295 Object
*machine
= qdev_get_machine();
296 ObjectClass
*oc
= object_get_class(machine
);
297 MachineClass
*mc
= MACHINE_CLASS(oc
);
299 if (mc
->has_dynamic_sysbus
) {
300 /* Our machine can handle dynamic sysbus devices, we're all good */
305 * Loop through all dynamically created devices and check whether there
306 * are sysbus devices among them. If there are, error out.
308 foreach_dynamic_sysbus_device(error_on_sysbus_device
, NULL
);
311 static void machine_class_init(ObjectClass
*oc
, void *data
)
313 MachineClass
*mc
= MACHINE_CLASS(oc
);
315 /* Default 128 MB as guest ram size */
316 mc
->default_ram_size
= 128 * M_BYTE
;
319 static void machine_class_base_init(ObjectClass
*oc
, void *data
)
321 if (!object_class_is_abstract(oc
)) {
322 MachineClass
*mc
= MACHINE_CLASS(oc
);
323 const char *cname
= object_class_get_name(oc
);
324 assert(g_str_has_suffix(cname
, TYPE_MACHINE_SUFFIX
));
325 mc
->name
= g_strndup(cname
,
326 strlen(cname
) - strlen(TYPE_MACHINE_SUFFIX
));
330 static void machine_initfn(Object
*obj
)
332 MachineState
*ms
= MACHINE(obj
);
334 ms
->kernel_irqchip_allowed
= true;
335 ms
->kvm_shadow_mem
= -1;
336 ms
->dump_guest_core
= true;
337 ms
->mem_merge
= true;
339 object_property_add_str(obj
, "accel",
340 machine_get_accel
, machine_set_accel
, NULL
);
341 object_property_set_description(obj
, "accel",
344 object_property_add_bool(obj
, "kernel-irqchip",
346 machine_set_kernel_irqchip
,
348 object_property_set_description(obj
, "kernel-irqchip",
349 "Use KVM in-kernel irqchip",
351 object_property_add(obj
, "kvm-shadow-mem", "int",
352 machine_get_kvm_shadow_mem
,
353 machine_set_kvm_shadow_mem
,
355 object_property_set_description(obj
, "kvm-shadow-mem",
356 "KVM shadow MMU size",
358 object_property_add_str(obj
, "kernel",
359 machine_get_kernel
, machine_set_kernel
, NULL
);
360 object_property_set_description(obj
, "kernel",
361 "Linux kernel image file",
363 object_property_add_str(obj
, "initrd",
364 machine_get_initrd
, machine_set_initrd
, NULL
);
365 object_property_set_description(obj
, "initrd",
366 "Linux initial ramdisk file",
368 object_property_add_str(obj
, "append",
369 machine_get_append
, machine_set_append
, NULL
);
370 object_property_set_description(obj
, "append",
371 "Linux kernel command line",
373 object_property_add_str(obj
, "dtb",
374 machine_get_dtb
, machine_set_dtb
, NULL
);
375 object_property_set_description(obj
, "dtb",
376 "Linux kernel device tree file",
378 object_property_add_str(obj
, "dumpdtb",
379 machine_get_dumpdtb
, machine_set_dumpdtb
, NULL
);
380 object_property_set_description(obj
, "dumpdtb",
381 "Dump current dtb to a file and quit",
383 object_property_add(obj
, "phandle-start", "int",
384 machine_get_phandle_start
,
385 machine_set_phandle_start
,
387 object_property_set_description(obj
, "phandle-start",
388 "The first phandle ID we may generate dynamically",
390 object_property_add_str(obj
, "dt-compatible",
391 machine_get_dt_compatible
,
392 machine_set_dt_compatible
,
394 object_property_set_description(obj
, "dt-compatible",
395 "Overrides the \"compatible\" property of the dt root node",
397 object_property_add_bool(obj
, "dump-guest-core",
398 machine_get_dump_guest_core
,
399 machine_set_dump_guest_core
,
401 object_property_set_description(obj
, "dump-guest-core",
402 "Include guest memory in a core dump",
404 object_property_add_bool(obj
, "mem-merge",
405 machine_get_mem_merge
,
406 machine_set_mem_merge
, NULL
);
407 object_property_set_description(obj
, "mem-merge",
408 "Enable/disable memory merge support",
410 object_property_add_bool(obj
, "usb",
412 machine_set_usb
, NULL
);
413 object_property_set_description(obj
, "usb",
414 "Set on/off to enable/disable usb",
416 object_property_add_bool(obj
, "igd-passthru",
417 machine_get_igd_gfx_passthru
,
418 machine_set_igd_gfx_passthru
, NULL
);
419 object_property_set_description(obj
, "igd-passthru",
420 "Set on/off to enable/disable igd passthrou",
422 object_property_add_str(obj
, "firmware",
423 machine_get_firmware
,
424 machine_set_firmware
, NULL
);
425 object_property_set_description(obj
, "firmware",
428 object_property_add_bool(obj
, "iommu",
430 machine_set_iommu
, NULL
);
431 object_property_set_description(obj
, "iommu",
432 "Set on/off to enable/disable Intel IOMMU (VT-d)",
434 object_property_add_bool(obj
, "suppress-vmdesc",
435 machine_get_suppress_vmdesc
,
436 machine_set_suppress_vmdesc
, NULL
);
437 object_property_set_description(obj
, "suppress-vmdesc",
438 "Set on to disable self-describing migration",
441 /* Register notifier when init is done for sysbus sanity checks */
442 ms
->sysbus_notifier
.notify
= machine_init_notify
;
443 qemu_add_machine_init_done_notifier(&ms
->sysbus_notifier
);
446 static void machine_finalize(Object
*obj
)
448 MachineState
*ms
= MACHINE(obj
);
451 g_free(ms
->kernel_filename
);
452 g_free(ms
->initrd_filename
);
453 g_free(ms
->kernel_cmdline
);
456 g_free(ms
->dt_compatible
);
457 g_free(ms
->firmware
);
460 bool machine_usb(MachineState
*machine
)
465 bool machine_kernel_irqchip_allowed(MachineState
*machine
)
467 return machine
->kernel_irqchip_allowed
;
470 bool machine_kernel_irqchip_required(MachineState
*machine
)
472 return machine
->kernel_irqchip_required
;
475 int machine_kvm_shadow_mem(MachineState
*machine
)
477 return machine
->kvm_shadow_mem
;
480 int machine_phandle_start(MachineState
*machine
)
482 return machine
->phandle_start
;
485 bool machine_dump_guest_core(MachineState
*machine
)
487 return machine
->dump_guest_core
;
490 bool machine_mem_merge(MachineState
*machine
)
492 return machine
->mem_merge
;
495 static const TypeInfo machine_info
= {
496 .name
= TYPE_MACHINE
,
497 .parent
= TYPE_OBJECT
,
499 .class_size
= sizeof(MachineClass
),
500 .class_init
= machine_class_init
,
501 .class_base_init
= machine_class_base_init
,
502 .instance_size
= sizeof(MachineState
),
503 .instance_init
= machine_initfn
,
504 .instance_finalize
= machine_finalize
,
507 static void machine_register_types(void)
509 type_register_static(&machine_info
);
512 type_init(machine_register_types
)