Commit 67b915a5 authored by bellard's avatar bellard

win32 port (initial patch by kazu)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@692 c046a42c-6fe2-441c-8c8c-71466251a162
parent bb27c190
......@@ -24,6 +24,7 @@ version 0.5.3:
- VM save/restore commands
- new timer API
- more precise RTC emulation (periodic timers + time updates)
- Win32 port (initial patch by Kazu)
version 0.5.2:
......
include config-host.mak
CFLAGS=-Wall -O2 -g
ifdef CONFIG_WIN32
CFLAGS+=-fpack-struct
endif
LDFLAGS=-g
LIBS=
DEFINES+=-D_GNU_SOURCE
ifndef CONFIG_WIN32
TOOLS=qemu-mkcow
endif
all: dyngen $(TOOLS) qemu-doc.html qemu.1
all: dyngen$(EXESUF) $(TOOLS) qemu-doc.html qemu.1
for d in $(TARGET_DIRS); do \
make -C $$d $@ || exit 1 ; \
done
......@@ -14,7 +19,7 @@ all: dyngen $(TOOLS) qemu-doc.html qemu.1
qemu-mkcow: qemu-mkcow.o
$(HOST_CC) -o $@ $^ $(LIBS)
dyngen: dyngen.o
dyngen$(EXESUF): dyngen.o
$(HOST_CC) -o $@ $^ $(LIBS)
%.o: %.c
......@@ -23,7 +28,7 @@ dyngen: dyngen.o
clean:
# avoid old build problems by removing potentially incorrect old files
rm -f config.mak config.h op-i386.h opc-i386.h gen-op-i386.h op-arm.h opc-arm.h gen-op-arm.h
rm -f *.o *.a $(TOOLS) dyngen TAGS qemu.pod
rm -f *.o *.a $(TOOLS) dyngen$(EXESUF) TAGS qemu.pod
make -C tests clean
for d in $(TARGET_DIRS); do \
make -C $$d $@ || exit 1 ; \
......
......@@ -11,12 +11,12 @@ CFLAGS=-Wall -O2 -g
LDFLAGS=-g
LIBS=
HELPER_CFLAGS=$(CFLAGS)
DYNGEN=../dyngen
DYNGEN=../dyngen$(EXESUF)
# user emulator name
QEMU_USER=qemu-$(TARGET_ARCH)
# system emulator name
ifdef CONFIG_SOFTMMU
QEMU_SYSTEM=qemu
QEMU_SYSTEM=qemu$(EXESUF)
else
QEMU_SYSTEM=qemu-fast
endif
......@@ -146,6 +146,9 @@ endif
DEFINES+=-D_GNU_SOURCE
LIBS+=-lm
ifdef CONFIG_WIN32
LIBS+=-lwinmm
endif
# profiling code
ifdef TARGET_GPROF
......@@ -219,9 +222,12 @@ ifeq ($(ARCH),alpha)
endif
# must use static linking to avoid leaving stuff in virtual address space
VL_OBJS=vl.o osdep.o block.o monitor.o gdbstub.o \
VL_OBJS=vl.o osdep.o block.o monitor.o \
ide.o ne2000.o pckbd.o vga.o sb16.o dma.o oss.o \
fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o
ifdef CONFIG_GDBSTUB
VL_OBJS+=gdbstub.o
endif
ifeq ($(TARGET_ARCH), ppc)
VL_OBJS+= hw.o
endif
......
short term:
----------
- handle fast timers + add explicit clocks
- OS/2 install bug
- win 95 install bug
- handle Self Modifying Code even if modifying current TB (BE OS 5 install)
- physical memory cache (reduce qemu-fast address space size to about 32 MB)
- better code fetch
- XP security bug
- handle Self Modifying Code even if modifying current TB (BE OS 5 install)
- cycle counter for all archs
- TLB code protection support for PPC
- add sysenter/sysexit and fxsr for L4 pistachio 686
......
......@@ -21,29 +21,11 @@
* 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 <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/wait.h>
#include <netinet/in.h>
#include "vl.h"
#define NO_THUNK_TYPE_SIZE
#include "thunk.h"
#ifndef _WIN32
#include <sys/mman.h>
#endif
#include "cow.h"
......@@ -97,11 +79,14 @@ BlockDriverState *bdrv_new(const char *device_name)
int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
{
int fd, cow_fd;
int fd;
int64_t size;
char template[] = "/tmp/vl.XXXXXX";
struct cow_header_v2 cow_header;
#ifndef _WIN32
char template[] = "/tmp/vl.XXXXXX";
int cow_fd;
struct stat st;
#endif
bs->read_only = 0;
bs->fd = -1;
......@@ -110,10 +95,18 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
strcpy(bs->filename, filename);
/* open standard HD image */
#ifdef _WIN32
fd = open(filename, O_RDWR | O_BINARY);
#else
fd = open(filename, O_RDWR | O_LARGEFILE);
#endif
if (fd < 0) {
/* read only image on disk */
#ifdef _WIN32
fd = open(filename, O_RDONLY | O_BINARY);
#else
fd = open(filename, O_RDONLY | O_LARGEFILE);
#endif
if (fd < 0) {
perror(filename);
goto fail;
......@@ -128,8 +121,9 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
fprintf(stderr, "%s: could not read header\n", filename);
goto fail;
}
if (cow_header.magic == htonl(COW_MAGIC) &&
cow_header.version == htonl(COW_VERSION)) {
#ifndef _WIN32
if (be32_to_cpu(cow_header.magic) == COW_MAGIC &&
be32_to_cpu(cow_header.version) == COW_VERSION) {
/* cow image found */
size = cow_header.size;
#ifndef WORDS_BIGENDIAN
......@@ -144,7 +138,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
fprintf(stderr, "%s: could not find original disk image '%s'\n", filename, cow_header.backing_file);
goto fail;
}
if (st.st_mtime != htonl(cow_header.mtime)) {
if (st.st_mtime != be32_to_cpu(cow_header.mtime)) {
fprintf(stderr, "%s: original raw disk image '%s' does not match saved timestamp\n", filename, cow_header.backing_file);
goto fail;
}
......@@ -164,13 +158,16 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
bs->cow_bitmap = bs->cow_bitmap_addr + sizeof(cow_header);
bs->cow_sectors_offset = (bs->cow_bitmap_size + 511) & ~511;
snapshot = 0;
} else {
} else
#endif
{
/* standard raw image */
size = lseek64(fd, 0, SEEK_END);
bs->total_sectors = size / 512;
bs->fd = fd;
}
#ifndef _WIN32
if (snapshot) {
/* create a temporary COW file */
cow_fd = mkstemp(template);
......@@ -190,6 +187,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
bs->cow_bitmap = bs->cow_bitmap_addr;
bs->cow_sectors_offset = 0;
}
#endif
bs->inserted = 1;
......@@ -206,9 +204,11 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
void bdrv_close(BlockDriverState *bs)
{
if (bs->inserted) {
#ifndef _WIN32
/* we unmap the mapping so that it is written to the COW file */
if (bs->cow_bitmap_addr)
munmap(bs->cow_bitmap_addr, bs->cow_bitmap_size);
#endif
if (bs->cow_fd >= 0)
close(bs->cow_fd);
if (bs->fd >= 0)
......
......@@ -68,10 +68,16 @@ case "$cpu" in
esac
gprof="no"
bigendian="no"
mingw32="no"
EXESUF=""
gdbstub="yes"
# OS specific
targetos=`uname -s`
case $targetos in
MINGW32*)
mingw32="yes"
;;
*) ;;
esac
......@@ -136,6 +142,8 @@ for opt do
;;
--disable-sdl) sdl="no"
;;
--enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-"
;;
esac
done
......@@ -148,6 +156,14 @@ cc="${cross_prefix}${cc}"
ar="${cross_prefix}${ar}"
strip="${cross_prefix}${strip}"
if test "$mingw32" = "yes" ; then
host_cc="$cc"
target_list="i386-softmmu"
prefix="/c/Program Files/Qemu"
EXESUF=".exe"
gdbstub="no"
fi
if test -z "$cross_prefix" ; then
# ---
......@@ -206,6 +222,7 @@ echo " --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]"
echo " --cc=CC use C compiler CC [$cc]"
echo " --make=MAKE use specified make [$make]"
echo " --static enable static build [$static]"
echo " --enable-mingw32 enable Win32 cross compilation with mingw32"
echo ""
echo "NOTE: The object files are build at the place where configure is launched"
exit 1
......@@ -227,6 +244,8 @@ echo "target list $target_list"
echo "gprof enabled $gprof"
echo "static build $static"
echo "SDL support $sdl"
echo "mingw32 support $mingw32"
if test $sdl_too_old = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have FFplay/SDL support"
fi
......@@ -253,6 +272,7 @@ echo "AR=$ar" >> $config_mak
echo "STRIP=$strip -s -R .comment -R .note" >> $config_mak
echo "CFLAGS=$CFLAGS" >> $config_mak
echo "LDFLAGS=$LDFLAGS" >> $config_mak
echo "EXESUF=$EXESUF" >> $config_mak
if test "$cpu" = "i386" ; then
echo "ARCH=i386" >> $config_mak
echo "#define HOST_I386 1" >> $config_h
......@@ -294,7 +314,15 @@ if test "$bigendian" = "yes" ; then
echo "WORDS_BIGENDIAN=yes" >> $config_mak
echo "#define WORDS_BIGENDIAN 1" >> $config_h
fi
echo "#define HAVE_BYTESWAP_H 1" >> $config_h
if test "$mingw32" = "yes" ; then
echo "CONFIG_WIN32=yes" >> $config_mak
else
echo "#define HAVE_BYTESWAP_H 1" >> $config_h
fi
if test "$gdbstub" = "yes" ; then
echo "CONFIG_GDBSTUB=yes" >> $config_mak
echo "#define CONFIG_GDBSTUB 1" >> $config_h
fi
if test "$gprof" = "yes" ; then
echo "TARGET_GPROF=yes" >> $config_mak
echo "#define HAVE_GPROF 1" >> $config_h
......
......@@ -592,6 +592,8 @@ void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32)
#endif /* TARGET_I386 */
#if !defined(CONFIG_SOFTMMU)
#undef EAX
#undef ECX
#undef EDX
......@@ -925,3 +927,5 @@ int cpu_signal_handler(int host_signum, struct siginfo *info,
#error host CPU specific signal handler needed
#endif
#endif /* !defined(CONFIG_SOFTMMU) */
This diff is collapsed.
......@@ -141,7 +141,7 @@ int tlb_set_page(CPUState *env, uint32_t vaddr, uint32_t paddr, int prot,
#if defined(__powerpc__)
#define USE_DIRECT_JUMP
#endif
#if defined(__i386__)
#if defined(__i386__) && !defined(_WIN32)
#define USE_DIRECT_JUMP
#endif
......@@ -322,13 +322,19 @@ do {\
#elif defined(__i386__) && defined(USE_DIRECT_JUMP)
#ifdef _WIN32
#define ASM_PREVIOUS_SECTION ".section .text\n"
#else
#define ASM_PREVIOUS_SECTION ".previous\n"
#endif
/* we patch the jump instruction directly */
#define JUMP_TB(opname, tbparam, n, eip)\
do {\
asm volatile (".section \".data\"\n"\
asm volatile (".section .data\n"\
"__op_label" #n "." stringify(opname) ":\n"\
".long 1f\n"\
".previous\n"\
ASM_PREVIOUS_SECTION \
"jmp __op_jmp" #n "\n"\
"1:\n");\
T0 = (long)(tbparam) + (n);\
......
......@@ -17,6 +17,7 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
......@@ -24,9 +25,10 @@
#include <errno.h>
#include <unistd.h>
#include <inttypes.h>
#if !defined(CONFIG_SOFTMMU)
#include <sys/mman.h>
#endif
#include "config.h"
#include "cpu.h"
#include "exec-all.h"
......@@ -121,7 +123,11 @@ static void page_init(void)
{
/* NOTE: we can always suppose that host_page_size >=
TARGET_PAGE_SIZE */
#ifdef _WIN32
real_host_page_size = 4096;
#else
real_host_page_size = getpagesize();
#endif
if (host_page_size == 0)
host_page_size = real_host_page_size;
if (host_page_size < TARGET_PAGE_SIZE)
......@@ -1369,14 +1375,14 @@ int tlb_set_page(CPUState *env, uint32_t vaddr, uint32_t paddr, int prot,
index = (vaddr >> 12) & (CPU_TLB_SIZE - 1);
addend -= vaddr;
if (prot & PROT_READ) {
if (prot & PAGE_READ) {
env->tlb_read[is_user][index].address = address;
env->tlb_read[is_user][index].addend = addend;
} else {
env->tlb_read[is_user][index].address = -1;
env->tlb_read[is_user][index].addend = -1;
}
if (prot & PROT_WRITE) {
if (prot & PAGE_WRITE) {
if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM) {
/* ROM: access is ignored (same as unassigned) */
env->tlb_write[is_user][index].address = vaddr | IO_MEM_ROM;
......
......@@ -17,18 +17,12 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include "vl.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <signal.h>
#include <fcntl.h>
#include "vl.h"
//#define DEBUG_GDB
......
......@@ -21,11 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include "cpu.h"
#include "vl.h"
#define log(...) fprintf (stderr, "dma: " __VA_ARGS__)
......
......@@ -21,11 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "vl.h"
/********************************************************/
......
......@@ -21,26 +21,6 @@
* 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 <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/wait.h>
#include <netinet/in.h>
#include "cpu.h"
#include "vl.h"
//#define DEBUG_PIT
......
......@@ -21,26 +21,6 @@
* 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 <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/wait.h>
#include <netinet/in.h>
#include "cpu.h"
#include "vl.h"
/* debug PIC */
......
......@@ -21,31 +21,6 @@
* 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 <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/wait.h>
#include <netinet/in.h>
#define NO_THUNK_TYPE_SIZE
#include "thunk.h"
#include "cpu.h"
#include "exec-all.h"
#include "vl.h"
/* debug IDE devices */
......@@ -375,6 +350,15 @@ static void padstr8(uint8_t *buf, int buf_size, const char *src)
}
}
static void put_le16(uint16_t *p, unsigned int v)
{
#ifdef WORDS_BIGENDIAN
*p = bswap16(v);
#else
*p = v;
#endif
}
static void ide_identify(IDEState *s)
{
uint16_t *p;
......@@ -382,43 +366,43 @@ static void ide_identify(IDEState *s)
memset(s->io_buffer, 0, 512);
p = (uint16_t *)s->io_buffer;
stw_raw(p + 0, 0x0040);
stw_raw(p + 1, s->cylinders);
stw_raw(p + 3, s->heads);
stw_raw(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
stw_raw(p + 5, 512); /* XXX: retired, remove ? */
stw_raw(p + 6, s->sectors);
put_le16(p + 0, 0x0040);
put_le16(p + 1, s->cylinders);
put_le16(p + 3, s->heads);
put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
put_le16(p + 5, 512); /* XXX: retired, remove ? */
put_le16(p + 6, s->sectors);
padstr((uint8_t *)(p + 10), "QM00001", 20); /* serial number */
stw_raw(p + 20, 3); /* XXX: retired, remove ? */
stw_raw(p + 21, 512); /* cache size in sectors */
stw_raw(p + 22, 4); /* ecc bytes */
put_le16(p + 20, 3); /* XXX: retired, remove ? */
put_le16(p + 21, 512); /* cache size in sectors */
put_le16(p + 22, 4); /* ecc bytes */
padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */
#if MAX_MULT_SECTORS > 1
stw_raw(p + 47, 0x8000 | MAX_MULT_SECTORS);
put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
#endif
stw_raw(p + 48, 1); /* dword I/O */
stw_raw(p + 49, 1 << 9); /* LBA supported, no DMA */
stw_raw(p + 51, 0x200); /* PIO transfer cycle */
stw_raw(p + 52, 0x200); /* DMA transfer cycle */
stw_raw(p + 53, 1); /* words 54-58 are valid */
stw_raw(p + 54, s->cylinders);
stw_raw(p + 55, s->heads);
stw_raw(p + 56, s->sectors);
put_le16(p + 48, 1); /* dword I/O */
put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
put_le16(p + 51, 0x200); /* PIO transfer cycle */
put_le16(p + 52, 0x200); /* DMA transfer cycle */
put_le16(p + 53, 1); /* words 54-58 are valid */
put_le16(p + 54, s->cylinders);
put_le16(p + 55, s->heads);
put_le16(p + 56, s->sectors);
oldsize = s->cylinders * s->heads * s->sectors;
stw_raw(p + 57, oldsize);
stw_raw(p + 58, oldsize >> 16);
put_le16(p + 57, oldsize);
put_le16(p + 58, oldsize >> 16);
if (s->mult_sectors)
stw_raw(p + 59, 0x100 | s->mult_sectors);
stw_raw(p + 60, s->nb_sectors);
stw_raw(p + 61, s->nb_sectors >> 16);
stw_raw(p + 80, (1 << 1) | (1 << 2));
stw_raw(p + 82, (1 << 14));
stw_raw(p + 83, (1 << 14));
stw_raw(p + 84, (1 << 14));
stw_raw(p + 85, (1 << 14));
stw_raw(p + 86, 0);
stw_raw(p + 87, (1 << 14));
put_le16(p + 59, 0x100 | s->mult_sectors);
put_le16(p + 60, s->nb_sectors);
put_le16(p + 61, s->nb_sectors >> 16);
put_le16(p + 80, (1 << 1) | (1 << 2));
put_le16(p + 82, (1 << 14));
put_le16(p + 83, (1 << 14));
put_le16(p + 84, (1 << 14));
put_le16(p + 85, (1 << 14));
put_le16(p + 86, 0);
put_le16(p + 87, (1 << 14));
}
static void ide_atapi_identify(IDEState *s)
......@@ -428,32 +412,32 @@ static void ide_atapi_identify(IDEState *s)
memset(s->io_buffer, 0, 512);
p = (uint16_t *)s->io_buffer;
/* Removable CDROM, 50us response, 12 byte packets */
stw_raw(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
stw_raw(p + 1, s->cylinders);
stw_raw(p + 3, s->heads);
stw_raw(p + 4, 512 * s->sectors); /* sectors */
stw_raw(p + 5, 512); /* sector size */
stw_raw(p + 6, s->sectors);
put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
put_le16(p + 1, s->cylinders);
put_le16(p + 3, s->heads);