#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>
#endif
#ifdef CONFIG_SDL
+#include <SDL/SDL.h>
#if defined(__linux__)
/* SDL use the pthreads and they modify sigaction. We don't
want that. */
#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
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 */
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)
{
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],
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)
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;
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");
/* 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)
tcgetattr (0, &tty);
oldtty = tty;
+ old_fd0_flags = fcntl(0, F_GETFL);
tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
|INLCR|IGNCR|ICRNL|IXON);
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);
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);
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]);
}
}
+/* 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
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);
}
"-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"
#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
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 {
{ "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 },
case QEMU_OPTION_pci:
pci_enabled = 1;
break;
+ case QEMU_OPTION_isa:
+ pci_enabled = 0;
+ break;
case QEMU_OPTION_prep:
prep_enabled = 1;
break;
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;
}
}
}
#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
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();