]> Git Repo - qemu.git/blobdiff - vl.c
Mac OS X port (Pierre d'Herbemont)
[qemu.git] / vl.c
diff --git a/vl.c b/vl.c
index cdebcc2035d8f596deb96d5bf17ee93e0db1bddd..6fdb7d2aa78cd0a0223f872c8b773c54010b79bf 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -40,7 +40,9 @@
 #include <sys/socket.h>
 #ifdef _BSD
 #include <sys/stat.h>
+#ifndef __APPLE__
 #include <libutil.h>
+#endif
 #else
 #include <linux/if.h>
 #include <linux/if_tun.h>
@@ -63,6 +65,7 @@
 #endif
 
 #ifdef CONFIG_SDL
+#include <SDL/SDL.h>
 #if defined(__linux__)
 /* SDL use the pthreads and they modify sigaction. We don't
    want that. */
@@ -96,7 +99,7 @@ extern void __sigaction();
 #ifdef TARGET_PPC
 #define DEFAULT_RAM_SIZE 144
 #else
-#define DEFAULT_RAM_SIZE 32
+#define DEFAULT_RAM_SIZE 128
 #endif
 /* in ms */
 #define GUI_REFRESH_INTERVAL 30
@@ -127,10 +130,13 @@ SerialState *serial_console;
 QEMUTimer *gui_timer;
 int vm_running;
 int audio_enabled = 0;
-int pci_enabled = 0;
+int pci_enabled = 1;
 int prep_enabled = 0;
 int rtc_utc = 1;
-int cirrus_vga_enabled = 0;
+int cirrus_vga_enabled = 1;
+int graphic_width = 800;
+int graphic_height = 600;
+int graphic_depth = 15;
 
 /***********************************************************/
 /* x86 ISA bus support */
@@ -290,6 +296,18 @@ char *pstrcat(char *buf, int buf_size, const char *s)
     return buf;
 }
 
+/* return the size or -1 if error */
+int get_image_size(const char *filename)
+{
+    int fd, size;
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0)
+        return -1;
+    size = lseek(fd, 0, SEEK_END);
+    close(fd);
+    return size;
+}
+
 /* return the size or -1 if error */
 int load_image(const char *filename, uint8_t *addr)
 {
@@ -772,6 +790,35 @@ void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
 static void host_alarm_handler(int host_signum)
 #endif
 {
+#if 0
+#define DISP_FREQ 1000
+    {
+        static int64_t delta_min = INT64_MAX;
+        static int64_t delta_max, delta_cum, last_clock, delta, ti;
+        static int count;
+        ti = qemu_get_clock(vm_clock);
+        if (last_clock != 0) {
+            delta = ti - last_clock;
+            if (delta < delta_min)
+                delta_min = delta;
+            if (delta > delta_max)
+                delta_max = delta;
+            delta_cum += delta;
+            if (++count == DISP_FREQ) {
+                printf("timer: min=%lld us max=%lld us avg=%lld us avg_freq=%0.3f Hz\n",
+                       muldiv64(delta_min, 1000000, ticks_per_sec),
+                       muldiv64(delta_max, 1000000, ticks_per_sec),
+                       muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),
+                       (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));
+                count = 0;
+                delta_min = INT64_MAX;
+                delta_max = 0;
+                delta_cum = 0;
+            }
+        }
+        last_clock = ti;
+    }
+#endif
     if (qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
                            qemu_get_clock(vm_clock)) ||
         qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],
@@ -865,6 +912,7 @@ static void init_timers(void)
            the emulated kernel requested a too high timer frequency */
         getitimer(ITIMER_REAL, &itv);
 
+#if defined(__linux__)
         if (itv.it_interval.tv_usec > 1000) {
             /* try to use /dev/rtc to have a faster timer */
             if (start_rtc_timer() < 0)
@@ -880,7 +928,9 @@ static void init_timers(void)
             sigaction(SIGIO, &act, NULL);
             fcntl(rtc_fd, F_SETFL, O_ASYNC);
             fcntl(rtc_fd, F_SETOWN, getpid());
-        } else {
+        } else 
+#endif /* defined(__linux__) */
+        {
         use_itimer:
             pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * 
                                    PIT_FREQ) / 1000000;
@@ -910,14 +960,14 @@ int serial_open_device(void)
 
 int serial_open_device(void)
 {
-    char slave_name[1024];
-    int master_fd, slave_fd;
-
     if (serial_console == NULL && nographic) {
         /* use console for serial port */
         return 0;
     } else {
 #if 0
+        char slave_name[1024];
+        int master_fd, slave_fd;
+        
         /* Not satisfying */
         if (openpty(&master_fd, &slave_fd, slave_name, NULL, NULL) < 0) {
             fprintf(stderr, "warning: could not create pseudo terminal for serial port\n");
@@ -1169,10 +1219,12 @@ static void term_init(void)
 
 /* init terminal so that we can grab keys */
 static struct termios oldtty;
+static int old_fd0_flags;
 
 static void term_exit(void)
 {
     tcsetattr (0, TCSANOW, &oldtty);
+    fcntl(0, F_SETFL, old_fd0_flags);
 }
 
 static void term_init(void)
@@ -1181,6 +1233,7 @@ static void term_init(void)
 
     tcgetattr (0, &tty);
     oldtty = tty;
+    old_fd0_flags = fcntl(0, F_GETFL);
 
     tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
                           |INLCR|IGNCR|ICRNL|IXON);
@@ -1555,6 +1608,7 @@ int qemu_loadvm(const char *filename)
 
 static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
 {
+    qemu_put_be32(f, dt->selector);
     qemu_put_be32(f, (uint32_t)dt->base);
     qemu_put_be32(f, dt->limit);
     qemu_put_be32(f, dt->flags);
@@ -1562,6 +1616,7 @@ static void cpu_put_seg(QEMUFile *f, SegmentCache *dt)
 
 static void cpu_get_seg(QEMUFile *f, SegmentCache *dt)
 {
+    dt->selector = qemu_get_be32(f);
     dt->base = (uint8_t *)qemu_get_be32(f);
     dt->limit = qemu_get_be32(f);
     dt->flags = qemu_get_be32(f);
@@ -1635,7 +1690,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     uint32_t hflags;
     uint16_t fpus, fpuc, fptag;
 
-    if (version_id != 1)
+    if (version_id != 2)
         return -EINVAL;
     for(i = 0; i < 8; i++)
         qemu_get_be32s(f, &env->regs[i]);
@@ -1819,6 +1874,62 @@ void vm_stop(int reason)
     }
 }
 
+/* reset/shutdown handler */
+
+typedef struct QEMUResetEntry {
+    QEMUResetHandler *func;
+    void *opaque;
+    struct QEMUResetEntry *next;
+} QEMUResetEntry;
+
+static QEMUResetEntry *first_reset_entry;
+static int reset_requested;
+static int shutdown_requested;
+
+void qemu_register_reset(QEMUResetHandler *func, void *opaque)
+{
+    QEMUResetEntry **pre, *re;
+
+    pre = &first_reset_entry;
+    while (*pre != NULL)
+        pre = &(*pre)->next;
+    re = qemu_mallocz(sizeof(QEMUResetEntry));
+    re->func = func;
+    re->opaque = opaque;
+    re->next = NULL;
+    *pre = re;
+}
+
+void qemu_system_reset(void)
+{
+    QEMUResetEntry *re;
+
+    /* reset all devices */
+    for(re = first_reset_entry; re != NULL; re = re->next) {
+        re->func(re->opaque);
+    }
+}
+
+void qemu_system_reset_request(void)
+{
+    reset_requested = 1;
+    cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+}
+
+void qemu_system_shutdown_request(void)
+{
+    shutdown_requested = 1;
+    cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT);
+}
+
+static void main_cpu_reset(void *opaque)
+{
+#ifdef TARGET_I386
+    CPUState *env = opaque;
+    cpu_reset(env);
+#endif
+}
+
 int main_loop(void)
 {
 #ifndef _WIN32
@@ -1833,10 +1944,15 @@ int main_loop(void)
     for(;;) {
         if (vm_running) {
             ret = cpu_exec(env);
-            if (reset_requested) {
+            if (shutdown_requested) {
                 ret = EXCP_INTERRUPT; 
                 break;
             }
+            if (reset_requested) {
+                reset_requested = 0;
+                qemu_system_reset();
+                ret = EXCP_INTERRUPT; 
+            }
             if (ret == EXCP_DEBUG) {
                 vm_stop(EXCP_DEBUG);
             }
@@ -1967,6 +2083,10 @@ void help(void)
            "-nographic      disable graphical output and redirect serial I/Os to console\n"
            "-enable-audio   enable audio support\n"
            "-localtime      set the real time clock to local time [default=utc]\n"
+#ifdef TARGET_PPC
+           "-prep           Simulate a PREP system (default is PowerMAC)\n"
+           "-g WxH[xDEPTH]  Set the initial VGA graphic mode\n"
+#endif
            "\n"
            "Network options:\n"
            "-nics n         simulate 'n' network cards [default=1]\n"
@@ -1993,7 +2113,11 @@ void help(void)
 #ifdef USE_CODE_COPY
            "-no-code-copy   disable code copy acceleration\n"
 #endif
-
+#ifdef TARGET_I386
+           "-isa            simulate an ISA-only system (default is PCI system)\n"
+           "-std-vga        simulate a standard VGA card with VESA Bochs Extensions\n"
+           "                (default is CL-GD5446 PCI VGA)\n"
+#endif
            "\n"
            "During emulation, use C-a h to get terminal commands:\n",
 #ifdef CONFIG_SOFTMMU
@@ -2052,9 +2176,12 @@ enum {
     QEMU_OPTION_L,
     QEMU_OPTION_no_code_copy,
     QEMU_OPTION_pci,
+    QEMU_OPTION_isa,
     QEMU_OPTION_prep,
     QEMU_OPTION_localtime,
     QEMU_OPTION_cirrusvga,
+    QEMU_OPTION_g,
+    QEMU_OPTION_std_vga,
 };
 
 typedef struct QEMUOption {
@@ -2101,8 +2228,11 @@ const QEMUOption qemu_options[] = {
     { "no-code-copy", 0, QEMU_OPTION_no_code_copy },
 #ifdef TARGET_PPC
     { "prep", 0, QEMU_OPTION_prep },
+    { "g", 1, QEMU_OPTION_g },
 #endif
     { "localtime", 0, QEMU_OPTION_localtime },
+    { "isa", 0, QEMU_OPTION_isa },
+    { "std-vga", 0, QEMU_OPTION_std_vga },
 
     /* temporary options */
     { "pci", 0, QEMU_OPTION_pci },
@@ -2380,6 +2510,9 @@ int main(int argc, char **argv)
             case QEMU_OPTION_pci:
                 pci_enabled = 1;
                 break;
+            case QEMU_OPTION_isa:
+                pci_enabled = 0;
+                break;
             case QEMU_OPTION_prep:
                 prep_enabled = 1;
                 break;
@@ -2389,6 +2522,43 @@ int main(int argc, char **argv)
             case QEMU_OPTION_cirrusvga:
                 cirrus_vga_enabled = 1;
                 break;
+            case QEMU_OPTION_std_vga:
+                cirrus_vga_enabled = 0;
+                break;
+            case QEMU_OPTION_g:
+                {
+                    const char *p;
+                    int w, h, depth;
+                    p = optarg;
+                    w = strtol(p, (char **)&p, 10);
+                    if (w <= 0) {
+                    graphic_error:
+                        fprintf(stderr, "qemu: invalid resolution or depth\n");
+                        exit(1);
+                    }
+                    if (*p != 'x')
+                        goto graphic_error;
+                    p++;
+                    h = strtol(p, (char **)&p, 10);
+                    if (h <= 0)
+                        goto graphic_error;
+                    if (*p == 'x') {
+                        p++;
+                        depth = strtol(p, (char **)&p, 10);
+                        if (depth != 8 && depth != 15 && depth != 16 && 
+                            depth != 24 && depth != 32)
+                            goto graphic_error;
+                    } else if (*p == '\0') {
+                        depth = graphic_depth;
+                    } else {
+                        goto graphic_error;
+                    }
+                    
+                    graphic_width = w;
+                    graphic_height = h;
+                    graphic_depth = depth;
+                }
+                break;
             }
         }
     }
@@ -2465,8 +2635,8 @@ int main(int argc, char **argv)
 
 #ifdef CONFIG_SOFTMMU
 #ifdef _BSD
-    /* mallocs are always aligned on BSD. */
-    phys_ram_base = malloc(phys_ram_size);
+    /* mallocs are always aligned on BSD. valloc is better for correctness */
+    phys_ram_base = valloc(phys_ram_size);
 #else
     phys_ram_base = memalign(TARGET_PAGE_SIZE, phys_ram_size);
 #endif
@@ -2560,8 +2730,9 @@ int main(int argc, char **argv)
     cpu_single_env = env;
 
     register_savevm("timer", 0, 1, timer_save, timer_load, env);
-    register_savevm("cpu", 0, 1, cpu_save, cpu_load, env);
+    register_savevm("cpu", 0, 2, cpu_save, cpu_load, env);
     register_savevm("ram", 0, 1, ram_save, ram_load, NULL);
+    qemu_register_reset(main_cpu_reset, global_env);
 
     init_ioports();
     cpu_calibrate_ticks();
This page took 0.034073 seconds and 4 git commands to generate.