#include <sys/time.h>
#include <zlib.h>
-/* Needed early for _BSD etc. */
+/* Needed early for HOST_BSD etc. */
#include "config-host.h"
#ifndef _WIN32
#include <dirent.h>
#include <netdb.h>
#include <sys/select.h>
-#ifdef _BSD
+#ifdef HOST_BSD
#include <sys/stat.h>
#if defined(__FreeBSD__) || defined(__DragonFly__)
#include <libutil.h>
#endif
#ifdef _WIN32
+#include <windows.h>
#include <malloc.h>
#include <sys/timeb.h>
#include <mmsystem.h>
#include "hw/isa.h"
#include "hw/baum.h"
#include "hw/bt.h"
+#include "hw/smbios.h"
+#include "hw/xen.h"
+#include "bt-host.h"
#include "net.h"
#include "monitor.h"
#include "console.h"
#include "qemu-char.h"
#include "cache-utils.h"
#include "block.h"
+#include "dma.h"
#include "audio/audio.h"
#include "migration.h"
#include "kvm.h"
int rtc_td_hack = 0;
#endif
int usb_enabled = 0;
+int singlestep = 0;
int smp_cpus = 1;
const char *vnc_display;
int acpi_enabled = 1;
int no_shutdown = 0;
int cursor_hide = 1;
int graphic_rotate = 0;
+#ifndef _WIN32
int daemonize = 0;
+#endif
const char *option_rom[MAX_OPTION_ROMS];
int nb_option_roms;
int semihosting_enabled = 0;
int nb_drives_opt;
struct drive_opt drives_opt[MAX_DRIVES];
+int nb_numa_nodes;
+uint64_t node_mem[MAX_NODES];
+uint64_t node_cpumask[MAX_NODES];
+
static CPUState *cur_cpu;
static CPUState *next_cpu;
static int event_pending = 1;
{
LOG_IOPORT("outb: %04x %02x\n", addr, val);
ioport_write(0, addr, val);
-#ifdef USE_KQEMU
+#ifdef CONFIG_KQEMU
if (env)
env->last_io_time = cpu_get_time_fast();
#endif
{
LOG_IOPORT("outw: %04x %04x\n", addr, val);
ioport_write(1, addr, val);
-#ifdef USE_KQEMU
+#ifdef CONFIG_KQEMU
if (env)
env->last_io_time = cpu_get_time_fast();
#endif
{
LOG_IOPORT("outl: %04x %08x\n", addr, val);
ioport_write(2, addr, val);
-#ifdef USE_KQEMU
+#ifdef CONFIG_KQEMU
if (env)
env->last_io_time = cpu_get_time_fast();
#endif
int val;
val = ioport_read(0, addr);
LOG_IOPORT("inb : %04x %02x\n", addr, val);
-#ifdef USE_KQEMU
+#ifdef CONFIG_KQEMU
if (env)
env->last_io_time = cpu_get_time_fast();
#endif
int val;
val = ioport_read(1, addr);
LOG_IOPORT("inw : %04x %04x\n", addr, val);
-#ifdef USE_KQEMU
+#ifdef CONFIG_KQEMU
if (env)
env->last_io_time = cpu_get_time_fast();
#endif
int val;
val = ioport_read(2, addr);
LOG_IOPORT("inl : %04x %08x\n", addr, val);
-#ifdef USE_KQEMU
+#ifdef CONFIG_KQEMU
if (env)
env->last_io_time = cpu_get_time_fast();
#endif
}
#ifdef _WIN32
-void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
- DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
+static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
+ DWORD_PTR dwUser, DWORD_PTR dw1,
+ DWORD_PTR dw2)
#else
static void host_alarm_handler(int host_signum)
#endif
if (env) {
/* stop the currently executing cpu because a timer occured */
cpu_exit(env);
-#ifdef USE_KQEMU
+#ifdef CONFIG_KQEMU
if (env->kqemu_enabled) {
kqemu_cpu_interrupt(env);
}
}
#endif
-const char *get_opt_name(char *buf, int buf_size, const char *p)
+const char *get_opt_name(char *buf, int buf_size, const char *p, char delim)
{
char *q;
q = buf;
- while (*p != '\0' && *p != '=') {
+ while (*p != '\0' && *p != delim) {
if (q && (q - buf) < buf_size - 1)
*q++ = *p;
p++;
p = str;
for(;;) {
- p = get_opt_name(option, sizeof(option), p);
+ p = get_opt_name(option, sizeof(option), p, '=');
if (*p != '=')
break;
p++;
int i;
p = str;
- for(;;) {
- p = get_opt_name(buf, buf_size, p);
+ while (*p != '\0') {
+ p = get_opt_name(buf, buf_size, p, '=');
if (*p != '=')
return -1;
p++;
return drives_table_idx;
}
+static void numa_add(const char *optarg)
+{
+ char option[128];
+ char *endptr;
+ unsigned long long value, endvalue;
+ int nodenr;
+
+ optarg = get_opt_name(option, 128, optarg, ',') + 1;
+ if (!strcmp(option, "node")) {
+ if (get_param_value(option, 128, "nodeid", optarg) == 0) {
+ nodenr = nb_numa_nodes;
+ } else {
+ nodenr = strtoull(option, NULL, 10);
+ }
+
+ if (get_param_value(option, 128, "mem", optarg) == 0) {
+ node_mem[nodenr] = 0;
+ } else {
+ value = strtoull(option, &endptr, 0);
+ switch (*endptr) {
+ case 0: case 'M': case 'm':
+ value <<= 20;
+ break;
+ case 'G': case 'g':
+ value <<= 30;
+ break;
+ }
+ node_mem[nodenr] = value;
+ }
+ if (get_param_value(option, 128, "cpus", optarg) == 0) {
+ node_cpumask[nodenr] = 0;
+ } else {
+ value = strtoull(option, &endptr, 10);
+ if (value >= 64) {
+ value = 63;
+ fprintf(stderr, "only 64 CPUs in NUMA mode supported.\n");
+ } else {
+ if (*endptr == '-') {
+ endvalue = strtoull(endptr+1, &endptr, 10);
+ if (endvalue >= 63) {
+ endvalue = 62;
+ fprintf(stderr,
+ "only 63 CPUs in NUMA mode supported.\n");
+ }
+ value = (1 << (endvalue + 1)) - (1 << value);
+ } else {
+ value = 1 << value;
+ }
+ }
+ node_cpumask[nodenr] = value;
+ }
+ nb_numa_nodes++;
+ }
+ return;
+}
+
/***********************************************************/
/* USB devices */
/***********************************************************/
/* register display */
+struct DisplayAllocator default_allocator = {
+ defaultallocator_create_displaysurface,
+ defaultallocator_resize_displaysurface,
+ defaultallocator_free_displaysurface
+};
+
void register_displaystate(DisplayState *ds)
{
DisplayState **s;
return display_state;
}
+DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
+{
+ if(ds->allocator == &default_allocator) ds->allocator = da;
+ return ds->allocator;
+}
+
/* dumb display */
static void dumb_display_init(void)
{
DisplayState *ds = qemu_mallocz(sizeof(DisplayState));
- ds->surface = qemu_create_displaysurface(640, 480, 32, 640 * 4);
+ ds->allocator = &default_allocator;
+ ds->surface = qemu_create_displaysurface(ds, 640, 480);
register_displaystate(ds);
}
/***********************************************************/
/* I/O handling */
-#define MAX_IO_HANDLERS 64
-
typedef struct IOHandlerRecord {
int fd;
IOCanRWHandler *fd_read_poll;
int ret;
ram_addr_t i;
- if (qemu_get_be32(f) != phys_ram_size)
+ if (qemu_get_be32(f) != last_ram_offset)
return -EINVAL;
- for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {
- ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);
+ 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;
}
ram_addr_t addr = 0;
int found = 0;
- while (addr < phys_ram_size) {
+ while (addr < last_ram_offset) {
if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
- uint8_t ch;
+ uint8_t *p;
cpu_physical_memory_reset_dirty(current_addr,
current_addr + TARGET_PAGE_SIZE,
MIGRATION_DIRTY_FLAG);
- ch = *(phys_ram_base + current_addr);
+ p = qemu_get_ram_ptr(current_addr);
- if (is_dup_page(phys_ram_base + current_addr, ch)) {
+ if (is_dup_page(p, *p)) {
qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
- qemu_put_byte(f, ch);
+ qemu_put_byte(f, *p);
} else {
qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
- qemu_put_buffer(f, phys_ram_base + current_addr, TARGET_PAGE_SIZE);
+ qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
}
found = 1;
break;
}
addr += TARGET_PAGE_SIZE;
- current_addr = (saved_addr + addr) % phys_ram_size;
+ current_addr = (saved_addr + addr) % last_ram_offset;
}
return found;
ram_addr_t addr;
ram_addr_t count = 0;
- for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) {
+ for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
count++;
}
if (stage == 1) {
/* Make sure all dirty bits are set */
- for (addr = 0; addr < phys_ram_size; addr += TARGET_PAGE_SIZE) {
+ for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
cpu_physical_memory_set_dirty(addr);
}
/* Enable dirty memory tracking */
cpu_physical_memory_set_dirty_tracking(1);
- qemu_put_be64(f, phys_ram_size | RAM_SAVE_FLAG_MEM_SIZE);
+ qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
}
while (!qemu_file_rate_limit(f)) {
/* try transferring iterative blocks of memory */
if (stage == 3) {
- cpu_physical_memory_set_dirty_tracking(0);
/* flush all remaining blocks regardless of rate limiting */
while (ram_save_block(f) != 0);
+ cpu_physical_memory_set_dirty_tracking(0);
}
qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
if (ram_decompress_open(s, f) < 0)
return -EINVAL;
- for(i = 0; i < phys_ram_size; i+= BDRV_HASH_BLOCK_SIZE) {
+ 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, phys_ram_base + i, BDRV_HASH_BLOCK_SIZE) < 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;
}
return ram_load_v1(f, opaque);
if (version_id == 2) {
- if (qemu_get_be32(f) != phys_ram_size)
+ if (qemu_get_be32(f) != last_ram_offset)
return -EINVAL;
return ram_load_dead(f, opaque);
}
addr &= TARGET_PAGE_MASK;
if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
- if (addr != phys_ram_size)
+ if (addr != last_ram_offset)
return -EINVAL;
}
if (flags & RAM_SAVE_FLAG_COMPRESS) {
uint8_t ch = qemu_get_byte(f);
- memset(phys_ram_base + addr, ch, TARGET_PAGE_SIZE);
+ memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE);
} else if (flags & RAM_SAVE_FLAG_PAGE)
- qemu_get_buffer(f, phys_ram_base + addr, TARGET_PAGE_SIZE);
+ qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
} while (!(flags & RAM_SAVE_FLAG_EOS));
return 0;
CPUState *env = cpu_single_env;
if (env) {
cpu_exit(env);
-#ifdef USE_KQEMU
+#ifdef CONFIG_KQEMU
if (env->kqemu_enabled) {
kqemu_cpu_interrupt(env);
}
for(re = first_reset_entry; re != NULL; re = re->next) {
re->func(re->opaque);
}
+ if (kvm_enabled())
+ kvm_sync_vcpus();
}
void qemu_system_reset_request(void)
return ret;
}
+static void version(void)
+{
+ printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
+}
+
static void help(int exitcode)
{
- /* Please keep in synch with QEMU_OPTION_ enums, qemu_options[]
- and qemu-doc.texi */
- printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
- "usage: %s [options] [disk_image]\n"
+ version();
+ printf("usage: %s [options] [disk_image]\n"
"\n"
"'disk_image' is a raw hard image image for IDE hard disk 0\n"
"\n"
- "Standard options:\n"
- "-h or -help display this help and exit\n"
- "-M machine select emulated machine (-M ? for list)\n"
- "-cpu cpu select CPU (-cpu ? for list)\n"
- "-smp n set the number of CPUs to 'n' [default=1]\n"
- "-fda/-fdb file use 'file' as floppy disk 0/1 image\n"
- "-hda/-hdb file use 'file' as IDE hard disk 0/1 image\n"
- "-hdc/-hdd file use 'file' as IDE hard disk 2/3 image\n"
- "-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][,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"
- "-pflash file use 'file' as a parallel flash image\n"
- "-boot [a|c|d|n] boot on floppy (a), hard disk (c), CD-ROM (d), or network (n)\n"
- "-snapshot write to temporary files instead of disk image files\n"
- "-m megs set virtual RAM size to megs MB [default=%d]\n"
-#ifndef _WIN32
- "-k language use keyboard layout (for example \"fr\" for French)\n"
-#endif
-#ifdef HAS_AUDIO
- "-audio-help print list of audio drivers and their options\n"
- "-soundhw c1,... enable audio support\n"
- " and only specified sound cards (comma separated list)\n"
- " use -soundhw ? to get the list of supported cards\n"
- " use -soundhw all to enable all of them\n"
-#endif
- "-usb enable the USB driver (will be the default soon)\n"
- "-usbdevice name add the host or guest USB device 'name'\n"
- "-name string set the name of the guest\n"
- "-uuid %%08x-%%04x-%%04x-%%04x-%%012x\n"
- " specify machine UUID\n"
- "\n"
- "Display options:\n"
- "-nographic disable graphical output and redirect serial I/Os to console\n"
-#ifdef CONFIG_CURSES
- "-curses use a curses/ncurses interface instead of SDL\n"
-#endif
-#ifdef CONFIG_SDL
- "-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
- "-portrait rotate graphical output 90 deg left (only PXA LCD)\n"
- "-vga [std|cirrus|vmware|none]\n"
- " select video card type\n"
- "-full-screen start in full screen\n"
-#if defined(TARGET_PPC) || defined(TARGET_SPARC)
- "-g WxH[xDEPTH] Set the initial graphical resolution and depth\n"
-#endif
- "-vnc display start a VNC server on display\n"
- "\n"
- "Network options:\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][,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][,name=str],ifname=name\n"
- " connect the host TAP network interface to VLAN 'n'\n"
-#else
- "-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][,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][,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][,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"
- " ownership and permissions for communication port.\n"
-#endif
- "-net none use it alone to have zero network devices; if no -net option\n"
- " is provided, the default is '-net nic -net user'\n"
-#ifdef CONFIG_SLIRP
- "-tftp dir allow tftp access to files in dir [-net user]\n"
- "-bootp file advertise file in BOOTP replies\n"
-#ifndef _WIN32
- "-smb dir allow SMB access to files in 'dir' [-net user]\n"
-#endif
- "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
- " redirect TCP or UDP connections from host to guest [-net user]\n"
-#endif
- "\n"
- "-bt hci,null dumb bluetooth HCI - doesn't respond to commands\n"
- "-bt hci,host[:id]\n"
- " use host's HCI with the given name\n"
- "-bt hci[,vlan=n]\n"
- " emulate a standard HCI in virtual scatternet 'n'\n"
- "-bt vhci[,vlan=n]\n"
- " add host computer to virtual scatternet 'n' using VHCI\n"
- "-bt device:dev[,vlan=n]\n"
- " emulate a bluetooth device 'dev' in scatternet 'n'\n"
- "\n"
-#ifdef TARGET_I386
- "\n"
- "i386 target only:\n"
- "-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"
- "-no-fd-bootchk disable boot signature checking for floppy disks\n"
- "-no-acpi disable ACPI\n"
- "-no-hpet disable HPET\n"
- "-acpitable [sig=str][,rev=n][,oem_id=str][,oem_table_id=str][,oem_rev=n][,asl_compiler_id=str][,asl_compiler_rev=n][,data=file1[:file2]...]\n"
- " ACPI table description\n"
-#endif
- "Linux boot specific:\n"
- "-kernel bzImage use 'bzImage' as kernel image\n"
- "-append cmdline use 'cmdline' as kernel command line\n"
- "-initrd file use 'file' as initial ram disk\n"
- "\n"
- "Debug/Expert options:\n"
- "-serial dev redirect the serial port to char device 'dev'\n"
- "-parallel dev redirect the parallel port to char device 'dev'\n"
- "-monitor dev redirect the monitor to char device 'dev'\n"
- "-pidfile file write PID to 'file'\n"
- "-S freeze CPU at startup (use 'c' to start execution)\n"
- "-s wait gdb connection to port\n"
- "-p port set gdb connection port [default=%s]\n"
- "-d item1,... output log to %s (use -d ? for a list of log items)\n"
- "-hdachs c,h,s[,t]\n"
- " force hard disk 0 physical geometry and the optional BIOS\n"
- " translation (t=none or lba) (usually qemu can guess them)\n"
- "-L path set the directory for the BIOS, VGA BIOS and keymaps\n"
- "-bios file set the filename for the BIOS\n"
-#ifdef USE_KQEMU
- "-kernel-kqemu enable KQEMU full virtualization (default is user mode only)\n"
- "-no-kqemu disable KQEMU kernel module usage\n"
-#endif
-#ifdef CONFIG_KVM
- "-enable-kvm enable KVM full virtualization support\n"
-#endif
- "-no-reboot exit instead of rebooting\n"
- "-no-shutdown stop before shutdown\n"
- "-loadvm [tag|id]\n"
- " start right away with a saved state (loadvm in monitor)\n"
-#ifndef _WIN32
- "-daemonize daemonize QEMU after initializing\n"
-#endif
- "-option-rom rom load a file, rom, into the option ROM space\n"
-#if defined(TARGET_SPARC) || defined(TARGET_PPC)
- "-prom-env variable=value\n"
- " set OpenBIOS nvram variables\n"
-#endif
- "-clock force the use of the given methods for timer alarm.\n"
- " To see what timers are available use -clock ?\n"
- "-localtime set the real time clock to local time [default=utc]\n"
- "-startdate select initial date of the clock\n"
- "-icount [N|auto]\n"
- " enable virtual instruction counter with 2^N clock ticks per instruction\n"
- "-echr chr set terminal escape character instead of ctrl-a\n"
- "-virtioconsole c\n"
- " set virtio console\n"
- "-show-cursor show cursor\n"
-#if defined(TARGET_ARM) || defined(TARGET_M68K)
- "-semihosting semihosting mode\n"
-#endif
-#if defined(TARGET_ARM)
- "-old-param old param mode\n"
-#endif
- "-tb-size n set TB size\n"
- "-incoming p prepare for incoming migration, listen on port p\n"
-#ifndef _WIN32
- "-chroot dir Chroot to dir just before starting the VM.\n"
- "-runas user Change to user id user just before starting the VM.\n"
-#endif
+#define DEF(option, opt_arg, opt_enum, opt_help) \
+ opt_help
+#define DEFHEADING(text) stringify(text) "\n"
+#include "qemu-options.h"
+#undef DEF
+#undef DEFHEADING
+#undef GEN_DOCS
"\n"
"During emulation, the following keys are useful:\n"
"ctrl-alt-f toggle full screen\n"
#define HAS_ARG 0x0001
enum {
- /* Please keep in synch with help, qemu_options[] and
- qemu-doc.texi */
- /* Standard options: */
- QEMU_OPTION_h,
- QEMU_OPTION_M,
- QEMU_OPTION_cpu,
- QEMU_OPTION_smp,
- QEMU_OPTION_fda,
- QEMU_OPTION_fdb,
- QEMU_OPTION_hda,
- QEMU_OPTION_hdb,
- QEMU_OPTION_hdc,
- QEMU_OPTION_hdd,
- QEMU_OPTION_cdrom,
- QEMU_OPTION_drive,
- QEMU_OPTION_mtdblock,
- QEMU_OPTION_sd,
- QEMU_OPTION_pflash,
- QEMU_OPTION_boot,
- QEMU_OPTION_snapshot,
- QEMU_OPTION_m,
- QEMU_OPTION_k,
- QEMU_OPTION_audio_help,
- QEMU_OPTION_soundhw,
- QEMU_OPTION_usb,
- QEMU_OPTION_usbdevice,
- QEMU_OPTION_name,
- QEMU_OPTION_uuid,
-
- /* Display options: */
- QEMU_OPTION_nographic,
- QEMU_OPTION_curses,
- QEMU_OPTION_no_frame,
- QEMU_OPTION_alt_grab,
- QEMU_OPTION_no_quit,
- QEMU_OPTION_sdl,
- QEMU_OPTION_portrait,
- QEMU_OPTION_vga,
- QEMU_OPTION_full_screen,
- QEMU_OPTION_g,
- QEMU_OPTION_vnc,
-
- /* Network options: */
- QEMU_OPTION_net,
- QEMU_OPTION_tftp,
- QEMU_OPTION_bootp,
- QEMU_OPTION_smb,
- QEMU_OPTION_redir,
- QEMU_OPTION_bt,
-
- /* i386 target only: */
- QEMU_OPTION_win2k_hack,
- QEMU_OPTION_rtc_td_hack,
- QEMU_OPTION_no_fd_bootchk,
- QEMU_OPTION_no_acpi,
- QEMU_OPTION_no_hpet,
- QEMU_OPTION_acpitable,
-
- /* Linux boot specific: */
- QEMU_OPTION_kernel,
- QEMU_OPTION_append,
- QEMU_OPTION_initrd,
-
- /* Debug/Expert options: */
- QEMU_OPTION_serial,
- QEMU_OPTION_parallel,
- QEMU_OPTION_monitor,
- QEMU_OPTION_pidfile,
- QEMU_OPTION_S,
- QEMU_OPTION_s,
- QEMU_OPTION_p,
- QEMU_OPTION_d,
- QEMU_OPTION_hdachs,
- QEMU_OPTION_L,
- QEMU_OPTION_bios,
- QEMU_OPTION_kernel_kqemu,
- QEMU_OPTION_no_kqemu,
- QEMU_OPTION_enable_kvm,
- QEMU_OPTION_no_reboot,
- QEMU_OPTION_no_shutdown,
- QEMU_OPTION_loadvm,
- QEMU_OPTION_daemonize,
- QEMU_OPTION_option_rom,
- QEMU_OPTION_prom_env,
- QEMU_OPTION_clock,
- QEMU_OPTION_localtime,
- QEMU_OPTION_startdate,
- QEMU_OPTION_icount,
- QEMU_OPTION_echr,
- QEMU_OPTION_virtiocon,
- QEMU_OPTION_show_cursor,
- QEMU_OPTION_semihosting,
- QEMU_OPTION_old_param,
- QEMU_OPTION_tb_size,
- QEMU_OPTION_incoming,
- QEMU_OPTION_chroot,
- QEMU_OPTION_runas,
+#define DEF(option, opt_arg, opt_enum, opt_help) \
+ opt_enum,
+#define DEFHEADING(text)
+#include "qemu-options.h"
+#undef DEF
+#undef DEFHEADING
+#undef GEN_DOCS
};
typedef struct QEMUOption {
} QEMUOption;
static const QEMUOption qemu_options[] = {
- /* Please keep in synch with help, QEMU_OPTION_ enums, and
- qemu-doc.texi */
- /* Standard options: */
{ "h", 0, QEMU_OPTION_h },
- { "help", 0, QEMU_OPTION_h },
- { "M", HAS_ARG, QEMU_OPTION_M },
- { "cpu", HAS_ARG, QEMU_OPTION_cpu },
- { "smp", HAS_ARG, QEMU_OPTION_smp },
- { "fda", HAS_ARG, QEMU_OPTION_fda },
- { "fdb", HAS_ARG, QEMU_OPTION_fdb },
- { "hda", HAS_ARG, QEMU_OPTION_hda },
- { "hdb", HAS_ARG, QEMU_OPTION_hdb },
- { "hdc", HAS_ARG, QEMU_OPTION_hdc },
- { "hdd", HAS_ARG, QEMU_OPTION_hdd },
- { "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
- { "drive", HAS_ARG, QEMU_OPTION_drive },
- { "mtdblock", HAS_ARG, QEMU_OPTION_mtdblock },
- { "sd", HAS_ARG, QEMU_OPTION_sd },
- { "pflash", HAS_ARG, QEMU_OPTION_pflash },
- { "boot", HAS_ARG, QEMU_OPTION_boot },
- { "snapshot", 0, QEMU_OPTION_snapshot },
- { "m", HAS_ARG, QEMU_OPTION_m },
-#ifndef _WIN32
- { "k", HAS_ARG, QEMU_OPTION_k },
-#endif
-#ifdef HAS_AUDIO
- { "audio-help", 0, QEMU_OPTION_audio_help },
- { "soundhw", HAS_ARG, QEMU_OPTION_soundhw },
-#endif
- { "usb", 0, QEMU_OPTION_usb },
- { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
- { "name", HAS_ARG, QEMU_OPTION_name },
- { "uuid", HAS_ARG, QEMU_OPTION_uuid },
-
- /* Display options: */
- { "nographic", 0, QEMU_OPTION_nographic },
-#ifdef CONFIG_CURSES
- { "curses", 0, QEMU_OPTION_curses },
-#endif
-#ifdef CONFIG_SDL
- { "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
- { "portrait", 0, QEMU_OPTION_portrait },
- { "vga", HAS_ARG, QEMU_OPTION_vga },
- { "full-screen", 0, QEMU_OPTION_full_screen },
-#if defined(TARGET_PPC) || defined(TARGET_SPARC)
- { "g", 1, QEMU_OPTION_g },
-#endif
- { "vnc", HAS_ARG, QEMU_OPTION_vnc },
-
- /* Network options: */
- { "net", HAS_ARG, QEMU_OPTION_net},
-#ifdef CONFIG_SLIRP
- { "tftp", HAS_ARG, QEMU_OPTION_tftp },
- { "bootp", HAS_ARG, QEMU_OPTION_bootp },
-#ifndef _WIN32
- { "smb", HAS_ARG, QEMU_OPTION_smb },
-#endif
- { "redir", HAS_ARG, QEMU_OPTION_redir },
-#endif
- { "bt", HAS_ARG, QEMU_OPTION_bt },
-#ifdef TARGET_I386
- /* i386 target only: */
- { "win2k-hack", 0, QEMU_OPTION_win2k_hack },
- { "rtc-td-hack", 0, QEMU_OPTION_rtc_td_hack },
- { "no-fd-bootchk", 0, QEMU_OPTION_no_fd_bootchk },
- { "no-acpi", 0, QEMU_OPTION_no_acpi },
- { "no-hpet", 0, QEMU_OPTION_no_hpet },
- { "acpitable", HAS_ARG, QEMU_OPTION_acpitable },
-#endif
-
- /* Linux boot specific: */
- { "kernel", HAS_ARG, QEMU_OPTION_kernel },
- { "append", HAS_ARG, QEMU_OPTION_append },
- { "initrd", HAS_ARG, QEMU_OPTION_initrd },
-
- /* Debug/Expert options: */
- { "serial", HAS_ARG, QEMU_OPTION_serial },
- { "parallel", HAS_ARG, QEMU_OPTION_parallel },
- { "monitor", HAS_ARG, QEMU_OPTION_monitor },
- { "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
- { "S", 0, QEMU_OPTION_S },
- { "s", 0, QEMU_OPTION_s },
- { "p", HAS_ARG, QEMU_OPTION_p },
- { "d", HAS_ARG, QEMU_OPTION_d },
- { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
- { "L", HAS_ARG, QEMU_OPTION_L },
- { "bios", HAS_ARG, QEMU_OPTION_bios },
-#ifdef USE_KQEMU
- { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
- { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
-#endif
-#ifdef CONFIG_KVM
- { "enable-kvm", 0, QEMU_OPTION_enable_kvm },
-#endif
- { "no-reboot", 0, QEMU_OPTION_no_reboot },
- { "no-shutdown", 0, QEMU_OPTION_no_shutdown },
- { "loadvm", HAS_ARG, QEMU_OPTION_loadvm },
- { "daemonize", 0, QEMU_OPTION_daemonize },
- { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
-#if defined(TARGET_SPARC) || defined(TARGET_PPC)
- { "prom-env", HAS_ARG, QEMU_OPTION_prom_env },
-#endif
- { "clock", HAS_ARG, QEMU_OPTION_clock },
- { "localtime", 0, QEMU_OPTION_localtime },
- { "startdate", HAS_ARG, QEMU_OPTION_startdate },
- { "icount", HAS_ARG, QEMU_OPTION_icount },
- { "echr", HAS_ARG, QEMU_OPTION_echr },
- { "virtioconsole", HAS_ARG, QEMU_OPTION_virtiocon },
- { "show-cursor", 0, QEMU_OPTION_show_cursor },
-#if defined(TARGET_ARM) || defined(TARGET_M68K)
- { "semihosting", 0, QEMU_OPTION_semihosting },
-#endif
-#if defined(TARGET_ARM)
- { "old-param", 0, QEMU_OPTION_old_param },
-#endif
- { "tb-size", HAS_ARG, QEMU_OPTION_tb_size },
- { "incoming", HAS_ARG, QEMU_OPTION_incoming },
- { "chroot", HAS_ARG, QEMU_OPTION_chroot },
- { "runas", HAS_ARG, QEMU_OPTION_runas },
+#define DEF(option, opt_arg, opt_enum, opt_help) \
+ { option, opt_arg, opt_enum },
+#define DEFHEADING(text)
+#include "qemu-options.h"
+#undef DEF
+#undef DEFHEADING
+#undef GEN_DOCS
{ NULL },
};
}
#endif
-static int qemu_uuid_parse(const char *str, uint8_t *uuid)
+int qemu_uuid_parse(const char *str, uint8_t *uuid)
{
int ret;
if(ret != 16)
return -1;
+#ifdef TARGET_I386
+ smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
+#endif
+
return 0;
}
int main(int argc, char **argv, char **envp)
{
#ifdef CONFIG_GDBSTUB
- int use_gdbstub;
- const char *gdbstub_port;
+ const char *gdbstub_dev = NULL;
#endif
uint32_t boot_devices_bitmap = 0;
int i;
const char *cpu_model;
const char *usb_devices[MAX_USB_CMDLINE];
int usb_devices_index;
+#ifndef _WIN32
int fds[2];
+#endif
int tb_size;
const char *pid_file = NULL;
const char *incoming = NULL;
+#ifndef _WIN32
int fd = 0;
struct passwd *pwd = NULL;
const char *chroot_dir = NULL;
const char *run_as = NULL;
+#endif
+ CPUState *env;
qemu_cache_utils_init(envp);
initrd_filename = NULL;
ram_size = 0;
vga_ram_size = VGA_RAM_SIZE;
-#ifdef CONFIG_GDBSTUB
- use_gdbstub = 0;
- gdbstub_port = DEFAULT_GDBSTUB_PORT;
-#endif
snapshot = 0;
nographic = 0;
curses = 0;
virtio_consoles[i] = NULL;
virtio_console_index = 0;
+ for (i = 0; i < MAX_NODES; i++) {
+ node_mem[i] = 0;
+ node_cpumask[i] = 0;
+ }
+
usb_devices_index = 0;
nb_net_clients = 0;
nb_bt_opts = 0;
nb_drives = 0;
nb_drives_opt = 0;
+ nb_numa_nodes = 0;
hda_index = -1;
nb_nics = 0;
",trans=none" : "");
}
break;
+ case QEMU_OPTION_numa:
+ if (nb_numa_nodes >= MAX_NODES) {
+ fprintf(stderr, "qemu: too many NUMA nodes\n");
+ exit(1);
+ }
+ numa_add(optarg);
+ break;
case QEMU_OPTION_nographic:
nographic = 1;
break;
break;
#endif
case QEMU_OPTION_redir:
- net_slirp_redir(optarg);
+ net_slirp_redir(NULL, optarg);
break;
#endif
case QEMU_OPTION_bt:
case QEMU_OPTION_h:
help(0);
break;
+ case QEMU_OPTION_version:
+ version();
+ exit(0);
+ break;
case QEMU_OPTION_m: {
uint64_t value;
char *ptr;
/* On 32-bit hosts, QEMU is limited by virtual address space */
if (value > (2047 << 20)
-#ifndef USE_KQEMU
+#ifndef CONFIG_KQEMU
&& HOST_LONG_BITS == 32
#endif
) {
break;
#ifdef CONFIG_GDBSTUB
case QEMU_OPTION_s:
- use_gdbstub = 1;
+ gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
break;
- case QEMU_OPTION_p:
- gdbstub_port = optarg;
+ case QEMU_OPTION_gdb:
+ gdbstub_dev = optarg;
break;
#endif
case QEMU_OPTION_L:
case QEMU_OPTION_bios:
bios_name = optarg;
break;
+ case QEMU_OPTION_singlestep:
+ singlestep = 1;
+ break;
case QEMU_OPTION_S:
autostart = 0;
break;
+#ifndef _WIN32
case QEMU_OPTION_k:
keyboard_layout = optarg;
break;
+#endif
case QEMU_OPTION_localtime:
rtc_utc = 0;
break;
case QEMU_OPTION_vga:
select_vgahw (optarg);
break;
+#if defined(TARGET_PPC) || defined(TARGET_SPARC)
case QEMU_OPTION_g:
{
const char *p;
graphic_depth = depth;
}
break;
+#endif
case QEMU_OPTION_echr:
{
char *r;
exit(1);
}
break;
+ case QEMU_OPTION_smbios:
+ if(smbios_entry_add(optarg) < 0) {
+ fprintf(stderr, "Wrong smbios provided\n");
+ exit(1);
+ }
+ break;
#endif
-#ifdef USE_KQEMU
+#ifdef CONFIG_KQEMU
case QEMU_OPTION_no_kqemu:
kqemu_allowed = 0;
break;
#ifdef CONFIG_KVM
case QEMU_OPTION_enable_kvm:
kvm_allowed = 1;
-#ifdef USE_KQEMU
+#ifdef CONFIG_KQEMU
kqemu_allowed = 0;
#endif
break;
case QEMU_OPTION_vnc:
vnc_display = optarg;
break;
+#ifdef TARGET_I386
case QEMU_OPTION_no_acpi:
acpi_enabled = 0;
break;
case QEMU_OPTION_no_hpet:
no_hpet = 1;
break;
+#endif
case QEMU_OPTION_no_reboot:
no_reboot = 1;
break;
exit(1);
}
break;
+#ifndef _WIN32
case QEMU_OPTION_daemonize:
daemonize = 1;
break;
+#endif
case QEMU_OPTION_option_rom:
if (nb_option_roms >= MAX_OPTION_ROMS) {
fprintf(stderr, "Too many option ROMs\n");
option_rom[nb_option_roms] = optarg;
nb_option_roms++;
break;
+#if defined(TARGET_ARM) || defined(TARGET_M68K)
case QEMU_OPTION_semihosting:
semihosting_enabled = 1;
break;
+#endif
case QEMU_OPTION_name:
qemu_name = optarg;
break;
case QEMU_OPTION_incoming:
incoming = optarg;
break;
+#ifndef _WIN32
case QEMU_OPTION_chroot:
chroot_dir = optarg;
break;
case QEMU_OPTION_runas:
run_as = optarg;
break;
+#endif
+#ifdef CONFIG_XEN
+ case QEMU_OPTION_xen_domid:
+ xen_domid = atoi(optarg);
+ break;
+ case QEMU_OPTION_xen_create:
+ xen_mode = XEN_CREATE;
+ break;
+ case QEMU_OPTION_xen_attach:
+ xen_mode = XEN_ATTACH;
+ break;
+#endif
}
}
}
-#if defined(CONFIG_KVM) && defined(USE_KQEMU)
+#if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
if (kvm_allowed && kqemu_allowed) {
fprintf(stderr,
"You can not enable both KVM and kqemu at the same time\n");
signal(SIGTTOU, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
}
-#endif
if (pid_file && qemu_create_pidfile(pid_file) != 0) {
if (daemonize) {
fprintf(stderr, "Could not acquire pid file\n");
exit(1);
}
+#endif
-#ifdef USE_KQEMU
+#ifdef CONFIG_KQEMU
if (smp_cpus > 1)
kqemu_allowed = 0;
#endif
linux_boot = (kernel_filename != NULL);
net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
- if (!linux_boot && net_boot == 0 &&
- !machine->nodisk_ok && nb_drives_opt == 0)
- help(1);
-
if (!linux_boot && *kernel_cmdline != '\0') {
fprintf(stderr, "-append only allowed with -kernel option\n");
exit(1);
exit(1);
/* init the memory */
- phys_ram_size = machine->ram_require & ~RAMSIZE_FIXED;
-
- if (machine->ram_require & RAMSIZE_FIXED) {
- if (ram_size > 0) {
- if (ram_size < phys_ram_size) {
- fprintf(stderr, "Machine `%s' requires %llu bytes of memory\n",
- machine->name, (unsigned long long) phys_ram_size);
- exit(-1);
- }
-
- phys_ram_size = ram_size;
- } else
- ram_size = phys_ram_size;
- } else {
- if (ram_size == 0)
- ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
-
- phys_ram_size += ram_size;
- }
-
- phys_ram_base = qemu_vmalloc(phys_ram_size);
- if (!phys_ram_base) {
- fprintf(stderr, "Could not allocate physical memory\n");
- exit(1);
+ if (ram_size == 0)
+ ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
+
+#ifdef CONFIG_KQEMU
+ /* 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_base = qemu_vmalloc(kqemu_phys_ram_size);
+ if (!kqemu_phys_ram_base) {
+ fprintf(stderr, "Could not allocate physical memory\n");
+ exit(1);
+ }
}
+#endif
/* init the dynamic translator */
cpu_exec_init_all(tb_size * 1024 * 1024);
bdrv_init();
+ dma_helper_init();
/* we always create the cdrom drive, even if no disk is there */
}
}
+ if (nb_numa_nodes > 0) {
+ int i;
+
+ if (nb_numa_nodes > smp_cpus) {
+ nb_numa_nodes = smp_cpus;
+ }
+
+ /* If no memory size if given for any node, assume the default case
+ * and distribute the available memory equally across all nodes
+ */
+ for (i = 0; i < nb_numa_nodes; i++) {
+ if (node_mem[i] != 0)
+ break;
+ }
+ if (i == nb_numa_nodes) {
+ uint64_t usedmem = 0;
+
+ /* On Linux, the each node's border has to be 8MB aligned,
+ * the final node gets the rest.
+ */
+ for (i = 0; i < nb_numa_nodes - 1; i++) {
+ node_mem[i] = (ram_size / nb_numa_nodes) & ~((1 << 23UL) - 1);
+ usedmem += node_mem[i];
+ }
+ node_mem[i] = ram_size - usedmem;
+ }
+
+ for (i = 0; i < nb_numa_nodes; i++) {
+ if (node_cpumask[i] != 0)
+ break;
+ }
+ /* assigning the VCPUs round-robin is easier to implement, guest OSes
+ * must cope with this anyway, because there are BIOSes out there in
+ * real machines which also use this scheme.
+ */
+ if (i == nb_numa_nodes) {
+ for (i = 0; i < smp_cpus; i++) {
+ node_cpumask[i % nb_numa_nodes] |= 1 << i;
+ }
+ }
+ }
+
if (kvm_enabled()) {
int ret;
machine->init(ram_size, vga_ram_size, boot_devices,
kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
+
+ for (env = first_cpu; env != NULL; env = env->next_cpu) {
+ for (i = 0; i < nb_numa_nodes; i++) {
+ if (node_cpumask[i] & (1 << env->cpu_index)) {
+ env->numa_node = i;
+ }
+ }
+ }
+
current_machine = machine;
/* Set KVM's vcpu state to qemu's initial CPUState. */
}
#ifdef CONFIG_GDBSTUB
- if (use_gdbstub) {
- /* XXX: use standard host:port notation and modify options
- accordingly. */
- if (gdbserver_start(gdbstub_port) < 0) {
- fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",
- gdbstub_port);
- exit(1);
- }
+ 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 (autostart)
vm_start();
+#ifndef _WIN32
if (daemonize) {
uint8_t status = 0;
ssize_t len;
exit(1);
}
-#ifndef _WIN32
if (run_as) {
pwd = getpwnam(run_as);
if (!pwd) {
exit(1);
}
}
-#endif
if (daemonize) {
dup2(fd, 0);
close(fd);
}
+#endif
main_loop();
quit_timers();