diff options
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; |