| 50 |
|
|
| 51 |
#include "vl.h" |
#include "vl.h" |
| 52 |
|
|
|
#define DEBUG_LOGFILE "/tmp/vl.log" |
|
| 53 |
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" |
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" |
| 54 |
#define BIOS_FILENAME "bios.bin" |
#define BIOS_FILENAME "bios.bin" |
| 55 |
#define VGABIOS_FILENAME "vgabios.bin" |
#define VGABIOS_FILENAME "vgabios.bin" |
| 208 |
char phys_ram_file[1024]; |
char phys_ram_file[1024]; |
| 209 |
CPUX86State *global_env; |
CPUX86State *global_env; |
| 210 |
CPUX86State *cpu_single_env; |
CPUX86State *cpu_single_env; |
|
FILE *logfile = NULL; |
|
|
int loglevel; |
|
| 211 |
IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; |
IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; |
| 212 |
IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; |
IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; |
| 213 |
BlockDriverState *bs_table[MAX_DISKS]; |
BlockDriverState *bs_table[MAX_DISKS]; |
| 829 |
int dummy_refresh_clock; |
int dummy_refresh_clock; |
| 830 |
int pit_min_timer_count = 0; |
int pit_min_timer_count = 0; |
| 831 |
|
|
| 832 |
int64_t get_clock(void) |
|
| 833 |
|
#if defined(__powerpc__) |
| 834 |
|
|
| 835 |
|
static inline uint32_t get_tbl(void) |
| 836 |
{ |
{ |
| 837 |
struct timeval tv; |
uint32_t tbl; |
| 838 |
gettimeofday(&tv, NULL); |
asm volatile("mftb %0" : "=r" (tbl)); |
| 839 |
return tv.tv_sec * 1000000LL + tv.tv_usec; |
return tbl; |
| 840 |
} |
} |
| 841 |
|
|
| 842 |
int64_t cpu_get_ticks(void) |
static inline uint32_t get_tbu(void) |
| 843 |
|
{ |
| 844 |
|
uint32_t tbl; |
| 845 |
|
asm volatile("mftbu %0" : "=r" (tbl)); |
| 846 |
|
return tbl; |
| 847 |
|
} |
| 848 |
|
|
| 849 |
|
int64_t cpu_get_real_ticks(void) |
| 850 |
|
{ |
| 851 |
|
uint32_t l, h, h1; |
| 852 |
|
/* NOTE: we test if wrapping has occurred */ |
| 853 |
|
do { |
| 854 |
|
h = get_tbu(); |
| 855 |
|
l = get_tbl(); |
| 856 |
|
h1 = get_tbu(); |
| 857 |
|
} while (h != h1); |
| 858 |
|
return ((int64_t)h << 32) | l; |
| 859 |
|
} |
| 860 |
|
|
| 861 |
|
#elif defined(__i386__) |
| 862 |
|
|
| 863 |
|
int64_t cpu_get_real_ticks(void) |
| 864 |
{ |
{ |
| 865 |
int64_t val; |
int64_t val; |
| 866 |
asm("rdtsc" : "=A" (val)); |
asm("rdtsc" : "=A" (val)); |
| 867 |
return val; |
return val; |
| 868 |
} |
} |
| 869 |
|
|
| 870 |
|
#else |
| 871 |
|
#error unsupported CPU |
| 872 |
|
#endif |
| 873 |
|
|
| 874 |
|
static int64_t cpu_ticks_offset; |
| 875 |
|
static int64_t cpu_ticks_last; |
| 876 |
|
|
| 877 |
|
int64_t cpu_get_ticks(void) |
| 878 |
|
{ |
| 879 |
|
return cpu_get_real_ticks() + cpu_ticks_offset; |
| 880 |
|
} |
| 881 |
|
|
| 882 |
|
/* enable cpu_get_ticks() */ |
| 883 |
|
void cpu_enable_ticks(void) |
| 884 |
|
{ |
| 885 |
|
cpu_ticks_offset = cpu_ticks_last - cpu_get_real_ticks(); |
| 886 |
|
} |
| 887 |
|
|
| 888 |
|
/* disable cpu_get_ticks() : the clock is stopped. You must not call |
| 889 |
|
cpu_get_ticks() after that. */ |
| 890 |
|
void cpu_disable_ticks(void) |
| 891 |
|
{ |
| 892 |
|
cpu_ticks_last = cpu_get_ticks(); |
| 893 |
|
} |
| 894 |
|
|
| 895 |
|
int64_t get_clock(void) |
| 896 |
|
{ |
| 897 |
|
struct timeval tv; |
| 898 |
|
gettimeofday(&tv, NULL); |
| 899 |
|
return tv.tv_sec * 1000000LL + tv.tv_usec; |
| 900 |
|
} |
| 901 |
|
|
| 902 |
void cpu_calibrate_ticks(void) |
void cpu_calibrate_ticks(void) |
| 903 |
{ |
{ |
| 904 |
int64_t usec, ticks; |
int64_t usec, ticks; |
| 3350 |
} |
} |
| 3351 |
|
|
| 3352 |
serial_ok = 1; |
serial_ok = 1; |
| 3353 |
|
cpu_enable_ticks(); |
| 3354 |
for(;;) { |
for(;;) { |
| 3355 |
ret = cpu_x86_exec(env); |
ret = cpu_x86_exec(env); |
| 3356 |
if (reset_requested) |
if (reset_requested) { |
| 3357 |
|
ret = EXCP_INTERRUPT; |
| 3358 |
break; |
break; |
| 3359 |
if (ret == EXCP_DEBUG) |
} |
| 3360 |
return EXCP_DEBUG; |
if (ret == EXCP_DEBUG) { |
| 3361 |
|
ret = EXCP_DEBUG; |
| 3362 |
|
break; |
| 3363 |
|
} |
| 3364 |
/* if hlt instruction, we wait until the next IRQ */ |
/* if hlt instruction, we wait until the next IRQ */ |
| 3365 |
if (ret == EXCP_HLT) |
if (ret == EXCP_HLT) |
| 3366 |
timeout = 10; |
timeout = 10; |
| 3417 |
uint8_t buf[1]; |
uint8_t buf[1]; |
| 3418 |
/* stop emulation if requested by gdb */ |
/* stop emulation if requested by gdb */ |
| 3419 |
n = read(gdbstub_fd, buf, 1); |
n = read(gdbstub_fd, buf, 1); |
| 3420 |
if (n == 1) |
if (n == 1) { |
| 3421 |
|
ret = EXCP_INTERRUPT; |
| 3422 |
break; |
break; |
| 3423 |
|
} |
| 3424 |
} |
} |
| 3425 |
} |
} |
| 3426 |
|
|
| 3437 |
gui_refresh_pending = 0; |
gui_refresh_pending = 0; |
| 3438 |
} |
} |
| 3439 |
} |
} |
| 3440 |
return EXCP_INTERRUPT; |
cpu_disable_ticks(); |
| 3441 |
|
return ret; |
| 3442 |
} |
} |
| 3443 |
|
|
| 3444 |
void help(void) |
void help(void) |
| 3596 |
} |
} |
| 3597 |
break; |
break; |
| 3598 |
case 'd': |
case 'd': |
| 3599 |
loglevel = 1; |
cpu_set_log(CPU_LOG_ALL); |
| 3600 |
break; |
break; |
| 3601 |
case 'n': |
case 'n': |
| 3602 |
pstrcpy(network_script, sizeof(network_script), optarg); |
pstrcpy(network_script, sizeof(network_script), optarg); |
| 3624 |
|
|
| 3625 |
/* init debug */ |
/* init debug */ |
| 3626 |
setvbuf(stdout, NULL, _IOLBF, 0); |
setvbuf(stdout, NULL, _IOLBF, 0); |
|
if (loglevel) { |
|
|
logfile = fopen(DEBUG_LOGFILE, "w"); |
|
|
if (!logfile) { |
|
|
perror(DEBUG_LOGFILE); |
|
|
_exit(1); |
|
|
} |
|
|
setvbuf(logfile, NULL, _IOLBF, 0); |
|
|
} |
|
| 3627 |
|
|
| 3628 |
/* init network tun interface */ |
/* init network tun interface */ |
| 3629 |
if (net_fd < 0) |
if (net_fd < 0) |