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-visit.h"
15 #include "qapi/visitor.h"
16 #include "hw/sysbus.h"
17 #include "sysemu/sysemu.h"
18 #include "qemu/error-report.h"
20 static char *machine_get_accel(Object
*obj
, Error
**errp
)
22 MachineState
*ms
= MACHINE(obj
);
24 return g_strdup(ms
->accel
);
27 static void machine_set_accel(Object
*obj
, const char *value
, Error
**errp
)
29 MachineState
*ms
= MACHINE(obj
);
32 ms
->accel
= g_strdup(value
);
35 static void machine_set_kernel_irqchip(Object
*obj
, Visitor
*v
,
36 void *opaque
, const char *name
,
40 MachineState
*ms
= MACHINE(obj
);
43 visit_type_OnOffSplit(v
, &mode
, name
, &err
);
45 error_propagate(errp
, err
);
50 ms
->kernel_irqchip_allowed
= true;
51 ms
->kernel_irqchip_required
= true;
52 ms
->kernel_irqchip_split
= false;
54 case ON_OFF_SPLIT_OFF
:
55 ms
->kernel_irqchip_allowed
= false;
56 ms
->kernel_irqchip_required
= false;
57 ms
->kernel_irqchip_split
= false;
59 case ON_OFF_SPLIT_SPLIT
:
60 ms
->kernel_irqchip_allowed
= true;
61 ms
->kernel_irqchip_required
= true;
62 ms
->kernel_irqchip_split
= true;
70 static void machine_get_kvm_shadow_mem(Object
*obj
, Visitor
*v
,
71 void *opaque
, const char *name
,
74 MachineState
*ms
= MACHINE(obj
);
75 int64_t value
= ms
->kvm_shadow_mem
;
77 visit_type_int(v
, &value
, name
, errp
);
80 static void machine_set_kvm_shadow_mem(Object
*obj
, Visitor
*v
,
81 void *opaque
, const char *name
,
84 MachineState
*ms
= MACHINE(obj
);
88 visit_type_int(v
, &value
, name
, &error
);
90 error_propagate(errp
, error
);
94 ms
->kvm_shadow_mem
= value
;
97 static char *machine_get_kernel(Object
*obj
, Error
**errp
)
99 MachineState
*ms
= MACHINE(obj
);
101 return g_strdup(ms
->kernel_filename
);
104 static void machine_set_kernel(Object
*obj
, const char *value
, Error
**errp
)
106 MachineState
*ms
= MACHINE(obj
);
108 g_free(ms
->kernel_filename
);
109 ms
->kernel_filename
= g_strdup(value
);
112 static char *machine_get_initrd(Object
*obj
, Error
**errp
)
114 MachineState
*ms
= MACHINE(obj
);
116 return g_strdup(ms
->initrd_filename
);
119 static void machine_set_initrd(Object
*obj
, const char *value
, Error
**errp
)
121 MachineState
*ms
= MACHINE(obj
);
123 g_free(ms
->initrd_filename
);
124 ms
->initrd_filename
= g_strdup(value
);
127 static char *machine_get_append(Object
*obj
, Error
**errp
)
129 MachineState
*ms
= MACHINE(obj
);
131 return g_strdup(ms
->kernel_cmdline
);
134 static void machine_set_append(Object
*obj
, const char *value
, Error
**errp
)
136 MachineState
*ms
= MACHINE(obj
);
138 g_free(ms
->kernel_cmdline
);
139 ms
->kernel_cmdline
= g_strdup(value
);
142 static char *machine_get_dtb(Object
*obj
, Error
**errp
)
144 MachineState
*ms
= MACHINE(obj
);
146 return g_strdup(ms
->dtb
);
149 static void machine_set_dtb(Object
*obj
, const char *value
, Error
**errp
)
151 MachineState
*ms
= MACHINE(obj
);
154 ms
->dtb
= g_strdup(value
);
157 static char *machine_get_dumpdtb(Object
*obj
, Error
**errp
)
159 MachineState
*ms
= MACHINE(obj
);
161 return g_strdup(ms
->dumpdtb
);
164 static void machine_set_dumpdtb(Object
*obj
, const char *value
, Error
**errp
)
166 MachineState
*ms
= MACHINE(obj
);
169 ms
->dumpdtb
= g_strdup(value
);
172 static void machine_get_phandle_start(Object
*obj
, Visitor
*v
,
173 void *opaque
, const char *name
,
176 MachineState
*ms
= MACHINE(obj
);
177 int64_t value
= ms
->phandle_start
;
179 visit_type_int(v
, &value
, name
, errp
);
182 static void machine_set_phandle_start(Object
*obj
, Visitor
*v
,
183 void *opaque
, const char *name
,
186 MachineState
*ms
= MACHINE(obj
);
190 visit_type_int(v
, &value
, name
, &error
);
192 error_propagate(errp
, error
);
196 ms
->phandle_start
= value
;
199 static char *machine_get_dt_compatible(Object
*obj
, Error
**errp
)
201 MachineState
*ms
= MACHINE(obj
);
203 return g_strdup(ms
->dt_compatible
);
206 static void machine_set_dt_compatible(Object
*obj
, const char *value
, Error
**errp
)
208 MachineState
*ms
= MACHINE(obj
);
210 g_free(ms
->dt_compatible
);
211 ms
->dt_compatible
= g_strdup(value
);
214 static bool machine_get_dump_guest_core(Object
*obj
, Error
**errp
)
216 MachineState
*ms
= MACHINE(obj
);
218 return ms
->dump_guest_core
;
221 static void machine_set_dump_guest_core(Object
*obj
, bool value
, Error
**errp
)
223 MachineState
*ms
= MACHINE(obj
);
225 ms
->dump_guest_core
= value
;
228 static bool machine_get_mem_merge(Object
*obj
, Error
**errp
)
230 MachineState
*ms
= MACHINE(obj
);
232 return ms
->mem_merge
;
235 static void machine_set_mem_merge(Object
*obj
, bool value
, Error
**errp
)
237 MachineState
*ms
= MACHINE(obj
);
239 ms
->mem_merge
= value
;
242 static bool machine_get_usb(Object
*obj
, Error
**errp
)
244 MachineState
*ms
= MACHINE(obj
);
249 static void machine_set_usb(Object
*obj
, bool value
, Error
**errp
)
251 MachineState
*ms
= MACHINE(obj
);
254 ms
->usb_disabled
= !value
;
257 static bool machine_get_igd_gfx_passthru(Object
*obj
, Error
**errp
)
259 MachineState
*ms
= MACHINE(obj
);
261 return ms
->igd_gfx_passthru
;
264 static void machine_set_igd_gfx_passthru(Object
*obj
, bool value
, Error
**errp
)
266 MachineState
*ms
= MACHINE(obj
);
268 ms
->igd_gfx_passthru
= value
;
271 static char *machine_get_firmware(Object
*obj
, Error
**errp
)
273 MachineState
*ms
= MACHINE(obj
);
275 return g_strdup(ms
->firmware
);
278 static void machine_set_firmware(Object
*obj
, const char *value
, Error
**errp
)
280 MachineState
*ms
= MACHINE(obj
);
282 g_free(ms
->firmware
);
283 ms
->firmware
= g_strdup(value
);
286 static bool machine_get_iommu(Object
*obj
, Error
**errp
)
288 MachineState
*ms
= MACHINE(obj
);
293 static void machine_set_iommu(Object
*obj
, bool value
, Error
**errp
)
295 MachineState
*ms
= MACHINE(obj
);
300 static void machine_set_suppress_vmdesc(Object
*obj
, bool value
, Error
**errp
)
302 MachineState
*ms
= MACHINE(obj
);
304 ms
->suppress_vmdesc
= value
;
307 static bool machine_get_suppress_vmdesc(Object
*obj
, Error
**errp
)
309 MachineState
*ms
= MACHINE(obj
);
311 return ms
->suppress_vmdesc
;
314 static int error_on_sysbus_device(SysBusDevice
*sbdev
, void *opaque
)
316 error_report("Option '-device %s' cannot be handled by this machine",
317 object_class_get_name(object_get_class(OBJECT(sbdev
))));
321 static void machine_init_notify(Notifier
*notifier
, void *data
)
323 Object
*machine
= qdev_get_machine();
324 ObjectClass
*oc
= object_get_class(machine
);
325 MachineClass
*mc
= MACHINE_CLASS(oc
);
327 if (mc
->has_dynamic_sysbus
) {
328 /* Our machine can handle dynamic sysbus devices, we're all good */
333 * Loop through all dynamically created devices and check whether there
334 * are sysbus devices among them. If there are, error out.
336 foreach_dynamic_sysbus_device(error_on_sysbus_device
, NULL
);
339 static void machine_class_init(ObjectClass
*oc
, void *data
)
341 MachineClass
*mc
= MACHINE_CLASS(oc
);
343 /* Default 128 MB as guest ram size */
344 mc
->default_ram_size
= 128 * M_BYTE
;
345 mc
->rom_file_has_mr
= true;
348 static void machine_class_base_init(ObjectClass
*oc
, void *data
)
350 if (!object_class_is_abstract(oc
)) {
351 MachineClass
*mc
= MACHINE_CLASS(oc
);
352 const char *cname
= object_class_get_name(oc
);
353 assert(g_str_has_suffix(cname
, TYPE_MACHINE_SUFFIX
));
354 mc
->name
= g_strndup(cname
,
355 strlen(cname
) - strlen(TYPE_MACHINE_SUFFIX
));
359 static void machine_initfn(Object
*obj
)
361 MachineState
*ms
= MACHINE(obj
);
363 ms
->kernel_irqchip_allowed
= true;
364 ms
->kvm_shadow_mem
= -1;
365 ms
->dump_guest_core
= true;
366 ms
->mem_merge
= true;
368 object_property_add_str(obj
, "accel",
369 machine_get_accel
, machine_set_accel
, NULL
);
370 object_property_set_description(obj
, "accel",
373 object_property_add(obj
, "kernel-irqchip", "OnOffSplit",
375 machine_set_kernel_irqchip
,
377 object_property_set_description(obj
, "kernel-irqchip",
378 "Configure KVM in-kernel irqchip",
380 object_property_add(obj
, "kvm-shadow-mem", "int",
381 machine_get_kvm_shadow_mem
,
382 machine_set_kvm_shadow_mem
,
384 object_property_set_description(obj
, "kvm-shadow-mem",
385 "KVM shadow MMU size",
387 object_property_add_str(obj
, "kernel",
388 machine_get_kernel
, machine_set_kernel
, NULL
);
389 object_property_set_description(obj
, "kernel",
390 "Linux kernel image file",
392 object_property_add_str(obj
, "initrd",
393 machine_get_initrd
, machine_set_initrd
, NULL
);
394 object_property_set_description(obj
, "initrd",
395 "Linux initial ramdisk file",
397 object_property_add_str(obj
, "append",
398 machine_get_append
, machine_set_append
, NULL
);
399 object_property_set_description(obj
, "append",
400 "Linux kernel command line",
402 object_property_add_str(obj
, "dtb",
403 machine_get_dtb
, machine_set_dtb
, NULL
);
404 object_property_set_description(obj
, "dtb",
405 "Linux kernel device tree file",
407 object_property_add_str(obj
, "dumpdtb",
408 machine_get_dumpdtb
, machine_set_dumpdtb
, NULL
);
409 object_property_set_description(obj
, "dumpdtb",
410 "Dump current dtb to a file and quit",
412 object_property_add(obj
, "phandle-start", "int",
413 machine_get_phandle_start
,
414 machine_set_phandle_start
,
416 object_property_set_description(obj
, "phandle-start",
417 "The first phandle ID we may generate dynamically",
419 object_property_add_str(obj
, "dt-compatible",
420 machine_get_dt_compatible
,
421 machine_set_dt_compatible
,
423 object_property_set_description(obj
, "dt-compatible",
424 "Overrides the \"compatible\" property of the dt root node",
426 object_property_add_bool(obj
, "dump-guest-core",
427 machine_get_dump_guest_core
,
428 machine_set_dump_guest_core
,
430 object_property_set_description(obj
, "dump-guest-core",
431 "Include guest memory in a core dump",
433 object_property_add_bool(obj
, "mem-merge",
434 machine_get_mem_merge
,
435 machine_set_mem_merge
, NULL
);
436 object_property_set_description(obj
, "mem-merge",
437 "Enable/disable memory merge support",
439 object_property_add_bool(obj
, "usb",
441 machine_set_usb
, NULL
);
442 object_property_set_description(obj
, "usb",
443 "Set on/off to enable/disable usb",
445 object_property_add_bool(obj
, "igd-passthru",
446 machine_get_igd_gfx_passthru
,
447 machine_set_igd_gfx_passthru
, NULL
);
448 object_property_set_description(obj
, "igd-passthru",
449 "Set on/off to enable/disable igd passthrou",
451 object_property_add_str(obj
, "firmware",
452 machine_get_firmware
,
453 machine_set_firmware
, NULL
);
454 object_property_set_description(obj
, "firmware",
457 object_property_add_bool(obj
, "iommu",
459 machine_set_iommu
, NULL
);
460 object_property_set_description(obj
, "iommu",
461 "Set on/off to enable/disable Intel IOMMU (VT-d)",
463 object_property_add_bool(obj
, "suppress-vmdesc",
464 machine_get_suppress_vmdesc
,
465 machine_set_suppress_vmdesc
, NULL
);
466 object_property_set_description(obj
, "suppress-vmdesc",
467 "Set on to disable self-describing migration",
470 /* Register notifier when init is done for sysbus sanity checks */
471 ms
->sysbus_notifier
.notify
= machine_init_notify
;
472 qemu_add_machine_init_done_notifier(&ms
->sysbus_notifier
);
475 static void machine_finalize(Object
*obj
)
477 MachineState
*ms
= MACHINE(obj
);
480 g_free(ms
->kernel_filename
);
481 g_free(ms
->initrd_filename
);
482 g_free(ms
->kernel_cmdline
);
485 g_free(ms
->dt_compatible
);
486 g_free(ms
->firmware
);
489 bool machine_usb(MachineState
*machine
)
494 bool machine_kernel_irqchip_allowed(MachineState
*machine
)
496 return machine
->kernel_irqchip_allowed
;
499 bool machine_kernel_irqchip_required(MachineState
*machine
)
501 return machine
->kernel_irqchip_required
;
504 bool machine_kernel_irqchip_split(MachineState
*machine
)
506 return machine
->kernel_irqchip_split
;
509 int machine_kvm_shadow_mem(MachineState
*machine
)
511 return machine
->kvm_shadow_mem
;
514 int machine_phandle_start(MachineState
*machine
)
516 return machine
->phandle_start
;
519 bool machine_dump_guest_core(MachineState
*machine
)
521 return machine
->dump_guest_core
;
524 bool machine_mem_merge(MachineState
*machine
)
526 return machine
->mem_merge
;
529 static const TypeInfo machine_info
= {
530 .name
= TYPE_MACHINE
,
531 .parent
= TYPE_OBJECT
,
533 .class_size
= sizeof(MachineClass
),
534 .class_init
= machine_class_init
,
535 .class_base_init
= machine_class_base_init
,
536 .instance_size
= sizeof(MachineState
),
537 .instance_init
= machine_initfn
,
538 .instance_finalize
= machine_finalize
,
541 static void machine_register_types(void)
543 type_register_static(&machine_info
);
546 type_init(machine_register_types
)