diff options
author | Blue Swirl <blauwirbel@gmail.com> | 2010-03-29 19:23:52 +0000 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2010-03-29 19:23:52 +0000 |
commit | ad96090a01d848df67d70c5259ed8aa321fa8716 (patch) | |
tree | 0f1403fdf30208dfefdc3bf45189c98d530cf6a9 /vl.c | |
parent | 296af7c9524cffbedda258b95272ade25b0a726e (diff) | |
download | hqemu-ad96090a01d848df67d70c5259ed8aa321fa8716.zip hqemu-ad96090a01d848df67d70c5259ed8aa321fa8716.tar.gz |
Refactor target specific handling, compile vl.c only once
Move target specific functions and RAM handling to arch_init.c.
Add a flag to QEMUOptions structure to indicate for which
architectures the option is allowed, check the flag
in run time and remove conditional code in option handling.
Now that no target dependencies remain, compile vl.c only once
for all targets.
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'vl.c')
-rw-r--r-- | vl.c | 476 |
1 files changed, 37 insertions, 439 deletions
@@ -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,7 @@ 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 +221,12 @@ 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; @@ -497,7 +480,6 @@ static void configure_rtc(QemuOpts *opts) exit(1); } } -#ifdef TARGET_I386 value = qemu_opt_get(opts, "driftfix"); if (value) { if (!strcmp(value, "slew")) { @@ -509,7 +491,6 @@ static void configure_rtc(QemuOpts *opts) exit(1); } } -#endif } #ifdef _WIN32 @@ -1669,206 +1650,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; @@ -2295,8 +2076,8 @@ static void version(void) static void help(int exitcode) { const char *options_help = -#define DEF(option, opt_arg, opt_enum, opt_help) \ - opt_help +#define DEF(option, opt_arg, opt_enum, opt_help, arch_mask) \ + opt_help #define DEFHEADING(text) stringify(text) "\n" #include "qemu-options.h" #undef DEF @@ -2323,7 +2104,7 @@ static void help(int exitcode) #define HAS_ARG 0x0001 enum { -#define DEF(option, opt_arg, opt_enum, opt_help) \ +#define DEF(option, opt_arg, opt_enum, opt_help, arch_mask) \ opt_enum, #define DEFHEADING(text) #include "qemu-options.h" @@ -2336,12 +2117,13 @@ typedef struct QEMUOption { const char *name; int flags; int index; + uint32_t arch_mask; } 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 }, + { "h", 0, QEMU_OPTION_h, QEMU_ARCH_ALL }, +#define DEF(option, opt_arg, opt_enum, opt_help, arch_mask) \ + { option, opt_arg, opt_enum, arch_mask }, #define DEFHEADING(text) #include "qemu-options.h" #undef DEF @@ -2349,148 +2131,6 @@ static const QEMUOption qemu_options[] = { #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; @@ -2525,7 +2165,6 @@ static void select_vgahw (const char *p) } } -#ifdef TARGET_I386 static int balloon_parse(const char *arg) { QemuOpts *opts; @@ -2550,7 +2189,6 @@ static int balloon_parse(const char *arg) return -1; } -#endif #ifdef _WIN32 static BOOL WINAPI qemu_ctrl_handler(DWORD type) @@ -2560,54 +2198,6 @@ static BOOL WINAPI qemu_ctrl_handler(DWORD type) } #endif -int qemu_uuid_parse(const char *str, uint8_t *uuid) -{ - int ret; - - if(strlen(str) != 36) - return -1; - - ret = sscanf(str, UUID_FMT, &uuid[0], &uuid[1], &uuid[2], &uuid[3], - &uuid[4], &uuid[5], &uuid[6], &uuid[7], &uuid[8], &uuid[9], - &uuid[10], &uuid[11], &uuid[12], &uuid[13], &uuid[14], &uuid[15]); - - if(ret != 16) - return -1; - -#ifdef TARGET_I386 - smbios_add_field(1, offsetof(struct smbios_type_1, uuid), 16, uuid); -#endif - - return 0; -} - -#ifdef TARGET_I386 -static void do_acpitable_option(const char *optarg) -{ - if (acpi_table_add(optarg) < 0) { - fprintf(stderr, "Wrong acpi table provided\n"); - exit(1); - } -} -#endif - -#ifdef TARGET_I386 -static void do_smbios_option(const char *optarg) -{ - if (smbios_entry_add(optarg) < 0) { - fprintf(stderr, "Wrong smbios provided\n"); - exit(1); - } -} -#endif - -static void cpudef_init(void) -{ -#if defined(cpudef_setup) - cpudef_setup(); /* parse cpu definitions in target config file */ -#endif -} - #ifndef _WIN32 static void termsig_handler(int signal) @@ -3147,7 +2737,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) { @@ -3169,6 +2759,10 @@ int main(int argc, char **argv, char **envp) const QEMUOption *popt; popt = lookup_opt(argc, argv, &optarg, &optind); + if (!(popt->arch_mask & arch_type)) { + printf("Option %s not supported for this target\n", popt->name); + exit(1); + } switch(popt->index) { case QEMU_OPTION_M: machine = find_machine(optarg); @@ -3372,11 +2966,9 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_fdb: drive_add(optarg, FD_ALIAS, popt->index - QEMU_OPTION_fda); break; -#ifdef TARGET_I386 case QEMU_OPTION_no_fd_bootchk: fd_bootchk = 0; break; -#endif case QEMU_OPTION_netdev: if (net_client_parse(&qemu_netdev_opts, optarg) == -1) { exit(1); @@ -3408,15 +3000,21 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_bt: add_device_config(DEV_BT, optarg); break; -#ifdef HAS_AUDIO case QEMU_OPTION_audio_help: + if (!(audio_available())) { + printf("Option %s not supported for this target\n", popt->name); + exit(1); + } AUD_help (); exit (0); break; case QEMU_OPTION_soundhw: + if (!(audio_available())) { + printf("Option %s not supported for this target\n", popt->name); + exit(1); + } select_soundhw (optarg); break; -#endif case QEMU_OPTION_h: help(0); break; @@ -3491,7 +3089,6 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_vga: select_vgahw (optarg); break; -#if defined(TARGET_PPC) || defined(TARGET_SPARC) case QEMU_OPTION_g: { const char *p; @@ -3526,7 +3123,6 @@ int main(int argc, char **argv, char **envp) graphic_depth = depth; } break; -#endif case QEMU_OPTION_echr: { char *r; @@ -3622,7 +3218,6 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_pidfile: pid_file = optarg; break; -#ifdef TARGET_I386 case QEMU_OPTION_win2k_hack: win2k_install_hack = 1; break; @@ -3635,12 +3230,13 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_smbios: do_smbios_option(optarg); break; -#endif -#ifdef CONFIG_KVM case QEMU_OPTION_enable_kvm: + if (!(kvm_available())) { + printf("Option %s not supported for this target\n", popt->name); + exit(1); + } kvm_allowed = 1; break; -#endif case QEMU_OPTION_usb: usb_enabled = 1; break; @@ -3673,7 +3269,6 @@ int main(int argc, char **argv, char **envp) display_type = DT_VNC; vnc_display = optarg; break; -#ifdef TARGET_I386 case QEMU_OPTION_no_acpi: acpi_enabled = 0; break; @@ -3686,7 +3281,6 @@ int main(int argc, char **argv, char **envp) exit(1); } break; -#endif case QEMU_OPTION_no_reboot: no_reboot = 1; break; @@ -3716,11 +3310,9 @@ int main(int argc, char **argv, char **envp) option_rom[nb_option_roms] = optarg; nb_option_roms++; break; -#if defined(TARGET_ARM) || defined(TARGET_M68K) case QEMU_OPTION_semihosting: semihosting_enabled = 1; break; -#endif case QEMU_OPTION_name: qemu_name = qemu_strdup(optarg); { @@ -3736,7 +3328,6 @@ int main(int argc, char **argv, char **envp) } } break; -#if defined(TARGET_SPARC) || defined(TARGET_PPC) case QEMU_OPTION_prom_env: if (nb_prom_envs >= MAX_PROM_ENVS) { fprintf(stderr, "Too many prom variables\n"); @@ -3745,12 +3336,9 @@ int main(int argc, char **argv, char **envp) prom_envs[nb_prom_envs] = optarg; nb_prom_envs++; break; -#endif -#ifdef TARGET_ARM case QEMU_OPTION_old_param: old_param = 1; break; -#endif case QEMU_OPTION_clock: configure_alarms(optarg); break; @@ -3795,17 +3383,27 @@ int main(int argc, char **argv, char **envp) run_as = optarg; break; #endif -#ifdef CONFIG_XEN case QEMU_OPTION_xen_domid: + if (!(xen_available())) { + printf("Option %s not supported for this target\n", popt->name); + exit(1); + } xen_domid = atoi(optarg); break; case QEMU_OPTION_xen_create: + if (!(xen_available())) { + printf("Option %s not supported for this target\n", popt->name); + exit(1); + } xen_mode = XEN_CREATE; break; case QEMU_OPTION_xen_attach: + if (!(xen_available())) { + printf("Option %s not supported for this target\n", popt->name); + exit(1); + } xen_mode = XEN_ATTACH; break; -#endif case QEMU_OPTION_readconfig: { FILE *fp; |