[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH, RFC] Refactor target specific handling out of vl.c
From: |
Blue Swirl |
Subject: |
[Qemu-devel] [PATCH, RFC] Refactor target specific handling out of vl.c |
Date: |
Sat, 27 Mar 2010 13:06:55 +0200 |
This is very much work in progress, it does not compile yet. However,
the only target dependencies remaining are QEMU_OPTION_xxx enums and
the target specific option handling in the option parsing loop. I
haven't got a good plan for that, except maybe QEMUOption structure
could have a field that specifies for which targets the option is
valid. Any ideas?
There also are some pieces (set_cpu_log, debug_requested, gdbstub.h
and kvm.h cleanup, allow balloon options to all targets) that deserve
separate patches.
RAM handling could go to a new file, perhaps in hw/ram.c instead of arch_init.c.
Comments?
This depends on the various previous patches I sent. I set up a public git tree:
http://repo.or.cz/w/qemu/blueswirl.git
git://repo.or.cz/qemu/blueswirl.git
Not-quite-signed-off-by-yet: Blue Swirl <address@hidden>
---
Makefile.objs | 2 +-
Makefile.target | 2 +-
arch_init.c | 461 +++++++++++++++++++++++++++++++++++++++++++++++++++++
arch_init.h | 20 +++
balloon.h | 2 -
cpu-all.h | 1 -
cpus.c | 18 ++-
cpus.h | 1 +
gdbstub.h | 11 +-
hw/smbios.c | 1 +
kvm.h | 4 +-
qemu-common.h | 2 +
qemu-options.hx | 2 -
vl.c | 475 ++++---------------------------------------------------
14 files changed, 543 insertions(+), 459 deletions(-)
create mode 100644 arch_init.c
create mode 100644 arch_init.h
diff --git a/Makefile.objs b/Makefile.objs
index 1c360a6..4ff3214 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -127,7 +127,7 @@ user-obj-y += cutils.o cache-utils.o
# libhw
hw-obj-y =
-hw-obj-y += loader.o
+hw-obj-y += vl.o loader.o
hw-obj-y += virtio.o virtio-console.o
hw-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
hw-obj-y += fw_cfg.o pci.o pci_host.o pcie_host.o
diff --git a/Makefile.target b/Makefile.target
index 156b4bd..98cf52c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -161,7 +161,7 @@ endif #CONFIG_BSD_USER
# System emulator target
ifdef CONFIG_SOFTMMU
-obj-y = vl.o cpus.o monitor.o machine.o gdbstub.o
+obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o
obj-y += qemu-timer.o
# virtio has to be here due to weird dependency between PCI and virtio-net.
# need to fix this properly
diff --git a/arch_init.c b/arch_init.c
new file mode 100644
index 0000000..eb4dc07
--- /dev/null
+++ b/arch_init.c
@@ -0,0 +1,461 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the
"Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include <stdint.h>
+#include <stdarg.h>
+#include <sys/mman.h>
+#include "config.h"
+#include "monitor.h"
+#include "sysemu.h"
+#include "arch_init.h"
+#include "audio/audio.h"
+#include "hw/pc.h"
+#include "hw/pci.h"
+#include "hw/audiodev.h"
+#include "kvm.h"
+#include "migration.h"
+#include "net.h"
+#include "gdbstub.h"
+
+#ifdef TARGET_SPARC
+int graphic_width = 1024;
+int graphic_height = 768;
+int graphic_depth = 8;
+#else
+int graphic_width = 800;
+int graphic_height = 600;
+int graphic_depth = 15;
+#endif
+
+#ifdef TARGET_I386
+int rtc_td_hack = 0;
+#endif
+
+#ifdef TARGET_ARM
+int old_param = 0;
+#endif
+
+#if defined(TARGET_SPARC) || defined(TARGET_PPC)
+unsigned int nb_prom_envs = 0;
+const char *prom_envs[MAX_PROM_ENVS];
+#endif
+
+const char arch_config_name[] = CONFIG_QEMU_CONFDIR "/target-"
TARGET_ARCH ".conf";
+
+/***********************************************************/
+/* ram save/restore */
+
+#define RAM_SAVE_FLAG_FULL 0x01 /* Obsolete, not used anymore */
+#define RAM_SAVE_FLAG_COMPRESS 0x02
+#define RAM_SAVE_FLAG_MEM_SIZE 0x04
+#define RAM_SAVE_FLAG_PAGE 0x08
+#define RAM_SAVE_FLAG_EOS 0x10
+
+static int is_dup_page(uint8_t *page, uint8_t ch)
+{
+ uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
+ uint32_t *array = (uint32_t *)page;
+ int i;
+
+ for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
+ if (array[i] != val)
+ return 0;
+ }
+
+ return 1;
+}
+
+static int ram_save_block(QEMUFile *f)
+{
+ static ram_addr_t current_addr = 0;
+ ram_addr_t saved_addr = current_addr;
+ ram_addr_t addr = 0;
+ int found = 0;
+
+ while (addr < last_ram_offset) {
+ if (cpu_physical_memory_get_dirty(current_addr,
MIGRATION_DIRTY_FLAG)) {
+ uint8_t *p;
+
+ cpu_physical_memory_reset_dirty(current_addr,
+ current_addr + TARGET_PAGE_SIZE,
+ MIGRATION_DIRTY_FLAG);
+
+ p = qemu_get_ram_ptr(current_addr);
+
+ if (is_dup_page(p, *p)) {
+ qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
+ qemu_put_byte(f, *p);
+ } else {
+ qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
+ qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
+ }
+
+ found = 1;
+ break;
+ }
+ addr += TARGET_PAGE_SIZE;
+ current_addr = (saved_addr + addr) % last_ram_offset;
+ }
+
+ return found;
+}
+
+static uint64_t bytes_transferred;
+
+static ram_addr_t ram_save_remaining(void)
+{
+ ram_addr_t addr;
+ ram_addr_t count = 0;
+
+ for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
+ if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
+ 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;
+}
+
+int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)
+{
+ ram_addr_t addr;
+ uint64_t bytes_transferred_last;
+ double bwidth = 0;
+ uint64_t expected_time = 0;
+
+ if (stage < 0) {
+ cpu_physical_memory_set_dirty_tracking(0);
+ return 0;
+ }
+
+ if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
+ qemu_file_set_error(f);
+ return 0;
+ }
+
+ if (stage == 1) {
+ bytes_transferred = 0;
+
+ /* Make sure all dirty bits are set */
+ for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
+ if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG)) {
+ cpu_physical_memory_set_dirty(addr);
+ }
+ }
+
+ /* Enable dirty memory tracking */
+ cpu_physical_memory_set_dirty_tracking(1);
+
+ qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
+ }
+
+ bytes_transferred_last = bytes_transferred;
+ bwidth = qemu_get_clock_ns(rt_clock);
+
+ while (!qemu_file_rate_limit(f)) {
+ int ret;
+
+ ret = ram_save_block(f);
+ bytes_transferred += ret * TARGET_PAGE_SIZE;
+ if (ret == 0) { /* no more blocks */
+ break;
+ }
+ }
+
+ bwidth = qemu_get_clock_ns(rt_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 */
+ if (stage == 3) {
+ /* flush all remaining blocks regardless of rate limiting */
+ while (ram_save_block(f) != 0) {
+ bytes_transferred += TARGET_PAGE_SIZE;
+ }
+ cpu_physical_memory_set_dirty_tracking(0);
+ }
+
+ qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
+
+ expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
+
+ return (stage == 2) && (expected_time <= migrate_max_downtime());
+}
+
+int ram_load(QEMUFile *f, void *opaque, int version_id)
+{
+ ram_addr_t addr;
+ int flags;
+
+ if (version_id != 3) {
+ return -EINVAL;
+ }
+
+ do {
+ addr = qemu_get_be64(f);
+
+ flags = addr & ~TARGET_PAGE_MASK;
+ addr &= TARGET_PAGE_MASK;
+
+ if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
+ if (addr != last_ram_offset)
+ return -EINVAL;
+ }
+
+ if (flags & RAM_SAVE_FLAG_COMPRESS) {
+ uint8_t ch = qemu_get_byte(f);
+ 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) {
+ qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
+ }
+ if (qemu_file_has_error(f)) {
+ return -EIO;
+ }
+ } while (!(flags & RAM_SAVE_FLAG_EOS));
+
+ return 0;
+}
+
+void qemu_service_io(void)
+{
+ qemu_notify_event();
+}
+
+#ifdef HAS_AUDIO
+struct soundhw soundhw[] = {
+#ifdef HAS_AUDIO_CHOICE
+#if defined(TARGET_I386) || defined(TARGET_MIPS)
+ {
+ "pcspk",
+ "PC speaker",
+ 0,
+ 1,
+ { .init_isa = pcspk_audio_init }
+ },
+#endif
+
+#ifdef CONFIG_SB16
+ {
+ "sb16",
+ "Creative Sound Blaster 16",
+ 0,
+ 1,
+ { .init_isa = SB16_init }
+ },
+#endif
+
+#ifdef CONFIG_CS4231A
+ {
+ "cs4231a",
+ "CS4231A",
+ 0,
+ 1,
+ { .init_isa = cs4231a_init }
+ },
+#endif
+
+#ifdef CONFIG_ADLIB
+ {
+ "adlib",
+#ifdef HAS_YMF262
+ "Yamaha YMF262 (OPL3)",
+#else
+ "Yamaha YM3812 (OPL2)",
+#endif
+ 0,
+ 1,
+ { .init_isa = Adlib_init }
+ },
+#endif
+
+#ifdef CONFIG_GUS
+ {
+ "gus",
+ "Gravis Ultrasound GF1",
+ 0,
+ 1,
+ { .init_isa = GUS_init }
+ },
+#endif
+
+#ifdef CONFIG_AC97
+ {
+ "ac97",
+ "Intel 82801AA AC97 Audio",
+ 0,
+ 0,
+ { .init_pci = ac97_init }
+ },
+#endif
+
+#ifdef CONFIG_ES1370
+ {
+ "es1370",
+ "ENSONIQ AudioPCI ES1370",
+ 0,
+ 0,
+ { .init_pci = es1370_init }
+ },
+#endif
+
+#endif /* HAS_AUDIO_CHOICE */
+
+ { NULL, NULL, 0, 0, { NULL } }
+};
+
+void select_soundhw(const char *optarg)
+{
+ struct soundhw *c;
+
+ if (*optarg == '?') {
+ show_valid_cards:
+
+ printf("Valid sound card names (comma separated):\n");
+ for (c = soundhw; c->name; ++c) {
+ printf ("%-11s %s\n", c->name, c->descr);
+ }
+ printf("\n-soundhw all will enable all of the above\n");
+ exit(*optarg != '?');
+ }
+ else {
+ size_t l;
+ const char *p;
+ char *e;
+ int bad_card = 0;
+
+ if (!strcmp(optarg, "all")) {
+ for (c = soundhw; c->name; ++c) {
+ c->enabled = 1;
+ }
+ return;
+ }
+
+ p = optarg;
+ while (*p) {
+ e = strchr(p, ',');
+ l = !e ? strlen(p) : (size_t) (e - p);
+
+ for (c = soundhw; c->name; ++c) {
+ if (!strncmp(c->name, p, l) && !c->name[l]) {
+ c->enabled = 1;
+ break;
+ }
+ }
+
+ if (!c->name) {
+ if (l > 80) {
+ fprintf(stderr,
+ "Unknown sound card name (too big to show)\n");
+ }
+ else {
+ fprintf(stderr, "Unknown sound card name `%.*s'\n",
+ (int) l, p);
+ }
+ bad_card = 1;
+ }
+ p += l + (e != NULL);
+ }
+
+ if (bad_card) {
+ goto show_valid_cards;
+ }
+ }
+}
+#endif
+
+void help(int exitcode)
+{
+ const char *options_help =
+#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
+ ;
+ version();
+ printf("usage: %s [options] [disk_image]\n"
+ "\n"
+ "'disk_image' is a raw hard image image for IDE hard disk 0\n"
+ "\n"
+ "%s\n"
+ "During emulation, the following keys are useful:\n"
+ "ctrl-alt-f toggle full screen\n"
+ "ctrl-alt-n switch to virtual console 'n'\n"
+ "ctrl-alt toggle mouse and keyboard grab\n"
+ "\n"
+ "When using -nographic, press 'ctrl-a h' to get some help.\n",
+ "qemu",
+ options_help);
+ exit(exitcode);
+}
+
+#define HAS_ARG 0x0001
+
+enum {
+#define DEF(option, opt_arg, opt_enum, opt_help) \
+ opt_enum,
+#define DEFHEADING(text)
+#include "qemu-options.h"
+#undef DEF
+#undef DEFHEADING
+#undef GEN_DOCS
+};
+
+const QEMUOption qemu_options[] = {
+ { "h", 0, QEMU_OPTION_h },
+#define DEF(option, opt_arg, opt_enum, opt_help) \
+ { option, opt_arg, opt_enum },
+#define DEFHEADING(text)
+#include "qemu-options.h"
+#undef DEF
+#undef DEFHEADING
+#undef GEN_DOCS
+ { NULL },
+};
+
diff --git a/arch_init.h b/arch_init.h
new file mode 100644
index 0000000..67d504b
--- /dev/null
+++ b/arch_init.h
@@ -0,0 +1,20 @@
+#ifndef QEMU_ARCH_INIT_H
+#define QEMU_ARCH_INIT_H
+
+extern const char arch_config_name[];
+
+typedef struct QEMUOption {
+ const char *name;
+ int flags;
+ int index;
+} QEMUOption;
+
+extern const QEMUOption qemu_options[];
+
+void select_soundhw(const char *optarg);
+int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque);
+int ram_load(QEMUFile *f, void *opaque, int version_id);
+void help(int exitcode);
+void version(void);
+
+#endif
diff --git a/balloon.h b/balloon.h
index c3a1ad3..8c019eb 100644
--- a/balloon.h
+++ b/balloon.h
@@ -14,8 +14,6 @@
#ifndef _QEMU_BALLOON_H
#define _QEMU_BALLOON_H
-#include "cpu-defs.h"
-
typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target,
MonitorCompletion cb, void *cb_data);
diff --git a/cpu-all.h b/cpu-all.h
index f281a91..9942d49 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -756,7 +756,6 @@ void page_set_flags(target_ulong start,
target_ulong end, int flags);
int page_check_range(target_ulong start, target_ulong len, int flags);
#endif
-void cpu_exec_init_all(unsigned long tb_size);
CPUState *cpu_copy(CPUState *env);
CPUState *qemu_get_cpu(int cpu);
diff --git a/cpus.c b/cpus.c
index c7b0520..9a8c2f7 100644
--- a/cpus.c
+++ b/cpus.c
@@ -735,7 +735,7 @@ bool tcg_cpu_exec(void)
if (ret == EXCP_DEBUG) {
gdb_set_stop_cpu(env);
- debug_requested = 1;
+ debug_requested = EXCP_DEBUG;
break;
}
}
@@ -755,3 +755,19 @@ void set_numa_modes(void)
}
}
}
+
+void set_cpu_log(const char *optarg)
+{
+ int mask;
+ const CPULogItem *item;
+
+ mask = cpu_str_to_log_mask(optarg);
+ if (!mask) {
+ printf("Log items (comma separated):\n");
+ for (item = cpu_log_items; item->mask != 0; item++) {
+ printf("%-10s %s\n", item->name, item->help);
+ }
+ exit(1);
+ }
+ cpu_set_log(mask);
+}
diff --git a/cpus.h b/cpus.h
index e543b30..67c9a3b 100644
--- a/cpus.h
+++ b/cpus.h
@@ -13,5 +13,6 @@ extern int debug_requested;
void vm_state_notify(int running, int reason);
bool tcg_cpu_exec(void);
void set_numa_modes(void);
+void set_cpu_log(const char *optarg);
#endif
diff --git a/gdbstub.h b/gdbstub.h
index 5740041..08fbe9c 100644
--- a/gdbstub.h
+++ b/gdbstub.h
@@ -10,6 +10,7 @@
#define GDB_WATCHPOINT_READ 3
#define GDB_WATCHPOINT_ACCESS 4
+#ifdef NEED_CPU_H
typedef void (*gdb_syscall_complete_cb)(CPUState *env,
target_ulong ret, target_ulong err);
@@ -21,15 +22,19 @@ int gdb_queuesig (void);
int gdb_handlesig (CPUState *, int);
void gdb_exit(CPUState *, int);
void gdb_signalled(CPUState *, int);
-int gdbserver_start(int);
void gdbserver_fork(CPUState *);
-#else
-int gdbserver_start(const char *port);
#endif
/* Get or set a register. Returns the size of the register. */
typedef int (*gdb_reg_cb)(CPUState *env, uint8_t *buf, int reg);
void gdb_register_coprocessor(CPUState *env,
gdb_reg_cb get_reg, gdb_reg_cb set_reg,
int num_regs, const char *xml, int g_pos);
+#endif
+
+#ifdef CONFIG_USER_ONLY
+int gdbserver_start(int);
+#else
+int gdbserver_start(const char *port);
+#endif
#endif
diff --git a/hw/smbios.c b/hw/smbios.c
index a3ae1de..9f2fe1b 100644
--- a/hw/smbios.c
+++ b/hw/smbios.c
@@ -167,6 +167,7 @@ static void smbios_build_type_1_fields(const char *t)
fprintf(stderr, "Invalid SMBIOS UUID string\n");
exit(1);
}
+ smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, buf);
}
if (get_param_value(buf, sizeof(buf), "sku", t))
smbios_add_field(1, offsetof(struct smbios_type_1, sku_number_str),
diff --git a/kvm.h b/kvm.h
index fd8d0c1..3bee843 100644
--- a/kvm.h
+++ b/kvm.h
@@ -14,7 +14,7 @@
#ifndef QEMU_KVM_H
#define QEMU_KVM_H
-#include "config.h"
+#include "config-host.h"
#include "qemu-queue.h"
#ifdef CONFIG_KVM
@@ -31,6 +31,7 @@ struct kvm_run;
int kvm_init(int smp_cpus);
+#ifdef NEED_CPU_H
int kvm_init_vcpu(CPUState *env);
int kvm_cpu_exec(CPUState *env);
@@ -162,3 +163,4 @@ static inline void cpu_synchronize_post_init(CPUState *env)
}
#endif
+#endif
diff --git a/qemu-common.h b/qemu-common.h
index 087c034..d881a39 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -231,6 +231,8 @@ typedef struct SSIBus SSIBus;
typedef uint64_t pcibus_t;
+void cpu_exec_init_all(unsigned long tb_size);
+
/* CPU save/load. */
void cpu_save(QEMUFile *f, void *opaque);
int cpu_load(QEMUFile *f, void *opaque, int version_id);
diff --git a/qemu-options.hx b/qemu-options.hx
index 8450b45..c972984 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -807,12 +807,10 @@ STEXI
Disable HPET support.
ETEXI
-#ifdef TARGET_I386
DEF("balloon", HAS_ARG, QEMU_OPTION_balloon,
"-balloon none disable balloon device\n"
"-balloon virtio[,addr=str]\n"
" enable virtio balloon device (default)\n")
-#endif
STEXI
@item -balloon none
@findex -balloon
diff --git a/vl.c b/vl.c
index 2eef69e..50d419f 100644
--- a/vl.c
+++ b/vl.c
@@ -120,7 +120,6 @@ int main(int argc, char **argv)
#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"
@@ -153,14 +152,13 @@ int main(int argc, char **argv)
#include "disas.h"
-#include "exec-all.h"
-
#include "qemu_socket.h"
#include "slirp/libslirp.h"
#include "qemu-queue.h"
#include "cpus.h"
+#include "arch_init.h"
//#define DEBUG_NET
//#define DEBUG_SLIRP
@@ -191,15 +189,6 @@ static int rtc_utc = 1;
static int rtc_date_offset = -1; /* -1 means no change */
QEMUClock *rtc_clock;
int vga_interface_type = VGA_NONE;
-#ifdef TARGET_SPARC
-int graphic_width = 1024;
-int graphic_height = 768;
-int graphic_depth = 8;
-#else
-int graphic_width = 800;
-int graphic_height = 600;
-int graphic_depth = 15;
-#endif
static int full_screen = 0;
#ifdef CONFIG_SDL
static int no_frame = 0;
@@ -209,9 +198,6 @@ CharDriverState *serial_hds[MAX_SERIAL_PORTS];
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
int win2k_install_hack = 0;
-#ifdef TARGET_I386
-int rtc_td_hack = 0;
-#endif
int usb_enabled = 0;
int singlestep = 0;
int smp_cpus = 1;
@@ -234,16 +220,9 @@ const char *watchdog;
const char *option_rom[MAX_OPTION_ROMS];
int nb_option_roms;
int semihosting_enabled = 0;
-#ifdef TARGET_ARM
-int old_param = 0;
-#endif
const char *qemu_name;
int alt_grab = 0;
int ctrl_grab = 0;
-#if defined(TARGET_SPARC) || defined(TARGET_PPC)
-unsigned int nb_prom_envs = 0;
-const char *prom_envs[MAX_PROM_ENVS];
-#endif
int boot_menu;
int nb_numa_nodes;
@@ -468,7 +447,7 @@ static void configure_rtc_date_offset(const char
*startdate, int legacy)
}
}
-static void configure_rtc(QemuOpts *opts)
+static void configure_rtc(QemuOpts *opts, int driftfix)
{
const char *value;
@@ -493,19 +472,19 @@ static void configure_rtc(QemuOpts *opts)
exit(1);
}
}
-#ifdef CONFIG_TARGET_I386
- value = qemu_opt_get(opts, "driftfix");
- if (value) {
- if (!strcmp(buf, "slew")) {
- rtc_td_hack = 1;
- } else if (!strcmp(buf, "none")) {
- rtc_td_hack = 0;
- } else {
- fprintf(stderr, "qemu: invalid option value '%s'\n", value);
- exit(1);
+ if (driftfix) {
+ value = qemu_opt_get(opts, "driftfix");
+ if (value) {
+ if (!strcmp(value, "slew")) {
+ rtc_td_hack = 1;
+ } else if (!strcmp(value, "none")) {
+ rtc_td_hack = 0;
+ } else {
+ fprintf(stderr, "qemu: invalid option value '%s'\n", value);
+ exit(1);
+ }
}
}
-#endif
}
#ifdef _WIN32
@@ -1665,206 +1644,6 @@ void qemu_del_wait_object(HANDLE handle,
WaitObjectFunc *func, void *opaque)
#endif
/***********************************************************/
-/* ram save/restore */
-
-#define RAM_SAVE_FLAG_FULL 0x01 /* Obsolete, not used anymore */
-#define RAM_SAVE_FLAG_COMPRESS 0x02
-#define RAM_SAVE_FLAG_MEM_SIZE 0x04
-#define RAM_SAVE_FLAG_PAGE 0x08
-#define RAM_SAVE_FLAG_EOS 0x10
-
-static int is_dup_page(uint8_t *page, uint8_t ch)
-{
- uint32_t val = ch << 24 | ch << 16 | ch << 8 | ch;
- uint32_t *array = (uint32_t *)page;
- int i;
-
- for (i = 0; i < (TARGET_PAGE_SIZE / 4); i++) {
- if (array[i] != val)
- return 0;
- }
-
- return 1;
-}
-
-static int ram_save_block(QEMUFile *f)
-{
- static ram_addr_t current_addr = 0;
- ram_addr_t saved_addr = current_addr;
- ram_addr_t addr = 0;
- int found = 0;
-
- while (addr < last_ram_offset) {
- if (cpu_physical_memory_get_dirty(current_addr,
MIGRATION_DIRTY_FLAG)) {
- uint8_t *p;
-
- cpu_physical_memory_reset_dirty(current_addr,
- current_addr + TARGET_PAGE_SIZE,
- MIGRATION_DIRTY_FLAG);
-
- p = qemu_get_ram_ptr(current_addr);
-
- if (is_dup_page(p, *p)) {
- qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_COMPRESS);
- qemu_put_byte(f, *p);
- } else {
- qemu_put_be64(f, current_addr | RAM_SAVE_FLAG_PAGE);
- qemu_put_buffer(f, p, TARGET_PAGE_SIZE);
- }
-
- found = 1;
- break;
- }
- addr += TARGET_PAGE_SIZE;
- current_addr = (saved_addr + addr) % last_ram_offset;
- }
-
- return found;
-}
-
-static uint64_t bytes_transferred;
-
-static ram_addr_t ram_save_remaining(void)
-{
- ram_addr_t addr;
- ram_addr_t count = 0;
-
- for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
- if (cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
- 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(Monitor *mon, QEMUFile *f, int stage, void *opaque)
-{
- ram_addr_t addr;
- uint64_t bytes_transferred_last;
- double bwidth = 0;
- uint64_t expected_time = 0;
-
- if (stage < 0) {
- cpu_physical_memory_set_dirty_tracking(0);
- return 0;
- }
-
- if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {
- qemu_file_set_error(f);
- return 0;
- }
-
- if (stage == 1) {
- bytes_transferred = 0;
-
- /* Make sure all dirty bits are set */
- for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {
- if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))
- cpu_physical_memory_set_dirty(addr);
- }
-
- /* Enable dirty memory tracking */
- cpu_physical_memory_set_dirty_tracking(1);
-
- qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);
- }
-
- bytes_transferred_last = bytes_transferred;
- bwidth = qemu_get_clock_ns(rt_clock);
-
- while (!qemu_file_rate_limit(f)) {
- int ret;
-
- ret = ram_save_block(f);
- bytes_transferred += ret * TARGET_PAGE_SIZE;
- if (ret == 0) /* no more blocks */
- break;
- }
-
- bwidth = qemu_get_clock_ns(rt_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 */
- if (stage == 3) {
- /* flush all remaining blocks regardless of rate limiting */
- while (ram_save_block(f) != 0) {
- bytes_transferred += TARGET_PAGE_SIZE;
- }
- cpu_physical_memory_set_dirty_tracking(0);
- }
-
- qemu_put_be64(f, RAM_SAVE_FLAG_EOS);
-
- expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;
-
- return (stage == 2) && (expected_time <= migrate_max_downtime());
-}
-
-static int ram_load(QEMUFile *f, void *opaque, int version_id)
-{
- ram_addr_t addr;
- int flags;
-
- if (version_id != 3)
- return -EINVAL;
-
- do {
- addr = qemu_get_be64(f);
-
- flags = addr & ~TARGET_PAGE_MASK;
- addr &= TARGET_PAGE_MASK;
-
- if (flags & RAM_SAVE_FLAG_MEM_SIZE) {
- if (addr != last_ram_offset)
- return -EINVAL;
- }
-
- if (flags & RAM_SAVE_FLAG_COMPRESS) {
- uint8_t ch = qemu_get_byte(f);
- 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) {
- qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE);
- }
- if (qemu_file_has_error(f)) {
- return -EIO;
- }
- } while (!(flags & RAM_SAVE_FLAG_EOS));
-
- return 0;
-}
-
-void qemu_service_io(void)
-{
- qemu_notify_event();
-}
-
-/***********************************************************/
/* machine registration */
static QEMUMachine *first_machine = NULL;
@@ -2256,8 +2035,8 @@ static void main_loop(void)
#endif
} while (vm_can_run());
- if (qemu_debug_requested()) {
- vm_stop(EXCP_DEBUG);
+ if ((r = qemu_debug_requested())) {
+ vm_stop(r);
}
if (qemu_shutdown_requested()) {
monitor_protocol_event(QEVENT_SHUTDOWN, NULL);
@@ -2283,39 +2062,11 @@ static void main_loop(void)
pause_all_vcpus();
}
-static void version(void)
+void version(void)
{
printf("QEMU PC emulator version " QEMU_VERSION QEMU_PKGVERSION
", Copyright (c) 2003-2008 Fabrice Bellard\n");
}
-static void help(int exitcode)
-{
- const char *options_help =
-#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
- ;
- version();
- printf("usage: %s [options] [disk_image]\n"
- "\n"
- "'disk_image' is a raw hard image image for IDE hard disk 0\n"
- "\n"
- "%s\n"
- "During emulation, the following keys are useful:\n"
- "ctrl-alt-f toggle full screen\n"
- "ctrl-alt-n switch to virtual console 'n'\n"
- "ctrl-alt toggle mouse and keyboard grab\n"
- "\n"
- "When using -nographic, press 'ctrl-a h' to get some help.\n",
- "qemu",
- options_help);
- exit(exitcode);
-}
-
#define HAS_ARG 0x0001
enum {
@@ -2328,165 +2079,6 @@ enum {
#undef GEN_DOCS
};
-typedef struct QEMUOption {
- const char *name;
- int flags;
- int index;
-} QEMUOption;
-
-static const QEMUOption qemu_options[] = {
- { "h", 0, QEMU_OPTION_h },
-#define DEF(option, opt_arg, opt_enum, opt_help) \
- { option, opt_arg, opt_enum },
-#define DEFHEADING(text)
-#include "qemu-options.h"
-#undef DEF
-#undef DEFHEADING
-#undef GEN_DOCS
- { NULL },
-};
-
-#ifdef HAS_AUDIO
-struct soundhw soundhw[] = {
-#ifdef HAS_AUDIO_CHOICE
-#if defined(TARGET_I386) || defined(TARGET_MIPS)
- {
- "pcspk",
- "PC speaker",
- 0,
- 1,
- { .init_isa = pcspk_audio_init }
- },
-#endif
-
-#ifdef CONFIG_SB16
- {
- "sb16",
- "Creative Sound Blaster 16",
- 0,
- 1,
- { .init_isa = SB16_init }
- },
-#endif
-
-#ifdef CONFIG_CS4231A
- {
- "cs4231a",
- "CS4231A",
- 0,
- 1,
- { .init_isa = cs4231a_init }
- },
-#endif
-
-#ifdef CONFIG_ADLIB
- {
- "adlib",
-#ifdef HAS_YMF262
- "Yamaha YMF262 (OPL3)",
-#else
- "Yamaha YM3812 (OPL2)",
-#endif
- 0,
- 1,
- { .init_isa = Adlib_init }
- },
-#endif
-
-#ifdef CONFIG_GUS
- {
- "gus",
- "Gravis Ultrasound GF1",
- 0,
- 1,
- { .init_isa = GUS_init }
- },
-#endif
-
-#ifdef CONFIG_AC97
- {
- "ac97",
- "Intel 82801AA AC97 Audio",
- 0,
- 0,
- { .init_pci = ac97_init }
- },
-#endif
-
-#ifdef CONFIG_ES1370
- {
- "es1370",
- "ENSONIQ AudioPCI ES1370",
- 0,
- 0,
- { .init_pci = es1370_init }
- },
-#endif
-
-#endif /* HAS_AUDIO_CHOICE */
-
- { NULL, NULL, 0, 0, { NULL } }
-};
-
-static void select_soundhw (const char *optarg)
-{
- struct soundhw *c;
-
- if (*optarg == '?') {
- show_valid_cards:
-
- printf ("Valid sound card names (comma separated):\n");
- for (c = soundhw; c->name; ++c) {
- printf ("%-11s %s\n", c->name, c->descr);
- }
- printf ("\n-soundhw all will enable all of the above\n");
- exit (*optarg != '?');
- }
- else {
- size_t l;
- const char *p;
- char *e;
- int bad_card = 0;
-
- if (!strcmp (optarg, "all")) {
- for (c = soundhw; c->name; ++c) {
- c->enabled = 1;
- }
- return;
- }
-
- p = optarg;
- while (*p) {
- e = strchr (p, ',');
- l = !e ? strlen (p) : (size_t) (e - p);
-
- for (c = soundhw; c->name; ++c) {
- if (!strncmp (c->name, p, l) && !c->name[l]) {
- c->enabled = 1;
- break;
- }
- }
-
- if (!c->name) {
- if (l > 80) {
- fprintf (stderr,
- "Unknown sound card name (too big to show)\n");
- }
- else {
- fprintf (stderr, "Unknown sound card name `%.*s'\n",
- (int) l, p);
- }
- bad_card = 1;
- }
- p += l + (e != NULL);
- }
-
- if (bad_card)
- goto show_valid_cards;
- }
-}
-#endif
-
static void select_vgahw (const char *p)
{
const char *opts;
@@ -2521,7 +2113,6 @@ static void select_vgahw (const char *p)
}
}
-#ifdef TARGET_I386
static int balloon_parse(const char *arg)
{
QemuOpts *opts;
@@ -2546,7 +2137,6 @@ static int balloon_parse(const char *arg)
return -1;
}
-#endif
#ifdef _WIN32
static BOOL WINAPI qemu_ctrl_handler(DWORD type)
@@ -2570,10 +2160,6 @@ int qemu_uuid_parse(const char *str, uint8_t *uuid)
if(ret != 16)
return -1;
-#ifdef TARGET_I386
- smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid);
-#endif
-
return 0;
}
@@ -3116,7 +2702,7 @@ int main(int argc, char **argv, char **envp)
fclose(fp);
}
- fname = CONFIG_QEMU_CONFDIR "/target-" TARGET_ARCH ".conf";
+ fname = arch_config_name;
fp = fopen(fname, "r");
if (fp) {
if (qemu_config_parse(fp, fname) != 0) {
@@ -3433,20 +3019,7 @@ int main(int argc, char **argv, char **envp)
break;
#endif
case QEMU_OPTION_d:
- {
- int mask;
- const CPULogItem *item;
-
- mask = cpu_str_to_log_mask(optarg);
- if (!mask) {
- printf("Log items (comma separated):\n");
- for(item = cpu_log_items; item->mask != 0; item++) {
- printf("%-10s %s\n", item->name, item->help);
- }
- exit(1);
- }
- cpu_set_log(mask);
- }
+ set_cpu_log(optarg);
break;
case QEMU_OPTION_s:
gdbstub_dev = "tcp::" DEFAULT_GDBSTUB_PORT;
@@ -3670,13 +3243,13 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_no_hpet:
no_hpet = 1;
break;
+#endif
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:
no_reboot = 1;
break;
@@ -3692,6 +3265,10 @@ int main(int argc, char **argv, char **envp)
" Wrong format.\n");
exit(1);
}
+#ifdef TARGET_I386
+ smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16,
+ qemu_uuid);
+#endif
break;
#ifndef _WIN32
case QEMU_OPTION_daemonize:
@@ -3753,7 +3330,11 @@ int main(int argc, char **argv, char **envp)
fprintf(stderr, "parse error: %s\n", optarg);
exit(1);
}
- configure_rtc(opts);
+#ifdef TARGET_I386
+ configure_rtc(opts, 1);
+#else
+ configure_rtc(opts, 0);
+#endif
break;
case QEMU_OPTION_tb_size:
tb_size = strtol(optarg, NULL, 0);
--
1.6.2.4
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Qemu-devel] [PATCH, RFC] Refactor target specific handling out of vl.c,
Blue Swirl <=