83 |
|
|
84 |
#include "exec-all.h" |
#include "exec-all.h" |
85 |
|
|
|
//#define DO_TB_FLUSH |
|
|
|
|
86 |
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" |
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" |
87 |
|
|
88 |
//#define DEBUG_UNUSED_IOPORT |
//#define DEBUG_UNUSED_IOPORT |
107 |
|
|
108 |
const char *bios_dir = CONFIG_QEMU_SHAREDIR; |
const char *bios_dir = CONFIG_QEMU_SHAREDIR; |
109 |
char phys_ram_file[1024]; |
char phys_ram_file[1024]; |
|
CPUState *global_env; |
|
|
CPUState *cpu_single_env; |
|
110 |
void *ioport_opaque[MAX_IOPORTS]; |
void *ioport_opaque[MAX_IOPORTS]; |
111 |
IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; |
IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; |
112 |
IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; |
IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; |
152 |
USBPort *vm_usb_ports[MAX_VM_USB_PORTS]; |
USBPort *vm_usb_ports[MAX_VM_USB_PORTS]; |
153 |
USBDevice *vm_usb_hub; |
USBDevice *vm_usb_hub; |
154 |
static VLANState *first_vlan; |
static VLANState *first_vlan; |
155 |
|
int smp_cpus = 1; |
156 |
|
|
157 |
/***********************************************************/ |
/***********************************************************/ |
158 |
/* x86 ISA bus support */ |
/* x86 ISA bus support */ |
424 |
void hw_error(const char *fmt, ...) |
void hw_error(const char *fmt, ...) |
425 |
{ |
{ |
426 |
va_list ap; |
va_list ap; |
427 |
|
CPUState *env; |
428 |
|
|
429 |
va_start(ap, fmt); |
va_start(ap, fmt); |
430 |
fprintf(stderr, "qemu: hardware error: "); |
fprintf(stderr, "qemu: hardware error: "); |
431 |
vfprintf(stderr, fmt, ap); |
vfprintf(stderr, fmt, ap); |
432 |
fprintf(stderr, "\n"); |
fprintf(stderr, "\n"); |
433 |
|
for(env = first_cpu; env != NULL; env = env->next_cpu) { |
434 |
|
fprintf(stderr, "CPU #%d:\n", env->cpu_index); |
435 |
#ifdef TARGET_I386 |
#ifdef TARGET_I386 |
436 |
cpu_dump_state(global_env, stderr, fprintf, X86_DUMP_FPU | X86_DUMP_CCOP); |
cpu_dump_state(env, stderr, fprintf, X86_DUMP_FPU); |
437 |
#else |
#else |
438 |
cpu_dump_state(global_env, stderr, fprintf, 0); |
cpu_dump_state(env, stderr, fprintf, 0); |
439 |
#endif |
#endif |
440 |
|
} |
441 |
va_end(ap); |
va_end(ap); |
442 |
abort(); |
abort(); |
443 |
} |
} |
880 |
qemu_get_clock(vm_clock)) || |
qemu_get_clock(vm_clock)) || |
881 |
qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME], |
qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME], |
882 |
qemu_get_clock(rt_clock))) { |
qemu_get_clock(rt_clock))) { |
883 |
/* stop the cpu because a timer occured */ |
CPUState *env = cpu_single_env; |
884 |
cpu_interrupt(global_env, CPU_INTERRUPT_EXIT); |
if (env) { |
885 |
|
/* stop the currently executing cpu because a timer occured */ |
886 |
|
cpu_interrupt(env, CPU_INTERRUPT_EXIT); |
887 |
#ifdef USE_KQEMU |
#ifdef USE_KQEMU |
888 |
if (global_env->kqemu_enabled) { |
if (env->kqemu_enabled) { |
889 |
kqemu_cpu_interrupt(global_env); |
kqemu_cpu_interrupt(env); |
890 |
} |
} |
891 |
#endif |
#endif |
892 |
|
} |
893 |
} |
} |
894 |
} |
} |
895 |
|
|
2974 |
goto the_end; |
goto the_end; |
2975 |
} |
} |
2976 |
for(;;) { |
for(;;) { |
|
#if defined (DO_TB_FLUSH) |
|
|
tb_flush(global_env); |
|
|
#endif |
|
2977 |
len = qemu_get_byte(f); |
len = qemu_get_byte(f); |
2978 |
if (feof(f)) |
if (feof(f)) |
2979 |
break; |
break; |
3584 |
void qemu_system_reset_request(void) |
void qemu_system_reset_request(void) |
3585 |
{ |
{ |
3586 |
reset_requested = 1; |
reset_requested = 1; |
3587 |
cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); |
if (cpu_single_env) |
3588 |
|
cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); |
3589 |
} |
} |
3590 |
|
|
3591 |
void qemu_system_shutdown_request(void) |
void qemu_system_shutdown_request(void) |
3592 |
{ |
{ |
3593 |
shutdown_requested = 1; |
shutdown_requested = 1; |
3594 |
cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); |
if (cpu_single_env) |
3595 |
|
cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); |
3596 |
} |
} |
3597 |
|
|
3598 |
void qemu_system_powerdown_request(void) |
void qemu_system_powerdown_request(void) |
3599 |
{ |
{ |
3600 |
powerdown_requested = 1; |
powerdown_requested = 1; |
3601 |
cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); |
if (cpu_single_env) |
3602 |
} |
cpu_interrupt(cpu_single_env, CPU_INTERRUPT_EXIT); |
|
|
|
|
static void main_cpu_reset(void *opaque) |
|
|
{ |
|
|
#if defined(TARGET_I386) || defined(TARGET_SPARC) |
|
|
CPUState *env = opaque; |
|
|
cpu_reset(env); |
|
|
#endif |
|
3603 |
} |
} |
3604 |
|
|
3605 |
void main_loop_wait(int timeout) |
void main_loop_wait(int timeout) |
3680 |
qemu_get_clock(rt_clock)); |
qemu_get_clock(rt_clock)); |
3681 |
} |
} |
3682 |
|
|
3683 |
|
static CPUState *cur_cpu; |
3684 |
|
|
3685 |
|
static CPUState *find_next_cpu(void) |
3686 |
|
{ |
3687 |
|
CPUState *env; |
3688 |
|
env = cur_cpu; |
3689 |
|
for(;;) { |
3690 |
|
/* get next cpu */ |
3691 |
|
env = env->next_cpu; |
3692 |
|
if (!env) |
3693 |
|
env = first_cpu; |
3694 |
|
if (!env->cpu_halted) |
3695 |
|
break; |
3696 |
|
/* all CPUs are halted ? */ |
3697 |
|
if (env == cur_cpu) |
3698 |
|
return NULL; |
3699 |
|
} |
3700 |
|
cur_cpu = env; |
3701 |
|
return env; |
3702 |
|
} |
3703 |
|
|
3704 |
int main_loop(void) |
int main_loop(void) |
3705 |
{ |
{ |
3706 |
int ret, timeout; |
int ret, timeout; |
3707 |
CPUState *env = global_env; |
CPUState *env; |
3708 |
|
|
3709 |
|
cur_cpu = first_cpu; |
3710 |
for(;;) { |
for(;;) { |
3711 |
if (vm_running) { |
if (vm_running) { |
3712 |
ret = cpu_exec(env); |
/* find next cpu to run */ |
3713 |
|
/* XXX: handle HLT correctly */ |
3714 |
|
env = find_next_cpu(); |
3715 |
|
if (!env) |
3716 |
|
ret = EXCP_HLT; |
3717 |
|
else |
3718 |
|
ret = cpu_exec(env); |
3719 |
if (shutdown_requested) { |
if (shutdown_requested) { |
3720 |
ret = EXCP_INTERRUPT; |
ret = EXCP_INTERRUPT; |
3721 |
break; |
break; |
3798 |
" connect the host TAP network interface to VLAN 'n' and use\n" |
" connect the host TAP network interface to VLAN 'n' and use\n" |
3799 |
" the network script 'file' (default=%s);\n" |
" the network script 'file' (default=%s);\n" |
3800 |
" use 'fd=h' to connect to an already opened TAP interface\n" |
" use 'fd=h' to connect to an already opened TAP interface\n" |
3801 |
"-net socket[,vlan=n][,fd=x][,listen=[host]:port][,connect=host:port]\n" |
"-net socket[,vlan=n][,fd=h][,listen=[host]:port][,connect=host:port]\n" |
3802 |
" connect the vlan 'n' to another VLAN using a socket connection\n" |
" connect the vlan 'n' to another VLAN using a socket connection\n" |
3803 |
#endif |
#endif |
3804 |
"-net none use it alone to have zero network devices; if no -net option\n" |
"-net none use it alone to have zero network devices; if no -net option\n" |
3923 |
QEMU_OPTION_win2k_hack, |
QEMU_OPTION_win2k_hack, |
3924 |
QEMU_OPTION_usb, |
QEMU_OPTION_usb, |
3925 |
QEMU_OPTION_usbdevice, |
QEMU_OPTION_usbdevice, |
3926 |
|
QEMU_OPTION_smp, |
3927 |
}; |
}; |
3928 |
|
|
3929 |
typedef struct QEMUOption { |
typedef struct QEMUOption { |
3990 |
{ "pidfile", HAS_ARG, QEMU_OPTION_pidfile }, |
{ "pidfile", HAS_ARG, QEMU_OPTION_pidfile }, |
3991 |
{ "win2k-hack", 0, QEMU_OPTION_win2k_hack }, |
{ "win2k-hack", 0, QEMU_OPTION_win2k_hack }, |
3992 |
{ "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice }, |
{ "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice }, |
3993 |
|
{ "smp", HAS_ARG, QEMU_OPTION_smp }, |
3994 |
|
|
3995 |
/* temporary options */ |
/* temporary options */ |
3996 |
{ "usb", 0, QEMU_OPTION_usb }, |
{ "usb", 0, QEMU_OPTION_usb }, |
4146 |
#endif |
#endif |
4147 |
int i, cdrom_index; |
int i, cdrom_index; |
4148 |
int snapshot, linux_boot; |
int snapshot, linux_boot; |
|
CPUState *env; |
|
4149 |
const char *initrd_filename; |
const char *initrd_filename; |
4150 |
const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD]; |
const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD]; |
4151 |
const char *kernel_filename, *kernel_cmdline; |
const char *kernel_filename, *kernel_cmdline; |
4536 |
optarg); |
optarg); |
4537 |
usb_devices_index++; |
usb_devices_index++; |
4538 |
break; |
break; |
4539 |
|
case QEMU_OPTION_smp: |
4540 |
|
smp_cpus = atoi(optarg); |
4541 |
|
if (smp_cpus < 1 || smp_cpus > 8) { |
4542 |
|
fprintf(stderr, "Invalid number of CPUs\n"); |
4543 |
|
exit(1); |
4544 |
|
} |
4545 |
|
break; |
4546 |
} |
} |
4547 |
} |
} |
4548 |
} |
} |
4691 |
} |
} |
4692 |
} |
} |
4693 |
|
|
4694 |
/* init CPU state */ |
register_savevm("timer", 0, 1, timer_save, timer_load, NULL); |
|
env = cpu_init(); |
|
|
global_env = env; |
|
|
cpu_single_env = env; |
|
|
|
|
|
register_savevm("timer", 0, 1, timer_save, timer_load, env); |
|
|
register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); |
|
4695 |
register_savevm("ram", 0, 1, ram_save, ram_load, NULL); |
register_savevm("ram", 0, 1, ram_save, ram_load, NULL); |
|
qemu_register_reset(main_cpu_reset, global_env); |
|
4696 |
|
|
4697 |
init_ioports(); |
init_ioports(); |
4698 |
cpu_calibrate_ticks(); |
cpu_calibrate_ticks(); |