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) |