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 bool machine_get_kernel_irqchip(Object
*obj
, Error
**errp
)
36 MachineState
*ms
= MACHINE(obj
);
38 return ms
->kernel_irqchip
;
41 static void machine_set_kernel_irqchip(Object
*obj
, bool value
, Error
**errp
)
43 MachineState
*ms
= MACHINE(obj
);
45 ms
->kernel_irqchip
= value
;
48 static void machine_get_kvm_shadow_mem(Object
*obj
, Visitor
*v
,
49 void *opaque
, const char *name
,
52 MachineState
*ms
= MACHINE(obj
);
53 int64_t value
= ms
->kvm_shadow_mem
;
55 visit_type_int(v
, &value
, name
, errp
);
58 static void machine_set_kvm_shadow_mem(Object
*obj
, Visitor
*v
,
59 void *opaque
, const char *name
,
62 MachineState
*ms
= MACHINE(obj
);
66 visit_type_int(v
, &value
, name
, &error
);
68 error_propagate(errp
, error
);
72 ms
->kvm_shadow_mem
= value
;
75 static char *machine_get_kernel(Object
*obj
, Error
**errp
)
77 MachineState
*ms
= MACHINE(obj
);
79 return g_strdup(ms
->kernel_filename
);
82 static void machine_set_kernel(Object
*obj
, const char *value
, Error
**errp
)
84 MachineState
*ms
= MACHINE(obj
);
86 g_free(ms
->kernel_filename
);
87 ms
->kernel_filename
= g_strdup(value
);
90 static char *machine_get_initrd(Object
*obj
, Error
**errp
)
92 MachineState
*ms
= MACHINE(obj
);
94 return g_strdup(ms
->initrd_filename
);
97 static void machine_set_initrd(Object
*obj
, const char *value
, Error
**errp
)
99 MachineState
*ms
= MACHINE(obj
);
101 g_free(ms
->initrd_filename
);
102 ms
->initrd_filename
= g_strdup(value
);
105 static char *machine_get_append(Object
*obj
, Error
**errp
)
107 MachineState
*ms
= MACHINE(obj
);
109 return g_strdup(ms
->kernel_cmdline
);
112 static void machine_set_append(Object
*obj
, const char *value
, Error
**errp
)
114 MachineState
*ms
= MACHINE(obj
);
116 g_free(ms
->kernel_cmdline
);
117 ms
->kernel_cmdline
= g_strdup(value
);
120 static char *machine_get_dtb(Object
*obj
, Error
**errp
)
122 MachineState
*ms
= MACHINE(obj
);
124 return g_strdup(ms
->dtb
);
127 static void machine_set_dtb(Object
*obj
, const char *value
, Error
**errp
)
129 MachineState
*ms
= MACHINE(obj
);
132 ms
->dtb
= g_strdup(value
);
135 static char *machine_get_dumpdtb(Object
*obj
, Error
**errp
)
137 MachineState
*ms
= MACHINE(obj
);
139 return g_strdup(ms
->dumpdtb
);
142 static void machine_set_dumpdtb(Object
*obj
, const char *value
, Error
**errp
)
144 MachineState
*ms
= MACHINE(obj
);
147 ms
->dumpdtb
= g_strdup(value
);
150 static void machine_get_phandle_start(Object
*obj
, Visitor
*v
,
151 void *opaque
, const char *name
,
154 MachineState
*ms
= MACHINE(obj
);
155 int64_t value
= ms
->phandle_start
;
157 visit_type_int(v
, &value
, name
, errp
);
160 static void machine_set_phandle_start(Object
*obj
, Visitor
*v
,
161 void *opaque
, const char *name
,
164 MachineState
*ms
= MACHINE(obj
);
168 visit_type_int(v
, &value
, name
, &error
);
170 error_propagate(errp
, error
);
174 ms
->phandle_start
= value
;
177 static char *machine_get_dt_compatible(Object
*obj
, Error
**errp
)
179 MachineState
*ms
= MACHINE(obj
);
181 return g_strdup(ms
->dt_compatible
);
184 static void machine_set_dt_compatible(Object
*obj
, const char *value
, Error
**errp
)
186 MachineState
*ms
= MACHINE(obj
);
188 g_free(ms
->dt_compatible
);
189 ms
->dt_compatible
= g_strdup(value
);
192 static bool machine_get_dump_guest_core(Object
*obj
, Error
**errp
)
194 MachineState
*ms
= MACHINE(obj
);
196 return ms
->dump_guest_core
;
199 static void machine_set_dump_guest_core(Object
*obj
, bool value
, Error
**errp
)
201 MachineState
*ms
= MACHINE(obj
);
203 ms
->dump_guest_core
= value
;
206 static bool machine_get_mem_merge(Object
*obj
, Error
**errp
)
208 MachineState
*ms
= MACHINE(obj
);
210 return ms
->mem_merge
;
213 static void machine_set_mem_merge(Object
*obj
, bool value
, Error
**errp
)
215 MachineState
*ms
= MACHINE(obj
);
217 ms
->mem_merge
= value
;
220 static bool machine_get_usb(Object
*obj
, Error
**errp
)
222 MachineState
*ms
= MACHINE(obj
);
227 static void machine_set_usb(Object
*obj
, bool value
, Error
**errp
)
229 MachineState
*ms
= MACHINE(obj
);
234 static char *machine_get_firmware(Object
*obj
, Error
**errp
)
236 MachineState
*ms
= MACHINE(obj
);
238 return g_strdup(ms
->firmware
);
241 static void machine_set_firmware(Object
*obj
, const char *value
, Error
**errp
)
243 MachineState
*ms
= MACHINE(obj
);
245 g_free(ms
->firmware
);
246 ms
->firmware
= g_strdup(value
);
249 static bool machine_get_iommu(Object
*obj
, Error
**errp
)
251 MachineState
*ms
= MACHINE(obj
);
256 static void machine_set_iommu(Object
*obj
, bool value
, Error
**errp
)
258 MachineState
*ms
= MACHINE(obj
);
263 static int error_on_sysbus_device(SysBusDevice
*sbdev
, void *opaque
)
265 error_report("Option '-device %s' cannot be handled by this machine",
266 object_class_get_name(object_get_class(OBJECT(sbdev
))));
270 static void machine_init_notify(Notifier
*notifier
, void *data
)
272 Object
*machine
= qdev_get_machine();
273 ObjectClass
*oc
= object_get_class(machine
);
274 MachineClass
*mc
= MACHINE_CLASS(oc
);
276 if (mc
->has_dynamic_sysbus
) {
277 /* Our machine can handle dynamic sysbus devices, we're all good */
282 * Loop through all dynamically created devices and check whether there
283 * are sysbus devices among them. If there are, error out.
285 foreach_dynamic_sysbus_device(error_on_sysbus_device
, NULL
);
288 static void machine_initfn(Object
*obj
)
290 MachineState
*ms
= MACHINE(obj
);
292 object_property_add_str(obj
, "accel",
293 machine_get_accel
, machine_set_accel
, NULL
);
294 object_property_set_description(obj
, "accel",
297 object_property_add_bool(obj
, "kernel-irqchip",
298 machine_get_kernel_irqchip
,
299 machine_set_kernel_irqchip
,
301 object_property_set_description(obj
, "kernel-irqchip",
302 "Use KVM in-kernel irqchip",
304 object_property_add(obj
, "kvm-shadow-mem", "int",
305 machine_get_kvm_shadow_mem
,
306 machine_set_kvm_shadow_mem
,
308 object_property_set_description(obj
, "kvm-shadow-mem",
309 "KVM shadow MMU size",
311 object_property_add_str(obj
, "kernel",
312 machine_get_kernel
, machine_set_kernel
, NULL
);
313 object_property_set_description(obj
, "kernel",
314 "Linux kernel image file",
316 object_property_add_str(obj
, "initrd",
317 machine_get_initrd
, machine_set_initrd
, NULL
);
318 object_property_set_description(obj
, "initrd",
319 "Linux initial ramdisk file",
321 object_property_add_str(obj
, "append",
322 machine_get_append
, machine_set_append
, NULL
);
323 object_property_set_description(obj
, "append",
324 "Linux kernel command line",
326 object_property_add_str(obj
, "dtb",
327 machine_get_dtb
, machine_set_dtb
, NULL
);
328 object_property_set_description(obj
, "dtb",
329 "Linux kernel device tree file",
331 object_property_add_str(obj
, "dumpdtb",
332 machine_get_dumpdtb
, machine_set_dumpdtb
, NULL
);
333 object_property_set_description(obj
, "dumpdtb",
334 "Dump current dtb to a file and quit",
336 object_property_add(obj
, "phandle-start", "int",
337 machine_get_phandle_start
,
338 machine_set_phandle_start
,
340 object_property_set_description(obj
, "phandle-start",
341 "The first phandle ID we may generate dynamically",
343 object_property_add_str(obj
, "dt-compatible",
344 machine_get_dt_compatible
,
345 machine_set_dt_compatible
,
347 object_property_set_description(obj
, "dt-compatible",
348 "Overrides the \"compatible\" property of the dt root node",
350 object_property_add_bool(obj
, "dump-guest-core",
351 machine_get_dump_guest_core
,
352 machine_set_dump_guest_core
,
354 object_property_set_description(obj
, "dump-guest-core",
355 "Include guest memory in a core dump",
357 object_property_add_bool(obj
, "mem-merge",
358 machine_get_mem_merge
,
359 machine_set_mem_merge
, NULL
);
360 object_property_set_description(obj
, "mem-merge",
361 "Enable/disable memory merge support",
363 object_property_add_bool(obj
, "usb",
365 machine_set_usb
, NULL
);
366 object_property_set_description(obj
, "usb",
367 "Set on/off to enable/disable usb",
369 object_property_add_str(obj
, "firmware",
370 machine_get_firmware
,
371 machine_set_firmware
, NULL
);
372 object_property_set_description(obj
, "firmware",
375 object_property_add_bool(obj
, "iommu",
377 machine_set_iommu
, NULL
);
378 object_property_set_description(obj
, "iommu",
379 "Set on/off to enable/disable Intel IOMMU (VT-d)",
382 /* Register notifier when init is done for sysbus sanity checks */
383 ms
->sysbus_notifier
.notify
= machine_init_notify
;
384 qemu_add_machine_init_done_notifier(&ms
->sysbus_notifier
);
387 static void machine_finalize(Object
*obj
)
389 MachineState
*ms
= MACHINE(obj
);
392 g_free(ms
->kernel_filename
);
393 g_free(ms
->initrd_filename
);
394 g_free(ms
->kernel_cmdline
);
397 g_free(ms
->dt_compatible
);
398 g_free(ms
->firmware
);
401 bool machine_usb(MachineState
*machine
)
406 bool machine_iommu(MachineState
*machine
)
408 return machine
->iommu
;
411 static const TypeInfo machine_info
= {
412 .name
= TYPE_MACHINE
,
413 .parent
= TYPE_OBJECT
,
415 .class_size
= sizeof(MachineClass
),
416 .instance_size
= sizeof(MachineState
),
417 .instance_init
= machine_initfn
,
418 .instance_finalize
= machine_finalize
,
421 static void machine_register_types(void)
423 type_register_static(&machine_info
);
426 type_init(machine_register_types
)