#include "hw/isa.h"
#include "hw/baum.h"
#include "hw/bt.h"
+#include "hw/watchdog.h"
#include "hw/smbios.h"
#include "hw/xen.h"
#include "bt-host.h"
to store the VM snapshots */
DriveInfo drives_table[MAX_DRIVES+1];
int nb_drives;
-static int vga_ram_size;
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
static DisplayState *display_state;
-int nographic;
-static int curses;
-static int sdl;
+DisplayType display_type = DT_DEFAULT;
const char* keyboard_layout = NULL;
int64_t ticks_per_sec;
ram_addr_t ram_size;
#ifndef _WIN32
int daemonize = 0;
#endif
+WatchdogTimerModel *watchdog = NULL;
+int watchdog_action = WDT_RESET;
const char *option_rom[MAX_OPTION_ROMS];
int nb_option_roms;
int semihosting_enabled = 0;
static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)
{
- return t->flags & ALARM_FLAG_DYNTICKS;
+ return t && (t->flags & ALARM_FLAG_DYNTICKS);
}
static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
qemu_get_clock(rt_clock))) {
qemu_event_increment();
- alarm_timer->flags |= ALARM_FLAG_EXPIRED;
+ if (alarm_timer) alarm_timer->flags |= ALARM_FLAG_EXPIRED;
#ifndef CONFIG_IOTHREAD
if (next_cpu) {
sigaction(SIGALRM, &act, NULL);
+ /*
+ * Initialize ev struct to 0 to avoid valgrind complaining
+ * about uninitialized data in timer_create call
+ */
+ memset(&ev, 0, sizeof(ev));
ev.sigev_value.sival_int = 0;
ev.sigev_notify = SIGEV_SIGNAL;
ev.sigev_signo = SIGALRM;
return 0;
}
-int check_params(char *buf, int buf_size,
- const char * const *params, const char *str)
+int check_params(const char * const *params, const char *str)
{
+ int name_buf_size = 1;
const char *p;
- int i;
+ char *name_buf;
+ int i, len;
+ int ret = 0;
+
+ for (i = 0; params[i] != NULL; i++) {
+ len = strlen(params[i]) + 1;
+ if (len > name_buf_size) {
+ name_buf_size = len;
+ }
+ }
+ name_buf = qemu_malloc(name_buf_size);
p = str;
while (*p != '\0') {
- p = get_opt_name(buf, buf_size, p, '=');
- if (*p != '=')
- return -1;
+ p = get_opt_name(name_buf, name_buf_size, p, '=');
+ if (*p != '=') {
+ ret = -1;
+ break;
+ }
p++;
for(i = 0; params[i] != NULL; i++)
- if (!strcmp(params[i], buf))
+ if (!strcmp(params[i], name_buf))
break;
- if (params[i] == NULL)
- return -1;
+ if (params[i] == NULL) {
+ ret = -1;
+ break;
+ }
p = get_opt_value(NULL, 0, p);
if (*p != ',')
break;
p++;
}
- return 0;
+
+ qemu_free(name_buf);
+ return ret;
}
/***********************************************************/
"cache", "format", "serial", "werror",
NULL };
- if (check_params(buf, sizeof(buf), params, str) < 0) {
+ if (check_params(params, str) < 0) {
fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
buf, str);
return -1;
drives_table[drives_table_idx].unit = unit_id;
drives_table[drives_table_idx].onerror = onerror;
drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;
- strncpy(drives_table[nb_drives].serial, serial, sizeof(serial));
+ strncpy(drives_table[drives_table_idx].serial, serial, sizeof(serial));
nb_drives++;
switch(type) {
case IF_MTD:
case IF_VIRTIO:
break;
+ case IF_COUNT:
+ abort();
}
if (!file[0])
return -2;
/* PCMCIA/Cardbus */
static struct pcmcia_socket_entry_s {
- struct pcmcia_socket_s *socket;
+ PCMCIASocket *socket;
struct pcmcia_socket_entry_s *next;
} *pcmcia_sockets = 0;
-void pcmcia_socket_register(struct pcmcia_socket_s *socket)
+void pcmcia_socket_register(PCMCIASocket *socket)
{
struct pcmcia_socket_entry_s *entry;
pcmcia_sockets = entry;
}
-void pcmcia_socket_unregister(struct pcmcia_socket_s *socket)
+void pcmcia_socket_unregister(PCMCIASocket *socket)
{
struct pcmcia_socket_entry_s *entry, **ptr;
}
static ram_addr_t ram_save_threshold = 10;
+static uint64_t bytes_transferred = 0;
static ram_addr_t ram_save_remaining(void)
{
return count;
}
+uint64_t ram_bytes_remaining(void)
+{
+ return ram_save_remaining() * TARGET_PAGE_SIZE;
+}
+
+uint64_t ram_bytes_transferred(void)
+{
+ return bytes_transferred;
+}
+
+uint64_t ram_bytes_total(void)
+{
+ return last_ram_offset;
+}
+
static int ram_save_live(QEMUFile *f, int stage, void *opaque)
{
ram_addr_t addr;
int ret;
ret = ram_save_block(f);
+ bytes_transferred += ret * TARGET_PAGE_SIZE;
if (ret == 0) /* no more blocks */
break;
}
if (stage == 3) {
/* flush all remaining blocks regardless of rate limiting */
- while (ram_save_block(f) != 0);
+ while (ram_save_block(f) != 0) {
+ bytes_transferred += TARGET_PAGE_SIZE;
+ }
cpu_physical_memory_set_dirty_tracking(0);
}
return NULL;
}
+static QEMUMachine *find_default_machine(void)
+{
+ QEMUMachine *m;
+
+ for(m = first_machine; m != NULL; m = m->next) {
+ if (m->is_default) {
+ return m;
+ }
+ }
+ return NULL;
+}
+
/***********************************************************/
/* main execution loop */
(void *)(unsigned long)fds[0]);
io_thread_fd = fds[1];
+ return 0;
+
fail:
close(fds[0]);
close(fds[1]);
int main(int argc, char **argv, char **envp)
{
-#ifdef CONFIG_GDBSTUB
const char *gdbstub_dev = NULL;
-#endif
uint32_t boot_devices_bitmap = 0;
int i;
int snapshot, linux_boot, net_boot;
const char *run_as = NULL;
#endif
CPUState *env;
+ int show_vnc_port = 0;
qemu_cache_utils_init(envp);
}
#endif
- register_machines();
- machine = first_machine;
+ module_call_init(MODULE_INIT_MACHINE);
+ machine = find_default_machine();
cpu_model = NULL;
initrd_filename = NULL;
ram_size = 0;
- vga_ram_size = VGA_RAM_SIZE;
snapshot = 0;
- nographic = 0;
- curses = 0;
kernel_filename = NULL;
kernel_cmdline = "";
cyls = heads = secs = 0;
tb_size = 0;
autostart= 1;
+ register_watchdogs();
+
optind = 1;
for(;;) {
if (optind >= argc)
for(m = first_machine; m != NULL; m = m->next) {
printf("%-10s %s%s\n",
m->name, m->desc,
- m == first_machine ? " (default)" : "");
+ m->is_default ? " (default)" : "");
}
exit(*optarg != '?');
}
numa_add(optarg);
break;
case QEMU_OPTION_nographic:
- nographic = 1;
+ display_type = DT_NOGRAPHIC;
break;
#ifdef CONFIG_CURSES
case QEMU_OPTION_curses:
- curses = 1;
+ display_type = DT_CURSES;
break;
#endif
case QEMU_OPTION_portrait:
cpu_set_log(mask);
}
break;
-#ifdef CONFIG_GDBSTUB
case QEMU_OPTION_s:
gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
break;
case QEMU_OPTION_gdb:
gdbstub_dev = optarg;
break;
-#endif
case QEMU_OPTION_L:
bios_dir = optarg;
break;
serial_devices[serial_device_index] = optarg;
serial_device_index++;
break;
+ case QEMU_OPTION_watchdog:
+ i = select_watchdog(optarg);
+ if (i > 0)
+ exit (i == 1 ? 1 : 0);
+ break;
+ case QEMU_OPTION_watchdog_action:
+ if (select_watchdog_action(optarg) == -1) {
+ fprintf(stderr, "Unknown -watchdog-action parameter\n");
+ exit(1);
+ }
+ break;
case QEMU_OPTION_virtiocon:
if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
fprintf(stderr, "qemu: too many virtio consoles\n");
no_quit = 1;
break;
case QEMU_OPTION_sdl:
- sdl = 1;
+ display_type = DT_SDL;
break;
#endif
case QEMU_OPTION_pidfile:
}
break;
case QEMU_OPTION_vnc:
+ display_type = DT_VNC;
vnc_display = optarg;
break;
#ifdef TARGET_I386
exit(1);
}
- if (nographic) {
+ if (display_type == DT_NOGRAPHIC) {
if (serial_device_index == 0)
serial_devices[0] = "stdio";
if (parallel_device_index == 0)
/* FIXME: This is a nasty hack because kqemu can't cope with dynamic
guest ram allocation. It needs to go away. */
if (kqemu_allowed) {
- kqemu_phys_ram_size = ram_size + VGA_RAM_SIZE + 4 * 1024 * 1024;
+ kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
if (!kqemu_phys_ram_base) {
fprintf(stderr, "Could not allocate physical memory\n");
}
}
- machine->init(ram_size, vga_ram_size, boot_devices,
+ module_call_init(MODULE_INIT_DEVICE);
+
+ machine->init(ram_size, boot_devices,
kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
dumb_display_init();
/* just use the first displaystate for the moment */
ds = display_state;
- /* terminal init */
- if (nographic) {
- if (curses) {
- fprintf(stderr, "fatal: -nographic can't be used with -curses\n");
- exit(1);
- }
- } else {
+
+ if (display_type == DT_DEFAULT) {
+#if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
+ display_type = DT_SDL;
+#else
+ display_type = DT_VNC;
+ vnc_display = "localhost:0,to=99";
+ show_vnc_port = 1;
+#endif
+ }
+
+
+ switch (display_type) {
+ case DT_NOGRAPHIC:
+ break;
#if defined(CONFIG_CURSES)
- if (curses) {
- /* At the moment curses cannot be used with other displays */
- curses_display_init(ds, full_screen);
- } else
+ case DT_CURSES:
+ curses_display_init(ds, full_screen);
+ break;
#endif
- {
- if (vnc_display != NULL) {
- vnc_display_init(ds);
- if (vnc_display_open(ds, vnc_display) < 0)
- exit(1);
- }
#if defined(CONFIG_SDL)
- if (sdl || !vnc_display)
- sdl_display_init(ds, full_screen, no_frame);
+ case DT_SDL:
+ sdl_display_init(ds, full_screen, no_frame);
+ break;
#elif defined(CONFIG_COCOA)
- if (sdl || !vnc_display)
- cocoa_display_init(ds, full_screen);
+ case DT_SDL:
+ cocoa_display_init(ds, full_screen);
+ break;
#endif
- }
+ case DT_VNC:
+ vnc_display_init(ds);
+ if (vnc_display_open(ds, vnc_display) < 0)
+ exit(1);
+
+ if (show_vnc_port) {
+ printf("VNC server running on `%s'\n", vnc_display_local_addr(ds));
+ }
+ break;
+ default:
+ break;
}
dpy_resize(ds);
dcl = dcl->next;
}
- if (nographic || (vnc_display && !sdl)) {
+ if (display_type == DT_NOGRAPHIC || display_type == DT_VNC) {
nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
}
}
}
-#ifdef CONFIG_GDBSTUB
if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n",
gdbstub_dev);
exit(1);
}
-#endif
if (loadvm)
do_loadvm(cur_mon, loadvm);