#define DEFAULT_RAM_SIZE 128
+/* Maximum number of monitor devices */
+#define MAX_MONITOR_DEVICES 10
+
static const char *data_dir;
const char *bios_name = NULL;
/* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
static DisplayState *display_state;
DisplayType display_type = DT_DEFAULT;
const char* keyboard_layout = NULL;
-int64_t ticks_per_sec;
ram_addr_t ram_size;
int nb_nics;
NICInfo nd_table[MAX_NICS];
}
}
-void do_mouse_set(Monitor *mon, int index)
+void do_mouse_set(Monitor *mon, const QDict *qdict)
{
QEMUPutMouseEntry *cursor;
int i = 0;
+ int index = qdict_get_int(qdict, "index");
if (!qemu_put_mouse_event_head) {
monitor_printf(mon, "No mouse devices connected\n");
/***********************************************************/
/* real time host monotonic timer */
-#define QEMU_TIMER_BASE 1000000000LL
-
#ifdef WIN32
static int64_t clock_freq;
{
LARGE_INTEGER ti;
QueryPerformanceCounter(&ti);
- return muldiv64(ti.QuadPart, QEMU_TIMER_BASE, clock_freq);
+ return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
}
#else
/***********************************************************/
/* guest cycle counter */
-static int64_t cpu_ticks_prev;
-static int64_t cpu_ticks_offset;
-static int64_t cpu_clock_offset;
-static int cpu_ticks_enabled;
+typedef struct TimersState {
+ int64_t cpu_ticks_prev;
+ int64_t cpu_ticks_offset;
+ int64_t cpu_clock_offset;
+ int32_t cpu_ticks_enabled;
+ int64_t dummy;
+} TimersState;
+
+TimersState timers_state;
/* return the host CPU cycle counter and handle stop/restart */
int64_t cpu_get_ticks(void)
if (use_icount) {
return cpu_get_icount();
}
- if (!cpu_ticks_enabled) {
- return cpu_ticks_offset;
+ if (!timers_state.cpu_ticks_enabled) {
+ return timers_state.cpu_ticks_offset;
} else {
int64_t ticks;
ticks = cpu_get_real_ticks();
- if (cpu_ticks_prev > ticks) {
+ if (timers_state.cpu_ticks_prev > ticks) {
/* Note: non increasing ticks may happen if the host uses
software suspend */
- cpu_ticks_offset += cpu_ticks_prev - ticks;
+ timers_state.cpu_ticks_offset += timers_state.cpu_ticks_prev - ticks;
}
- cpu_ticks_prev = ticks;
- return ticks + cpu_ticks_offset;
+ timers_state.cpu_ticks_prev = ticks;
+ return ticks + timers_state.cpu_ticks_offset;
}
}
static int64_t cpu_get_clock(void)
{
int64_t ti;
- if (!cpu_ticks_enabled) {
- return cpu_clock_offset;
+ if (!timers_state.cpu_ticks_enabled) {
+ return timers_state.cpu_clock_offset;
} else {
ti = get_clock();
- return ti + cpu_clock_offset;
+ return ti + timers_state.cpu_clock_offset;
}
}
/* enable cpu_get_ticks() */
void cpu_enable_ticks(void)
{
- if (!cpu_ticks_enabled) {
- cpu_ticks_offset -= cpu_get_real_ticks();
- cpu_clock_offset -= get_clock();
- cpu_ticks_enabled = 1;
+ if (!timers_state.cpu_ticks_enabled) {
+ timers_state.cpu_ticks_offset -= cpu_get_real_ticks();
+ timers_state.cpu_clock_offset -= get_clock();
+ timers_state.cpu_ticks_enabled = 1;
}
}
cpu_get_ticks() after that. */
void cpu_disable_ticks(void)
{
- if (cpu_ticks_enabled) {
- cpu_ticks_offset = cpu_get_ticks();
- cpu_clock_offset = cpu_get_clock();
- cpu_ticks_enabled = 0;
+ if (timers_state.cpu_ticks_enabled) {
+ timers_state.cpu_ticks_offset = cpu_get_ticks();
+ timers_state.cpu_clock_offset = cpu_get_clock();
+ timers_state.cpu_ticks_enabled = 0;
}
}
fairly approximate, so ignore small variation.
When the guest is idle real and virtual time will be aligned in
the IO wait loop. */
-#define ICOUNT_WOBBLE (QEMU_TIMER_BASE / 10)
+#define ICOUNT_WOBBLE (get_ticks_per_sec() / 10)
static void icount_adjust(void)
{
static void icount_adjust_vm(void * opaque)
{
qemu_mod_timer(icount_vm_timer,
- qemu_get_clock(vm_clock) + QEMU_TIMER_BASE / 10);
+ qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10);
icount_adjust();
}
qemu_get_clock(rt_clock) + 1000);
icount_vm_timer = qemu_new_timer(vm_clock, icount_adjust_vm, NULL);
qemu_mod_timer(icount_vm_timer,
- qemu_get_clock(vm_clock) + QEMU_TIMER_BASE / 10);
+ qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10);
}
static struct qemu_alarm_timer alarm_timers[] = {
exit(0);
}
- arg = strdup(opt);
+ arg = qemu_strdup(opt);
/* Reorder the array */
name = strtok(arg, ",");
name = strtok(NULL, ",");
}
- free(arg);
+ qemu_free(arg);
if (cur) {
/* Disable remaining timers */
static void init_timers(void)
{
init_get_clock();
- ticks_per_sec = QEMU_TIMER_BASE;
rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
}
}
}
-static void timer_save(QEMUFile *f, void *opaque)
-{
- if (cpu_ticks_enabled) {
- hw_error("cannot save state if virtual timers are running");
- }
- qemu_put_be64(f, cpu_ticks_offset);
- qemu_put_be64(f, ticks_per_sec);
- qemu_put_be64(f, cpu_clock_offset);
-}
-
-static int timer_load(QEMUFile *f, void *opaque, int version_id)
-{
- if (version_id != 1 && version_id != 2)
- return -EINVAL;
- if (cpu_ticks_enabled) {
- return -EINVAL;
- }
- cpu_ticks_offset=qemu_get_be64(f);
- ticks_per_sec=qemu_get_be64(f);
- if (version_id == 2) {
- cpu_clock_offset=qemu_get_be64(f);
+static const VMStateDescription vmstate_timers = {
+ .name = "timer",
+ .version_id = 2,
+ .minimum_version_id = 1,
+ .minimum_version_id_old = 1,
+ .fields = (VMStateField []) {
+ VMSTATE_INT64(cpu_ticks_offset, TimersState),
+ VMSTATE_INT64(dummy, TimersState),
+ VMSTATE_INT64_V(cpu_clock_offset, TimersState, 2),
+ VMSTATE_END_OF_LIST()
}
- return 0;
-}
+};
static void qemu_event_increment(void);
delta_cum += delta;
if (++count == DISP_FREQ) {
printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",
- muldiv64(delta_min, 1000000, ticks_per_sec),
- muldiv64(delta_max, 1000000, ticks_per_sec),
- muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),
- (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));
+ muldiv64(delta_min, 1000000, get_ticks_per_sec()),
+ muldiv64(delta_max, 1000000, get_ticks_per_sec()),
+ muldiv64(delta_cum, 1000000 / DISP_FREQ, get_ticks_per_sec()),
+ (double)get_ticks_per_sec() / ((double)delta_cum / DISP_FREQ));
count = 0;
delta_min = INT64_MAX;
delta_max = 0;
translation = BIOS_ATA_TRANSLATION_AUTO;
cache = 1;
- if (machine->use_scsi) {
+ if (machine && machine->use_scsi) {
type = IF_SCSI;
max_devs = MAX_SCSI_DEVS;
pstrcpy(devname, sizeof(devname), "scsi");
/***********************************************************/
/* USB devices */
-static USBPort *used_usb_ports;
-static USBPort *free_usb_ports;
-
-/* ??? Maybe change this to register a hub to keep track of the topology. */
-void qemu_register_usb_port(USBPort *port, void *opaque, int index,
- usb_attachfn attach)
-{
- port->opaque = opaque;
- port->index = index;
- port->attach = attach;
- port->next = free_usb_ports;
- free_usb_ports = port;
-}
-
-int usb_device_add_dev(USBDevice *dev)
-{
- USBPort *port;
-
- /* Find a USB port to add the device to. */
- port = free_usb_ports;
- if (!port->next) {
- USBDevice *hub;
-
- /* Create a new hub and chain it on. */
- free_usb_ports = NULL;
- port->next = used_usb_ports;
- used_usb_ports = port;
-
- hub = usb_hub_init(VM_USB_HUB_SIZE);
- usb_attach(port, hub);
- port = free_usb_ports;
- }
-
- free_usb_ports = port->next;
- port->next = used_usb_ports;
- used_usb_ports = port;
- usb_attach(port, dev);
- return 0;
-}
-
static void usb_msd_password_cb(void *opaque, int err)
{
USBDevice *dev = opaque;
if (!err)
- usb_device_add_dev(dev);
+ usb_device_attach(dev);
else
- dev->handle_destroy(dev);
+ dev->info->handle_destroy(dev);
}
+static struct {
+ const char *name;
+ const char *qdev;
+} usbdevs[] = {
+ {
+ .name = "mouse",
+ .qdev = "QEMU USB Mouse",
+ },{
+ .name = "tablet",
+ .qdev = "QEMU USB Tablet",
+ },{
+ .name = "keyboard",
+ .qdev = "QEMU USB Keyboard",
+ },{
+ .name = "wacom-tablet",
+ .qdev = "QEMU PenPartner Tablet",
+ }
+};
+
static int usb_device_add(const char *devname, int is_hotplug)
{
const char *p;
- USBDevice *dev;
+ USBBus *bus = usb_bus_find(-1 /* any */);
+ USBDevice *dev = NULL;
+ int i;
- if (!free_usb_ports)
+ if (!usb_enabled)
return -1;
+ /* simple devices which don't need extra care */
+ for (i = 0; i < ARRAY_SIZE(usbdevs); i++) {
+ if (strcmp(devname, usbdevs[i].name) != 0)
+ continue;
+ dev = usb_create_simple(bus, usbdevs[i].qdev);
+ goto done;
+ }
+
+ /* the other ones */
if (strstart(devname, "host:", &p)) {
dev = usb_host_device_open(p);
- } else if (!strcmp(devname, "mouse")) {
- dev = usb_mouse_init();
- } else if (!strcmp(devname, "tablet")) {
- dev = usb_tablet_init();
- } else if (!strcmp(devname, "keyboard")) {
- dev = usb_keyboard_init();
} else if (strstart(devname, "disk:", &p)) {
BlockDriverState *bs;
return 0;
}
}
- } else if (!strcmp(devname, "wacom-tablet")) {
- dev = usb_wacom_init();
} else if (strstart(devname, "serial:", &p)) {
dev = usb_serial_init(p);
#ifdef CONFIG_BRLAPI
if (!dev)
return -1;
- return usb_device_add_dev(dev);
-}
-
-int usb_device_del_addr(int bus_num, int addr)
-{
- USBPort *port;
- USBPort **lastp;
- USBDevice *dev;
-
- if (!used_usb_ports)
- return -1;
-
- if (bus_num != 0)
- return -1;
-
- lastp = &used_usb_ports;
- port = used_usb_ports;
- while (port && port->dev->addr != addr) {
- lastp = &port->next;
- port = port->next;
- }
-
- if (!port)
- return -1;
-
- dev = port->dev;
- *lastp = port->next;
- usb_attach(port, NULL);
- dev->handle_destroy(dev);
- port->next = free_usb_ports;
- free_usb_ports = port;
+done:
return 0;
}
if (strstart(devname, "host:", &p))
return usb_host_device_close(p);
- if (!used_usb_ports)
+ if (!usb_enabled)
return -1;
p = strchr(devname, '.');
bus_num = strtoul(devname, NULL, 0);
addr = strtoul(p + 1, NULL, 0);
- return usb_device_del_addr(bus_num, addr);
+ return usb_device_delete_addr(bus_num, addr);
}
static int usb_parse(const char *cmdline)
return usb_device_add(cmdline, 0);
}
-void do_usb_add(Monitor *mon, const char *devname)
+void do_usb_add(Monitor *mon, const QDict *qdict)
{
- usb_device_add(devname, 1);
+ usb_device_add(qdict_get_str(qdict, "devname"), 1);
}
-void do_usb_del(Monitor *mon, const char *devname)
+void do_usb_del(Monitor *mon, const QDict *qdict)
{
- usb_device_del(devname);
-}
-
-void usb_info(Monitor *mon)
-{
- USBDevice *dev;
- USBPort *port;
- const char *speed_str;
-
- if (!usb_enabled) {
- monitor_printf(mon, "USB support not enabled\n");
- return;
- }
-
- for (port = used_usb_ports; port; port = port->next) {
- dev = port->dev;
- if (!dev)
- continue;
- switch(dev->speed) {
- case USB_SPEED_LOW:
- speed_str = "1.5";
- break;
- case USB_SPEED_FULL:
- speed_str = "12";
- break;
- case USB_SPEED_HIGH:
- speed_str = "480";
- break;
- default:
- speed_str = "?";
- break;
- }
- monitor_printf(mon, " Device %d.%d, Speed %s Mb/s, Product %s\n",
- 0, dev->addr, speed_str, dev->devname);
- }
+ usb_device_del(qdict_get_str(qdict, "devname"));
}
/***********************************************************/
/***********************************************************/
/* ram save/restore */
-static int ram_get_page(QEMUFile *f, uint8_t *buf, int len)
-{
- int v;
-
- v = qemu_get_byte(f);
- switch(v) {
- case 0:
- if (qemu_get_buffer(f, buf, len) != len)
- return -EIO;
- break;
- case 1:
- v = qemu_get_byte(f);
- memset(buf, v, len);
- break;
- default:
- return -EINVAL;
- }
-
- if (qemu_file_has_error(f))
- return -EIO;
-
- return 0;
-}
-
-static int ram_load_v1(QEMUFile *f, void *opaque)
-{
- int ret;
- ram_addr_t i;
-
- if (qemu_get_be32(f) != last_ram_offset)
- return -EINVAL;
- for(i = 0; i < last_ram_offset; i+= TARGET_PAGE_SIZE) {
- ret = ram_get_page(f, qemu_get_ram_ptr(i), TARGET_PAGE_SIZE);
- if (ret)
- return ret;
- }
- return 0;
-}
-
-#define BDRV_HASH_BLOCK_SIZE 1024
-#define IOBUF_SIZE 4096
-#define RAM_CBLOCK_MAGIC 0xfabe
-
-typedef struct RamDecompressState {
- z_stream zstream;
- QEMUFile *f;
- uint8_t buf[IOBUF_SIZE];
-} RamDecompressState;
-
-static int ram_decompress_open(RamDecompressState *s, QEMUFile *f)
-{
- int ret;
- memset(s, 0, sizeof(*s));
- s->f = f;
- ret = inflateInit(&s->zstream);
- if (ret != Z_OK)
- return -1;
- return 0;
-}
-
-static int ram_decompress_buf(RamDecompressState *s, uint8_t *buf, int len)
-{
- int ret, clen;
-
- s->zstream.avail_out = len;
- s->zstream.next_out = buf;
- while (s->zstream.avail_out > 0) {
- if (s->zstream.avail_in == 0) {
- if (qemu_get_be16(s->f) != RAM_CBLOCK_MAGIC)
- return -1;
- clen = qemu_get_be16(s->f);
- if (clen > IOBUF_SIZE)
- return -1;
- qemu_get_buffer(s->f, s->buf, clen);
- s->zstream.avail_in = clen;
- s->zstream.next_in = s->buf;
- }
- ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
- if (ret != Z_OK && ret != Z_STREAM_END) {
- return -1;
- }
- }
- return 0;
-}
-
-static void ram_decompress_close(RamDecompressState *s)
-{
- inflateEnd(&s->zstream);
-}
-
-#define RAM_SAVE_FLAG_FULL 0x01
+#define RAM_SAVE_FLAG_FULL 0x01 /* Obsolete, not used anymore */
#define RAM_SAVE_FLAG_COMPRESS 0x02
#define RAM_SAVE_FLAG_MEM_SIZE 0x04
#define RAM_SAVE_FLAG_PAGE 0x08
return (stage == 2) && (expected_time <= migrate_max_downtime());
}
-static int ram_load_dead(QEMUFile *f, void *opaque)
-{
- RamDecompressState s1, *s = &s1;
- uint8_t buf[10];
- ram_addr_t i;
-
- if (ram_decompress_open(s, f) < 0)
- return -EINVAL;
- for(i = 0; i < last_ram_offset; i+= BDRV_HASH_BLOCK_SIZE) {
- if (ram_decompress_buf(s, buf, 1) < 0) {
- fprintf(stderr, "Error while reading ram block header\n");
- goto error;
- }
- if (buf[0] == 0) {
- if (ram_decompress_buf(s, qemu_get_ram_ptr(i),
- BDRV_HASH_BLOCK_SIZE) < 0) {
- fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
- goto error;
- }
- } else {
- error:
- printf("Error block header\n");
- return -EINVAL;
- }
- }
- ram_decompress_close(s);
-
- return 0;
-}
-
static int ram_load(QEMUFile *f, void *opaque, int version_id)
{
ram_addr_t addr;
int flags;
- if (version_id == 1)
- return ram_load_v1(f, opaque);
-
- if (version_id == 2) {
- if (qemu_get_be32(f) != last_ram_offset)
- return -EINVAL;
- return ram_load_dead(f, opaque);
- }
-
if (version_id != 3)
return -EINVAL;
return -EINVAL;
}
- if (flags & RAM_SAVE_FLAG_FULL) {
- if (ram_load_dead(f, opaque) < 0)
- return -EINVAL;
- }
-
if (flags & RAM_SAVE_FLAG_COMPRESS) {
uint8_t ch = qemu_get_byte(f);
memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
block_io_signals();
qemu_thread_self(env->thread);
+ if (kvm_enabled())
+ kvm_init_vcpu(env);
/* signal CPU creation */
qemu_mutex_lock(&qemu_global_mutex);
static void kvm_start_vcpu(CPUState *env)
{
- kvm_init_vcpu(env);
env->thread = qemu_mallocz(sizeof(QemuThread));
env->halt_cond = qemu_mallocz(sizeof(QemuCond));
qemu_cond_init(env->halt_cond);
l = !e ? strlen (p) : (size_t) (e - p);
for (c = soundhw; c->name; ++c) {
- if (!strncmp (c->name, p, l)) {
+ if (!strncmp (c->name, p, l) && !c->name[l]) {
c->enabled = 1;
break;
}
char *dir;
char *p = NULL;
char *res;
-#ifdef PATH_MAX
char buf[PATH_MAX];
-#endif
size_t max_len;
#if defined(__linux__)
/* If we don't have any way of figuring out the actual executable
location then try argv[0]. */
if (!p) {
-#ifdef PATH_MAX
- p = buf;
-#endif
- p = realpath(argv0, p);
+ p = realpath(argv0, buf);
if (!p) {
return NULL;
}
res = NULL;
}
}
-#ifndef PATH_MAX
- free(p);
-#endif
+
return res;
}
#undef SHARE_SUFFIX
/* If name contains path separators then try it as a straight path. */
if ((strchr(name, '/') || strchr(name, '\\'))
&& access(name, R_OK) == 0) {
- return strdup(name);
+ return qemu_strdup(name);
}
switch (type) {
case QEMU_FILE_TYPE_BIOS:
QemuOpts *hda_opts = NULL, *opts;
int optind;
const char *r, *optarg;
- CharDriverState *monitor_hd = NULL;
- const char *monitor_device;
+ CharDriverState *monitor_hds[MAX_MONITOR_DEVICES];
+ const char *monitor_devices[MAX_MONITOR_DEVICES];
+ int monitor_device_index;
const char *serial_devices[MAX_SERIAL_PORTS];
int serial_device_index;
const char *parallel_devices[MAX_PARALLEL_PORTS];
kernel_cmdline = "";
cyls = heads = secs = 0;
translation = BIOS_ATA_TRANSLATION_AUTO;
- monitor_device = "vc:80Cx24C";
serial_devices[0] = "vc:80Cx24C";
for(i = 1; i < MAX_SERIAL_PORTS; i++)
virtio_consoles[i] = NULL;
virtio_console_index = 0;
+ monitor_devices[0] = "vc:80Cx24C";
+ for (i = 1; i < MAX_MONITOR_DEVICES; i++) {
+ monitor_devices[i] = NULL;
+ }
+ monitor_device_index = 0;
+
for (i = 0; i < MAX_NODES; i++) {
node_mem[i] = 0;
node_cpumask[i] = 0;
break;
}
case QEMU_OPTION_monitor:
- monitor_device = optarg;
+ if (monitor_device_index >= MAX_MONITOR_DEVICES) {
+ fprintf(stderr, "qemu: too many monitor devices\n");
+ exit(1);
+ }
+ monitor_devices[monitor_device_index] = optarg;
+ monitor_device_index++;
+ break;
+ case QEMU_OPTION_chardev:
+ opts = qemu_opts_parse(&qemu_chardev_opts, optarg, "backend");
+ if (!opts) {
+ fprintf(stderr, "parse error: %s\n", optarg);
+ exit(1);
+ }
+ if (NULL == qemu_chr_open_opts(opts, NULL)) {
+ exit(1);
+ }
break;
case QEMU_OPTION_serial:
if (serial_device_index >= MAX_SERIAL_PORTS) {
}
}
+ if (kvm_enabled()) {
+ int ret;
+
+ ret = kvm_init(smp_cpus);
+ if (ret < 0) {
+ fprintf(stderr, "failed to initialize KVM\n");
+ exit(1);
+ }
+ }
+
/* If no data_dir is specified then try to find it relative to the
executable path. */
if (!data_dir) {
serial_devices[0] = "stdio";
if (parallel_device_index == 0)
parallel_devices[0] = "null";
- if (strncmp(monitor_device, "vc", 2) == 0)
- monitor_device = "stdio";
+ if (strncmp(monitor_devices[0], "vc", 2) == 0) {
+ monitor_devices[0] = "stdio";
+ }
}
#ifndef _WIN32
if (qemu_opts_foreach(&qemu_drive_opts, drive_init_func, machine, 1) != 0)
exit(1);
- register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
+ vmstate_register(0, &vmstate_timers ,&timers_state);
register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
/* Maintain compatibility with multiple stdio monitors */
- if (!strcmp(monitor_device,"stdio")) {
+ if (!strcmp(monitor_devices[0],"stdio")) {
for (i = 0; i < MAX_SERIAL_PORTS; i++) {
const char *devname = serial_devices[i];
if (devname && !strcmp(devname,"mon:stdio")) {
- monitor_device = NULL;
+ monitor_devices[0] = NULL;
break;
} else if (devname && !strcmp(devname,"stdio")) {
- monitor_device = NULL;
+ monitor_devices[0] = NULL;
serial_devices[i] = "mon:stdio";
break;
}
}
}
- if (kvm_enabled()) {
- int ret;
-
- ret = kvm_init(smp_cpus);
- if (ret < 0) {
- fprintf(stderr, "failed to initialize KVM\n");
- exit(1);
- }
- }
-
- if (monitor_device) {
- monitor_hd = qemu_chr_open("monitor", monitor_device, NULL);
- if (!monitor_hd) {
- fprintf(stderr, "qemu: could not open monitor device '%s'\n", monitor_device);
- exit(1);
+ for (i = 0; i < MAX_MONITOR_DEVICES; i++) {
+ const char *devname = monitor_devices[i];
+ if (devname && strcmp(devname, "none")) {
+ char label[32];
+ if (i == 0) {
+ snprintf(label, sizeof(label), "monitor");
+ } else {
+ snprintf(label, sizeof(label), "monitor%d", i);
+ }
+ monitor_hds[i] = qemu_chr_open(label, devname, NULL);
+ if (!monitor_hds[i]) {
+ fprintf(stderr, "qemu: could not open monitor device '%s'\n",
+ devname);
+ exit(1);
+ }
}
}
text_consoles_set_display(display_state);
qemu_chr_initial_reset();
- if (monitor_device && monitor_hd)
- monitor_init(monitor_hd, MONITOR_USE_READLINE | MONITOR_IS_DEFAULT);
+ for (i = 0; i < MAX_MONITOR_DEVICES; i++) {
+ if (monitor_devices[i] && monitor_hds[i]) {
+ monitor_init(monitor_hds[i],
+ MONITOR_USE_READLINE |
+ ((i == 0) ? MONITOR_IS_DEFAULT : 0));
+ }
+ }
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
const char *devname = serial_devices[i];