mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 16:23:55 -06:00
win32 port (initial patch by kazu)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@692 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
bb27c19087
commit
67b915a5dd
33 changed files with 1160 additions and 763 deletions
185
vl.c
185
vl.c
|
@ -21,35 +21,40 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "vl.h"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <malloc.h>
|
||||
#include <termios.h>
|
||||
#include <sys/poll.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/times.h>
|
||||
#include <sys/wait.h>
|
||||
#include <pty.h>
|
||||
#include <sys/times.h>
|
||||
|
||||
#include <termios.h>
|
||||
#include <sys/poll.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_tun.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <sys/timeb.h>
|
||||
#include <windows.h>
|
||||
#define getopt_long_only getopt_long
|
||||
#define memalign(align, size) malloc(size)
|
||||
#endif
|
||||
|
||||
|
||||
#include "disas.h"
|
||||
|
||||
#include "vl.h"
|
||||
#include "exec-all.h"
|
||||
|
||||
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
|
||||
|
@ -375,11 +380,17 @@ void cpu_disable_ticks(void)
|
|||
}
|
||||
}
|
||||
|
||||
int64_t get_clock(void)
|
||||
static int64_t get_clock(void)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
struct _timeb tb;
|
||||
_ftime(&tb);
|
||||
return ((int64_t)tb.time * 1000 + (int64_t)tb.millitm) * 1000;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return tv.tv_sec * 1000000LL + tv.tv_usec;
|
||||
#endif
|
||||
}
|
||||
|
||||
void cpu_calibrate_ticks(void)
|
||||
|
@ -388,7 +399,11 @@ void cpu_calibrate_ticks(void)
|
|||
|
||||
usec = get_clock();
|
||||
ticks = cpu_get_real_ticks();
|
||||
#ifdef _WIN32
|
||||
Sleep(50);
|
||||
#else
|
||||
usleep(50 * 1000);
|
||||
#endif
|
||||
usec = get_clock() - usec;
|
||||
ticks = cpu_get_real_ticks() - ticks;
|
||||
ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec;
|
||||
|
@ -438,8 +453,10 @@ QEMUClock *rt_clock;
|
|||
QEMUClock *vm_clock;
|
||||
|
||||
static QEMUTimer *active_timers[2];
|
||||
#ifndef _WIN32
|
||||
/* frequency of the times() clock tick */
|
||||
static int timer_freq;
|
||||
#endif
|
||||
|
||||
QEMUClock *qemu_new_clock(int type)
|
||||
{
|
||||
|
@ -550,12 +567,16 @@ int64_t qemu_get_clock(QEMUClock *clock)
|
|||
{
|
||||
switch(clock->type) {
|
||||
case QEMU_TIMER_REALTIME:
|
||||
#ifdef _WIN32
|
||||
return GetTickCount();
|
||||
#else
|
||||
/* XXX: portability among Linux hosts */
|
||||
if (timer_freq == 100) {
|
||||
return times(NULL) * 10;
|
||||
} else {
|
||||
return ((int64_t)times(NULL) * 1000) / timer_freq;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
case QEMU_TIMER_VIRTUAL:
|
||||
return cpu_get_ticks();
|
||||
|
@ -608,7 +629,12 @@ static int timer_load(QEMUFile *f, void *opaque, int version_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,
|
||||
DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
|
||||
#else
|
||||
static void host_alarm_handler(int host_signum)
|
||||
#endif
|
||||
{
|
||||
if (qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
|
||||
qemu_get_clock(vm_clock)) ||
|
||||
|
@ -621,39 +647,66 @@ static void host_alarm_handler(int host_signum)
|
|||
|
||||
static void init_timers(void)
|
||||
{
|
||||
struct sigaction act;
|
||||
struct itimerval itv;
|
||||
|
||||
/* get times() syscall frequency */
|
||||
timer_freq = sysconf(_SC_CLK_TCK);
|
||||
|
||||
rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
|
||||
vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
|
||||
|
||||
/* timer signal */
|
||||
sigfillset(&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
#ifdef _WIN32
|
||||
{
|
||||
int count=0;
|
||||
MMRESULT timerID = timeSetEvent(10, // interval (ms)
|
||||
0, // resolution
|
||||
host_alarm_handler, // function
|
||||
(DWORD)&count, // user parameter
|
||||
TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
|
||||
if( !timerID ) {
|
||||
perror("failed timer alarm");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
pit_min_timer_count = ((uint64_t)10000 * PIT_FREQ) / 1000000;
|
||||
#else
|
||||
{
|
||||
struct sigaction act;
|
||||
struct itimerval itv;
|
||||
|
||||
/* get times() syscall frequency */
|
||||
timer_freq = sysconf(_SC_CLK_TCK);
|
||||
|
||||
/* timer signal */
|
||||
sigfillset(&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
#if defined (TARGET_I386) && defined(USE_CODE_COPY)
|
||||
act.sa_flags |= SA_ONSTACK;
|
||||
act.sa_flags |= SA_ONSTACK;
|
||||
#endif
|
||||
act.sa_handler = host_alarm_handler;
|
||||
sigaction(SIGALRM, &act, NULL);
|
||||
|
||||
itv.it_interval.tv_sec = 0;
|
||||
itv.it_interval.tv_usec = 1000;
|
||||
itv.it_value.tv_sec = 0;
|
||||
itv.it_value.tv_usec = 10 * 1000;
|
||||
setitimer(ITIMER_REAL, &itv, NULL);
|
||||
/* we probe the tick duration of the kernel to inform the user if
|
||||
the emulated kernel requested a too high timer frequency */
|
||||
getitimer(ITIMER_REAL, &itv);
|
||||
pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * PIT_FREQ) /
|
||||
1000000;
|
||||
}
|
||||
#endif
|
||||
act.sa_handler = host_alarm_handler;
|
||||
sigaction(SIGALRM, &act, NULL);
|
||||
|
||||
itv.it_interval.tv_sec = 0;
|
||||
itv.it_interval.tv_usec = 1000;
|
||||
itv.it_value.tv_sec = 0;
|
||||
itv.it_value.tv_usec = 10 * 1000;
|
||||
setitimer(ITIMER_REAL, &itv, NULL);
|
||||
/* we probe the tick duration of the kernel to inform the user if
|
||||
the emulated kernel requested a too high timer frequency */
|
||||
getitimer(ITIMER_REAL, &itv);
|
||||
pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * PIT_FREQ) /
|
||||
1000000;
|
||||
}
|
||||
|
||||
/***********************************************************/
|
||||
/* serial device */
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
int serial_open_device(void)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int serial_open_device(void)
|
||||
{
|
||||
char slave_name[1024];
|
||||
|
@ -672,9 +725,24 @@ int serial_open_device(void)
|
|||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***********************************************************/
|
||||
/* Linux network device redirector */
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static int net_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void net_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int tun_open(char *ifname, int ifname_size)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
@ -753,9 +821,23 @@ void net_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
|
|||
write(nd->fd, buf, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/***********************************************************/
|
||||
/* dumb display */
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
static void term_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void term_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* init terminal so that we can grab keys */
|
||||
static struct termios oldtty;
|
||||
|
||||
|
@ -790,6 +872,8 @@ static void term_init(void)
|
|||
fcntl(0, F_SETFL, O_NONBLOCK);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
|
||||
{
|
||||
}
|
||||
|
@ -1396,10 +1480,13 @@ void vm_stop(int reason)
|
|||
|
||||
int main_loop(void)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf;
|
||||
int ret, n, timeout, max_size;
|
||||
uint8_t buf[4096];
|
||||
IOHandlerRecord *ioh, *ioh_next;
|
||||
uint8_t buf[4096];
|
||||
int n, max_size;
|
||||
#endif
|
||||
int ret, timeout;
|
||||
CPUState *env = global_env;
|
||||
|
||||
for(;;) {
|
||||
|
@ -1422,6 +1509,7 @@ int main_loop(void)
|
|||
timeout = 10;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
/* poll any events */
|
||||
/* XXX: separate device handlers from system ones */
|
||||
pf = ufds;
|
||||
|
@ -1471,6 +1559,7 @@ int main_loop(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vm_running) {
|
||||
qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
|
||||
|
@ -1592,7 +1681,10 @@ static uint8_t *signal_stack;
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int c, i, use_gdbstub, gdbstub_port, long_index, has_cdrom;
|
||||
#ifdef CONFIG_GDBSTUB
|
||||
int use_gdbstub, gdbstub_port;
|
||||
#endif
|
||||
int c, i, long_index, has_cdrom;
|
||||
int snapshot, linux_boot;
|
||||
CPUState *env;
|
||||
const char *initrd_filename;
|
||||
|
@ -1601,8 +1693,10 @@ int main(int argc, char **argv)
|
|||
DisplayState *ds = &display_state;
|
||||
int cyls, heads, secs;
|
||||
|
||||
#if !defined(CONFIG_SOFTMMU)
|
||||
/* we never want that malloc() uses mmap() */
|
||||
mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
|
||||
#endif
|
||||
initrd_filename = NULL;
|
||||
for(i = 0; i < MAX_FD; i++)
|
||||
fd_filename[i] = NULL;
|
||||
|
@ -1611,8 +1705,10 @@ int main(int argc, char **argv)
|
|||
ram_size = 32 * 1024 * 1024;
|
||||
vga_ram_size = VGA_RAM_SIZE;
|
||||
pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
|
||||
#ifdef CONFIG_GDBSTUB
|
||||
use_gdbstub = 0;
|
||||
gdbstub_port = DEFAULT_GDBSTUB_PORT;
|
||||
#endif
|
||||
snapshot = 0;
|
||||
nographic = 0;
|
||||
kernel_filename = NULL;
|
||||
|
@ -1773,12 +1869,14 @@ int main(int argc, char **argv)
|
|||
case 'n':
|
||||
pstrcpy(network_script, sizeof(network_script), optarg);
|
||||
break;
|
||||
#ifdef CONFIG_GDBSTUB
|
||||
case 's':
|
||||
use_gdbstub = 1;
|
||||
break;
|
||||
case 'p':
|
||||
gdbstub_port = atoi(optarg);
|
||||
break;
|
||||
#endif
|
||||
case 'L':
|
||||
bios_dir = optarg;
|
||||
break;
|
||||
|
@ -1976,6 +2074,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
{
|
||||
struct sigaction act;
|
||||
sigfillset(&act.sa_mask);
|
||||
|
@ -1983,10 +2082,12 @@ int main(int argc, char **argv)
|
|||
act.sa_handler = SIG_IGN;
|
||||
sigaction(SIGPIPE, &act, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
|
||||
qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
|
||||
|
||||
#ifdef CONFIG_GDBSTUB
|
||||
if (use_gdbstub) {
|
||||
if (gdbserver_start(gdbstub_port) < 0) {
|
||||
fprintf(stderr, "Could not open gdbserver socket on port %d\n",
|
||||
|
@ -1995,7 +2096,9 @@ int main(int argc, char **argv)
|
|||
} else {
|
||||
printf("Waiting gdb connection on port %d\n", gdbstub_port);
|
||||
}
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
vm_start();
|
||||
}
|
||||
term_init();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue