Diff for /qemu/vl.c between versions 1.1.1.11 and 1.1.1.12

version 1.1.1.11, 2018/04/24 17:16:12 version 1.1.1.12, 2018/04/24 17:20:16
Line 21 Line 21
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.   * THE SOFTWARE.
  */   */
 #include "hw/hw.h"  
 #include "hw/boards.h"  
 #include "hw/usb.h"  
 #include "hw/pcmcia.h"  
 #include "hw/pc.h"  
 #include "hw/audiodev.h"  
 #include "hw/isa.h"  
 #include "hw/baum.h"  
 #include "hw/bt.h"  
 #include "net.h"  
 #include "console.h"  
 #include "sysemu.h"  
 #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 <unistd.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <signal.h>  #include <signal.h>
Line 51 Line 29
 #include <sys/time.h>  #include <sys/time.h>
 #include <zlib.h>  #include <zlib.h>
   
   /* Needed early for HOST_BSD etc. */
   #include "config-host.h"
   /* Needed early to override system queue definitions on BSD */
   #include "sys-queue.h"
   
 #ifndef _WIN32  #ifndef _WIN32
   #include <libgen.h>
 #include <pwd.h>  #include <pwd.h>
 #include <sys/times.h>  #include <sys/times.h>
 #include <sys/wait.h>  #include <sys/wait.h>
Line 72 Line 56
 #include <dirent.h>  #include <dirent.h>
 #include <netdb.h>  #include <netdb.h>
 #include <sys/select.h>  #include <sys/select.h>
 #ifdef _BSD  #ifdef HOST_BSD
 #include <sys/stat.h>  #include <sys/stat.h>
 #ifdef __FreeBSD__  #if defined(__FreeBSD__) || defined(__DragonFly__)
 #include <libutil.h>  #include <libutil.h>
 #else  #else
 #include <util.h>  #include <util.h>
Line 86 Line 70
 #include <pty.h>  #include <pty.h>
 #include <malloc.h>  #include <malloc.h>
 #include <linux/rtc.h>  #include <linux/rtc.h>
   #include <sys/prctl.h>
   
 /* For the benefit of older linux systems which don't supply it,  /* For the benefit of older linux systems which don't supply it,
    we use a local copy of hpet.h. */     we use a local copy of hpet.h. */
Line 113 Line 98
 #endif  #endif
 #endif  #endif
   
 #include "qemu_socket.h"  
   
 #if defined(CONFIG_SLIRP)  
 #include "libslirp.h"  
 #endif  
   
 #if defined(__OpenBSD__)  #if defined(__OpenBSD__)
 #include <util.h>  #include <util.h>
 #endif  #endif
Line 128 Line 107
 #endif  #endif
   
 #ifdef _WIN32  #ifdef _WIN32
   #include <windows.h>
 #include <malloc.h>  #include <malloc.h>
 #include <sys/timeb.h>  #include <sys/timeb.h>
 #include <mmsystem.h>  #include <mmsystem.h>
Line 136 Line 116
 #endif  #endif
   
 #ifdef CONFIG_SDL  #ifdef CONFIG_SDL
 #ifdef __APPLE__  #if defined(__APPLE__) || defined(main)
 #include <SDL/SDL.h>  #include <SDL.h>
 int qemu_main(int argc, char **argv, char **envp);  int qemu_main(int argc, char **argv, char **envp);
 int main(int argc, char **argv)  int main(int argc, char **argv)
 {  {
     qemu_main(argc, argv, NULL);      return qemu_main(argc, argv, NULL);
 }  }
 #undef main  #undef main
 #define main qemu_main  #define main qemu_main
Line 153  int main(int argc, char **argv) Line 133  int main(int argc, char **argv)
 #define main qemu_main  #define main qemu_main
 #endif /* CONFIG_COCOA */  #endif /* CONFIG_COCOA */
   
   #include "hw/hw.h"
   #include "hw/boards.h"
   #include "hw/usb.h"
   #include "hw/pcmcia.h"
   #include "hw/pc.h"
   #include "hw/audiodev.h"
   #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"
   #include "net.h"
   #include "monitor.h"
   #include "console.h"
   #include "sysemu.h"
   #include "gdbstub.h"
   #include "qemu-timer.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"
   #include "balloon.h"
   #include "qemu-option.h"
   
 #include "disas.h"  #include "disas.h"
   
 #include "exec-all.h"  #include "exec-all.h"
   
 //#define DEBUG_UNUSED_IOPORT  #include "qemu_socket.h"
 //#define DEBUG_IOPORT  
 //#define DEBUG_NET  
 //#define DEBUG_SLIRP  
   
   #include "slirp/libslirp.h"
   
 #ifdef DEBUG_IOPORT  //#define DEBUG_NET
 #  define LOG_IOPORT(...) qemu_log_mask(CPU_LOG_IOPORT, ## __VA_ARGS__)  //#define DEBUG_SLIRP
 #else  
 #  define LOG_IOPORT(...) do { } while (0)  
 #endif  
   
 #define DEFAULT_RAM_SIZE 128  #define DEFAULT_RAM_SIZE 128
   
Line 177  int main(int argc, char **argv) Line 181  int main(int argc, char **argv)
 /* Max number of bluetooth switches on the commandline.  */  /* Max number of bluetooth switches on the commandline.  */
 #define MAX_BT_CMDLINE 10  #define MAX_BT_CMDLINE 10
   
 /* XXX: use a two level table to limit memory usage */  static const char *data_dir;
 #define MAX_IOPORTS 65536  
   
 const char *bios_dir = CONFIG_QEMU_SHAREDIR;  
 const char *bios_name = NULL;  const char *bios_name = NULL;
 static void *ioport_opaque[MAX_IOPORTS];  
 static IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];  
 static IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];  
 /* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available  /* Note: drives_table[MAX_DRIVES] is a dummy block driver if none available
    to store the VM snapshots */     to store the VM snapshots */
 DriveInfo drives_table[MAX_DRIVES+1];  DriveInfo drives_table[MAX_DRIVES+1];
 int nb_drives;  int nb_drives;
 static int vga_ram_size;  
 enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;  enum vga_retrace_method vga_retrace_method = VGA_RETRACE_DUMB;
 static DisplayState *display_state;  static DisplayState *display_state;
 int nographic;  DisplayType display_type = DT_DEFAULT;
 static int curses;  
 static int sdl;  
 const char* keyboard_layout = NULL;  const char* keyboard_layout = NULL;
 int64_t ticks_per_sec;  int64_t ticks_per_sec;
 ram_addr_t ram_size;  ram_addr_t ram_size;
 int nb_nics;  int nb_nics;
 NICInfo nd_table[MAX_NICS];  NICInfo nd_table[MAX_NICS];
 int vm_running;  int vm_running;
 static int autostart;  int autostart;
 static int rtc_utc = 1;  static int rtc_utc = 1;
 static int rtc_date_offset = -1; /* -1 means no change */  static int rtc_date_offset = -1; /* -1 means no change */
 int cirrus_vga_enabled = 1;  int vga_interface_type = VGA_CIRRUS;
 int std_vga_enabled = 0;  
 int vmsvga_enabled = 0;  
 #ifdef TARGET_SPARC  #ifdef TARGET_SPARC
 int graphic_width = 1024;  int graphic_width = 1024;
 int graphic_height = 768;  int graphic_height = 768;
Line 229  int win2k_install_hack = 0; Line 222  int win2k_install_hack = 0;
 int rtc_td_hack = 0;  int rtc_td_hack = 0;
 #endif  #endif
 int usb_enabled = 0;  int usb_enabled = 0;
   int singlestep = 0;
 int smp_cpus = 1;  int smp_cpus = 1;
 const char *vnc_display;  const char *vnc_display;
 int acpi_enabled = 1;  int acpi_enabled = 1;
 int no_hpet = 0;  int no_hpet = 0;
   int virtio_balloon = 1;
   const char *virtio_balloon_devaddr;
 int fd_bootchk = 1;  int fd_bootchk = 1;
 int no_reboot = 0;  int no_reboot = 0;
 int no_shutdown = 0;  int no_shutdown = 0;
 int cursor_hide = 1;  int cursor_hide = 1;
 int graphic_rotate = 0;  int graphic_rotate = 0;
   #ifndef _WIN32
 int daemonize = 0;  int daemonize = 0;
   #endif
   WatchdogTimerModel *watchdog = NULL;
   int watchdog_action = WDT_RESET;
 const char *option_rom[MAX_OPTION_ROMS];  const char *option_rom[MAX_OPTION_ROMS];
 int nb_option_roms;  int nb_option_roms;
 int semihosting_enabled = 0;  int semihosting_enabled = 0;
Line 253  const char *prom_envs[MAX_PROM_ENVS]; Line 253  const char *prom_envs[MAX_PROM_ENVS];
 #endif  #endif
 int nb_drives_opt;  int nb_drives_opt;
 struct drive_opt drives_opt[MAX_DRIVES];  struct drive_opt drives_opt[MAX_DRIVES];
   int boot_menu;
   
   int nb_numa_nodes;
   uint64_t node_mem[MAX_NODES];
   uint64_t node_cpumask[MAX_NODES];
   
 static CPUState *cur_cpu;  static CPUState *cur_cpu;
 static CPUState *next_cpu;  static CPUState *next_cpu;
 static int event_pending = 1;  static int timer_alarm_pending = 1;
 /* Conversion factor from emulated instructions to virtual clock ticks.  */  /* Conversion factor from emulated instructions to virtual clock ticks.  */
 static int icount_time_shift;  static int icount_time_shift;
 /* Arbitrarily pick 1MIPS as the minimum allowable speed.  */  /* Arbitrarily pick 1MIPS as the minimum allowable speed.  */
Line 269  static QEMUTimer *nographic_timer; Line 274  static QEMUTimer *nographic_timer;
   
 uint8_t qemu_uuid[16];  uint8_t qemu_uuid[16];
   
   static QEMUBootSetHandler *boot_set_handler;
   static void *boot_set_opaque;
   
 /***********************************************************/  /***********************************************************/
 /* x86 ISA bus support */  /* x86 ISA bus support */
   
 target_phys_addr_t isa_mem_base = 0;  target_phys_addr_t isa_mem_base = 0;
 PicState2 *isa_pic;  PicState2 *isa_pic;
   
 static IOPortReadFunc default_ioport_readb, default_ioport_readw, default_ioport_readl;  
 static IOPortWriteFunc default_ioport_writeb, default_ioport_writew, default_ioport_writel;  
   
 static uint32_t ioport_read(int index, uint32_t address)  
 {  
     static IOPortReadFunc *default_func[3] = {  
         default_ioport_readb,  
         default_ioport_readw,  
         default_ioport_readl  
     };  
     IOPortReadFunc *func = ioport_read_table[index][address];  
     if (!func)  
         func = default_func[index];  
     return func(ioport_opaque[address], address);  
 }  
   
 static void ioport_write(int index, uint32_t address, uint32_t data)  
 {  
     static IOPortWriteFunc *default_func[3] = {  
         default_ioport_writeb,  
         default_ioport_writew,  
         default_ioport_writel  
     };  
     IOPortWriteFunc *func = ioport_write_table[index][address];  
     if (!func)  
         func = default_func[index];  
     func(ioport_opaque[address], address, data);  
 }  
   
 static uint32_t default_ioport_readb(void *opaque, uint32_t address)  
 {  
 #ifdef DEBUG_UNUSED_IOPORT  
     fprintf(stderr, "unused inb: port=0x%04x\n", address);  
 #endif  
     return 0xff;  
 }  
   
 static void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data)  
 {  
 #ifdef DEBUG_UNUSED_IOPORT  
     fprintf(stderr, "unused outb: port=0x%04x data=0x%02x\n", address, data);  
 #endif  
 }  
   
 /* default is to make two byte accesses */  
 static uint32_t default_ioport_readw(void *opaque, uint32_t address)  
 {  
     uint32_t data;  
     data = ioport_read(0, address);  
     address = (address + 1) & (MAX_IOPORTS - 1);  
     data |= ioport_read(0, address) << 8;  
     return data;  
 }  
   
 static void default_ioport_writew(void *opaque, uint32_t address, uint32_t data)  
 {  
     ioport_write(0, address, data & 0xff);  
     address = (address + 1) & (MAX_IOPORTS - 1);  
     ioport_write(0, address, (data >> 8) & 0xff);  
 }  
   
 static uint32_t default_ioport_readl(void *opaque, uint32_t address)  
 {  
 #ifdef DEBUG_UNUSED_IOPORT  
     fprintf(stderr, "unused inl: port=0x%04x\n", address);  
 #endif  
     return 0xffffffff;  
 }  
   
 static void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)  
 {  
 #ifdef DEBUG_UNUSED_IOPORT  
     fprintf(stderr, "unused outl: port=0x%04x data=0x%02x\n", address, data);  
 #endif  
 }  
   
 /* size is the word size in byte */  
 int register_ioport_read(int start, int length, int size,  
                          IOPortReadFunc *func, void *opaque)  
 {  
     int i, bsize;  
   
     if (size == 1) {  
         bsize = 0;  
     } else if (size == 2) {  
         bsize = 1;  
     } else if (size == 4) {  
         bsize = 2;  
     } else {  
         hw_error("register_ioport_read: invalid size");  
         return -1;  
     }  
     for(i = start; i < start + length; i += size) {  
         ioport_read_table[bsize][i] = func;  
         if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)  
             hw_error("register_ioport_read: invalid opaque");  
         ioport_opaque[i] = opaque;  
     }  
     return 0;  
 }  
   
 /* size is the word size in byte */  
 int register_ioport_write(int start, int length, int size,  
                           IOPortWriteFunc *func, void *opaque)  
 {  
     int i, bsize;  
   
     if (size == 1) {  
         bsize = 0;  
     } else if (size == 2) {  
         bsize = 1;  
     } else if (size == 4) {  
         bsize = 2;  
     } else {  
         hw_error("register_ioport_write: invalid size");  
         return -1;  
     }  
     for(i = start; i < start + length; i += size) {  
         ioport_write_table[bsize][i] = func;  
         if (ioport_opaque[i] != NULL && ioport_opaque[i] != opaque)  
             hw_error("register_ioport_write: invalid opaque");  
         ioport_opaque[i] = opaque;  
     }  
     return 0;  
 }  
   
 void isa_unassign_ioport(int start, int length)  
 {  
     int i;  
   
     for(i = start; i < start + length; i++) {  
         ioport_read_table[0][i] = default_ioport_readb;  
         ioport_read_table[1][i] = default_ioport_readw;  
         ioport_read_table[2][i] = default_ioport_readl;  
   
         ioport_write_table[0][i] = default_ioport_writeb;  
         ioport_write_table[1][i] = default_ioport_writew;  
         ioport_write_table[2][i] = default_ioport_writel;  
   
         ioport_opaque[i] = NULL;  
     }  
 }  
   
 /***********************************************************/  
   
 void cpu_outb(CPUState *env, int addr, int val)  
 {  
     LOG_IOPORT("outb: %04x %02x\n", addr, val);  
     ioport_write(0, addr, val);  
 #ifdef USE_KQEMU  
     if (env)  
         env->last_io_time = cpu_get_time_fast();  
 #endif  
 }  
   
 void cpu_outw(CPUState *env, int addr, int val)  
 {  
     LOG_IOPORT("outw: %04x %04x\n", addr, val);  
     ioport_write(1, addr, val);  
 #ifdef USE_KQEMU  
     if (env)  
         env->last_io_time = cpu_get_time_fast();  
 #endif  
 }  
   
 void cpu_outl(CPUState *env, int addr, int val)  
 {  
     LOG_IOPORT("outl: %04x %08x\n", addr, val);  
     ioport_write(2, addr, val);  
 #ifdef USE_KQEMU  
     if (env)  
         env->last_io_time = cpu_get_time_fast();  
 #endif  
 }  
   
 int cpu_inb(CPUState *env, int addr)  
 {  
     int val;  
     val = ioport_read(0, addr);  
     LOG_IOPORT("inb : %04x %02x\n", addr, val);  
 #ifdef USE_KQEMU  
     if (env)  
         env->last_io_time = cpu_get_time_fast();  
 #endif  
     return val;  
 }  
   
 int cpu_inw(CPUState *env, int addr)  
 {  
     int val;  
     val = ioport_read(1, addr);  
     LOG_IOPORT("inw : %04x %04x\n", addr, val);  
 #ifdef USE_KQEMU  
     if (env)  
         env->last_io_time = cpu_get_time_fast();  
 #endif  
     return val;  
 }  
   
 int cpu_inl(CPUState *env, int addr)  
 {  
     int val;  
     val = ioport_read(2, addr);  
     LOG_IOPORT("inl : %04x %08x\n", addr, val);  
 #ifdef USE_KQEMU  
     if (env)  
         env->last_io_time = cpu_get_time_fast();  
 #endif  
     return val;  
 }  
   
 /***********************************************************/  /***********************************************************/
 void hw_error(const char *fmt, ...)  void hw_error(const char *fmt, ...)
 {  {
Line 507  void hw_error(const char *fmt, ...) Line 304  void hw_error(const char *fmt, ...)
     va_end(ap);      va_end(ap);
     abort();      abort();
 }  }
   
   static void set_proc_name(const char *s)
   {
   #if defined(__linux__) && defined(PR_SET_NAME)
       char name[16];
       if (!s)
           return;
       name[sizeof(name) - 1] = 0;
       strncpy(name, s, sizeof(name));
       /* Could rewrite argv[0] too, but that's a bit more complicated.
          This simple way is enough for `top'. */
       prctl(PR_SET_NAME, name);
   #endif          
   }
     
 /***************/  /***************/
 /* ballooning */  /* ballooning */
Line 653  int kbd_mouse_is_absolute(void) Line 464  int kbd_mouse_is_absolute(void)
     return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;      return qemu_put_mouse_event_current->qemu_put_mouse_event_absolute;
 }  }
   
 void do_info_mice(void)  void do_info_mice(Monitor *mon)
 {  {
     QEMUPutMouseEntry *cursor;      QEMUPutMouseEntry *cursor;
     int index = 0;      int index = 0;
   
     if (!qemu_put_mouse_event_head) {      if (!qemu_put_mouse_event_head) {
         term_printf("No mouse devices connected\n");          monitor_printf(mon, "No mouse devices connected\n");
         return;          return;
     }      }
   
     term_printf("Mouse devices available:\n");      monitor_printf(mon, "Mouse devices available:\n");
     cursor = qemu_put_mouse_event_head;      cursor = qemu_put_mouse_event_head;
     while (cursor != NULL) {      while (cursor != NULL) {
         term_printf("%c Mouse #%d: %s\n",          monitor_printf(mon, "%c Mouse #%d: %s\n",
                     (cursor == qemu_put_mouse_event_current ? '*' : ' '),                         (cursor == qemu_put_mouse_event_current ? '*' : ' '),
                     index, cursor->qemu_put_mouse_event_name);                         index, cursor->qemu_put_mouse_event_name);
         index++;          index++;
         cursor = cursor->next;          cursor = cursor->next;
     }      }
 }  }
   
 void do_mouse_set(int index)  void do_mouse_set(Monitor *mon, int index)
 {  {
     QEMUPutMouseEntry *cursor;      QEMUPutMouseEntry *cursor;
     int i = 0;      int i = 0;
   
     if (!qemu_put_mouse_event_head) {      if (!qemu_put_mouse_event_head) {
         term_printf("No mouse devices connected\n");          monitor_printf(mon, "No mouse devices connected\n");
         return;          return;
     }      }
   
Line 693  void do_mouse_set(int index) Line 504  void do_mouse_set(int index)
     if (cursor != NULL)      if (cursor != NULL)
         qemu_put_mouse_event_current = cursor;          qemu_put_mouse_event_current = cursor;
     else      else
         term_printf("Mouse at given index not found\n");          monitor_printf(mon, "Mouse at given index not found\n");
 }  }
   
 /* compute with 96 bit intermediate result: (a*b)/c */  /* compute with 96 bit intermediate result: (a*b)/c */
Line 755  static int use_rt_clock; Line 566  static int use_rt_clock;
 static void init_get_clock(void)  static void init_get_clock(void)
 {  {
     use_rt_clock = 0;      use_rt_clock = 0;
 #if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000)  #if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
       || defined(__DragonFly__)
     {      {
         struct timespec ts;          struct timespec ts;
         if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {          if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
Line 767  static void init_get_clock(void) Line 579  static void init_get_clock(void)
   
 static int64_t get_clock(void)  static int64_t get_clock(void)
 {  {
 #if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000)  #if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
           || defined(__DragonFly__)
     if (use_rt_clock) {      if (use_rt_clock) {
         struct timespec ts;          struct timespec ts;
         clock_gettime(CLOCK_MONOTONIC, &ts);          clock_gettime(CLOCK_MONOTONIC, &ts);
Line 909  static void qemu_rearm_alarm_timer(struc Line 722  static void qemu_rearm_alarm_timer(struc
 #define MIN_TIMER_REARM_US 250  #define MIN_TIMER_REARM_US 250
   
 static struct qemu_alarm_timer *alarm_timer;  static struct qemu_alarm_timer *alarm_timer;
 #ifndef _WIN32  
 static int alarm_timer_rfd, alarm_timer_wfd;  
 #endif  
   
 #ifdef _WIN32  #ifdef _WIN32
   
 struct qemu_alarm_win32 {  struct qemu_alarm_win32 {
     MMRESULT timerId;      MMRESULT timerId;
     HANDLE host_alarm;  
     unsigned int period;      unsigned int period;
 } alarm_win32_data = {0, NULL, -1};  } alarm_win32_data = {0, -1};
   
 static int win32_start_timer(struct qemu_alarm_timer *t);  static int win32_start_timer(struct qemu_alarm_timer *t);
 static void win32_stop_timer(struct qemu_alarm_timer *t);  static void win32_stop_timer(struct qemu_alarm_timer *t);
Line 1174  void qemu_mod_timer(QEMUTimer *ts, int64 Line 983  void qemu_mod_timer(QEMUTimer *ts, int64
             qemu_rearm_alarm_timer(alarm_timer);              qemu_rearm_alarm_timer(alarm_timer);
         }          }
         /* Interrupt execution to force deadline recalculation.  */          /* Interrupt execution to force deadline recalculation.  */
         if (use_icount && cpu_single_env) {          if (use_icount)
             cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);              qemu_notify_event();
         }  
     }      }
 }  }
   
Line 1287  static int timer_load(QEMUFile *f, void  Line 1095  static int timer_load(QEMUFile *f, void 
     return 0;      return 0;
 }  }
   
   static void qemu_event_increment(void);
   
 #ifdef _WIN32  #ifdef _WIN32
 void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,  static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
                                  DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)                                          DWORD_PTR dwUser, DWORD_PTR dw1,
                                           DWORD_PTR dw2)
 #else  #else
 static void host_alarm_handler(int host_signum)  static void host_alarm_handler(int host_signum)
 #endif  #endif
Line 1329  static void host_alarm_handler(int host_ Line 1140  static void host_alarm_handler(int host_
                                qemu_get_clock(vm_clock))) ||                                 qemu_get_clock(vm_clock))) ||
         qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],          qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
                            qemu_get_clock(rt_clock))) {                             qemu_get_clock(rt_clock))) {
         CPUState *env = next_cpu;          qemu_event_increment();
   
 #ifdef _WIN32  
         struct qemu_alarm_win32 *data = ((struct qemu_alarm_timer*)dwUser)->priv;  
         SetEvent(data->host_alarm);  
 #else  
         static const char byte = 0;  
         write(alarm_timer_wfd, &byte, sizeof(byte));  
 #endif  
         if (alarm_timer) alarm_timer->flags |= ALARM_FLAG_EXPIRED;          if (alarm_timer) alarm_timer->flags |= ALARM_FLAG_EXPIRED;
   
         if (env) {  #ifndef CONFIG_IOTHREAD
           if (next_cpu) {
             /* stop the currently executing cpu because a timer occured */              /* stop the currently executing cpu because a timer occured */
             cpu_interrupt(env, CPU_INTERRUPT_EXIT);              cpu_exit(next_cpu);
 #ifdef USE_KQEMU  #ifdef CONFIG_KQEMU
             if (env->kqemu_enabled) {              if (next_cpu->kqemu_enabled) {
                 kqemu_cpu_interrupt(env);                  kqemu_cpu_interrupt(next_cpu);
             }              }
 #endif  #endif
         }          }
         event_pending = 1;  #endif
           timer_alarm_pending = 1;
           qemu_notify_event();
     }      }
 }  }
   
Line 1630  static void unix_stop_timer(struct qemu_ Line 1436  static void unix_stop_timer(struct qemu_
   
 #endif /* !defined(_WIN32) */  #endif /* !defined(_WIN32) */
   
 static void try_to_rearm_timer(void *opaque)  
 {  
     struct qemu_alarm_timer *t = opaque;  
 #ifndef _WIN32  
     ssize_t len;  
   
     /* Drain the notify pipe */  
     do {  
         char buffer[512];  
         len = read(alarm_timer_rfd, buffer, sizeof(buffer));  
     } while ((len == -1 && errno == EINTR) || len > 0);  
 #endif  
   
     if (t->flags & ALARM_FLAG_EXPIRED) {  
         alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;  
         qemu_rearm_alarm_timer(alarm_timer);  
     }  
 }  
   
 #ifdef _WIN32  #ifdef _WIN32
   
Line 1657  static int win32_start_timer(struct qemu Line 1445  static int win32_start_timer(struct qemu
     struct qemu_alarm_win32 *data = t->priv;      struct qemu_alarm_win32 *data = t->priv;
     UINT flags;      UINT flags;
   
     data->host_alarm = CreateEvent(NULL, FALSE, FALSE, NULL);  
     if (!data->host_alarm) {  
         perror("Failed CreateEvent");  
         return -1;  
     }  
   
     memset(&tc, 0, sizeof(tc));      memset(&tc, 0, sizeof(tc));
     timeGetDevCaps(&tc, sizeof(tc));      timeGetDevCaps(&tc, sizeof(tc));
   
Line 1685  static int win32_start_timer(struct qemu Line 1467  static int win32_start_timer(struct qemu
   
     if (!data->timerId) {      if (!data->timerId) {
         perror("Failed to initialize win32 alarm timer");          perror("Failed to initialize win32 alarm timer");
   
         timeEndPeriod(data->period);          timeEndPeriod(data->period);
         CloseHandle(data->host_alarm);  
         return -1;          return -1;
     }      }
   
     qemu_add_wait_object(data->host_alarm, try_to_rearm_timer, t);  
   
     return 0;      return 0;
 }  }
   
Line 1702  static void win32_stop_timer(struct qemu Line 1480  static void win32_stop_timer(struct qemu
   
     timeKillEvent(data->timerId);      timeKillEvent(data->timerId);
     timeEndPeriod(data->period);      timeEndPeriod(data->period);
   
     CloseHandle(data->host_alarm);  
 }  }
   
 static void win32_rearm_timer(struct qemu_alarm_timer *t)  static void win32_rearm_timer(struct qemu_alarm_timer *t)
Line 1730  static void win32_rearm_timer(struct qem Line 1506  static void win32_rearm_timer(struct qem
         perror("Failed to re-arm win32 alarm timer");          perror("Failed to re-arm win32 alarm timer");
   
         timeEndPeriod(data->period);          timeEndPeriod(data->period);
         CloseHandle(data->host_alarm);  
         exit(1);          exit(1);
     }      }
 }  }
Line 1742  static int init_timer_alarm(void) Line 1517  static int init_timer_alarm(void)
     struct qemu_alarm_timer *t = NULL;      struct qemu_alarm_timer *t = NULL;
     int i, err = -1;      int i, err = -1;
   
 #ifndef _WIN32  
     int fds[2];  
   
     err = pipe(fds);  
     if (err == -1)  
         return -errno;  
   
     err = fcntl_setfl(fds[0], O_NONBLOCK);  
     if (err < 0)  
         goto fail;  
   
     err = fcntl_setfl(fds[1], O_NONBLOCK);  
     if (err < 0)  
         goto fail;  
   
     alarm_timer_rfd = fds[0];  
     alarm_timer_wfd = fds[1];  
 #endif  
   
     for (i = 0; alarm_timers[i].name; i++) {      for (i = 0; alarm_timers[i].name; i++) {
         t = &alarm_timers[i];          t = &alarm_timers[i];
   
Line 1774  static int init_timer_alarm(void) Line 1530  static int init_timer_alarm(void)
         goto fail;          goto fail;
     }      }
   
 #ifndef _WIN32  
     qemu_set_fd_handler2(alarm_timer_rfd, NULL,  
                          try_to_rearm_timer, NULL, t);  
 #endif  
   
     alarm_timer = t;      alarm_timer = t;
   
     return 0;      return 0;
   
 fail:  fail:
 #ifndef _WIN32  
     close(fds[0]);  
     close(fds[1]);  
 #endif  
     return err;      return err;
 }  }
   
Line 1856  static int socket_init(void) Line 1603  static int socket_init(void)
 }  }
 #endif  #endif
   
 const char *get_opt_name(char *buf, int buf_size, const char *p)  int get_next_param_value(char *buf, int buf_size,
 {                           const char *tag, const char **pstr)
     char *q;  
   
     q = buf;  
     while (*p != '\0' && *p != '=') {  
         if (q && (q - buf) < buf_size - 1)  
             *q++ = *p;  
         p++;  
     }  
     if (q)  
         *q = '\0';  
   
     return p;  
 }  
   
 const char *get_opt_value(char *buf, int buf_size, const char *p)  
 {  
     char *q;  
   
     q = buf;  
     while (*p != '\0') {  
         if (*p == ',') {  
             if (*(p + 1) != ',')  
                 break;  
             p++;  
         }  
         if (q && (q - buf) < buf_size - 1)  
             *q++ = *p;  
         p++;  
     }  
     if (q)  
         *q = '\0';  
   
     return p;  
 }  
   
 int get_param_value(char *buf, int buf_size,  
                     const char *tag, const char *str)  
 {  {
     const char *p;      const char *p;
     char option[128];      char option[128];
   
     p = str;      p = *pstr;
     for(;;) {      for(;;) {
         p = get_opt_name(option, sizeof(option), p);          p = get_opt_name(option, sizeof(option), p, '=');
         if (*p != '=')          if (*p != '=')
             break;              break;
         p++;          p++;
         if (!strcmp(tag, option)) {          if (!strcmp(tag, option)) {
             (void)get_opt_value(buf, buf_size, p);              *pstr = get_opt_value(buf, buf_size, p);
               if (**pstr == ',') {
                   (*pstr)++;
               }
             return strlen(buf);              return strlen(buf);
         } else {          } else {
             p = get_opt_value(NULL, 0, p);              p = get_opt_value(NULL, 0, p);
Line 1918  int get_param_value(char *buf, int buf_s Line 1631  int get_param_value(char *buf, int buf_s
     return 0;      return 0;
 }  }
   
   int get_param_value(char *buf, int buf_size,
                       const char *tag, const char *str)
   {
       return get_next_param_value(buf, buf_size, tag, &str);
   }
   
 int check_params(char *buf, int buf_size,  int check_params(char *buf, int buf_size,
                  const char * const *params, const char *str)                   const char * const *params, const char *str)
 {  {
Line 1925  int check_params(char *buf, int buf_size Line 1644  int check_params(char *buf, int buf_size
     int i;      int i;
   
     p = str;      p = str;
     for(;;) {      while (*p != '\0') {
         p = get_opt_name(buf, buf_size, p);          p = get_opt_name(buf, buf_size, p, '=');
         if (*p != '=')          if (*p != '=') {
             return -1;              return -1;
           }
         p++;          p++;
         for(i = 0; params[i] != NULL; i++)          for (i = 0; params[i] != NULL; i++) {
             if (!strcmp(params[i], buf))              if (!strcmp(params[i], buf)) {
                 break;                  break;
         if (params[i] == NULL)              }
           }
           if (params[i] == NULL) {
             return -1;              return -1;
           }
         p = get_opt_value(NULL, 0, p);          p = get_opt_value(NULL, 0, p);
         if (*p != ',')          if (*p != ',') {
             break;              break;
           }
         p++;          p++;
     }      }
     return 0;      return 0;
Line 2138  static int bt_parse(const char *opt) Line 1862  static int bt_parse(const char *opt)
 /* QEMU Block devices */  /* QEMU Block devices */
   
 #define HD_ALIAS "index=%d,media=disk"  #define HD_ALIAS "index=%d,media=disk"
 #ifdef TARGET_PPC  
 #define CDROM_ALIAS "index=1,media=cdrom"  
 #else  
 #define CDROM_ALIAS "index=2,media=cdrom"  #define CDROM_ALIAS "index=2,media=cdrom"
 #endif  
 #define FD_ALIAS "index=%d,if=floppy"  #define FD_ALIAS "index=%d,if=floppy"
 #define PFLASH_ALIAS "if=pflash"  #define PFLASH_ALIAS "if=pflash"
 #define MTD_ALIAS "if=mtd"  #define MTD_ALIAS "if=mtd"
Line 2289  int drive_init(struct drive_opt *arg, in Line 2009  int drive_init(struct drive_opt *arg, in
     int index;      int index;
     int cache;      int cache;
     int bdrv_flags, onerror;      int bdrv_flags, onerror;
       const char *devaddr;
     int drives_table_idx;      int drives_table_idx;
     char *str = arg->opt;      char *str = arg->opt;
     static const char * const params[] = { "bus", "unit", "if", "index",      static const char * const params[] = { "bus", "unit", "if", "index",
                                            "cyls", "heads", "secs", "trans",                                             "cyls", "heads", "secs", "trans",
                                            "media", "snapshot", "file",                                             "media", "snapshot", "file",
                                            "cache", "format", "serial", "werror",                                             "cache", "format", "serial",
                                              "werror", "addr",
                                            NULL };                                             NULL };
   
     if (check_params(buf, sizeof(buf), params, str) < 0) {      if (check_params(buf, sizeof(buf), params, str) < 0) {
Line 2309  int drive_init(struct drive_opt *arg, in Line 2031  int drive_init(struct drive_opt *arg, in
     unit_id = -1;      unit_id = -1;
     translation = BIOS_ATA_TRANSLATION_AUTO;      translation = BIOS_ATA_TRANSLATION_AUTO;
     index = -1;      index = -1;
     cache = 3;      cache = 1;
   
     if (machine->use_scsi) {      if (machine->use_scsi) {
         type = IF_SCSI;          type = IF_SCSI;
Line 2363  int drive_init(struct drive_opt *arg, in Line 2085  int drive_init(struct drive_opt *arg, in
         } else if (!strcmp(buf, "virtio")) {          } else if (!strcmp(buf, "virtio")) {
             type = IF_VIRTIO;              type = IF_VIRTIO;
             max_devs = 0;              max_devs = 0;
         } else {          } else if (!strcmp(buf, "xen")) {
               type = IF_XEN;
               max_devs = 0;
           } else {
             fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);              fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);
             return -1;              return -1;
         }          }
Line 2505  int drive_init(struct drive_opt *arg, in Line 2230  int drive_init(struct drive_opt *arg, in
         }          }
     }      }
   
       devaddr = NULL;
       if (get_param_value(buf, sizeof(buf), "addr", str)) {
           if (type != IF_VIRTIO) {
               fprintf(stderr, "addr is not supported by in '%s'\n", str);
               return -1;
           }
           devaddr = strdup(buf);
       }
   
     /* compute bus and unit according index */      /* compute bus and unit according index */
   
     if (index != -1) {      if (index != -1) {
Line 2566  int drive_init(struct drive_opt *arg, in Line 2300  int drive_init(struct drive_opt *arg, in
     bdrv = bdrv_new(buf);      bdrv = bdrv_new(buf);
     drives_table_idx = drive_get_free_idx();      drives_table_idx = drive_get_free_idx();
     drives_table[drives_table_idx].bdrv = bdrv;      drives_table[drives_table_idx].bdrv = bdrv;
       drives_table[drives_table_idx].devaddr = devaddr;
     drives_table[drives_table_idx].type = type;      drives_table[drives_table_idx].type = type;
     drives_table[drives_table_idx].bus = bus_id;      drives_table[drives_table_idx].bus = bus_id;
     drives_table[drives_table_idx].unit = unit_id;      drives_table[drives_table_idx].unit = unit_id;
Line 2577  int drive_init(struct drive_opt *arg, in Line 2312  int drive_init(struct drive_opt *arg, in
     switch(type) {      switch(type) {
     case IF_IDE:      case IF_IDE:
     case IF_SCSI:      case IF_SCSI:
       case IF_XEN:
         switch(media) {          switch(media) {
         case MEDIA_DISK:          case MEDIA_DISK:
             if (cyls != 0) {              if (cyls != 0) {
Line 2599  int drive_init(struct drive_opt *arg, in Line 2335  int drive_init(struct drive_opt *arg, in
     case IF_MTD:      case IF_MTD:
     case IF_VIRTIO:      case IF_VIRTIO:
         break;          break;
       case IF_COUNT:
           abort();
     }      }
     if (!file[0])      if (!file[0])
         return -2;          return -2;
Line 2611  int drive_init(struct drive_opt *arg, in Line 2349  int drive_init(struct drive_opt *arg, in
         bdrv_flags |= BDRV_O_NOCACHE;          bdrv_flags |= BDRV_O_NOCACHE;
     else if (cache == 2) /* write-back */      else if (cache == 2) /* write-back */
         bdrv_flags |= BDRV_O_CACHE_WB;          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) {      if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) {
         fprintf(stderr, "qemu: could not open disk image %s\n",          fprintf(stderr, "qemu: could not open disk image %s\n",
                         file);                          file);
Line 2623  int drive_init(struct drive_opt *arg, in Line 2359  int drive_init(struct drive_opt *arg, in
     return drives_table_idx;      return drives_table_idx;
 }  }
   
 /***********************************************************/  void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque)
 /* USB devices */  {
       boot_set_handler = func;
 static USBPort *used_usb_ports;      boot_set_opaque = opaque;
 static USBPort *free_usb_ports;  }
   
 /* ??? Maybe change this to register a hub to keep track of the topology.  */  int qemu_boot_set(const char *boot_devices)
   {
       if (!boot_set_handler) {
           return -EINVAL;
       }
       return boot_set_handler(boot_set_opaque, boot_devices);
   }
   
   static int parse_bootdevices(char *devices)
   {
       /* We just do some generic consistency checks */
       const char *p;
       int bitmap = 0;
   
       for (p = devices; *p != '\0'; p++) {
           /* Allowed boot devices are:
            * a-b: floppy disk drives
            * c-f: IDE disk drives
            * g-m: machine implementation dependant drives
            * n-p: network devices
            * It's up to each machine implementation to check if the given boot
            * devices match the actual hardware implementation and firmware
            * features.
            */
           if (*p < 'a' || *p > 'p') {
               fprintf(stderr, "Invalid boot device '%c'\n", *p);
               exit(1);
           }
           if (bitmap & (1 << (*p - 'a'))) {
               fprintf(stderr, "Boot device '%c' was given twice\n", *p);
               exit(1);
           }
           bitmap |= 1 << (*p - 'a');
       }
       return bitmap;
   }
   
   static void restore_boot_devices(void *opaque)
   {
       char *standard_boot_devices = opaque;
   
       qemu_boot_set(standard_boot_devices);
   
       qemu_unregister_reset(restore_boot_devices, standard_boot_devices);
       qemu_free(standard_boot_devices);
   }
   
   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 */
   
   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,  void qemu_register_usb_port(USBPort *port, void *opaque, int index,
                             usb_attachfn attach)                              usb_attachfn attach)
 {  {
Line 2666  int usb_device_add_dev(USBDevice *dev) Line 2511  int usb_device_add_dev(USBDevice *dev)
     return 0;      return 0;
 }  }
   
   static void usb_msd_password_cb(void *opaque, int err)
   {
       USBDevice *dev = opaque;
   
       if (!err)
           usb_device_add_dev(dev);
       else
           dev->handle_destroy(dev);
   }
   
 static int usb_device_add(const char *devname, int is_hotplug)  static int usb_device_add(const char *devname, int is_hotplug)
 {  {
     const char *p;      const char *p;
Line 2685  static int usb_device_add(const char *de Line 2540  static int usb_device_add(const char *de
     } else if (strstart(devname, "disk:", &p)) {      } else if (strstart(devname, "disk:", &p)) {
         BlockDriverState *bs;          BlockDriverState *bs;
   
         dev = usb_msd_init(p, &bs);          dev = usb_msd_init(p);
         if (!dev)          if (!dev)
             return -1;              return -1;
           bs = usb_msd_get_bdrv(dev);
         if (bdrv_key_required(bs)) {          if (bdrv_key_required(bs)) {
             autostart = 0;              autostart = 0;
             if (is_hotplug && monitor_read_bdrv_key(bs) < 0) {              if (is_hotplug) {
                 dev->handle_destroy(dev);                  monitor_read_bdrv_key_start(cur_mon, bs, usb_msd_password_cb,
                 return -1;                                              dev);
                   return 0;
             }              }
         }          }
     } else if (!strcmp(devname, "wacom-tablet")) {      } else if (!strcmp(devname, "wacom-tablet")) {
Line 2706  static int usb_device_add(const char *de Line 2563  static int usb_device_add(const char *de
     } else if (strstart(devname, "net:", &p)) {      } else if (strstart(devname, "net:", &p)) {
         int nic = nb_nics;          int nic = nb_nics;
   
         if (net_client_init("nic", p) < 0)          if (net_client_init(NULL, "nic", p) < 0)
             return -1;              return -1;
         nd_table[nic].model = "usb";          nd_table[nic].model = "usb";
         dev = usb_net_init(&nd_table[nic]);          dev = usb_net_init(&nd_table[nic]);
Line 2773  static int usb_device_del(const char *de Line 2630  static int usb_device_del(const char *de
     return usb_device_del_addr(bus_num, addr);      return usb_device_del_addr(bus_num, addr);
 }  }
   
 void do_usb_add(const char *devname)  void do_usb_add(Monitor *mon, const char *devname)
 {  {
     usb_device_add(devname, 1);      usb_device_add(devname, 1);
 }  }
   
 void do_usb_del(const char *devname)  void do_usb_del(Monitor *mon, const char *devname)
 {  {
     usb_device_del(devname);      usb_device_del(devname);
 }  }
   
 void usb_info(void)  void usb_info(Monitor *mon)
 {  {
     USBDevice *dev;      USBDevice *dev;
     USBPort *port;      USBPort *port;
     const char *speed_str;      const char *speed_str;
   
     if (!usb_enabled) {      if (!usb_enabled) {
         term_printf("USB support not enabled\n");          monitor_printf(mon, "USB support not enabled\n");
         return;          return;
     }      }
   
Line 2812  void usb_info(void) Line 2669  void usb_info(void)
             speed_str = "?";              speed_str = "?";
             break;              break;
         }          }
         term_printf("  Device %d.%d, Speed %s Mb/s, Product %s\n",          monitor_printf(mon, "  Device %d.%d, Speed %s Mb/s, Product %s\n",
                     0, dev->addr, speed_str, dev->devname);                         0, dev->addr, speed_str, dev->devname);
     }      }
 }  }
   
Line 2821  void usb_info(void) Line 2678  void usb_info(void)
 /* PCMCIA/Cardbus */  /* PCMCIA/Cardbus */
   
 static struct pcmcia_socket_entry_s {  static struct pcmcia_socket_entry_s {
     struct pcmcia_socket_s *socket;      PCMCIASocket *socket;
     struct pcmcia_socket_entry_s *next;      struct pcmcia_socket_entry_s *next;
 } *pcmcia_sockets = 0;  } *pcmcia_sockets = 0;
   
 void pcmcia_socket_register(struct pcmcia_socket_s *socket)  void pcmcia_socket_register(PCMCIASocket *socket)
 {  {
     struct pcmcia_socket_entry_s *entry;      struct pcmcia_socket_entry_s *entry;
   
Line 2835  void pcmcia_socket_register(struct pcmci Line 2692  void pcmcia_socket_register(struct pcmci
     pcmcia_sockets = 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;      struct pcmcia_socket_entry_s *entry, **ptr;
   
Line 2847  void pcmcia_socket_unregister(struct pcm Line 2704  void pcmcia_socket_unregister(struct pcm
         }          }
 }  }
   
 void pcmcia_info(void)  void pcmcia_info(Monitor *mon)
 {  {
     struct pcmcia_socket_entry_s *iter;      struct pcmcia_socket_entry_s *iter;
   
     if (!pcmcia_sockets)      if (!pcmcia_sockets)
         term_printf("No PCMCIA sockets\n");          monitor_printf(mon, "No PCMCIA sockets\n");
   
     for (iter = pcmcia_sockets; iter; iter = iter->next)      for (iter = pcmcia_sockets; iter; iter = iter->next)
         term_printf("%s: %s\n", iter->socket->slot_string,          monitor_printf(mon, "%s: %s\n", iter->socket->slot_string,
                     iter->socket->attached ? iter->socket->card_string :                         iter->socket->attached ? iter->socket->card_string :
                     "Empty");                         "Empty");
 }  }
   
 /***********************************************************/  /***********************************************************/
 /* register display */  /* register display */
   
   struct DisplayAllocator default_allocator = {
       defaultallocator_create_displaysurface,
       defaultallocator_resize_displaysurface,
       defaultallocator_free_displaysurface
   };
   
 void register_displaystate(DisplayState *ds)  void register_displaystate(DisplayState *ds)
 {  {
     DisplayState **s;      DisplayState **s;
Line 2877  DisplayState *get_displaystate(void) Line 2741  DisplayState *get_displaystate(void)
     return display_state;      return display_state;
 }  }
   
   DisplayAllocator *register_displayallocator(DisplayState *ds, DisplayAllocator *da)
   {
       if(ds->allocator ==  &default_allocator) ds->allocator = da;
       return ds->allocator;
   }
   
 /* dumb display */  /* dumb display */
   
 static void dumb_display_init(void)  static void dumb_display_init(void)
 {  {
     DisplayState *ds = qemu_mallocz(sizeof(DisplayState));      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);      register_displaystate(ds);
 }  }
   
 /***********************************************************/  /***********************************************************/
 /* I/O handling */  /* I/O handling */
   
 #define MAX_IO_HANDLERS 64  
   
 typedef struct IOHandlerRecord {  typedef struct IOHandlerRecord {
     int fd;      int fd;
     IOCanRWHandler *fd_read_poll;      IOCanRWHandler *fd_read_poll;
Line 3066  static int ram_load_v1(QEMUFile *f, void Line 2935  static int ram_load_v1(QEMUFile *f, void
     int ret;      int ret;
     ram_addr_t i;      ram_addr_t i;
   
     if (qemu_get_be32(f) != phys_ram_size)      if (qemu_get_be32(f) != last_ram_offset)
         return -EINVAL;          return -EINVAL;
     for(i = 0; i < phys_ram_size; i+= TARGET_PAGE_SIZE) {      for(i = 0; i < last_ram_offset; i+= TARGET_PAGE_SIZE) {
         ret = ram_get_page(f, phys_ram_base + i, TARGET_PAGE_SIZE);          ret = ram_get_page(f, qemu_get_ram_ptr(i), TARGET_PAGE_SIZE);
         if (ret)          if (ret)
             return ret;              return ret;
     }      }
Line 3154  static int ram_save_block(QEMUFile *f) Line 3023  static int ram_save_block(QEMUFile *f)
     ram_addr_t addr = 0;      ram_addr_t addr = 0;
     int found = 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)) {          if (cpu_physical_memory_get_dirty(current_addr, MIGRATION_DIRTY_FLAG)) {
             uint8_t ch;              uint8_t *p;
   
             cpu_physical_memory_reset_dirty(current_addr,              cpu_physical_memory_reset_dirty(current_addr,
                                             current_addr + TARGET_PAGE_SIZE,                                              current_addr + TARGET_PAGE_SIZE,
                                             MIGRATION_DIRTY_FLAG);                                              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_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
                 qemu_put_byte(f, ch);                  qemu_put_byte(f, *p);
             } else {              } else {
                 qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);                  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;              found = 1;
             break;              break;
         }          }
         addr += TARGET_PAGE_SIZE;          addr += TARGET_PAGE_SIZE;
         current_addr = (saved_addr + addr) % phys_ram_size;          current_addr = (saved_addr + addr) % last_ram_offset;
     }      }
   
     return found;      return found;
 }  }
   
 static ram_addr_t ram_save_threshold = 10;  static uint64_t bytes_transferred = 0;
   
 static ram_addr_t ram_save_remaining(void)  static ram_addr_t ram_save_remaining(void)
 {  {
     ram_addr_t addr;      ram_addr_t addr;
     ram_addr_t count = 0;      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))          if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
             count++;              count++;
     }      }
Line 3197  static ram_addr_t ram_save_remaining(voi Line 3066  static ram_addr_t ram_save_remaining(voi
     return count;      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)  static int ram_save_live(QEMUFile *f, int stage, void *opaque)
 {  {
     ram_addr_t addr;      ram_addr_t addr;
       uint64_t bytes_transferred_last;
       double bwidth = 0;
       uint64_t expected_time = 0;
   
       if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
           qemu_file_set_error(f);
           return 0;
       }
   
     if (stage == 1) {      if (stage == 1) {
         /* Make sure all dirty bits are set */          /* 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))              if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
                 cpu_physical_memory_set_dirty(addr);                  cpu_physical_memory_set_dirty(addr);
         }          }
           
         /* Enable dirty memory tracking */          /* Enable dirty memory tracking */
         cpu_physical_memory_set_dirty_tracking(1);          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);
     }      }
   
       bytes_transferred_last = bytes_transferred;
       bwidth = get_clock();
   
     while (!qemu_file_rate_limit(f)) {      while (!qemu_file_rate_limit(f)) {
         int ret;          int ret;
   
         ret = ram_save_block(f);          ret = ram_save_block(f);
           bytes_transferred += ret * TARGET_PAGE_SIZE;
         if (ret == 0) /* no more blocks */          if (ret == 0) /* no more blocks */
             break;              break;
     }      }
   
       bwidth = get_clock() - bwidth;
       bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;
   
       /* if we haven't transferred anything this round, force expected_time to a
        * a very high value, but without crashing */
       if (bwidth == 0)
           bwidth = 0.000001;
   
     /* try transferring iterative blocks of memory */      /* try transferring iterative blocks of memory */
   
     if (stage == 3) {      if (stage == 3) {
   
         /* flush all remaining blocks regardless of rate limiting */          /* 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);          cpu_physical_memory_set_dirty_tracking(0);
     }      }
   
     qemu_put_be64(f, RAM_SAVE_FLAG_EOS);      qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
   
     return (stage == 2) && (ram_save_remaining() < ram_save_threshold);      expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
   
       return (stage == 2) && (expected_time <= migrate_max_downtime());
 }  }
   
 static int ram_load_dead(QEMUFile *f, void *opaque)  static int ram_load_dead(QEMUFile *f, void *opaque)
Line 3244  static int ram_load_dead(QEMUFile *f, vo Line 3152  static int ram_load_dead(QEMUFile *f, vo
   
     if (ram_decompress_open(s, f) < 0)      if (ram_decompress_open(s, f) < 0)
         return -EINVAL;          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) {          if (ram_decompress_buf(s, buf, 1) < 0) {
             fprintf(stderr, "Error while reading ram block header\n");              fprintf(stderr, "Error while reading ram block header\n");
             goto error;              goto error;
         }          }
         if (buf[0] == 0) {          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);                  fprintf(stderr, "Error while reading ram block address=0x%08" PRIx64, (uint64_t)i);
                 goto error;                  goto error;
             }              }
Line 3274  static int ram_load(QEMUFile *f, void *o Line 3183  static int ram_load(QEMUFile *f, void *o
         return ram_load_v1(f, opaque);          return ram_load_v1(f, opaque);
   
     if (version_id == 2) {      if (version_id == 2) {
         if (qemu_get_be32(f) != phys_ram_size)          if (qemu_get_be32(f) != last_ram_offset)
             return -EINVAL;              return -EINVAL;
         return ram_load_dead(f, opaque);          return ram_load_dead(f, opaque);
     }      }
Line 3289  static int ram_load(QEMUFile *f, void *o Line 3198  static int ram_load(QEMUFile *f, void *o
         addr &= TARGET_PAGE_MASK;          addr &= TARGET_PAGE_MASK;
   
         if (flags & RAM_SAVE_FLAG_MEM_SIZE) {          if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
             if (addr != phys_ram_size)              if (addr != last_ram_offset)
                 return -EINVAL;                  return -EINVAL;
         }          }
   
Line 3300  static int ram_load(QEMUFile *f, void *o Line 3209  static int ram_load(QEMUFile *f, void *o
                   
         if (flags & RAM_SAVE_FLAG_COMPRESS) {          if (flags & RAM_SAVE_FLAG_COMPRESS) {
             uint8_t ch = qemu_get_byte(f);              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);
   #ifndef _WIN32
               if (ch == 0 &&
                   (!kvm_enabled() || kvm_has_sync_mmu())) {
                   madvise(qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE, MADV_DONTNEED);
               }
   #endif
         } else if (flags & RAM_SAVE_FLAG_PAGE)          } 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));      } while (!(flags & RAM_SAVE_FLAG_EOS));
   
     return 0;      return 0;
Line 3310  static int ram_load(QEMUFile *f, void *o Line 3225  static int ram_load(QEMUFile *f, void *o
   
 void qemu_service_io(void)  void qemu_service_io(void)
 {  {
     CPUState *env = cpu_single_env;      qemu_notify_event();
     if (env) {  
         cpu_interrupt(env, CPU_INTERRUPT_EXIT);  
 #ifdef USE_KQEMU  
         if (env->kqemu_enabled) {  
             kqemu_cpu_interrupt(env);  
         }  
 #endif  
     }  
 }  }
   
 /***********************************************************/  /***********************************************************/
Line 3386  void qemu_bh_schedule_idle(QEMUBH *bh) Line 3293  void qemu_bh_schedule_idle(QEMUBH *bh)
   
 void qemu_bh_schedule(QEMUBH *bh)  void qemu_bh_schedule(QEMUBH *bh)
 {  {
     CPUState *env = cpu_single_env;  
     if (bh->scheduled)      if (bh->scheduled)
         return;          return;
     bh->scheduled = 1;      bh->scheduled = 1;
     bh->idle = 0;      bh->idle = 0;
     /* stop the currently executing CPU to execute the BH ASAP */      /* stop the currently executing CPU to execute the BH ASAP */
     if (env) {      qemu_notify_event();
         cpu_interrupt(env, CPU_INTERRUPT_EXIT);  
     }  
 }  }
   
 void qemu_bh_cancel(QEMUBH *bh)  void qemu_bh_cancel(QEMUBH *bh)
Line 3452  static QEMUMachine *find_machine(const c Line 3356  static QEMUMachine *find_machine(const c
     for(m = first_machine; m != NULL; m = m->next) {      for(m = first_machine; m != NULL; m = m->next) {
         if (!strcmp(m->name, name))          if (!strcmp(m->name, name))
             return m;              return m;
           if (m->alias && !strcmp(m->alias, name))
               return m;
       }
       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;      return NULL;
 }  }
Line 3519  static void vm_state_notify(int running, Line 3437  static void vm_state_notify(int running,
     }      }
 }  }
   
   static void resume_all_vcpus(void);
   static void pause_all_vcpus(void);
   
 void vm_start(void)  void vm_start(void)
 {  {
     if (!vm_running) {      if (!vm_running) {
Line 3526  void vm_start(void) Line 3447  void vm_start(void)
         vm_running = 1;          vm_running = 1;
         vm_state_notify(1, 0);          vm_state_notify(1, 0);
         qemu_rearm_alarm_timer(alarm_timer);          qemu_rearm_alarm_timer(alarm_timer);
     }          resume_all_vcpus();
 }  
   
 void vm_stop(int reason)  
 {  
     if (vm_running) {  
         cpu_disable_ticks();  
         vm_running = 0;  
         vm_state_notify(0, reason);  
     }      }
 }  }
   
 /* reset/shutdown handler */  /* reset/shutdown handler */
   
 typedef struct QEMUResetEntry {  typedef struct QEMUResetEntry {
       TAILQ_ENTRY(QEMUResetEntry) entry;
     QEMUResetHandler *func;      QEMUResetHandler *func;
     void *opaque;      void *opaque;
     struct QEMUResetEntry *next;  
 } QEMUResetEntry;  } QEMUResetEntry;
   
 static QEMUResetEntry *first_reset_entry;  static TAILQ_HEAD(reset_handlers, QEMUResetEntry) reset_handlers =
       TAILQ_HEAD_INITIALIZER(reset_handlers);
 static int reset_requested;  static int reset_requested;
 static int shutdown_requested;  static int shutdown_requested;
 static int powerdown_requested;  static int powerdown_requested;
   static int debug_requested;
   static int vmstop_requested;
   
 int qemu_shutdown_requested(void)  int qemu_shutdown_requested(void)
 {  {
Line 3572  int qemu_powerdown_requested(void) Line 3488  int qemu_powerdown_requested(void)
     return r;      return r;
 }  }
   
   static int qemu_debug_requested(void)
   {
       int r = debug_requested;
       debug_requested = 0;
       return r;
   }
   
   static int qemu_vmstop_requested(void)
   {
       int r = vmstop_requested;
       vmstop_requested = 0;
       return r;
   }
   
   static void do_vm_stop(int reason)
   {
       if (vm_running) {
           cpu_disable_ticks();
           vm_running = 0;
           pause_all_vcpus();
           vm_state_notify(0, reason);
       }
   }
   
 void qemu_register_reset(QEMUResetHandler *func, void *opaque)  void qemu_register_reset(QEMUResetHandler *func, void *opaque)
 {  {
     QEMUResetEntry **pre, *re;      QEMUResetEntry *re = qemu_mallocz(sizeof(QEMUResetEntry));
   
     pre = &first_reset_entry;  
     while (*pre != NULL)  
         pre = &(*pre)->next;  
     re = qemu_mallocz(sizeof(QEMUResetEntry));  
     re->func = func;      re->func = func;
     re->opaque = opaque;      re->opaque = opaque;
     re->next = NULL;      TAILQ_INSERT_TAIL(&reset_handlers, re, entry);
     *pre = re;  
 }  }
   
 void qemu_system_reset(void)  void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)
 {  {
     QEMUResetEntry *re;      QEMUResetEntry *re;
   
       TAILQ_FOREACH(re, &reset_handlers, entry) {
           if (re->func == func && re->opaque == opaque) {
               TAILQ_REMOVE(&reset_handlers, re, entry);
               qemu_free(re);
               return;
           }
       }
   }
   
   void qemu_system_reset(void)
   {
       QEMUResetEntry *re, *nre;
   
     /* reset all devices */      /* reset all devices */
     for(re = first_reset_entry; re != NULL; re = re->next) {      TAILQ_FOREACH_SAFE(re, &reset_handlers, entry, nre) {
         re->func(re->opaque);          re->func(re->opaque);
     }      }
 }  }
Line 3603  void qemu_system_reset_request(void) Line 3551  void qemu_system_reset_request(void)
     } else {      } else {
         reset_requested = 1;          reset_requested = 1;
     }      }
     if (cpu_single_env)      qemu_notify_event();
         cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);  
 }  }
   
 void qemu_system_shutdown_request(void)  void qemu_system_shutdown_request(void)
 {  {
     shutdown_requested = 1;      shutdown_requested = 1;
     if (cpu_single_env)      qemu_notify_event();
         cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);  
 }  }
   
 void qemu_system_powerdown_request(void)  void qemu_system_powerdown_request(void)
 {  {
     powerdown_requested = 1;      powerdown_requested = 1;
       qemu_notify_event();
   }
   
   #ifdef CONFIG_IOTHREAD
   static void qemu_system_vmstop_request(int reason)
   {
       vmstop_requested = reason;
       qemu_notify_event();
   }
   #endif
   
   #ifndef _WIN32
   static int io_thread_fd = -1;
   
   static void qemu_event_increment(void)
   {
       static const char byte = 0;
   
       if (io_thread_fd == -1)
           return;
   
       write(io_thread_fd, &byte, sizeof(byte));
   }
   
   static void qemu_event_read(void *opaque)
   {
       int fd = (unsigned long)opaque;
       ssize_t len;
   
       /* Drain the notify pipe */
       do {
           char buffer[512];
           len = read(fd, buffer, sizeof(buffer));
       } while ((len == -1 && errno == EINTR) || len > 0);
   }
   
   static int qemu_event_init(void)
   {
       int err;
       int fds[2];
   
       err = pipe(fds);
       if (err == -1)
           return -errno;
   
       err = fcntl_setfl(fds[0], O_NONBLOCK);
       if (err < 0)
           goto fail;
   
       err = fcntl_setfl(fds[1], O_NONBLOCK);
       if (err < 0)
           goto fail;
   
       qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,
                            (void *)(unsigned long)fds[0]);
   
       io_thread_fd = fds[1];
       return 0;
   
   fail:
       close(fds[0]);
       close(fds[1]);
       return err;
   }
   #else
   HANDLE qemu_event_handle;
   
   static void dummy_event_handler(void *opaque)
   {
   }
   
   static int qemu_event_init(void)
   {
       qemu_event_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
       if (!qemu_event_handle) {
           perror("Failed CreateEvent");
           return -1;
       }
       qemu_add_wait_object(qemu_event_handle, dummy_event_handler, NULL);
       return 0;
   }
   
   static void qemu_event_increment(void)
   {
       SetEvent(qemu_event_handle);
   }
   #endif
   
   static int cpu_can_run(CPUState *env)
   {
       if (env->stop)
           return 0;
       if (env->stopped)
           return 0;
       return 1;
   }
   
   #ifndef CONFIG_IOTHREAD
   static int qemu_init_main_loop(void)
   {
       return qemu_event_init();
   }
   
   void qemu_init_vcpu(void *_env)
   {
       CPUState *env = _env;
   
       if (kvm_enabled())
           kvm_init_vcpu(env);
       return;
   }
   
   int qemu_cpu_self(void *env)
   {
       return 1;
   }
   
   static void resume_all_vcpus(void)
   {
   }
   
   static void pause_all_vcpus(void)
   {
   }
   
   void qemu_cpu_kick(void *env)
   {
       return;
   }
   
   void qemu_notify_event(void)
   {
       CPUState *env = cpu_single_env;
   
       if (env) {
           cpu_exit(env);
   #ifdef USE_KQEMU
           if (env->kqemu_enabled)
               kqemu_cpu_interrupt(env);
   #endif
        }
   }
   
   #define qemu_mutex_lock_iothread() do { } while (0)
   #define qemu_mutex_unlock_iothread() do { } while (0)
   
   void vm_stop(int reason)
   {
       do_vm_stop(reason);
   }
   
   #else /* CONFIG_IOTHREAD */
   
   #include "qemu-thread.h"
   
   QemuMutex qemu_global_mutex;
   static QemuMutex qemu_fair_mutex;
   
   static QemuThread io_thread;
   
   static QemuThread *tcg_cpu_thread;
   static QemuCond *tcg_halt_cond;
   
   static int qemu_system_ready;
   /* cpu creation */
   static QemuCond qemu_cpu_cond;
   /* system init */
   static QemuCond qemu_system_cond;
   static QemuCond qemu_pause_cond;
   
   static void block_io_signals(void);
   static void unblock_io_signals(void);
   static int tcg_has_work(void);
   
   static int qemu_init_main_loop(void)
   {
       int ret;
   
       ret = qemu_event_init();
       if (ret)
           return ret;
   
       qemu_cond_init(&qemu_pause_cond);
       qemu_mutex_init(&qemu_fair_mutex);
       qemu_mutex_init(&qemu_global_mutex);
       qemu_mutex_lock(&qemu_global_mutex);
   
       unblock_io_signals();
       qemu_thread_self(&io_thread);
   
       return 0;
   }
   
   static void qemu_wait_io_event(CPUState *env)
   {
       while (!tcg_has_work())
           qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000);
   
       qemu_mutex_unlock(&qemu_global_mutex);
   
       /*
        * Users of qemu_global_mutex can be starved, having no chance
        * to acquire it since this path will get to it first.
        * So use another lock to provide fairness.
        */
       qemu_mutex_lock(&qemu_fair_mutex);
       qemu_mutex_unlock(&qemu_fair_mutex);
   
       qemu_mutex_lock(&qemu_global_mutex);
       if (env->stop) {
           env->stop = 0;
           env->stopped = 1;
           qemu_cond_signal(&qemu_pause_cond);
       }
   }
   
   static int qemu_cpu_exec(CPUState *env);
   
   static void *kvm_cpu_thread_fn(void *arg)
   {
       CPUState *env = arg;
   
       block_io_signals();
       qemu_thread_self(env->thread);
   
       /* signal CPU creation */
       qemu_mutex_lock(&qemu_global_mutex);
       env->created = 1;
       qemu_cond_signal(&qemu_cpu_cond);
   
       /* and wait for machine initialization */
       while (!qemu_system_ready)
           qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
   
       while (1) {
           if (cpu_can_run(env))
               qemu_cpu_exec(env);
           qemu_wait_io_event(env);
       }
   
       return NULL;
   }
   
   static void tcg_cpu_exec(void);
   
   static void *tcg_cpu_thread_fn(void *arg)
   {
       CPUState *env = arg;
   
       block_io_signals();
       qemu_thread_self(env->thread);
   
       /* signal CPU creation */
       qemu_mutex_lock(&qemu_global_mutex);
       for (env = first_cpu; env != NULL; env = env->next_cpu)
           env->created = 1;
       qemu_cond_signal(&qemu_cpu_cond);
   
       /* and wait for machine initialization */
       while (!qemu_system_ready)
           qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
   
       while (1) {
           tcg_cpu_exec();
           qemu_wait_io_event(cur_cpu);
       }
   
       return NULL;
   }
   
   void qemu_cpu_kick(void *_env)
   {
       CPUState *env = _env;
       qemu_cond_broadcast(env->halt_cond);
       if (kvm_enabled())
           qemu_thread_signal(env->thread, SIGUSR1);
   }
   
   int qemu_cpu_self(void *env)
   {
       return (cpu_single_env != NULL);
   }
   
   static void cpu_signal(int sig)
   {
     if (cpu_single_env)      if (cpu_single_env)
         cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);          cpu_exit(cpu_single_env);
   }
   
   static void block_io_signals(void)
   {
       sigset_t set;
       struct sigaction sigact;
   
       sigemptyset(&set);
       sigaddset(&set, SIGUSR2);
       sigaddset(&set, SIGIO);
       sigaddset(&set, SIGALRM);
       pthread_sigmask(SIG_BLOCK, &set, NULL);
   
       sigemptyset(&set);
       sigaddset(&set, SIGUSR1);
       pthread_sigmask(SIG_UNBLOCK, &set, NULL);
   
       memset(&sigact, 0, sizeof(sigact));
       sigact.sa_handler = cpu_signal;
       sigaction(SIGUSR1, &sigact, NULL);
   }
   
   static void unblock_io_signals(void)
   {
       sigset_t set;
   
       sigemptyset(&set);
       sigaddset(&set, SIGUSR2);
       sigaddset(&set, SIGIO);
       sigaddset(&set, SIGALRM);
       pthread_sigmask(SIG_UNBLOCK, &set, NULL);
   
       sigemptyset(&set);
       sigaddset(&set, SIGUSR1);
       pthread_sigmask(SIG_BLOCK, &set, NULL);
   }
   
   static void qemu_signal_lock(unsigned int msecs)
   {
       qemu_mutex_lock(&qemu_fair_mutex);
   
       while (qemu_mutex_trylock(&qemu_global_mutex)) {
           qemu_thread_signal(tcg_cpu_thread, SIGUSR1);
           if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs))
               break;
       }
       qemu_mutex_unlock(&qemu_fair_mutex);
   }
   
   static void qemu_mutex_lock_iothread(void)
   {
       if (kvm_enabled()) {
           qemu_mutex_lock(&qemu_fair_mutex);
           qemu_mutex_lock(&qemu_global_mutex);
           qemu_mutex_unlock(&qemu_fair_mutex);
       } else
           qemu_signal_lock(100);
   }
   
   static void qemu_mutex_unlock_iothread(void)
   {
       qemu_mutex_unlock(&qemu_global_mutex);
   }
   
   static int all_vcpus_paused(void)
   {
       CPUState *penv = first_cpu;
   
       while (penv) {
           if (!penv->stopped)
               return 0;
           penv = (CPUState *)penv->next_cpu;
       }
   
       return 1;
   }
   
   static void pause_all_vcpus(void)
   {
       CPUState *penv = first_cpu;
   
       while (penv) {
           penv->stop = 1;
           qemu_thread_signal(penv->thread, SIGUSR1);
           qemu_cpu_kick(penv);
           penv = (CPUState *)penv->next_cpu;
       }
   
       while (!all_vcpus_paused()) {
           qemu_cond_timedwait(&qemu_pause_cond, &qemu_global_mutex, 100);
           penv = first_cpu;
           while (penv) {
               qemu_thread_signal(penv->thread, SIGUSR1);
               penv = (CPUState *)penv->next_cpu;
           }
       }
   }
   
   static void resume_all_vcpus(void)
   {
       CPUState *penv = first_cpu;
   
       while (penv) {
           penv->stop = 0;
           penv->stopped = 0;
           qemu_thread_signal(penv->thread, SIGUSR1);
           qemu_cpu_kick(penv);
           penv = (CPUState *)penv->next_cpu;
       }
   }
   
   static void tcg_init_vcpu(void *_env)
   {
       CPUState *env = _env;
       /* share a single thread for all cpus with TCG */
       if (!tcg_cpu_thread) {
           env->thread = qemu_mallocz(sizeof(QemuThread));
           env->halt_cond = qemu_mallocz(sizeof(QemuCond));
           qemu_cond_init(env->halt_cond);
           qemu_thread_create(env->thread, tcg_cpu_thread_fn, env);
           while (env->created == 0)
               qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
           tcg_cpu_thread = env->thread;
           tcg_halt_cond = env->halt_cond;
       } else {
           env->thread = tcg_cpu_thread;
           env->halt_cond = tcg_halt_cond;
       }
   }
   
   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);
       qemu_thread_create(env->thread, kvm_cpu_thread_fn, env);
       while (env->created == 0)
           qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);
   }
   
   void qemu_init_vcpu(void *_env)
   {
       CPUState *env = _env;
   
       if (kvm_enabled())
           kvm_start_vcpu(env);
       else
           tcg_init_vcpu(env);
 }  }
   
   void qemu_notify_event(void)
   {
       qemu_event_increment();
   }
   
   void vm_stop(int reason)
   {
       QemuThread me;
       qemu_thread_self(&me);
   
       if (!qemu_thread_equal(&me, &io_thread)) {
           qemu_system_vmstop_request(reason);
           /*
            * FIXME: should not return to device code in case
            * vm_stop() has been requested.
            */
           if (cpu_single_env) {
               cpu_exit(cpu_single_env);
               cpu_single_env->stop = 1;
           }
           return;
       }
       do_vm_stop(reason);
   }
   
   #endif
   
   
 #ifdef _WIN32  #ifdef _WIN32
 static void host_main_loop_wait(int *timeout)  static void host_main_loop_wait(int *timeout)
 {  {
Line 3708  void main_loop_wait(int timeout) Line 4116  void main_loop_wait(int timeout)
     tv.tv_sec = timeout / 1000;      tv.tv_sec = timeout / 1000;
     tv.tv_usec = (timeout % 1000) * 1000;      tv.tv_usec = (timeout % 1000) * 1000;
   
 #if defined(CONFIG_SLIRP)      slirp_select_fill(&nfds, &rfds, &wfds, &xfds);
     if (slirp_is_inited()) {  
         slirp_select_fill(&nfds, &rfds, &wfds, &xfds);      qemu_mutex_unlock_iothread();
     }  
 #endif  
     ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);      ret = select(nfds + 1, &rfds, &wfds, &xfds, &tv);
       qemu_mutex_lock_iothread();
     if (ret > 0) {      if (ret > 0) {
         IOHandlerRecord **pioh;          IOHandlerRecord **pioh;
   
Line 3737  void main_loop_wait(int timeout) Line 4144  void main_loop_wait(int timeout)
                 pioh = &ioh->next;                  pioh = &ioh->next;
         }          }
     }      }
 #if defined(CONFIG_SLIRP)  
     if (slirp_is_inited()) {      slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0));
         if (ret < 0) {  
             FD_ZERO(&rfds);      /* rearm timer, if not periodic */
             FD_ZERO(&wfds);      if (alarm_timer->flags & ALARM_FLAG_EXPIRED) {
             FD_ZERO(&xfds);          alarm_timer->flags &= ~ALARM_FLAG_EXPIRED;
         }          qemu_rearm_alarm_timer(alarm_timer);
         slirp_select_poll(&rfds, &wfds, &xfds);  
     }      }
 #endif  
   
     /* vm time timers */      /* vm time timers */
     if (vm_running && likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))      if (vm_running) {
         qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],          if (!cur_cpu || likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER)))
                         qemu_get_clock(vm_clock));              qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
                   qemu_get_clock(vm_clock));
       }
   
     /* real time timers */      /* real time timers */
     qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],      qemu_run_timers(&active_timers[QEMU_TIMER_REALTIME],
Line 3763  void main_loop_wait(int timeout) Line 4170  void main_loop_wait(int timeout)
   
 }  }
   
 static int main_loop(void)  static int qemu_cpu_exec(CPUState *env)
 {  {
     int ret, timeout;      int ret;
 #ifdef CONFIG_PROFILER  #ifdef CONFIG_PROFILER
     int64_t ti;      int64_t ti;
 #endif  #endif
     CPUState *env;  
   
     cur_cpu = first_cpu;  
     next_cpu = cur_cpu->next_cpu ?: first_cpu;  
     for(;;) {  
         if (vm_running) {  
   
             for(;;) {  
                 /* get next cpu */  
                 env = next_cpu;  
 #ifdef CONFIG_PROFILER  #ifdef CONFIG_PROFILER
                 ti = profile_getclock();      ti = profile_getclock();
 #endif  #endif
                 if (use_icount) {      if (use_icount) {
                     int64_t count;          int64_t count;
                     int decr;          int decr;
                     qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);          qemu_icount -= (env->icount_decr.u16.low + env->icount_extra);
                     env->icount_decr.u16.low = 0;          env->icount_decr.u16.low = 0;
                     env->icount_extra = 0;          env->icount_extra = 0;
                     count = qemu_next_deadline();          count = qemu_next_deadline();
                     count = (count + (1 << icount_time_shift) - 1)          count = (count + (1 << icount_time_shift) - 1)
                             >> icount_time_shift;                  >> icount_time_shift;
                     qemu_icount += count;          qemu_icount += count;
                     decr = (count > 0xffff) ? 0xffff : count;          decr = (count > 0xffff) ? 0xffff : count;
                     count -= decr;          count -= decr;
                     env->icount_decr.u16.low = decr;          env->icount_decr.u16.low = decr;
                     env->icount_extra = count;          env->icount_extra = count;
                 }      }
                 ret = cpu_exec(env);      ret = cpu_exec(env);
 #ifdef CONFIG_PROFILER  #ifdef CONFIG_PROFILER
                 qemu_time += profile_getclock() - ti;      qemu_time += profile_getclock() - ti;
 #endif  #endif
                 if (use_icount) {      if (use_icount) {
                     /* Fold pending instructions back into the          /* Fold pending instructions back into the
                        instruction counter, and clear the interrupt flag.  */             instruction counter, and clear the interrupt flag.  */
                     qemu_icount -= (env->icount_decr.u16.low          qemu_icount -= (env->icount_decr.u16.low
                                     + env->icount_extra);                          + env->icount_extra);
                     env->icount_decr.u32 = 0;          env->icount_decr.u32 = 0;
                     env->icount_extra = 0;          env->icount_extra = 0;
                 }      }
                 next_cpu = env->next_cpu ?: first_cpu;      return ret;
                 if (event_pending && likely(ret != EXCP_DEBUG)) {  }
                     ret = EXCP_INTERRUPT;  
                     event_pending = 0;  
                     break;  
                 }  
                 if (ret == EXCP_HLT) {  
                     /* Give the next CPU a chance to run.  */  
                     cur_cpu = env;  
                     continue;  
                 }  
                 if (ret != EXCP_HALTED)  
                     break;  
                 /* all CPUs are halted ? */  
                 if (env == cur_cpu)  
                     break;  
             }  
             cur_cpu = env;  
   
             if (shutdown_requested) {  static void tcg_cpu_exec(void)
                 ret = EXCP_INTERRUPT;  {
                 if (no_shutdown) {      int ret = 0;
                     vm_stop(0);  
                     no_shutdown = 0;      if (next_cpu == NULL)
                 }          next_cpu = first_cpu;
                 else      for (; next_cpu != NULL; next_cpu = next_cpu->next_cpu) {
                     break;          CPUState *env = cur_cpu = next_cpu;
             }  
             if (reset_requested) {          if (!vm_running)
                 reset_requested = 0;              break;
                 qemu_system_reset();          if (timer_alarm_pending) {
                 ret = EXCP_INTERRUPT;              timer_alarm_pending = 0;
             }              break;
             if (powerdown_requested) {          }
                 powerdown_requested = 0;          if (cpu_can_run(env))
                 qemu_system_powerdown();              ret = qemu_cpu_exec(env);
                 ret = EXCP_INTERRUPT;          if (ret == EXCP_DEBUG) {
             }              gdb_set_stop_cpu(env);
             if (unlikely(ret == EXCP_DEBUG)) {              debug_requested = 1;
                 gdb_set_stop_cpu(cur_cpu);              break;
                 vm_stop(EXCP_DEBUG);  
             }  
             /* If all cpus are halted then wait until the next IRQ */  
             /* XXX: use timeout computed from timers */  
             if (ret == EXCP_HALTED) {  
                 if (use_icount) {  
                     int64_t add;  
                     int64_t delta;  
                     /* Advance virtual time to the next event.  */  
                     if (use_icount == 1) {  
                         /* When not using an adaptive execution frequency  
                            we tend to get badly out of sync with real time,  
                            so just delay for a reasonable amount of time.  */  
                         delta = 0;  
                     } else {  
                         delta = cpu_get_icount() - cpu_get_clock();  
                     }  
                     if (delta > 0) {  
                         /* If virtual time is ahead of real time then just  
                            wait for IO.  */  
                         timeout = (delta / 1000000) + 1;  
                     } else {  
                         /* Wait for either IO to occur or the next  
                            timer event.  */  
                         add = qemu_next_deadline();  
                         /* We advance the timer before checking for IO.  
                            Limit the amount we advance so that early IO  
                            activity won't get the guest too far ahead.  */  
                         if (add > 10000000)  
                             add = 10000000;  
                         delta += add;  
                         add = (add + (1 << icount_time_shift) - 1)  
                               >> icount_time_shift;  
                         qemu_icount += add;  
                         timeout = delta / 1000000;  
                         if (timeout < 0)  
                             timeout = 0;  
                     }  
                 } else {  
                     timeout = 5000;  
                 }  
             } else {  
                 timeout = 0;  
             }  
         } else {  
             if (shutdown_requested) {  
                 ret = EXCP_INTERRUPT;  
                 break;  
             }  
             timeout = 5000;  
         }          }
 #ifdef CONFIG_PROFILER  
         ti = profile_getclock();  
 #endif  
         main_loop_wait(timeout);  
 #ifdef CONFIG_PROFILER  
         dev_time += profile_getclock() - ti;  
 #endif  
     }      }
     cpu_disable_ticks();  
     return ret;  
 }  }
   
 static void help(int exitcode)  static int cpu_has_work(CPUState *env)
 {  {
     /* Please keep in synch with QEMU_OPTION_ enums, qemu_options[]      if (env->stop)
        and qemu-doc.texi */          return 1;
     printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"      if (env->stopped)
            "usage: %s [options] [disk_image]\n"          return 0;
            "\n"      if (!env->halted)
            "'disk_image' is a raw hard image image for IDE hard disk 0\n"          return 1;
            "\n"      if (qemu_cpu_has_work(env))
            "Standard options:\n"          return 1;
            "-h or -help     display this help and exit\n"      return 0;
            "-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"  static int tcg_has_work(void)
            "-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"      CPUState *env;
            "-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"      for (env = first_cpu; env != NULL; env = env->next_cpu)
            "-drive [file=file][,if=type][,bus=n][,unit=m][,media=d][,index=i]\n"          if (cpu_has_work(env))
            "       [,cyls=c,heads=h,secs=s[,trans=t]][,snapshot=on|off]\n"              return 1;
            "       [,cache=writethrough|writeback|none][,format=f][,serial=s]\n"      return 0;
            "                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"  static int qemu_calculate_timeout(void)
            "-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"  #ifndef CONFIG_IOTHREAD
            "-snapshot       write to temporary files instead of disk image files\n"      int timeout;
            "-m megs         set virtual RAM size to megs MB [default=%d]\n"  
 #ifndef _WIN32      if (!vm_running)
            "-k language     use keyboard layout (for example \"fr\" for French)\n"          timeout = 5000;
 #endif      else if (tcg_has_work())
 #ifdef HAS_AUDIO          timeout = 0;
            "-audio-help     print list of audio drivers and their options\n"      else if (!use_icount)
            "-soundhw c1,... enable audio support\n"          timeout = 5000;
            "                and only specified sound cards (comma separated list)\n"      else {
            "                use -soundhw ? to get the list of supported cards\n"       /* XXX: use timeout computed from timers */
            "                use -soundhw all to enable all of them\n"          int64_t add;
 #endif          int64_t delta;
            "-usb            enable the USB driver (will be the default soon)\n"          /* Advance virtual time to the next event.  */
            "-usbdevice name add the host or guest USB device 'name'\n"          if (use_icount == 1) {
            "-name string    set the name of the guest\n"              /* When not using an adaptive execution frequency
            "-uuid %%08x-%%04x-%%04x-%%04x-%%012x\n"                 we tend to get badly out of sync with real time,
            "                specify machine UUID\n"                 so just delay for a reasonable amount of time.  */
            "\n"              delta = 0;
            "Display options:\n"          } else {
            "-nographic      disable graphical output and redirect serial I/Os to console\n"              delta = cpu_get_icount() - cpu_get_clock();
 #ifdef CONFIG_CURSES          }
            "-curses         use a curses/ncurses interface instead of SDL\n"          if (delta > 0) {
 #endif              /* If virtual time is ahead of real time then just
 #ifdef CONFIG_SDL                 wait for IO.  */
            "-no-frame       open SDL window without a frame and window decorations\n"              timeout = (delta / 1000000) + 1;
            "-alt-grab       use Ctrl-Alt-Shift to grab mouse (instead of Ctrl-Alt)\n"          } else {
            "-no-quit        disable SDL window close capability\n"              /* Wait for either IO to occur or the next
            "-sdl            enable SDL\n"                 timer event.  */
 #endif              add = qemu_next_deadline();
            "-portrait       rotate graphical output 90 deg left (only PXA LCD)\n"              /* We advance the timer before checking for IO.
            "-vga [std|cirrus|vmware|none]\n"                 Limit the amount we advance so that early IO
            "                select video card type\n"                 activity won't get the guest too far ahead.  */
            "-full-screen    start in full screen\n"              if (add > 10000000)
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)                  add = 10000000;
            "-g WxH[xDEPTH]  Set the initial graphical resolution and depth\n"              delta += add;
 #endif              add = (add + (1 << icount_time_shift) - 1)
            "-vnc display    start a VNC server on display\n"                    >> icount_time_shift;
            "\n"              qemu_icount += add;
            "Network options:\n"              timeout = delta / 1000000;
            "-net nic[,vlan=n][,macaddr=addr][,model=type][,name=str]\n"              if (timeout < 0)
            "                create a new Network Interface Card and connect it to VLAN 'n'\n"                  timeout = 0;
 #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"      return timeout;
 #endif  #else /* CONFIG_IOTHREAD */
 #ifdef _WIN32      return 1000;
            "-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  #endif
            "-no-reboot      exit instead of rebooting\n"  }
            "-no-shutdown    stop before shutdown\n"  
            "-loadvm [tag|id]\n"  static int vm_can_run(void)
            "                start right away with a saved state (loadvm in monitor)\n"  {
 #ifndef _WIN32      if (powerdown_requested)
            "-daemonize      daemonize QEMU after initializing\n"          return 0;
       if (reset_requested)
           return 0;
       if (shutdown_requested)
           return 0;
       if (debug_requested)
           return 0;
       return 1;
   }
   
   static void main_loop(void)
   {
       int r;
   
   #ifdef CONFIG_IOTHREAD
       qemu_system_ready = 1;
       qemu_cond_broadcast(&qemu_system_cond);
 #endif  #endif
            "-option-rom rom load a file, rom, into the option ROM space\n"  
 #if defined(TARGET_SPARC) || defined(TARGET_PPC)      for (;;) {
            "-prom-env variable=value\n"          do {
            "                set OpenBIOS nvram variables\n"  #ifdef CONFIG_PROFILER
               int64_t ti;
 #endif  #endif
            "-clock          force the use of the given methods for timer alarm.\n"  #ifndef CONFIG_IOTHREAD
            "                To see what timers are available use -clock ?\n"              tcg_cpu_exec();
            "-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  #endif
 #if defined(TARGET_ARM)  #ifdef CONFIG_PROFILER
            "-old-param      old param mode\n"              ti = profile_getclock();
 #endif  #endif
            "-tb-size n      set TB size\n"              main_loop_wait(qemu_calculate_timeout());
            "-incoming p     prepare for incoming migration, listen on port p\n"  #ifdef CONFIG_PROFILER
 #ifndef _WIN32              dev_time += profile_getclock() - ti;
            "-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  #endif
           } while (vm_can_run());
   
           if (qemu_debug_requested())
               vm_stop(EXCP_DEBUG);
           if (qemu_shutdown_requested()) {
               if (no_shutdown) {
                   vm_stop(0);
                   no_shutdown = 0;
               } else
                   break;
           }
           if (qemu_reset_requested()) {
               pause_all_vcpus();
               qemu_system_reset();
               resume_all_vcpus();
           }
           if (qemu_powerdown_requested())
               qemu_system_powerdown();
           if ((r = qemu_vmstop_requested()))
               vm_stop(r);
       }
       pause_all_vcpus();
   }
   
   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)
   {
       version();
       printf("usage: %s [options] [disk_image]\n"
              "\n"
              "'disk_image' is a raw hard image image for IDE hard disk 0\n"
              "\n"
   #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"             "\n"
            "During emulation, the following keys are useful:\n"             "During emulation, the following keys are useful:\n"
            "ctrl-alt-f      toggle full screen\n"             "ctrl-alt-f      toggle full screen\n"
Line 4121  static void help(int exitcode) Line 4413  static void help(int exitcode)
 #define HAS_ARG 0x0001  #define HAS_ARG 0x0001
   
 enum {  enum {
     /* Please keep in synch with help, qemu_options[] and  #define DEF(option, opt_arg, opt_enum, opt_help)        \
        qemu-doc.texi */      opt_enum,
     /* Standard options: */  #define DEFHEADING(text)
     QEMU_OPTION_h,  #include "qemu-options.h"
     QEMU_OPTION_M,  #undef DEF
     QEMU_OPTION_cpu,  #undef DEFHEADING
     QEMU_OPTION_smp,  #undef GEN_DOCS
     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,  
 };  };
   
 typedef struct QEMUOption {  typedef struct QEMUOption {
Line 4227  typedef struct QEMUOption { Line 4429  typedef struct QEMUOption {
 } QEMUOption;  } QEMUOption;
   
 static const QEMUOption qemu_options[] = {  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 },      { "h", 0, QEMU_OPTION_h },
     { "help", 0, QEMU_OPTION_h },  #define DEF(option, opt_arg, opt_enum, opt_help)        \
     { "M", HAS_ARG, QEMU_OPTION_M },      { option, opt_arg, opt_enum },
     { "cpu", HAS_ARG, QEMU_OPTION_cpu },  #define DEFHEADING(text)
     { "smp", HAS_ARG, QEMU_OPTION_smp },  #include "qemu-options.h"
     { "fda", HAS_ARG, QEMU_OPTION_fda },  #undef DEF
     { "fdb", HAS_ARG, QEMU_OPTION_fdb },  #undef DEFHEADING
     { "hda", HAS_ARG, QEMU_OPTION_hda },  #undef GEN_DOCS
     { "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 },  
     { "k", HAS_ARG, QEMU_OPTION_k },  
 #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 },  
     { NULL },      { NULL },
 };  };
   
Line 4496  static void select_vgahw (const char *p) Line 4585  static void select_vgahw (const char *p)
 {  {
     const char *opts;      const char *opts;
   
       vga_interface_type = VGA_NONE;
     if (strstart(p, "std", &opts)) {      if (strstart(p, "std", &opts)) {
         std_vga_enabled = 1;          vga_interface_type = VGA_STD;
         cirrus_vga_enabled = 0;  
         vmsvga_enabled = 0;  
     } else if (strstart(p, "cirrus", &opts)) {      } else if (strstart(p, "cirrus", &opts)) {
         cirrus_vga_enabled = 1;          vga_interface_type = VGA_CIRRUS;
         std_vga_enabled = 0;  
         vmsvga_enabled = 0;  
     } else if (strstart(p, "vmware", &opts)) {      } else if (strstart(p, "vmware", &opts)) {
         cirrus_vga_enabled = 0;          vga_interface_type = VGA_VMWARE;
         std_vga_enabled = 0;      } else if (strstart(p, "xenfb", &opts)) {
         vmsvga_enabled = 1;          vga_interface_type = VGA_XENFB;
     } else if (strstart(p, "none", &opts)) {      } else if (!strstart(p, "none", &opts)) {
         cirrus_vga_enabled = 0;  
         std_vga_enabled = 0;  
         vmsvga_enabled = 0;  
     } else {  
     invalid_vga:      invalid_vga:
         fprintf(stderr, "Unknown vga type: %s\n", p);          fprintf(stderr, "Unknown vga type: %s\n", p);
         exit(1);          exit(1);
Line 4532  static void select_vgahw (const char *p) Line 4614  static void select_vgahw (const char *p)
     }      }
 }  }
   
   #ifdef TARGET_I386
   static int balloon_parse(const char *arg)
   {
       char buf[128];
       const char *p;
   
       if (!strcmp(arg, "none")) {
           virtio_balloon = 0;
       } else if (!strncmp(arg, "virtio", 6)) {
           virtio_balloon = 1;
           if (arg[6] == ',')  {
               p = arg + 7;
               if (get_param_value(buf, sizeof(buf), "addr", p)) {
                   virtio_balloon_devaddr = strdup(buf);
               }
           }
       } else {
           return -1;
       }
       return 0;
   }
   #endif
   
 #ifdef _WIN32  #ifdef _WIN32
 static BOOL WINAPI qemu_ctrl_handler(DWORD type)  static BOOL WINAPI qemu_ctrl_handler(DWORD type)
 {  {
Line 4540  static BOOL WINAPI qemu_ctrl_handler(DWO Line 4645  static BOOL WINAPI qemu_ctrl_handler(DWO
 }  }
 #endif  #endif
   
 static int qemu_uuid_parse(const char *str, uint8_t *uuid)  int qemu_uuid_parse(const char *str, uint8_t *uuid)
 {  {
     int ret;      int ret;
   
Line 4554  static int qemu_uuid_parse(const char *s Line 4659  static int qemu_uuid_parse(const char *s
     if(ret != 16)      if(ret != 16)
         return -1;          return -1;
   
   #ifdef TARGET_I386
       smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
   #endif
   
     return 0;      return 0;
 }  }
   
Line 4566  static void termsig_handler(int signal) Line 4675  static void termsig_handler(int signal)
     qemu_system_shutdown_request();      qemu_system_shutdown_request();
 }  }
   
 static void termsig_setup(void)  static void sigchld_handler(int signal)
   {
       waitpid(-1, NULL, WNOHANG);
   }
   
   static void sighandler_setup(void)
 {  {
     struct sigaction act;      struct sigaction act;
   
Line 4575  static void termsig_setup(void) Line 4689  static void termsig_setup(void)
     sigaction(SIGINT,  &act, NULL);      sigaction(SIGINT,  &act, NULL);
     sigaction(SIGHUP,  &act, NULL);      sigaction(SIGHUP,  &act, NULL);
     sigaction(SIGTERM, &act, NULL);      sigaction(SIGTERM, &act, NULL);
   
       act.sa_handler = sigchld_handler;
       act.sa_flags = SA_NOCLDSTOP;
       sigaction(SIGCHLD, &act, NULL);
 }  }
   
 #endif  #endif
   
 int main(int argc, char **argv, char **envp)  #ifdef _WIN32
   /* Look for support files in the same directory as the executable.  */
   static char *find_datadir(const char *argv0)
 {  {
 #ifdef CONFIG_GDBSTUB      char *p;
     int use_gdbstub;      char buf[MAX_PATH];
     const char *gdbstub_port;      DWORD len;
   
       len = GetModuleFileName(NULL, buf, sizeof(buf) - 1);
       if (len == 0) {
           return NULL;
       }
   
       buf[len] = 0;
       p = buf + len - 1;
       while (p != buf && *p != '\\')
           p--;
       *p = 0;
       if (access(buf, R_OK) == 0) {
           return qemu_strdup(buf);
       }
       return NULL;
   }
   #else /* !_WIN32 */
   
   /* Find a likely location for support files using the location of the binary.
      For installed binaries this will be "$bindir/../share/qemu".  When
      running from the build tree this will be "$bindir/../pc-bios".  */
   #define SHARE_SUFFIX "/share/qemu"
   #define BUILD_SUFFIX "/pc-bios"
   static char *find_datadir(const char *argv0)
   {
       char *dir;
       char *p = NULL;
       char *res;
   #ifdef PATH_MAX
       char buf[PATH_MAX];
   #endif
       size_t max_len;
   
   #if defined(__linux__)
       {
           int len;
           len = readlink("/proc/self/exe", buf, sizeof(buf) - 1);
           if (len > 0) {
               buf[len] = 0;
               p = buf;
           }
       }
   #elif defined(__FreeBSD__)
       {
           int len;
           len = readlink("/proc/curproc/file", buf, sizeof(buf) - 1);
           if (len > 0) {
               buf[len] = 0;
               p = buf;
           }
       }
   #endif
       /* 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);
           if (!p) {
               return NULL;
           }
       }
       dir = dirname(p);
       dir = dirname(dir);
   
       max_len = strlen(dir) +
           MAX(strlen(SHARE_SUFFIX), strlen(BUILD_SUFFIX)) + 1;
       res = qemu_mallocz(max_len);
       snprintf(res, max_len, "%s%s", dir, SHARE_SUFFIX);
       if (access(res, R_OK)) {
           snprintf(res, max_len, "%s%s", dir, BUILD_SUFFIX);
           if (access(res, R_OK)) {
               qemu_free(res);
               res = NULL;
           }
       }
   #ifndef PATH_MAX
       free(p);
   #endif
       return res;
   }
   #undef SHARE_SUFFIX
   #undef BUILD_SUFFIX
 #endif  #endif
   
   char *qemu_find_file(int type, const char *name)
   {
       int len;
       const char *subdir;
       char *buf;
   
       /* 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);
       }
       switch (type) {
       case QEMU_FILE_TYPE_BIOS:
           subdir = "";
           break;
       case QEMU_FILE_TYPE_KEYMAP:
           subdir = "keymaps/";
           break;
       default:
           abort();
       }
       len = strlen(data_dir) + strlen(name) + strlen(subdir) + 2;
       buf = qemu_mallocz(len);
       snprintf(buf, len, "%s/%s%s", data_dir, subdir, name);
       if (access(buf, R_OK)) {
           qemu_free(buf);
           return NULL;
       }
       return buf;
   }
   
   int main(int argc, char **argv, char **envp)
   {
       const char *gdbstub_dev = NULL;
     uint32_t boot_devices_bitmap = 0;      uint32_t boot_devices_bitmap = 0;
     int i;      int i;
     int snapshot, linux_boot, net_boot;      int snapshot, linux_boot, net_boot;
     const char *initrd_filename;      const char *initrd_filename;
     const char *kernel_filename, *kernel_cmdline;      const char *kernel_filename, *kernel_cmdline;
     const char *boot_devices = "";      char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
     DisplayState *ds;      DisplayState *ds;
     DisplayChangeListener *dcl;      DisplayChangeListener *dcl;
     int cyls, heads, secs, translation;      int cyls, heads, secs, translation;
Line 4614  int main(int argc, char **argv, char **e Line 4853  int main(int argc, char **argv, char **e
     const char *cpu_model;      const char *cpu_model;
     const char *usb_devices[MAX_USB_CMDLINE];      const char *usb_devices[MAX_USB_CMDLINE];
     int usb_devices_index;      int usb_devices_index;
   #ifndef _WIN32
     int fds[2];      int fds[2];
   #endif
     int tb_size;      int tb_size;
     const char *pid_file = NULL;      const char *pid_file = NULL;
     const char *incoming = NULL;      const char *incoming = NULL;
   #ifndef _WIN32
     int fd = 0;      int fd = 0;
     struct passwd *pwd = NULL;      struct passwd *pwd = NULL;
     const char *chroot_dir = NULL;      const char *chroot_dir = NULL;
     const char *run_as = NULL;      const char *run_as = NULL;
   #endif
       CPUState *env;
       int show_vnc_port = 0;
   
     qemu_cache_utils_init(envp);      qemu_cache_utils_init(envp);
   
Line 4656  int main(int argc, char **argv, char **e Line 4901  int main(int argc, char **argv, char **e
     }      }
 #endif  #endif
   
     register_machines();      module_call_init(MODULE_INIT_MACHINE);
     machine = first_machine;      machine = find_default_machine();
     cpu_model = NULL;      cpu_model = NULL;
     initrd_filename = NULL;      initrd_filename = NULL;
     ram_size = 0;      ram_size = 0;
     vga_ram_size = VGA_RAM_SIZE;  
 #ifdef CONFIG_GDBSTUB  
     use_gdbstub = 0;  
     gdbstub_port = DEFAULT_GDBSTUB_PORT;  
 #endif  
     snapshot = 0;      snapshot = 0;
     nographic = 0;  
     curses = 0;  
     kernel_filename = NULL;      kernel_filename = NULL;
     kernel_cmdline = "";      kernel_cmdline = "";
     cyls = heads = secs = 0;      cyls = heads = secs = 0;
Line 4689  int main(int argc, char **argv, char **e Line 4927  int main(int argc, char **argv, char **e
         virtio_consoles[i] = NULL;          virtio_consoles[i] = NULL;
     virtio_console_index = 0;      virtio_console_index = 0;
   
       for (i = 0; i < MAX_NODES; i++) {
           node_mem[i] = 0;
           node_cpumask[i] = 0;
       }
   
     usb_devices_index = 0;      usb_devices_index = 0;
   
     nb_net_clients = 0;      nb_net_clients = 0;
     nb_bt_opts = 0;      nb_bt_opts = 0;
     nb_drives = 0;      nb_drives = 0;
     nb_drives_opt = 0;      nb_drives_opt = 0;
       nb_numa_nodes = 0;
     hda_index = -1;      hda_index = -1;
   
     nb_nics = 0;      nb_nics = 0;
Line 4702  int main(int argc, char **argv, char **e Line 4946  int main(int argc, char **argv, char **e
     tb_size = 0;      tb_size = 0;
     autostart= 1;      autostart= 1;
   
       register_watchdogs();
   
     optind = 1;      optind = 1;
     for(;;) {      for(;;) {
         if (optind >= argc)          if (optind >= argc)
Line 4745  int main(int argc, char **argv, char **e Line 4991  int main(int argc, char **argv, char **e
                     QEMUMachine *m;                      QEMUMachine *m;
                     printf("Supported machines are:\n");                      printf("Supported machines are:\n");
                     for(m = first_machine; m != NULL; m = m->next) {                      for(m = first_machine; m != NULL; m = m->next) {
                           if (m->alias)
                               printf("%-10s %s (alias of %s)\n",
                                      m->alias, m->desc, m->name);
                         printf("%-10s %s%s\n",                          printf("%-10s %s%s\n",
                                m->name, m->desc,                                 m->name, m->desc,
                                m == first_machine ? " (default)" : "");                                 m->is_default ? " (default)" : "");
                     }                      }
                     exit(*optarg != '?');                      exit(*optarg != '?');
                 }                  }
Line 4844  int main(int argc, char **argv, char **e Line 5093  int main(int argc, char **argv, char **e
                                      ",trans=none" : "");                                       ",trans=none" : "");
                 }                  }
                 break;                  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:              case QEMU_OPTION_nographic:
                 nographic = 1;                  display_type = DT_NOGRAPHIC;
                 break;                  break;
 #ifdef CONFIG_CURSES  #ifdef CONFIG_CURSES
             case QEMU_OPTION_curses:              case QEMU_OPTION_curses:
                 curses = 1;                  display_type = DT_CURSES;
                 break;                  break;
 #endif  #endif
             case QEMU_OPTION_portrait:              case QEMU_OPTION_portrait:
Line 4865  int main(int argc, char **argv, char **e Line 5121  int main(int argc, char **argv, char **e
                 drive_add(optarg, CDROM_ALIAS);                  drive_add(optarg, CDROM_ALIAS);
                 break;                  break;
             case QEMU_OPTION_boot:              case QEMU_OPTION_boot:
                 boot_devices = optarg;  
                 /* We just do some generic consistency checks */  
                 {                  {
                     /* Could easily be extended to 64 devices if needed */                      static const char * const params[] = {
                     const char *p;                          "order", "once", "menu", NULL
                                           };
                     boot_devices_bitmap = 0;                      char buf[sizeof(boot_devices)];
                     for (p = boot_devices; *p != '\0'; p++) {                      char *standard_boot_devices;
                         /* Allowed boot devices are:                      int legacy = 0;
                          * a b     : floppy disk drives  
                          * c ... f : IDE disk drives                      if (!strchr(optarg, '=')) {
                          * g ... m : machine implementation dependant drives                          legacy = 1;
                          * n ... p : network devices                          pstrcpy(buf, sizeof(buf), optarg);
                          * It's up to each machine implementation to check                      } else if (check_params(buf, sizeof(buf), params, optarg) < 0) {
                          * if the given boot devices match the actual hardware                          fprintf(stderr,
                          * implementation and firmware features.                                  "qemu: unknown boot parameter '%s' in '%s'\n",
                          */                                  buf, optarg);
                         if (*p < 'a' || *p > 'q') {                          exit(1);
                             fprintf(stderr, "Invalid boot device '%c'\n", *p);                      }
                             exit(1);  
                       if (legacy ||
                           get_param_value(buf, sizeof(buf), "order", optarg)) {
                           boot_devices_bitmap = parse_bootdevices(buf);
                           pstrcpy(boot_devices, sizeof(boot_devices), buf);
                       }
                       if (!legacy) {
                           if (get_param_value(buf, sizeof(buf),
                                               "once", optarg)) {
                               boot_devices_bitmap |= parse_bootdevices(buf);
                               standard_boot_devices = qemu_strdup(boot_devices);
                               pstrcpy(boot_devices, sizeof(boot_devices), buf);
                               qemu_register_reset(restore_boot_devices,
                                                   standard_boot_devices);
                         }                          }
                         if (boot_devices_bitmap & (1 << (*p - 'a'))) {                          if (get_param_value(buf, sizeof(buf),
                             fprintf(stderr,                                              "menu", optarg)) {
                                     "Boot device '%c' was given twice\n",*p);                              if (!strcmp(buf, "on")) {
                             exit(1);                                  boot_menu = 1;
                               } else if (!strcmp(buf, "off")) {
                                   boot_menu = 0;
                               } else {
                                   fprintf(stderr,
                                           "qemu: invalid option value '%s'\n",
                                           buf);
                                   exit(1);
                               }
                         }                          }
                         boot_devices_bitmap |= 1 << (*p - 'a');  
                     }                      }
                 }                  }
                 break;                  break;
Line 4914  int main(int argc, char **argv, char **e Line 5188  int main(int argc, char **argv, char **e
                 break;                  break;
 #ifdef CONFIG_SLIRP  #ifdef CONFIG_SLIRP
             case QEMU_OPTION_tftp:              case QEMU_OPTION_tftp:
                 tftp_prefix = optarg;                  legacy_tftp_prefix = optarg;
                 break;                  break;
             case QEMU_OPTION_bootp:              case QEMU_OPTION_bootp:
                 bootp_filename = optarg;                  legacy_bootp_filename = optarg;
                 break;                  break;
 #ifndef _WIN32  #ifndef _WIN32
             case QEMU_OPTION_smb:              case QEMU_OPTION_smb:
                 net_slirp_smb(optarg);                  net_slirp_smb(optarg);
                 break;                  break;
 #endif  #endif
             case QEMU_OPTION_redir:              case QEMU_OPTION_redir:
Line 4947  int main(int argc, char **argv, char **e Line 5221  int main(int argc, char **argv, char **e
             case QEMU_OPTION_h:              case QEMU_OPTION_h:
                 help(0);                  help(0);
                 break;                  break;
               case QEMU_OPTION_version:
                   version();
                   exit(0);
                   break;
             case QEMU_OPTION_m: {              case QEMU_OPTION_m: {
                 uint64_t value;                  uint64_t value;
                 char *ptr;                  char *ptr;
Line 4966  int main(int argc, char **argv, char **e Line 5244  int main(int argc, char **argv, char **e
   
                 /* On 32-bit hosts, QEMU is limited by virtual address space */                  /* On 32-bit hosts, QEMU is limited by virtual address space */
                 if (value > (2047 << 20)                  if (value > (2047 << 20)
 #ifndef USE_KQEMU  #ifndef CONFIG_KQEMU
                     && HOST_LONG_BITS == 32                      && HOST_LONG_BITS == 32
 #endif  #endif
                     ) {                      ) {
Line 4996  int main(int argc, char **argv, char **e Line 5274  int main(int argc, char **argv, char **e
                     cpu_set_log(mask);                      cpu_set_log(mask);
                 }                  }
                 break;                  break;
 #ifdef CONFIG_GDBSTUB  
             case QEMU_OPTION_s:              case QEMU_OPTION_s:
                 use_gdbstub = 1;                  gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
                 break;                  break;
             case QEMU_OPTION_p:              case QEMU_OPTION_gdb:
                 gdbstub_port = optarg;                  gdbstub_dev = optarg;
                 break;                  break;
 #endif  
             case QEMU_OPTION_L:              case QEMU_OPTION_L:
                 bios_dir = optarg;                  data_dir = optarg;
                 break;                  break;
             case QEMU_OPTION_bios:              case QEMU_OPTION_bios:
                 bios_name = optarg;                  bios_name = optarg;
                 break;                  break;
               case QEMU_OPTION_singlestep:
                   singlestep = 1;
                   break;
             case QEMU_OPTION_S:              case QEMU_OPTION_S:
                 autostart = 0;                  autostart = 0;
                 break;                  break;
   #ifndef _WIN32
             case QEMU_OPTION_k:              case QEMU_OPTION_k:
                 keyboard_layout = optarg;                  keyboard_layout = optarg;
                 break;                  break;
   #endif
             case QEMU_OPTION_localtime:              case QEMU_OPTION_localtime:
                 rtc_utc = 0;                  rtc_utc = 0;
                 break;                  break;
             case QEMU_OPTION_vga:              case QEMU_OPTION_vga:
                 select_vgahw (optarg);                  select_vgahw (optarg);
                 break;                  break;
   #if defined(TARGET_PPC) || defined(TARGET_SPARC)
             case QEMU_OPTION_g:              case QEMU_OPTION_g:
                 {                  {
                     const char *p;                      const char *p;
Line 5056  int main(int argc, char **argv, char **e Line 5338  int main(int argc, char **argv, char **e
                     graphic_depth = depth;                      graphic_depth = depth;
                 }                  }
                 break;                  break;
   #endif
             case QEMU_OPTION_echr:              case QEMU_OPTION_echr:
                 {                  {
                     char *r;                      char *r;
Line 5075  int main(int argc, char **argv, char **e Line 5358  int main(int argc, char **argv, char **e
                 serial_devices[serial_device_index] = optarg;                  serial_devices[serial_device_index] = optarg;
                 serial_device_index++;                  serial_device_index++;
                 break;                  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:              case QEMU_OPTION_virtiocon:
                 if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {                  if (virtio_console_index >= MAX_VIRTIO_CONSOLES) {
                     fprintf(stderr, "qemu: too many virtio consoles\n");                      fprintf(stderr, "qemu: too many virtio consoles\n");
Line 5108  int main(int argc, char **argv, char **e Line 5402  int main(int argc, char **argv, char **e
                 no_quit = 1;                  no_quit = 1;
                 break;                  break;
             case QEMU_OPTION_sdl:              case QEMU_OPTION_sdl:
                 sdl = 1;                  display_type = DT_SDL;
                 break;                  break;
 #endif  #endif
             case QEMU_OPTION_pidfile:              case QEMU_OPTION_pidfile:
Line 5127  int main(int argc, char **argv, char **e Line 5421  int main(int argc, char **argv, char **e
                     exit(1);                      exit(1);
                 }                  }
                 break;                  break;
               case QEMU_OPTION_smbios:
                   if(smbios_entry_add(optarg) < 0) {
                       fprintf(stderr, "Wrong smbios provided\n");
                       exit(1);
                   }
                   break;
 #endif  #endif
 #ifdef USE_KQEMU  #ifdef CONFIG_KQEMU
             case QEMU_OPTION_no_kqemu:              case QEMU_OPTION_enable_kqemu:
                 kqemu_allowed = 0;                  kqemu_allowed = 1;
                 break;                  break;
             case QEMU_OPTION_kernel_kqemu:              case QEMU_OPTION_kernel_kqemu:
                 kqemu_allowed = 2;                  kqemu_allowed = 2;
Line 5139  int main(int argc, char **argv, char **e Line 5439  int main(int argc, char **argv, char **e
 #ifdef CONFIG_KVM  #ifdef CONFIG_KVM
             case QEMU_OPTION_enable_kvm:              case QEMU_OPTION_enable_kvm:
                 kvm_allowed = 1;                  kvm_allowed = 1;
 #ifdef USE_KQEMU  #ifdef CONFIG_KQEMU
                 kqemu_allowed = 0;                  kqemu_allowed = 0;
 #endif  #endif
                 break;                  break;
Line 5164  int main(int argc, char **argv, char **e Line 5464  int main(int argc, char **argv, char **e
                 }                  }
                 break;                  break;
             case QEMU_OPTION_vnc:              case QEMU_OPTION_vnc:
                   display_type = DT_VNC;
                 vnc_display = optarg;                  vnc_display = optarg;
                 break;                  break;
   #ifdef TARGET_I386
             case QEMU_OPTION_no_acpi:              case QEMU_OPTION_no_acpi:
                 acpi_enabled = 0;                  acpi_enabled = 0;
                 break;                  break;
             case QEMU_OPTION_no_hpet:              case QEMU_OPTION_no_hpet:
                 no_hpet = 1;                  no_hpet = 1;
                 break;                  break;
               case QEMU_OPTION_balloon:
                   if (balloon_parse(optarg) < 0) {
                       fprintf(stderr, "Unknown -balloon argument %s\n", optarg);
                       exit(1);
                   }
                   break;
   #endif
             case QEMU_OPTION_no_reboot:              case QEMU_OPTION_no_reboot:
                 no_reboot = 1;                  no_reboot = 1;
                 break;                  break;
Line 5188  int main(int argc, char **argv, char **e Line 5497  int main(int argc, char **argv, char **e
                     exit(1);                      exit(1);
                 }                  }
                 break;                  break;
   #ifndef _WIN32
             case QEMU_OPTION_daemonize:              case QEMU_OPTION_daemonize:
                 daemonize = 1;                  daemonize = 1;
                 break;                  break;
   #endif
             case QEMU_OPTION_option_rom:              case QEMU_OPTION_option_rom:
                 if (nb_option_roms >= MAX_OPTION_ROMS) {                  if (nb_option_roms >= MAX_OPTION_ROMS) {
                     fprintf(stderr, "Too many option ROMs\n");                      fprintf(stderr, "Too many option ROMs\n");
Line 5199  int main(int argc, char **argv, char **e Line 5510  int main(int argc, char **argv, char **e
                 option_rom[nb_option_roms] = optarg;                  option_rom[nb_option_roms] = optarg;
                 nb_option_roms++;                  nb_option_roms++;
                 break;                  break;
   #if defined(TARGET_ARM) || defined(TARGET_M68K)
             case QEMU_OPTION_semihosting:              case QEMU_OPTION_semihosting:
                 semihosting_enabled = 1;                  semihosting_enabled = 1;
                 break;                  break;
   #endif
             case QEMU_OPTION_name:              case QEMU_OPTION_name:
                 qemu_name = optarg;                  qemu_name = qemu_strdup(optarg);
                    {
                        char *p = strchr(qemu_name, ',');
                        if (p != NULL) {
                           *p++ = 0;
                           if (strncmp(p, "process=", 8)) {
                               fprintf(stderr, "Unknown subargument %s to -name", p);
                               exit(1);
                           }
                           p += 8;
                           set_proc_name(p);
                        }  
                    }      
                 break;                  break;
 #if defined(TARGET_SPARC) || defined(TARGET_PPC)  #if defined(TARGET_SPARC) || defined(TARGET_PPC)
             case QEMU_OPTION_prom_env:              case QEMU_OPTION_prom_env:
Line 5277  int main(int argc, char **argv, char **e Line 5602  int main(int argc, char **argv, char **e
             case QEMU_OPTION_incoming:              case QEMU_OPTION_incoming:
                 incoming = optarg;                  incoming = optarg;
                 break;                  break;
   #ifndef _WIN32
             case QEMU_OPTION_chroot:              case QEMU_OPTION_chroot:
                 chroot_dir = optarg;                  chroot_dir = optarg;
                 break;                  break;
             case QEMU_OPTION_runas:              case QEMU_OPTION_runas:
                 run_as = optarg;                  run_as = optarg;
                 break;                  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 no data_dir is specified then try to find it relative to the
          executable path.  */
       if (!data_dir) {
           data_dir = find_datadir(argv[0]);
       }
       /* If all else fails use the install patch specified when building.  */
       if (!data_dir) {
           data_dir = CONFIG_QEMU_SHAREDIR;
       }
   
   #if defined(CONFIG_KVM) && defined(CONFIG_KQEMU)
     if (kvm_allowed && kqemu_allowed) {      if (kvm_allowed && kqemu_allowed) {
         fprintf(stderr,          fprintf(stderr,
                 "You can not enable both KVM and kqemu at the same time\n");                  "You can not enable both KVM and kqemu at the same time\n");
Line 5303  int main(int argc, char **argv, char **e Line 5651  int main(int argc, char **argv, char **e
         exit(1);          exit(1);
     }      }
   
     if (nographic) {      if (display_type == DT_NOGRAPHIC) {
        if (serial_device_index == 0)         if (serial_device_index == 0)
            serial_devices[0] = "stdio";             serial_devices[0] = "stdio";
        if (parallel_device_index == 0)         if (parallel_device_index == 0)
Line 5355  int main(int argc, char **argv, char **e Line 5703  int main(int argc, char **argv, char **e
         signal(SIGTTOU, SIG_IGN);          signal(SIGTTOU, SIG_IGN);
         signal(SIGTTIN, SIG_IGN);          signal(SIGTTIN, SIG_IGN);
     }      }
 #endif  
   
     if (pid_file && qemu_create_pidfile(pid_file) != 0) {      if (pid_file && qemu_create_pidfile(pid_file) != 0) {
         if (daemonize) {          if (daemonize) {
Line 5365  int main(int argc, char **argv, char **e Line 5712  int main(int argc, char **argv, char **e
             fprintf(stderr, "Could not acquire pid file\n");              fprintf(stderr, "Could not acquire pid file\n");
         exit(1);          exit(1);
     }      }
   #endif
   
 #ifdef USE_KQEMU  #ifdef CONFIG_KQEMU
     if (smp_cpus > 1)      if (smp_cpus > 1)
         kqemu_allowed = 0;          kqemu_allowed = 0;
 #endif  #endif
       if (qemu_init_main_loop()) {
           fprintf(stderr, "qemu_init_main_loop failed\n");
           exit(1);
       }
     linux_boot = (kernel_filename != NULL);      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') {      if (!linux_boot && *kernel_cmdline != '\0') {
         fprintf(stderr, "-append only allowed with -kernel option\n");          fprintf(stderr, "-append only allowed with -kernel option\n");
Line 5387  int main(int argc, char **argv, char **e Line 5734  int main(int argc, char **argv, char **e
         exit(1);          exit(1);
     }      }
   
     /* boot to floppy or the default cd if no hard disk defined yet */  
     if (!boot_devices[0]) {  
         boot_devices = "cad";  
     }  
     setvbuf(stdout, NULL, _IOLBF, 0);      setvbuf(stdout, NULL, _IOLBF, 0);
   
     init_timers();      init_timers();
Line 5423  int main(int argc, char **argv, char **e Line 5766  int main(int argc, char **argv, char **e
         if (net_client_parse(net_clients[i]) < 0)          if (net_client_parse(net_clients[i]) < 0)
             exit(1);              exit(1);
     }      }
     net_client_check();  
   
 #ifdef TARGET_I386      net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
     /* XXX: this should be moved in the PC machine instantiation code */      net_set_boot_mask(net_boot);
     if (net_boot != 0) {  
         int netroms = 0;      net_client_check();
         for (i = 0; i < nb_nics && i < 4; i++) {  
             const char *model = nd_table[i].model;  
             char buf[1024];  
             if (net_boot & (1 << i)) {  
                 if (model == NULL)  
                     model = "ne2k_pci";  
                 snprintf(buf, sizeof(buf), "%s/pxe-%s.bin", bios_dir, model);  
                 if (get_image_size(buf) > 0) {  
                     if (nb_option_roms >= MAX_OPTION_ROMS) {  
                         fprintf(stderr, "Too many option ROMs\n");  
                         exit(1);  
                     }  
                     option_rom[nb_option_roms] = strdup(buf);  
                     nb_option_roms++;  
                     netroms++;  
                 }  
             }  
         }  
         if (netroms == 0) {  
             fprintf(stderr, "No valid PXE rom found for network device\n");  
             exit(1);  
         }  
     }  
 #endif  
   
     /* init the bluetooth world */      /* init the bluetooth world */
     for (i = 0; i < nb_bt_opts; i++)      for (i = 0; i < nb_bt_opts; i++)
Line 5460  int main(int argc, char **argv, char **e Line 5778  int main(int argc, char **argv, char **e
             exit(1);              exit(1);
   
     /* init the memory */      /* init the memory */
     phys_ram_size = machine->ram_require & ~RAMSIZE_FIXED;      if (ram_size == 0)
           ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
     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;  #ifdef CONFIG_KQEMU
         } else      /* FIXME: This is a nasty hack because kqemu can't cope with dynamic
             ram_size = phys_ram_size;         guest ram allocation.  It needs to go away.  */
     } else {      if (kqemu_allowed) {
         if (ram_size == 0)          kqemu_phys_ram_size = ram_size + 8 * 1024 * 1024 + 4 * 1024 * 1024;
             ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;          kqemu_phys_ram_base = qemu_vmalloc(kqemu_phys_ram_size);
           if (!kqemu_phys_ram_base) {
         phys_ram_size += ram_size;              fprintf(stderr, "Could not allocate physical memory\n");
     }              exit(1);
           }
     phys_ram_base = qemu_vmalloc(phys_ram_size);  
     if (!phys_ram_base) {  
         fprintf(stderr, "Could not allocate physical memory\n");  
         exit(1);  
     }      }
   #endif
   
     /* init the dynamic translator */      /* init the dynamic translator */
     cpu_exec_init_all(tb_size * 1024 * 1024);      cpu_exec_init_all(tb_size * 1024 * 1024);
   
     bdrv_init();      bdrv_init();
     dma_helper_init();  
   
     /* we always create the cdrom drive, even if no disk is there */      /* we always create the cdrom drive, even if no disk is there */
   
Line 5518  int main(int argc, char **argv, char **e Line 5825  int main(int argc, char **argv, char **e
   
 #ifndef _WIN32  #ifndef _WIN32
     /* must be after terminal init, SDL library changes signal handlers */      /* must be after terminal init, SDL library changes signal handlers */
     termsig_setup();      sighandler_setup();
 #endif  #endif
   
     /* Maintain compatibility with multiple stdio monitors */      /* Maintain compatibility with multiple stdio monitors */
Line 5536  int main(int argc, char **argv, char **e Line 5843  int main(int argc, char **argv, char **e
         }          }
     }      }
   
       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()) {      if (kvm_enabled()) {
         int ret;          int ret;
   
Line 5596  int main(int argc, char **argv, char **e Line 5945  int main(int argc, char **argv, char **e
         }          }
     }      }
   
     machine->init(ram_size, vga_ram_size, boot_devices,      module_call_init(MODULE_INIT_DEVICE);
                   kernel_filename, kernel_cmdline, initrd_filename, cpu_model);  
   
     current_machine = machine;      if (machine->compat_props) {
           qdev_prop_register_compat(machine->compat_props);
       }
       machine->init(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_sync_vcpus();      for (env = first_cpu; env != NULL; env = env->next_cpu) {
         if (ret < 0) {          for (i = 0; i < nb_numa_nodes; i++) {
             fprintf(stderr, "failed to initialize vcpus\n");              if (node_cpumask[i] & (1 << env->cpu_index)) {
             exit(1);                  env->numa_node = i;
               }
         }          }
     }      }
   
       current_machine = machine;
   
     /* init USB devices */      /* init USB devices */
     if (usb_enabled) {      if (usb_enabled) {
         for(i = 0; i < usb_devices_index; i++) {          for(i = 0; i < usb_devices_index; i++) {
Line 5626  int main(int argc, char **argv, char **e Line 5978  int main(int argc, char **argv, char **e
         dumb_display_init();          dumb_display_init();
     /* just use the first displaystate for the moment */      /* just use the first displaystate for the moment */
     ds = display_state;      ds = display_state;
     /* terminal init */  
     if (nographic) {      if (display_type == DT_DEFAULT) {
         if (curses) {  #if defined(CONFIG_SDL) || defined(CONFIG_COCOA)
             fprintf(stderr, "fatal: -nographic can't be used with -curses\n");          display_type = DT_SDL;
             exit(1);  #else
         }          display_type = DT_VNC;
     } else {           vnc_display = "localhost:0,to=99";
           show_vnc_port = 1;
   #endif
       }
           
   
       switch (display_type) {
       case DT_NOGRAPHIC:
           break;
 #if defined(CONFIG_CURSES)  #if defined(CONFIG_CURSES)
             if (curses) {      case DT_CURSES:
                 /* At the moment curses cannot be used with other displays */          curses_display_init(ds, full_screen);
                 curses_display_init(ds, full_screen);          break;
             } else  
 #endif  #endif
             {  
                 if (vnc_display != NULL) {  
                     vnc_display_init(ds);  
                     if (vnc_display_open(ds, vnc_display) < 0)  
                         exit(1);  
                 }  
 #if defined(CONFIG_SDL)  #if defined(CONFIG_SDL)
                 if (sdl || !vnc_display)      case DT_SDL:
                     sdl_display_init(ds, full_screen, no_frame);          sdl_display_init(ds, full_screen, no_frame);
           break;
 #elif defined(CONFIG_COCOA)  #elif defined(CONFIG_COCOA)
                 if (sdl || !vnc_display)      case DT_SDL:
                     cocoa_display_init(ds, full_screen);          cocoa_display_init(ds, full_screen);
           break;
 #endif  #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);      dpy_resize(ds);
   
Line 5665  int main(int argc, char **argv, char **e Line 6030  int main(int argc, char **argv, char **e
         dcl = dcl->next;          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);          nographic_timer = qemu_new_timer(rt_clock, nographic_update, NULL);
         qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));          qemu_mod_timer(nographic_timer, qemu_get_clock(rt_clock));
     }      }
Line 5674  int main(int argc, char **argv, char **e Line 6039  int main(int argc, char **argv, char **e
     qemu_chr_initial_reset();      qemu_chr_initial_reset();
   
     if (monitor_device && monitor_hd)      if (monitor_device && monitor_hd)
         monitor_init(monitor_hd, !nographic);          monitor_init(monitor_hd, MONITOR_USE_READLINE | MONITOR_IS_DEFAULT);
   
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {      for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         const char *devname = serial_devices[i];          const char *devname = serial_devices[i];
         if (devname && strcmp(devname, "none")) {          if (devname && strcmp(devname, "none")) {
             char label[32];  
             snprintf(label, sizeof(label), "serial%d", i);  
             if (strstart(devname, "vc", 0))              if (strstart(devname, "vc", 0))
                 qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);                  qemu_chr_printf(serial_hds[i], "serial%d console\r\n", i);
         }          }
Line 5689  int main(int argc, char **argv, char **e Line 6052  int main(int argc, char **argv, char **e
     for(i = 0; i < MAX_PARALLEL_PORTS; i++) {      for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
         const char *devname = parallel_devices[i];          const char *devname = parallel_devices[i];
         if (devname && strcmp(devname, "none")) {          if (devname && strcmp(devname, "none")) {
             char label[32];  
             snprintf(label, sizeof(label), "parallel%d", i);  
             if (strstart(devname, "vc", 0))              if (strstart(devname, "vc", 0))
                 qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);                  qemu_chr_printf(parallel_hds[i], "parallel%d console\r\n", i);
         }          }
Line 5699  int main(int argc, char **argv, char **e Line 6060  int main(int argc, char **argv, char **e
     for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {      for(i = 0; i < MAX_VIRTIO_CONSOLES; i++) {
         const char *devname = virtio_consoles[i];          const char *devname = virtio_consoles[i];
         if (virtcon_hds[i] && devname) {          if (virtcon_hds[i] && devname) {
             char label[32];  
             snprintf(label, sizeof(label), "virtcon%d", i);  
             if (strstart(devname, "vc", 0))              if (strstart(devname, "vc", 0))
                 qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);                  qemu_chr_printf(virtcon_hds[i], "virtio console%d\r\n", i);
         }          }
     }      }
   
 #ifdef CONFIG_GDBSTUB      if (gdbstub_dev && gdbserver_start(gdbstub_dev) < 0) {
     if (use_gdbstub) {          fprintf(stderr, "qemu: could not open gdbserver on device '%s'\n",
         /* XXX: use standard host:port notation and modify options                  gdbstub_dev);
            accordingly. */          exit(1);
         if (gdbserver_start(gdbstub_port) < 0) {  
             fprintf(stderr, "qemu: could not open gdbstub device on port '%s'\n",  
                     gdbstub_port);  
             exit(1);  
         }  
     }      }
 #endif  
   
     if (loadvm)      if (loadvm)
         do_loadvm(loadvm);          do_loadvm(cur_mon, loadvm);
   
     if (incoming) {      if (incoming) {
         autostart = 0; /* fixme how to deal with -daemonize */  
         qemu_start_incoming_migration(incoming);          qemu_start_incoming_migration(incoming);
     }      } else if (autostart) {
   
     if (autostart)  
         vm_start();          vm_start();
       }
   
   #ifndef _WIN32
     if (daemonize) {      if (daemonize) {
         uint8_t status = 0;          uint8_t status = 0;
         ssize_t len;          ssize_t len;
Line 5747  int main(int argc, char **argv, char **e Line 6099  int main(int argc, char **argv, char **e
             exit(1);              exit(1);
     }      }
   
 #ifndef _WIN32  
     if (run_as) {      if (run_as) {
         pwd = getpwnam(run_as);          pwd = getpwnam(run_as);
         if (!pwd) {          if (!pwd) {
Line 5778  int main(int argc, char **argv, char **e Line 6129  int main(int argc, char **argv, char **e
             exit(1);              exit(1);
         }          }
     }      }
 #endif  
   
     if (daemonize) {      if (daemonize) {
         dup2(fd, 0);          dup2(fd, 0);
Line 5787  int main(int argc, char **argv, char **e Line 6137  int main(int argc, char **argv, char **e
   
         close(fd);          close(fd);
     }      }
   #endif
   
     main_loop();      main_loop();
     quit_timers();      quit_timers();

Removed from v.1.1.1.11  
changed lines
  Added in v.1.1.1.12


unix.superglobalmegacorp.com