#include "qemu/sockets.h"
#include "hw/hw.h"
#include "hw/boards.h"
+#include "sysemu/accel.h"
#include "hw/usb.h"
-#include "hw/pcmcia.h"
#include "hw/i386/pc.h"
#include "hw/isa/isa.h"
#include "hw/bt.h"
unsigned int nb_prom_envs = 0;
const char *prom_envs[MAX_PROM_ENVS];
int boot_menu;
-static bool boot_strict;
+bool boot_strict;
uint8_t *boot_splash_filedata;
size_t boot_splash_filedata_size;
uint8_t qemu_extra_params_fw[2];
int icount_align_option;
-typedef struct FWBootEntry FWBootEntry;
-
-struct FWBootEntry {
- QTAILQ_ENTRY(FWBootEntry) link;
- int32_t bootindex;
- DeviceState *dev;
- char *suffix;
-};
-
-static QTAILQ_HEAD(, FWBootEntry) fw_boot_order =
- QTAILQ_HEAD_INITIALIZER(fw_boot_order);
int nb_numa_nodes;
int max_numa_nodeid;
NodeInfo numa_info[MAX_NODES];
+/* The bytes in qemu_uuid[] are in the order specified by RFC4122, _not_ in the
+ * little-endian "wire format" described in the SMBIOS 2.6 specification.
+ */
uint8_t qemu_uuid[16];
bool qemu_uuid_set;
static NotifierList machine_init_done_notifiers =
NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
-static bool tcg_allowed = true;
bool xen_allowed;
uint32_t xen_domid;
enum xen_mode xen_mode = XEN_EMULATE;
-static int tcg_tb_size;
static int has_defaults = 1;
static int default_serial = 1;
.name = PC_MACHINE_MAX_RAM_BELOW_4G,
.type = QEMU_OPT_SIZE,
.help = "maximum ram below the 4G boundary (32bit boundary)",
+ }, {
+ .name = PC_MACHINE_VMPORT,
+ .type = QEMU_OPT_STRING,
+ .help = "Enable vmport (pc & q35)",
},{
.name = "iommu",
.type = QEMU_OPT_BOOL,
g_free(normal_boot_order);
}
-void add_boot_device_path(int32_t bootindex, DeviceState *dev,
- const char *suffix)
-{
- FWBootEntry *node, *i;
-
- if (bootindex < 0) {
- return;
- }
-
- assert(dev != NULL || suffix != NULL);
-
- node = g_malloc0(sizeof(FWBootEntry));
- node->bootindex = bootindex;
- node->suffix = g_strdup(suffix);
- node->dev = dev;
-
- QTAILQ_FOREACH(i, &fw_boot_order, link) {
- if (i->bootindex == bootindex) {
- fprintf(stderr, "Two devices with same boot index %d\n", bootindex);
- exit(1);
- } else if (i->bootindex < bootindex) {
- continue;
- }
- QTAILQ_INSERT_BEFORE(i, node, link);
- return;
- }
- QTAILQ_INSERT_TAIL(&fw_boot_order, node, link);
-}
-
-DeviceState *get_boot_device(uint32_t position)
-{
- uint32_t counter = 0;
- FWBootEntry *i = NULL;
- DeviceState *res = NULL;
-
- if (!QTAILQ_EMPTY(&fw_boot_order)) {
- QTAILQ_FOREACH(i, &fw_boot_order, link) {
- if (counter == position) {
- res = i->dev;
- break;
- }
- counter++;
- }
- }
- return res;
-}
-
-/*
- * This function returns null terminated string that consist of new line
- * separated device paths.
- *
- * memory pointed by "size" is assigned total length of the array in bytes
- *
- */
-char *get_boot_devices_list(size_t *size, bool ignore_suffixes)
-{
- FWBootEntry *i;
- size_t total = 0;
- char *list = NULL;
-
- QTAILQ_FOREACH(i, &fw_boot_order, link) {
- char *devpath = NULL, *bootpath;
- size_t len;
-
- if (i->dev) {
- devpath = qdev_get_fw_dev_path(i->dev);
- assert(devpath);
- }
-
- if (i->suffix && !ignore_suffixes && devpath) {
- size_t bootpathlen = strlen(devpath) + strlen(i->suffix) + 1;
-
- bootpath = g_malloc(bootpathlen);
- snprintf(bootpath, bootpathlen, "%s%s", devpath, i->suffix);
- g_free(devpath);
- } else if (devpath) {
- bootpath = devpath;
- } else if (!ignore_suffixes) {
- assert(i->suffix);
- bootpath = g_strdup(i->suffix);
- } else {
- bootpath = g_strdup("");
- }
-
- if (total) {
- list[total-1] = '\n';
- }
- len = strlen(bootpath) + 1;
- list = g_realloc(list, total + len);
- memcpy(&list[total], bootpath, len);
- total += len;
- g_free(bootpath);
- }
-
- *size = total;
-
- if (boot_strict && *size > 0) {
- list[total-1] = '\n';
- list = g_realloc(list, total + 5);
- memcpy(&list[total], "HALT", 5);
- *size = total + 5;
- }
- return list;
-}
-
static QemuOptsList qemu_smp_opts = {
.name = "smp-opts",
.implied_opt_name = "cpus",
}
}
-/***********************************************************/
-/* PCMCIA/Cardbus */
-
-static struct pcmcia_socket_entry_s {
- PCMCIASocket *socket;
- struct pcmcia_socket_entry_s *next;
-} *pcmcia_sockets = 0;
-
-void pcmcia_socket_register(PCMCIASocket *socket)
-{
- struct pcmcia_socket_entry_s *entry;
-
- entry = g_malloc(sizeof(struct pcmcia_socket_entry_s));
- entry->socket = socket;
- entry->next = pcmcia_sockets;
- pcmcia_sockets = entry;
-}
-
-void pcmcia_socket_unregister(PCMCIASocket *socket)
-{
- struct pcmcia_socket_entry_s *entry, **ptr;
-
- ptr = &pcmcia_sockets;
- for (entry = *ptr; entry; ptr = &entry->next, entry = *ptr)
- if (entry->socket == socket) {
- *ptr = entry->next;
- g_free(entry);
- }
-}
-
-void pcmcia_info(Monitor *mon, const QDict *qdict)
-{
- struct pcmcia_socket_entry_s *iter;
-
- if (!pcmcia_sockets)
- monitor_printf(mon, "No PCMCIA sockets\n");
-
- for (iter = pcmcia_sockets; iter; iter = iter->next)
- monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,
- iter->socket->attached ? iter->socket->card_string :
- "Empty");
-}
-
/***********************************************************/
/* machine registration */
MachineClass *mc = MACHINE_CLASS(oc);
QEMUMachine *qm = data;
+ mc->family = qm->family;
mc->name = qm->name;
mc->alias = qm->alias;
mc->desc = qm->desc;
mc->no_floppy = qm->no_floppy;
mc->no_cdrom = qm->no_cdrom;
mc->no_sdcard = qm->no_sdcard;
+ mc->has_dynamic_sysbus = qm->has_dynamic_sysbus;
mc->is_default = qm->is_default;
mc->default_machine_opts = qm->default_machine_opts;
mc->default_boot_order = qm->default_boot_order;
+ mc->default_display = qm->default_display;
mc->compat_props = qm->compat_props;
mc->hw_version = qm->hw_version;
}
static int qemu_shutdown_requested(void)
{
- int r = shutdown_requested;
- shutdown_requested = 0;
- return r;
+ return atomic_xchg(&shutdown_requested, 0);
}
static void qemu_kill_report(void)
return 0;
}
-static void monitor_parse(const char *optarg, const char *mode)
+static void monitor_parse(const char *optarg, const char *mode, bool pretty)
{
static int monitor_device_index = 0;
QemuOpts *opts;
}
qemu_opt_set(opts, "mode", mode);
qemu_opt_set(opts, "chardev", label);
+ qemu_opt_set_bool(opts, "pretty", pretty);
if (def)
qemu_opt_set(opts, "default", "on");
monitor_device_index++;
return 0;
}
-static MachineClass *machine_parse(const char *name)
+static gint machine_class_cmp(gconstpointer a, gconstpointer b)
+{
+ const MachineClass *mc1 = a, *mc2 = b;
+ int res;
+
+ if (mc1->family == NULL) {
+ if (mc2->family == NULL) {
+ /* Compare standalone machine types against each other; they sort
+ * in increasing order.
+ */
+ return strcmp(object_class_get_name(OBJECT_CLASS(mc1)),
+ object_class_get_name(OBJECT_CLASS(mc2)));
+ }
+
+ /* Standalone machine types sort after families. */
+ return 1;
+ }
+
+ if (mc2->family == NULL) {
+ /* Families sort before standalone machine types. */
+ return -1;
+ }
+
+ /* Families sort between each other alphabetically increasingly. */
+ res = strcmp(mc1->family, mc2->family);
+ if (res != 0) {
+ return res;
+ }
+
+ /* Within the same family, machine types sort in decreasing order. */
+ return strcmp(object_class_get_name(OBJECT_CLASS(mc2)),
+ object_class_get_name(OBJECT_CLASS(mc1)));
+}
+
+ static MachineClass *machine_parse(const char *name)
{
MachineClass *mc = NULL;
GSList *el, *machines = object_class_get_list(TYPE_MACHINE, false);
error_printf("Use -machine help to list supported machines!\n");
} else {
printf("Supported machines are:\n");
+ machines = g_slist_sort(machines, machine_class_cmp);
for (el = machines; el; el = el->next) {
MachineClass *mc = el->data;
if (mc->alias) {
exit(!name || !is_help_option(name));
}
-static int tcg_init(MachineClass *mc)
-{
- tcg_exec_init(tcg_tb_size * 1024 * 1024);
- return 0;
-}
-
-static struct {
- const char *opt_name;
- const char *name;
- int (*available)(void);
- int (*init)(MachineClass *mc);
- bool *allowed;
-} accel_list[] = {
- { "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
- { "xen", "Xen", xen_available, xen_init, &xen_allowed },
- { "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed },
- { "qtest", "QTest", qtest_available, qtest_init_accel, &qtest_allowed },
-};
-
-static int configure_accelerator(MachineClass *mc)
-{
- const char *p;
- char buf[10];
- int i, ret;
- bool accel_initialised = false;
- bool init_failed = false;
-
- p = qemu_opt_get(qemu_get_machine_opts(), "accel");
- if (p == NULL) {
- /* Use the default "accelerator", tcg */
- p = "tcg";
- }
-
- while (!accel_initialised && *p != '\0') {
- if (*p == ':') {
- p++;
- }
- p = get_opt_name(buf, sizeof (buf), p, ':');
- for (i = 0; i < ARRAY_SIZE(accel_list); i++) {
- if (strcmp(accel_list[i].opt_name, buf) == 0) {
- if (!accel_list[i].available()) {
- printf("%s not supported for this target\n",
- accel_list[i].name);
- break;
- }
- *(accel_list[i].allowed) = true;
- ret = accel_list[i].init(mc);
- if (ret < 0) {
- init_failed = true;
- fprintf(stderr, "failed to initialize %s: %s\n",
- accel_list[i].name,
- strerror(-ret));
- *(accel_list[i].allowed) = false;
- } else {
- accel_initialised = true;
- }
- break;
- }
- }
- if (i == ARRAY_SIZE(accel_list)) {
- fprintf(stderr, "\"%s\" accelerator does not exist.\n", buf);
- }
- }
-
- if (!accel_initialised) {
- if (!init_failed) {
- fprintf(stderr, "No accelerator found!\n");
- }
- exit(1);
- }
-
- if (init_failed) {
- fprintf(stderr, "Back to %s accelerator.\n", accel_list[i].name);
- }
-
- return !accel_initialised;
-}
-
void qemu_add_exit_notifier(Notifier *notify)
{
notifier_list_add(&exit_notifiers, notify);
case QEMU_OPTION_monitor:
default_monitor = 0;
if (strncmp(optarg, "none", 4)) {
- monitor_parse(optarg, "readline");
+ monitor_parse(optarg, "readline", false);
}
break;
case QEMU_OPTION_qmp:
- monitor_parse(optarg, "control");
+ monitor_parse(optarg, "control", false);
+ default_monitor = 0;
+ break;
+ case QEMU_OPTION_qmp_pretty:
+ monitor_parse(optarg, "control", true);
default_monitor = 0;
break;
case QEMU_OPTION_mon:
configure_msg(opts);
break;
case QEMU_OPTION_dump_vmstate:
+ if (vmstate_dump_file) {
+ fprintf(stderr, "qemu: only one '-dump-vmstate' "
+ "option may be given\n");
+ exit(1);
+ }
vmstate_dump_file = fopen(optarg, "w");
if (vmstate_dump_file == NULL) {
fprintf(stderr, "open %s: %s\n", optarg, strerror(errno));
add_device_config(DEV_SCLP, "stdio");
}
if (default_monitor)
- monitor_parse("stdio", "readline");
+ monitor_parse("stdio", "readline", false);
}
} else {
if (default_serial)
if (default_parallel)
add_device_config(DEV_PARALLEL, "vc:80Cx24C");
if (default_monitor)
- monitor_parse("vc:80Cx24C", "readline");
+ monitor_parse("vc:80Cx24C", "readline", false);
if (default_virtcon)
add_device_config(DEV_VIRTCON, "vc:80Cx24C");
if (default_sclp) {
#endif
if (pid_file && qemu_create_pidfile(pid_file) != 0) {
- os_pidfile_error();
+ fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno));
exit(1);
}
exit(1);
}
- configure_accelerator(machine_class);
+ configure_accelerator(current_machine);
if (qtest_chrdev) {
Error *local_err = NULL;
/* If no default VGA is requested, the default is "none". */
if (default_vga) {
- if (cirrus_vga_available()) {
+ if (machine_class->default_display) {
+ vga_model = machine_class->default_display;
+ } else if (cirrus_vga_available()) {
vga_model = "cirrus";
} else if (vga_available()) {
vga_model = "std";