#include "gdbstub.h"
#include "qemu-timer.h"
#include "qemu-char.h"
+#include "cache-utils.h"
#include "block.h"
#include "audio/audio.h"
#include "migration.h"
#include "kvm.h"
+#include "balloon.h"
#include <unistd.h>
#include <fcntl.h>
#include "exec-all.h"
-#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
-#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
-#ifdef __sun__
-#define SMBD_COMMAND "/usr/sfw/sbin/smbd"
-#else
-#define SMBD_COMMAND "/usr/sbin/smbd"
-#endif
-
//#define DEBUG_UNUSED_IOPORT
//#define DEBUG_IOPORT
//#define DEBUG_NET
//#define DEBUG_SLIRP
+
+#ifdef DEBUG_IOPORT
+# define LOG_IOPORT(...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__)
+#else
+# define LOG_IOPORT(...) do { } while (0)
+#endif
+
#ifdef TARGET_PPC
#define DEFAULT_RAM_SIZE 144
#else
int nb_drives;
static int vga_ram_size;
enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
-DisplayState display_state;
+static DisplayState *display_state;
int nographic;
static int curses;
+static int sdl;
const char* keyboard_layout = NULL;
int64_t ticks_per_sec;
ram_addr_t ram_size;
static int rtc_utc = 1;
static int rtc_date_offset = -1; /* -1 means no change */
int cirrus_vga_enabled = 1;
+int std_vga_enabled = 0;
int vmsvga_enabled = 0;
#ifdef TARGET_SPARC
int graphic_width = 1024;
int no_quit = 0;
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
+CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
#ifdef TARGET_I386
int win2k_install_hack = 0;
+int rtc_td_hack = 0;
#endif
int usb_enabled = 0;
int smp_cpus = 1;
const char *vnc_display;
int acpi_enabled = 1;
+int no_hpet = 0;
int fd_bootchk = 1;
int no_reboot = 0;
int no_shutdown = 0;
#endif
const char *qemu_name;
int alt_grab = 0;
-#ifdef TARGET_SPARC
+#if defined(TARGET_SPARC) || defined(TARGET_PPC)
unsigned int nb_prom_envs = 0;
const char *prom_envs[MAX_PROM_ENVS];
#endif
static int64_t qemu_icount_bias;
static QEMUTimer *icount_rt_timer;
static QEMUTimer *icount_vm_timer;
+static QEMUTimer *nographic_timer;
uint8_t qemu_uuid[16];
void cpu_outb(CPUState *env, int addr, int val)
{
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "outb: %04x %02x\n", addr, val);
-#endif
+ LOG_IOPORT("outb: %04x %02x\n", addr, val);
ioport_write(0, addr, val);
#ifdef USE_KQEMU
if (env)
void cpu_outw(CPUState *env, int addr, int val)
{
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "outw: %04x %04x\n", addr, val);
-#endif
+ LOG_IOPORT("outw: %04x %04x\n", addr, val);
ioport_write(1, addr, val);
#ifdef USE_KQEMU
if (env)
void cpu_outl(CPUState *env, int addr, int val)
{
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "outl: %04x %08x\n", addr, val);
-#endif
+ LOG_IOPORT("outl: %04x %08x\n", addr, val);
ioport_write(2, addr, val);
#ifdef USE_KQEMU
if (env)
{
int val;
val = ioport_read(0, addr);
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "inb : %04x %02x\n", addr, val);
-#endif
+ LOG_IOPORT("inb : %04x %02x\n", addr, val);
#ifdef USE_KQEMU
if (env)
env->last_io_time = cpu_get_time_fast();
{
int val;
val = ioport_read(1, addr);
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "inw : %04x %04x\n", addr, val);
-#endif
+ LOG_IOPORT("inw : %04x %04x\n", addr, val);
#ifdef USE_KQEMU
if (env)
env->last_io_time = cpu_get_time_fast();
{
int val;
val = ioport_read(2, addr);
-#ifdef DEBUG_IOPORT
- if (loglevel & CPU_LOG_IOPORT)
- fprintf(logfile, "inl : %04x %08x\n", addr, val);
-#endif
+ LOG_IOPORT("inl : %04x %08x\n", addr, val);
#ifdef USE_KQEMU
if (env)
env->last_io_time = cpu_get_time_fast();
va_end(ap);
abort();
}
+
+/***************/
+/* ballooning */
+
+static QEMUBalloonEvent *qemu_balloon_event;
+void *qemu_balloon_event_opaque;
+
+void qemu_add_balloon_handler(QEMUBalloonEvent *func, void *opaque)
+{
+ qemu_balloon_event = func;
+ qemu_balloon_event_opaque = opaque;
+}
+
+void qemu_balloon(ram_addr_t target)
+{
+ if (qemu_balloon_event)
+ qemu_balloon_event(qemu_balloon_event_opaque, target);
+}
+
+ram_addr_t qemu_balloon_status(void)
+{
+ if (qemu_balloon_event)
+ return qemu_balloon_event(qemu_balloon_event_opaque, 0);
+ return 0;
+}
/***********************************************************/
/* keyboard/mouse */
{
int i;
int cur = 0;
- int count = (sizeof(alarm_timers) / sizeof(*alarm_timers)) - 1;
+ int count = ARRAY_SIZE(alarm_timers) - 1;
char *arg;
char *name;
struct qemu_alarm_timer tmp;
} while ((len == -1 && errno == EINTR) || len > 0);
#endif
- /* vm time timers */
- if (vm_running && likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
- qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
- qemu_get_clock(vm_clock));
-
- /* real time timers */
- qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
- qemu_get_clock(rt_clock));
-
if (t->flags & ALARM_FLAG_EXPIRED) {
alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;
qemu_rearm_alarm_timer(alarm_timer);
return max_bus;
}
+const char *drive_get_serial(BlockDriverState *bdrv)
+{
+ int index;
+
+ for (index = 0; index < nb_drives; index++)
+ if (drives_table[index].bdrv == bdrv)
+ return drives_table[index].serial;
+
+ return "\0";
+}
+
+BlockInterfaceErrorAction drive_get_onerror(BlockDriverState *bdrv)
+{
+ int index;
+
+ for (index = 0; index < nb_drives; index++)
+ if (drives_table[index].bdrv == bdrv)
+ return drives_table[index].onerror;
+
+ return BLOCK_ERR_REPORT;
+}
+
static void bdrv_format_print(void *opaque, const char *name)
{
fprintf(stderr, " %s", name);
char buf[128];
char file[1024];
char devname[128];
+ char serial[21];
const char *mediastr = "";
BlockInterfaceType type;
enum { MEDIA_DISK, MEDIA_CDROM } media;
int max_devs;
int index;
int cache;
- int bdrv_flags;
+ int bdrv_flags, onerror;
char *str = arg->opt;
static const char * const params[] = { "bus", "unit", "if", "index",
"cyls", "heads", "secs", "trans",
"media", "snapshot", "file",
- "cache", "format", NULL };
+ "cache", "format", "serial", "werror",
+ NULL };
if (check_params(buf, sizeof(buf), params, str) < 0) {
fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",
unit_id = -1;
translation = BIOS_ATA_TRANSLATION_AUTO;
index = -1;
- cache = 1;
+ cache = 3;
if (machine->use_scsi) {
type = IF_SCSI;
} else if (!strcmp(buf, "sd")) {
type = IF_SD;
max_devs = 0;
- } else {
+ } else if (!strcmp(buf, "virtio")) {
+ type = IF_VIRTIO;
+ max_devs = 0;
+ } else {
fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
return -1;
}
else
pstrcpy(file, sizeof(file), arg->file);
+ if (!get_param_value(serial, sizeof(serial), "serial", str))
+ memset(serial, 0, sizeof(serial));
+
+ onerror = BLOCK_ERR_REPORT;
+ if (get_param_value(buf, sizeof(serial), "werror", str)) {
+ if (type != IF_IDE) {
+ fprintf(stderr, "werror is supported only by IDE\n");
+ return -1;
+ }
+ if (!strcmp(buf, "ignore"))
+ onerror = BLOCK_ERR_IGNORE;
+ else if (!strcmp(buf, "enospc"))
+ onerror = BLOCK_ERR_STOP_ENOSPC;
+ else if (!strcmp(buf, "stop"))
+ onerror = BLOCK_ERR_STOP_ANY;
+ else if (!strcmp(buf, "report"))
+ onerror = BLOCK_ERR_REPORT;
+ else {
+ fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);
+ return -1;
+ }
+ }
+
/* compute bus and unit according index */
if (index != -1) {
drives_table[nb_drives].type = type;
drives_table[nb_drives].bus = bus_id;
drives_table[nb_drives].unit = unit_id;
+ drives_table[nb_drives].onerror = onerror;
+ strncpy(drives_table[nb_drives].serial, serial, sizeof(serial));
nb_drives++;
switch(type) {
break;
case IF_PFLASH:
case IF_MTD:
+ case IF_VIRTIO:
break;
}
if (!file[0])
bdrv_flags |= BDRV_O_NOCACHE;
else if (cache == 2) /* write-back */
bdrv_flags |= BDRV_O_CACHE_WB;
+ else if (cache == 3) /* not specified */
+ bdrv_flags |= BDRV_O_CACHE_DEF;
if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) {
fprintf(stderr, "qemu: could not open disk image %s\n",
file);
}
/***********************************************************/
-/* dumb display */
+/* register display */
-static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
+void register_displaystate(DisplayState *ds)
{
+ DisplayState **s;
+ s = &display_state;
+ while (*s != NULL)
+ s = &(*s)->next;
+ ds->next = NULL;
+ *s = ds;
}
-static void dumb_resize(DisplayState *ds, int w, int h)
+DisplayState *get_displaystate(void)
{
+ return display_state;
}
-static void dumb_display_init(DisplayState *ds)
+/* dumb display */
+
+static void dumb_display_init(void)
{
- ds->data = NULL;
- ds->linesize = 0;
- ds->depth = 0;
- ds->dpy_update = dumb_update;
- ds->dpy_resize = dumb_resize;
- ds->dpy_refresh = NULL;
- ds->gui_timer_interval = 0;
- ds->idle = 1;
+ DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
+ if (ds == NULL) {
+ fprintf(stderr, "dumb_display_init: DisplayState allocation failed\n");
+ exit(1);
+ }
+ ds->surface = qemu_create_displaysurface(640, 480, 32, 640 * 4);
+ register_displaystate(ds);
}
/***********************************************************/
static void gui_update(void *opaque)
{
+ uint64_t interval = GUI_REFRESH_INTERVAL;
DisplayState *ds = opaque;
- ds->dpy_refresh(ds);
- qemu_mod_timer(ds->gui_timer,
- (ds->gui_timer_interval ?
- ds->gui_timer_interval :
- GUI_REFRESH_INTERVAL)
- + qemu_get_clock(rt_clock));
+ DisplayChangeListener *dcl = ds->listeners;
+
+ dpy_refresh(ds);
+
+ while (dcl != NULL) {
+ if (dcl->gui_timer_interval &&
+ dcl->gui_timer_interval < interval)
+ interval = dcl->gui_timer_interval;
+ dcl = dcl->next;
+ }
+ qemu_mod_timer(ds->gui_timer, interval + qemu_get_clock(rt_clock));
+}
+
+static void nographic_update(void *opaque)
+{
+ uint64_t interval = GUI_REFRESH_INTERVAL;
+
+ qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock));
}
struct vm_change_state_entry {
}
#ifdef _WIN32
-void host_main_loop_wait(int *timeout)
+static void host_main_loop_wait(int *timeout)
{
int ret, ret2, i;
PollingEntry *pe;
*timeout = 0;
}
#else
-void host_main_loop_wait(int *timeout)
+static void host_main_loop_wait(int *timeout)
{
}
#endif
}
#endif
+ /* vm time timers */
+ if (vm_running && likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
+ qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
+ qemu_get_clock(vm_clock));
+
+ /* real time timers */
+ qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
+ qemu_get_clock(rt_clock));
+
/* Check bottom-halves last in case any of the earlier events triggered
them. */
qemu_bh_poll();
ret = EXCP_INTERRUPT;
}
if (unlikely(ret == EXCP_DEBUG)) {
+ gdb_set_stop_cpu(cur_cpu);
vm_stop(EXCP_DEBUG);
}
/* If all cpus are halted then wait until the next IRQ */
"-cdrom file use 'file' as IDE cdrom image (cdrom is ide1 master)\n"
"-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"
" [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"
- " [,cache=writethrough|writeback|none][,format=f]\n"
+ " [,cache=writethrough|writeback|none][,format=f][,serial=s]\n"
" use 'file' as a drive image\n"
"-mtdblock file use 'file' as on-board Flash memory image\n"
"-sd file use 'file' as SecureDigital card image\n"
"-no-frame open SDL window without a frame and window decorations\n"
"-alt-grab use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"
"-no-quit disable SDL window close capability\n"
+ "-sdl enable SDL\n"
#endif
#ifdef TARGET_I386
"-no-fd-bootchk disable boot signature checking for floppy disks\n"
" use -soundhw ? to get the list of supported cards\n"
" use -soundhw all to enable all of them\n"
#endif
- "-vga [std|cirrus|vmware]\n"
+ "-vga [std|cirrus|vmware|none]\n"
" select video card type\n"
"-localtime set the real time clock to local time [default=utc]\n"
"-full-screen start in full screen\n"
#ifdef TARGET_I386
"-win2k-hack use it when installing Windows 2000 to avoid a disk full bug\n"
+ "-rtc-td-hack use it to fix time drift in Windows ACPI HAL\n"
#endif
"-usb enable the USB driver (will be the default soon)\n"
"-usbdevice name add the host or guest USB device 'name'\n"
"-uuid %%08x-%%04x-%%04x-%%04x-%%012x specify machine UUID\n"
"\n"
"Network options:\n"
- "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
+ "-net nic[,vlan=n][,macaddr=addr][,model=type][,name=str]\n"
" create a new Network Interface Card and connect it to VLAN 'n'\n"
#ifdef CONFIG_SLIRP
- "-net user[,vlan=n][,hostname=host]\n"
+ "-net user[,vlan=n][,name=str][,hostname=host]\n"
" connect the user mode network stack to VLAN 'n' and send\n"
" hostname 'host' to DHCP clients\n"
#endif
#ifdef _WIN32
- "-net tap[,vlan=n],ifname=name\n"
+ "-net tap[,vlan=n][,name=str],ifname=name\n"
" connect the host TAP network interface to VLAN 'n'\n"
#else
- "-net tap[,vlan=n][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n"
+ "-net tap[,vlan=n][,name=str][,fd=h][,ifname=name][,script=file][,downscript=dfile]\n"
" connect the host TAP network interface to VLAN 'n' and use the\n"
" network scripts 'file' (default=%s)\n"
" and 'dfile' (default=%s);\n"
" use '[down]script=no' to disable script execution;\n"
" use 'fd=h' to connect to an already opened TAP interface\n"
#endif
- "-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n"
+ "-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
" connect the vlan 'n' to another VLAN using a socket connection\n"
- "-net socket[,vlan=n][,fd=h][,mcast=maddr:port]\n"
+ "-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port]\n"
" connect the vlan 'n' to multicast maddr and port\n"
#ifdef CONFIG_VDE
- "-net vde[,vlan=n][,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n"
+ "-net vde[,vlan=n][,name=str][,sock=socketpath][,port=n][,group=groupname][,mode=octalmode]\n"
" connect the vlan 'n' to port 'n' of a vde switch running\n"
" on host and listening for incoming connections on 'socketpath'.\n"
" Use group 'groupname' and mode 'octalmode' to change default\n"
#endif
#ifdef TARGET_I386
"-no-acpi disable ACPI\n"
+ "-no-hpet disable HPET\n"
#endif
#ifdef CONFIG_CURSES
"-curses use a curses/ncurses interface instead of SDL\n"
QEMU_OPTION_echr,
QEMU_OPTION_monitor,
QEMU_OPTION_serial,
+ QEMU_OPTION_virtiocon,
QEMU_OPTION_parallel,
QEMU_OPTION_loadvm,
QEMU_OPTION_full_screen,
QEMU_OPTION_no_frame,
QEMU_OPTION_alt_grab,
QEMU_OPTION_no_quit,
+ QEMU_OPTION_sdl,
QEMU_OPTION_pidfile,
QEMU_OPTION_no_kqemu,
QEMU_OPTION_kernel_kqemu,
QEMU_OPTION_enable_kvm,
QEMU_OPTION_win2k_hack,
+ QEMU_OPTION_rtc_td_hack,
QEMU_OPTION_usb,
QEMU_OPTION_usbdevice,
QEMU_OPTION_smp,
QEMU_OPTION_vnc,
QEMU_OPTION_no_acpi,
+ QEMU_OPTION_no_hpet,
QEMU_OPTION_curses,
QEMU_OPTION_no_reboot,
QEMU_OPTION_no_shutdown,
{ "echr", HAS_ARG, QEMU_OPTION_echr },
{ "monitor", HAS_ARG, QEMU_OPTION_monitor },
{ "serial", HAS_ARG, QEMU_OPTION_serial },
+ { "virtioconsole", HAS_ARG, QEMU_OPTION_virtiocon },
{ "parallel", HAS_ARG, QEMU_OPTION_parallel },
{ "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
{ "full-screen", 0, QEMU_OPTION_full_screen },
{ "no-frame", 0, QEMU_OPTION_no_frame },
{ "alt-grab", 0, QEMU_OPTION_alt_grab },
{ "no-quit", 0, QEMU_OPTION_no_quit },
+ { "sdl", 0, QEMU_OPTION_sdl },
#endif
{ "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
{ "win2k-hack", 0, QEMU_OPTION_win2k_hack },
+ { "rtc-td-hack", 0, QEMU_OPTION_rtc_td_hack },
{ "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
{ "smp", HAS_ARG, QEMU_OPTION_smp },
{ "vnc", HAS_ARG, QEMU_OPTION_vnc },
/* temporary options */
{ "usb", 0, QEMU_OPTION_usb },
{ "no-acpi", 0, QEMU_OPTION_no_acpi },
+ { "no-hpet", 0, QEMU_OPTION_no_hpet },
{ "no-reboot", 0, QEMU_OPTION_no_reboot },
{ "no-shutdown", 0, QEMU_OPTION_no_shutdown },
{ "show-cursor", 0, QEMU_OPTION_show_cursor },
{ "semihosting", 0, QEMU_OPTION_semihosting },
#endif
{ "name", HAS_ARG, QEMU_OPTION_name },
-#if defined(TARGET_SPARC)
+#if defined(TARGET_SPARC) || defined(TARGET_PPC)
{ "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
#endif
#if defined(TARGET_ARM)
{ .init_isa = pcspk_audio_init }
},
#endif
+
+#ifdef CONFIG_SB16
{
"sb16",
"Creative Sound Blaster 16",
1,
{ .init_isa = SB16_init }
},
+#endif
#ifdef CONFIG_CS4231A
{
},
#endif
+#ifdef CONFIG_ES1370
{
"es1370",
"ENSONIQ AudioPCI ES1370",
},
#endif
+#endif /* HAS_AUDIO_CHOICE */
+
{ NULL, NULL, 0, 0, { NULL } }
};
const char *opts;
if (strstart(p, "std", &opts)) {
+ std_vga_enabled = 1;
cirrus_vga_enabled = 0;
vmsvga_enabled = 0;
} else if (strstart(p, "cirrus", &opts)) {
cirrus_vga_enabled = 1;
+ std_vga_enabled = 0;
vmsvga_enabled = 0;
} else if (strstart(p, "vmware", &opts)) {
cirrus_vga_enabled = 0;
+ std_vga_enabled = 0;
vmsvga_enabled = 1;
+ } else if (strstart(p, "none", &opts)) {
+ cirrus_vga_enabled = 0;
+ std_vga_enabled = 0;
+ vmsvga_enabled = 0;
} else {
invalid_vga:
fprintf(stderr, "Unknown vga type: %s\n", p);
#endif
-int main(int argc, char **argv)
+int main(int argc, char **argv, char **envp)
{
#ifdef CONFIG_GDBSTUB
int use_gdbstub;
const char *initrd_filename;
const char *kernel_filename, *kernel_cmdline;
const char *boot_devices = "";
- DisplayState *ds = &display_state;
+ DisplayState *ds;
+ DisplayChangeListener *dcl;
int cyls, heads, secs, translation;
const char *net_clients[MAX_NET_CLIENTS];
int nb_net_clients;
int hda_index;
int optind;
const char *r, *optarg;
- CharDriverState *monitor_hd;
+ CharDriverState *monitor_hd = NULL;
const char *monitor_device;
const char *serial_devices[MAX_SERIAL_PORTS];
int serial_device_index;
const char *parallel_devices[MAX_PARALLEL_PORTS];
int parallel_device_index;
+ const char *virtio_consoles[MAX_VIRTIO_CONSOLES];
+ int virtio_console_index;
const char *loadvm = NULL;
QEMUMachine *machine;
const char *cpu_model;
int autostart;
const char *incoming = NULL;
+ qemu_cache_utils_init(envp);
+
LIST_INIT (&vm_change_state_head);
#ifndef _WIN32
{
parallel_devices[i] = NULL;
parallel_device_index = 0;
+ virtio_consoles[0] = "vc:80Cx24C";
+ for(i = 1; i < MAX_VIRTIO_CONSOLES; i++)
+ virtio_consoles[i] = NULL;
+ virtio_console_index = 0;
+
usb_devices_index = 0;
nb_net_clients = 0;
serial_devices[serial_device_index] = optarg;
serial_device_index++;
break;
+ case QEMU_OPTION_virtiocon:
+ if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
+ fprintf(stderr, "qemu: too many virtio consoles\n");
+ exit(1);
+ }
+ virtio_consoles[virtio_console_index] = optarg;
+ virtio_console_index++;
+ break;
case QEMU_OPTION_parallel:
if (parallel_device_index >= MAX_PARALLEL_PORTS) {
fprintf(stderr, "qemu: too many parallel ports\n");
case QEMU_OPTION_no_quit:
no_quit = 1;
break;
+ case QEMU_OPTION_sdl:
+ sdl = 1;
+ break;
#endif
case QEMU_OPTION_pidfile:
pid_file = optarg;
case QEMU_OPTION_win2k_hack:
win2k_install_hack = 1;
break;
+ case QEMU_OPTION_rtc_td_hack:
+ rtc_td_hack = 1;
+ break;
#endif
#ifdef USE_KQEMU
case QEMU_OPTION_no_kqemu:
case QEMU_OPTION_no_acpi:
acpi_enabled = 0;
break;
+ case QEMU_OPTION_no_hpet:
+ no_hpet = 1;
+ break;
case QEMU_OPTION_no_reboot:
no_reboot = 1;
break;
case QEMU_OPTION_name:
qemu_name = optarg;
break;
-#ifdef TARGET_SPARC
+#if defined(TARGET_SPARC) || defined(TARGET_PPC)
case QEMU_OPTION_prom_env:
if (nb_prom_envs >= MAX_PROM_ENVS) {
fprintf(stderr, "Too many prom variables\n");
parallel_devices[0] = "null";
if (strncmp(monitor_device, "vc", 2) == 0)
monitor_device = "stdio";
+ if (virtio_console_index == 0)
+ virtio_consoles[0] = "null";
}
#ifndef _WIN32
register_savevm("timer", 0, 2, timer_save, timer_load, NULL);
register_savevm_live("ram", 0, 3, ram_save_live, NULL, ram_load, NULL);
- /* terminal init */
- memset(&display_state, 0, sizeof(display_state));
- if (nographic) {
- if (curses) {
- fprintf(stderr, "fatal: -nographic can't be used with -curses\n");
- exit(1);
- }
- /* nearly nothing to do */
- dumb_display_init(ds);
- } else if (vnc_display != NULL) {
- vnc_display_init(ds);
- if (vnc_display_open(ds, vnc_display) < 0)
- exit(1);
- } else
-#if defined(CONFIG_CURSES)
- if (curses) {
- curses_display_init(ds, full_screen);
- } else
-#endif
- {
-#if defined(CONFIG_SDL)
- sdl_display_init(ds, full_screen, no_frame);
-#elif defined(CONFIG_COCOA)
- cocoa_display_init(ds, full_screen);
-#else
- dumb_display_init(ds);
-#endif
- }
-
#ifndef _WIN32
/* must be after terminal init, SDL library changes signal handlers */
termsig_setup();
}
}
}
+
+ 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);
+ 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);
}
- monitor_init(monitor_hd, !nographic);
}
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
if (devname && strcmp(devname, "none")) {
char label[32];
snprintf(label, sizeof(label), "serial%d", i);
- serial_hds[i] = qemu_chr_open(label, devname);
+ serial_hds[i] = qemu_chr_open(label, devname, NULL);
if (!serial_hds[i]) {
fprintf(stderr, "qemu: could not open serial device '%s'\n",
devname);
exit(1);
}
- if (strstart(devname, "vc", 0))
- qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
}
}
if (devname && strcmp(devname, "none")) {
char label[32];
snprintf(label, sizeof(label), "parallel%d", i);
- parallel_hds[i] = qemu_chr_open(label, devname);
+ parallel_hds[i] = qemu_chr_open(label, devname, NULL);
if (!parallel_hds[i]) {
fprintf(stderr, "qemu: could not open parallel device '%s'\n",
devname);
exit(1);
}
- if (strstart(devname, "vc", 0))
- qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
}
}
+ for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
+ const char *devname = virtio_consoles[i];
+ if (devname && strcmp(devname, "none")) {
+ char label[32];
+ snprintf(label, sizeof(label), "virtcon%d", i);
+ virtcon_hds[i] = qemu_chr_open(label, devname, NULL);
+ if (!virtcon_hds[i]) {
+ fprintf(stderr, "qemu: could not open virtio console '%s'\n",
+ devname);
+ exit(1);
+ }
+ }
+ }
+
+ machine->init(ram_size, vga_ram_size, boot_devices,
+ kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
+
+ /* Set KVM's vcpu state to qemu's initial CPUState. */
if (kvm_enabled()) {
int ret;
- ret = kvm_init(smp_cpus);
+ ret = kvm_sync_vcpus();
if (ret < 0) {
- fprintf(stderr, "failed to initialize KVM\n");
+ fprintf(stderr, "failed to initialize vcpus\n");
exit(1);
}
}
- machine->init(ram_size, vga_ram_size, boot_devices, ds,
- kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
-
/* init USB devices */
if (usb_enabled) {
for(i = 0; i < usb_devices_index; i++) {
}
}
- if (display_state.dpy_refresh) {
- display_state.gui_timer = qemu_new_timer(rt_clock, gui_update, &display_state);
- qemu_mod_timer(display_state.gui_timer, qemu_get_clock(rt_clock));
+ if (!display_state)
+ 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 defined(CONFIG_CURSES)
+ if (curses) {
+ /* At the moment curses cannot be used with other displays */
+ curses_display_init(ds, full_screen);
+ } else
+#endif
+ {
+ if (vnc_display != NULL) {
+ vnc_display_init(ds);
+ if (vnc_display_open(ds, vnc_display) < 0)
+ exit(1);
+ }
+ if (sdl || !vnc_display)
+#if defined(CONFIG_SDL)
+ sdl_display_init(ds, full_screen, no_frame);
+#elif defined(CONFIG_COCOA)
+ cocoa_display_init(ds, full_screen);
+#endif
+ }
+ }
+ dpy_resize(ds);
+
+ dcl = ds->listeners;
+ while (dcl != NULL) {
+ if (dcl->dpy_refresh != NULL) {
+ ds->gui_timer = qemu_new_timer(rt_clock, gui_update, ds);
+ qemu_mod_timer(ds->gui_timer, qemu_get_clock(rt_clock));
+ }
+ dcl = dcl->next;
+ }
+
+ if (nographic || (vnc_display && !sdl)) {
+ nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
+ qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
+ }
+
+ text_consoles_set_display(display_state);
+
+ if (monitor_device && monitor_hd)
+ monitor_init(monitor_hd, !nographic);
+
+ for(i = 0; i < MAX_SERIAL_PORTS; i++) {
+ const char *devname = serial_devices[i];
+ if (devname && strcmp(devname, "none")) {
+ char label[32];
+ snprintf(label, sizeof(label), "serial%d", i);
+ if (strstart(devname, "vc", 0))
+ qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
+ }
+ }
+
+ for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
+ const char *devname = parallel_devices[i];
+ if (devname && strcmp(devname, "none")) {
+ char label[32];
+ snprintf(label, sizeof(label), "parallel%d", i);
+ if (strstart(devname, "vc", 0))
+ qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
+ }
+ }
+
+ for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
+ const char *devname = virtio_consoles[i];
+ if (virtcon_hds[i] && devname) {
+ char label[32];
+ snprintf(label, sizeof(label), "virtcon%d", i);
+ if (strstart(devname, "vc", 0))
+ qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
+ }
}
#ifdef CONFIG_GDBSTUB