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:
bellard 2004-03-31 23:37:16 +00:00
parent bb27c19087
commit 67b915a5dd
33 changed files with 1160 additions and 763 deletions

View File

@ -24,6 +24,7 @@ version 0.5.3:
- VM save/restore commands - VM save/restore commands
- new timer API - new timer API
- more precise RTC emulation (periodic timers + time updates) - more precise RTC emulation (periodic timers + time updates)
- Win32 port (initial patch by Kazu)
version 0.5.2: version 0.5.2:

View File

@ -1,12 +1,17 @@
include config-host.mak include config-host.mak
CFLAGS=-Wall -O2 -g CFLAGS=-Wall -O2 -g
ifdef CONFIG_WIN32
CFLAGS+=-fpack-struct
endif
LDFLAGS=-g LDFLAGS=-g
LIBS= LIBS=
DEFINES+=-D_GNU_SOURCE DEFINES+=-D_GNU_SOURCE
ifndef CONFIG_WIN32
TOOLS=qemu-mkcow 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 \ for d in $(TARGET_DIRS); do \
make -C $$d $@ || exit 1 ; \ make -C $$d $@ || exit 1 ; \
done done
@ -14,7 +19,7 @@ all: dyngen $(TOOLS) qemu-doc.html qemu.1
qemu-mkcow: qemu-mkcow.o qemu-mkcow: qemu-mkcow.o
$(HOST_CC) -o $@ $^ $(LIBS) $(HOST_CC) -o $@ $^ $(LIBS)
dyngen: dyngen.o dyngen$(EXESUF): dyngen.o
$(HOST_CC) -o $@ $^ $(LIBS) $(HOST_CC) -o $@ $^ $(LIBS)
%.o: %.c %.o: %.c
@ -23,7 +28,7 @@ dyngen: dyngen.o
clean: clean:
# avoid old build problems by removing potentially incorrect old files # 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 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 make -C tests clean
for d in $(TARGET_DIRS); do \ for d in $(TARGET_DIRS); do \
make -C $$d $@ || exit 1 ; \ make -C $$d $@ || exit 1 ; \

View File

@ -11,12 +11,12 @@ CFLAGS=-Wall -O2 -g
LDFLAGS=-g LDFLAGS=-g
LIBS= LIBS=
HELPER_CFLAGS=$(CFLAGS) HELPER_CFLAGS=$(CFLAGS)
DYNGEN=../dyngen DYNGEN=../dyngen$(EXESUF)
# user emulator name # user emulator name
QEMU_USER=qemu-$(TARGET_ARCH) QEMU_USER=qemu-$(TARGET_ARCH)
# system emulator name # system emulator name
ifdef CONFIG_SOFTMMU ifdef CONFIG_SOFTMMU
QEMU_SYSTEM=qemu QEMU_SYSTEM=qemu$(EXESUF)
else else
QEMU_SYSTEM=qemu-fast QEMU_SYSTEM=qemu-fast
endif endif
@ -146,6 +146,9 @@ endif
DEFINES+=-D_GNU_SOURCE DEFINES+=-D_GNU_SOURCE
LIBS+=-lm LIBS+=-lm
ifdef CONFIG_WIN32
LIBS+=-lwinmm
endif
# profiling code # profiling code
ifdef TARGET_GPROF ifdef TARGET_GPROF
@ -219,9 +222,12 @@ ifeq ($(ARCH),alpha)
endif endif
# must use static linking to avoid leaving stuff in virtual address space # 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 \ 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 fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o
ifdef CONFIG_GDBSTUB
VL_OBJS+=gdbstub.o
endif
ifeq ($(TARGET_ARCH), ppc) ifeq ($(TARGET_ARCH), ppc)
VL_OBJS+= hw.o VL_OBJS+= hw.o
endif endif

5
TODO
View File

@ -1,9 +1,12 @@
short term: 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) - physical memory cache (reduce qemu-fast address space size to about 32 MB)
- better code fetch - better code fetch
- XP security bug - XP security bug
- handle Self Modifying Code even if modifying current TB (BE OS 5 install)
- cycle counter for all archs - cycle counter for all archs
- TLB code protection support for PPC - TLB code protection support for PPC
- add sysenter/sysexit and fxsr for L4 pistachio 686 - add sysenter/sysexit and fxsr for L4 pistachio 686

54
block.c
View File

@ -21,29 +21,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * 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" #include "vl.h"
#define NO_THUNK_TYPE_SIZE #ifndef _WIN32
#include "thunk.h" #include <sys/mman.h>
#endif
#include "cow.h" #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 bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
{ {
int fd, cow_fd; int fd;
int64_t size; int64_t size;
char template[] = "/tmp/vl.XXXXXX";
struct cow_header_v2 cow_header; struct cow_header_v2 cow_header;
#ifndef _WIN32
char template[] = "/tmp/vl.XXXXXX";
int cow_fd;
struct stat st; struct stat st;
#endif
bs->read_only = 0; bs->read_only = 0;
bs->fd = -1; bs->fd = -1;
@ -110,10 +95,18 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
strcpy(bs->filename, filename); strcpy(bs->filename, filename);
/* open standard HD image */ /* open standard HD image */
#ifdef _WIN32
fd = open(filename, O_RDWR | O_BINARY);
#else
fd = open(filename, O_RDWR | O_LARGEFILE); fd = open(filename, O_RDWR | O_LARGEFILE);
#endif
if (fd < 0) { if (fd < 0) {
/* read only image on disk */ /* read only image on disk */
#ifdef _WIN32
fd = open(filename, O_RDONLY | O_BINARY);
#else
fd = open(filename, O_RDONLY | O_LARGEFILE); fd = open(filename, O_RDONLY | O_LARGEFILE);
#endif
if (fd < 0) { if (fd < 0) {
perror(filename); perror(filename);
goto fail; 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); fprintf(stderr, "%s: could not read header\n", filename);
goto fail; goto fail;
} }
if (cow_header.magic == htonl(COW_MAGIC) && #ifndef _WIN32
cow_header.version == htonl(COW_VERSION)) { if (be32_to_cpu(cow_header.magic) == COW_MAGIC &&
be32_to_cpu(cow_header.version) == COW_VERSION) {
/* cow image found */ /* cow image found */
size = cow_header.size; size = cow_header.size;
#ifndef WORDS_BIGENDIAN #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); fprintf(stderr, "%s: could not find original disk image '%s'\n", filename, cow_header.backing_file);
goto fail; 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); fprintf(stderr, "%s: original raw disk image '%s' does not match saved timestamp\n", filename, cow_header.backing_file);
goto fail; 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_bitmap = bs->cow_bitmap_addr + sizeof(cow_header);
bs->cow_sectors_offset = (bs->cow_bitmap_size + 511) & ~511; bs->cow_sectors_offset = (bs->cow_bitmap_size + 511) & ~511;
snapshot = 0; snapshot = 0;
} else { } else
#endif
{
/* standard raw image */ /* standard raw image */
size = lseek64(fd, 0, SEEK_END); size = lseek64(fd, 0, SEEK_END);
bs->total_sectors = size / 512; bs->total_sectors = size / 512;
bs->fd = fd; bs->fd = fd;
} }
#ifndef _WIN32
if (snapshot) { if (snapshot) {
/* create a temporary COW file */ /* create a temporary COW file */
cow_fd = mkstemp(template); 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_bitmap = bs->cow_bitmap_addr;
bs->cow_sectors_offset = 0; bs->cow_sectors_offset = 0;
} }
#endif
bs->inserted = 1; bs->inserted = 1;
@ -206,9 +204,11 @@ int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot)
void bdrv_close(BlockDriverState *bs) void bdrv_close(BlockDriverState *bs)
{ {
if (bs->inserted) { if (bs->inserted) {
#ifndef _WIN32
/* we unmap the mapping so that it is written to the COW file */ /* we unmap the mapping so that it is written to the COW file */
if (bs->cow_bitmap_addr) if (bs->cow_bitmap_addr)
munmap(bs->cow_bitmap_addr, bs->cow_bitmap_size); munmap(bs->cow_bitmap_addr, bs->cow_bitmap_size);
#endif
if (bs->cow_fd >= 0) if (bs->cow_fd >= 0)
close(bs->cow_fd); close(bs->cow_fd);
if (bs->fd >= 0) if (bs->fd >= 0)

30
configure vendored
View File

@ -68,10 +68,16 @@ case "$cpu" in
esac esac
gprof="no" gprof="no"
bigendian="no" bigendian="no"
mingw32="no"
EXESUF=""
gdbstub="yes"
# OS specific # OS specific
targetos=`uname -s` targetos=`uname -s`
case $targetos in case $targetos in
MINGW32*)
mingw32="yes"
;;
*) ;; *) ;;
esac esac
@ -136,6 +142,8 @@ for opt do
;; ;;
--disable-sdl) sdl="no" --disable-sdl) sdl="no"
;; ;;
--enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-"
;;
esac esac
done done
@ -148,6 +156,14 @@ cc="${cross_prefix}${cc}"
ar="${cross_prefix}${ar}" ar="${cross_prefix}${ar}"
strip="${cross_prefix}${strip}" 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 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 " --cc=CC use C compiler CC [$cc]"
echo " --make=MAKE use specified make [$make]" echo " --make=MAKE use specified make [$make]"
echo " --static enable static build [$static]" echo " --static enable static build [$static]"
echo " --enable-mingw32 enable Win32 cross compilation with mingw32"
echo "" echo ""
echo "NOTE: The object files are build at the place where configure is launched" echo "NOTE: The object files are build at the place where configure is launched"
exit 1 exit 1
@ -227,6 +244,8 @@ echo "target list $target_list"
echo "gprof enabled $gprof" echo "gprof enabled $gprof"
echo "static build $static" echo "static build $static"
echo "SDL support $sdl" echo "SDL support $sdl"
echo "mingw32 support $mingw32"
if test $sdl_too_old = "yes"; then if test $sdl_too_old = "yes"; then
echo "-> Your SDL version is too old - please upgrade to have FFplay/SDL support" echo "-> Your SDL version is too old - please upgrade to have FFplay/SDL support"
fi fi
@ -253,6 +272,7 @@ echo "AR=$ar" >> $config_mak
echo "STRIP=$strip -s -R .comment -R .note" >> $config_mak echo "STRIP=$strip -s -R .comment -R .note" >> $config_mak
echo "CFLAGS=$CFLAGS" >> $config_mak echo "CFLAGS=$CFLAGS" >> $config_mak
echo "LDFLAGS=$LDFLAGS" >> $config_mak echo "LDFLAGS=$LDFLAGS" >> $config_mak
echo "EXESUF=$EXESUF" >> $config_mak
if test "$cpu" = "i386" ; then if test "$cpu" = "i386" ; then
echo "ARCH=i386" >> $config_mak echo "ARCH=i386" >> $config_mak
echo "#define HOST_I386 1" >> $config_h echo "#define HOST_I386 1" >> $config_h
@ -294,7 +314,15 @@ if test "$bigendian" = "yes" ; then
echo "WORDS_BIGENDIAN=yes" >> $config_mak echo "WORDS_BIGENDIAN=yes" >> $config_mak
echo "#define WORDS_BIGENDIAN 1" >> $config_h echo "#define WORDS_BIGENDIAN 1" >> $config_h
fi 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 if test "$gprof" = "yes" ; then
echo "TARGET_GPROF=yes" >> $config_mak echo "TARGET_GPROF=yes" >> $config_mak
echo "#define HAVE_GPROF 1" >> $config_h echo "#define HAVE_GPROF 1" >> $config_h

View File

@ -592,6 +592,8 @@ void cpu_x86_frstor(CPUX86State *s, uint8_t *ptr, int data32)
#endif /* TARGET_I386 */ #endif /* TARGET_I386 */
#if !defined(CONFIG_SOFTMMU)
#undef EAX #undef EAX
#undef ECX #undef ECX
#undef EDX #undef EDX
@ -925,3 +927,5 @@ int cpu_signal_handler(int host_signum, struct siginfo *info,
#error host CPU specific signal handler needed #error host CPU specific signal handler needed
#endif #endif
#endif /* !defined(CONFIG_SOFTMMU) */

1074
dyngen.c

File diff suppressed because it is too large Load Diff

View File

@ -141,7 +141,7 @@ int tlb_set_page(CPUState *env, uint32_t vaddr, uint32_t paddr, int prot,
#if defined(__powerpc__) #if defined(__powerpc__)
#define USE_DIRECT_JUMP #define USE_DIRECT_JUMP
#endif #endif
#if defined(__i386__) #if defined(__i386__) && !defined(_WIN32)
#define USE_DIRECT_JUMP #define USE_DIRECT_JUMP
#endif #endif
@ -322,13 +322,19 @@ do {\
#elif defined(__i386__) && defined(USE_DIRECT_JUMP) #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 */ /* we patch the jump instruction directly */
#define JUMP_TB(opname, tbparam, n, eip)\ #define JUMP_TB(opname, tbparam, n, eip)\
do {\ do {\
asm volatile (".section \".data\"\n"\ asm volatile (".section .data\n"\
"__op_label" #n "." stringify(opname) ":\n"\ "__op_label" #n "." stringify(opname) ":\n"\
".long 1f\n"\ ".long 1f\n"\
".previous\n"\ ASM_PREVIOUS_SECTION \
"jmp __op_jmp" #n "\n"\ "jmp __op_jmp" #n "\n"\
"1:\n");\ "1:\n");\
T0 = (long)(tbparam) + (n);\ T0 = (long)(tbparam) + (n);\

12
exec.c
View File

@ -17,6 +17,7 @@
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
@ -24,9 +25,10 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <inttypes.h> #include <inttypes.h>
#if !defined(CONFIG_SOFTMMU)
#include <sys/mman.h> #include <sys/mman.h>
#endif
#include "config.h"
#include "cpu.h" #include "cpu.h"
#include "exec-all.h" #include "exec-all.h"
@ -121,7 +123,11 @@ static void page_init(void)
{ {
/* NOTE: we can always suppose that host_page_size >= /* NOTE: we can always suppose that host_page_size >=
TARGET_PAGE_SIZE */ TARGET_PAGE_SIZE */
#ifdef _WIN32
real_host_page_size = 4096;
#else
real_host_page_size = getpagesize(); real_host_page_size = getpagesize();
#endif
if (host_page_size == 0) if (host_page_size == 0)
host_page_size = real_host_page_size; host_page_size = real_host_page_size;
if (host_page_size < TARGET_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); index = (vaddr >> 12) & (CPU_TLB_SIZE - 1);
addend -= vaddr; addend -= vaddr;
if (prot & PROT_READ) { if (prot & PAGE_READ) {
env->tlb_read[is_user][index].address = address; env->tlb_read[is_user][index].address = address;
env->tlb_read[is_user][index].addend = addend; env->tlb_read[is_user][index].addend = addend;
} else { } else {
env->tlb_read[is_user][index].address = -1; env->tlb_read[is_user][index].address = -1;
env->tlb_read[is_user][index].addend = -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) { if ((pd & ~TARGET_PAGE_MASK) == IO_MEM_ROM) {
/* ROM: access is ignored (same as unassigned) */ /* ROM: access is ignored (same as unassigned) */
env->tlb_write[is_user][index].address = vaddr | IO_MEM_ROM; env->tlb_write[is_user][index].address = vaddr | IO_MEM_ROM;

View File

@ -17,18 +17,12 @@
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <stdlib.h> #include "vl.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <signal.h> #include <signal.h>
#include <fcntl.h>
#include "vl.h"
//#define DEBUG_GDB //#define DEBUG_GDB

View File

@ -21,11 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include "cpu.h"
#include "vl.h" #include "vl.h"
#define log(...) fprintf (stderr, "dma: " __VA_ARGS__) #define log(...) fprintf (stderr, "dma: " __VA_ARGS__)

View File

@ -21,11 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "vl.h" #include "vl.h"
/********************************************************/ /********************************************************/

View File

@ -21,26 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * 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" #include "vl.h"
//#define DEBUG_PIT //#define DEBUG_PIT

View File

@ -21,26 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * 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" #include "vl.h"
/* debug PIC */ /* debug PIC */

136
hw/ide.c
View File

@ -21,31 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * 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" #include "vl.h"
/* debug IDE devices */ /* 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) static void ide_identify(IDEState *s)
{ {
uint16_t *p; uint16_t *p;
@ -382,43 +366,43 @@ static void ide_identify(IDEState *s)
memset(s->io_buffer, 0, 512); memset(s->io_buffer, 0, 512);
p = (uint16_t *)s->io_buffer; p = (uint16_t *)s->io_buffer;
stw_raw(p + 0, 0x0040); put_le16(p + 0, 0x0040);
stw_raw(p + 1, s->cylinders); put_le16(p + 1, s->cylinders);
stw_raw(p + 3, s->heads); put_le16(p + 3, s->heads);
stw_raw(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */ put_le16(p + 4, 512 * s->sectors); /* XXX: retired, remove ? */
stw_raw(p + 5, 512); /* XXX: retired, remove ? */ put_le16(p + 5, 512); /* XXX: retired, remove ? */
stw_raw(p + 6, s->sectors); put_le16(p + 6, s->sectors);
padstr((uint8_t *)(p + 10), "QM00001", 20); /* serial number */ padstr((uint8_t *)(p + 10), "QM00001", 20); /* serial number */
stw_raw(p + 20, 3); /* XXX: retired, remove ? */ put_le16(p + 20, 3); /* XXX: retired, remove ? */
stw_raw(p + 21, 512); /* cache size in sectors */ put_le16(p + 21, 512); /* cache size in sectors */
stw_raw(p + 22, 4); /* ecc bytes */ put_le16(p + 22, 4); /* ecc bytes */
padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */ padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */ padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40); /* model */
#if MAX_MULT_SECTORS > 1 #if MAX_MULT_SECTORS > 1
stw_raw(p + 47, 0x8000 | MAX_MULT_SECTORS); put_le16(p + 47, 0x8000 | MAX_MULT_SECTORS);
#endif #endif
stw_raw(p + 48, 1); /* dword I/O */ put_le16(p + 48, 1); /* dword I/O */
stw_raw(p + 49, 1 << 9); /* LBA supported, no DMA */ put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
stw_raw(p + 51, 0x200); /* PIO transfer cycle */ put_le16(p + 51, 0x200); /* PIO transfer cycle */
stw_raw(p + 52, 0x200); /* DMA transfer cycle */ put_le16(p + 52, 0x200); /* DMA transfer cycle */
stw_raw(p + 53, 1); /* words 54-58 are valid */ put_le16(p + 53, 1); /* words 54-58 are valid */
stw_raw(p + 54, s->cylinders); put_le16(p + 54, s->cylinders);
stw_raw(p + 55, s->heads); put_le16(p + 55, s->heads);
stw_raw(p + 56, s->sectors); put_le16(p + 56, s->sectors);
oldsize = s->cylinders * s->heads * s->sectors; oldsize = s->cylinders * s->heads * s->sectors;
stw_raw(p + 57, oldsize); put_le16(p + 57, oldsize);
stw_raw(p + 58, oldsize >> 16); put_le16(p + 58, oldsize >> 16);
if (s->mult_sectors) if (s->mult_sectors)
stw_raw(p + 59, 0x100 | s->mult_sectors); put_le16(p + 59, 0x100 | s->mult_sectors);
stw_raw(p + 60, s->nb_sectors); put_le16(p + 60, s->nb_sectors);
stw_raw(p + 61, s->nb_sectors >> 16); put_le16(p + 61, s->nb_sectors >> 16);
stw_raw(p + 80, (1 << 1) | (1 << 2)); put_le16(p + 80, (1 << 1) | (1 << 2));
stw_raw(p + 82, (1 << 14)); put_le16(p + 82, (1 << 14));
stw_raw(p + 83, (1 << 14)); put_le16(p + 83, (1 << 14));
stw_raw(p + 84, (1 << 14)); put_le16(p + 84, (1 << 14));
stw_raw(p + 85, (1 << 14)); put_le16(p + 85, (1 << 14));
stw_raw(p + 86, 0); put_le16(p + 86, 0);
stw_raw(p + 87, (1 << 14)); put_le16(p + 87, (1 << 14));
} }
static void ide_atapi_identify(IDEState *s) static void ide_atapi_identify(IDEState *s)
@ -428,32 +412,32 @@ static void ide_atapi_identify(IDEState *s)
memset(s->io_buffer, 0, 512); memset(s->io_buffer, 0, 512);
p = (uint16_t *)s->io_buffer; p = (uint16_t *)s->io_buffer;
/* Removable CDROM, 50us response, 12 byte packets */ /* Removable CDROM, 50us response, 12 byte packets */
stw_raw(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0)); put_le16(p + 0, (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0));
stw_raw(p + 1, s->cylinders); put_le16(p + 1, s->cylinders);
stw_raw(p + 3, s->heads); put_le16(p + 3, s->heads);
stw_raw(p + 4, 512 * s->sectors); /* sectors */ put_le16(p + 4, 512 * s->sectors); /* sectors */
stw_raw(p + 5, 512); /* sector size */ put_le16(p + 5, 512); /* sector size */
stw_raw(p + 6, s->sectors); put_le16(p + 6, s->sectors);
padstr((uint8_t *)(p + 10), "QM00001", 20); /* serial number */ padstr((uint8_t *)(p + 10), "QM00001", 20); /* serial number */
stw_raw(p + 20, 3); /* buffer type */ put_le16(p + 20, 3); /* buffer type */
stw_raw(p + 21, 512); /* cache size in sectors */ put_le16(p + 21, 512); /* cache size in sectors */
stw_raw(p + 22, 4); /* ecc bytes */ put_le16(p + 22, 4); /* ecc bytes */
padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */ padstr((uint8_t *)(p + 23), QEMU_VERSION, 8); /* firmware version */
padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */ padstr((uint8_t *)(p + 27), "QEMU CD-ROM", 40); /* model */
stw_raw(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */ put_le16(p + 48, 1); /* dword I/O (XXX: should not be set on CDROM) */
stw_raw(p + 49, 1 << 9); /* LBA supported, no DMA */ put_le16(p + 49, 1 << 9); /* LBA supported, no DMA */
stw_raw(p + 53, 3); /* words 64-70, 54-58 valid */ put_le16(p + 53, 3); /* words 64-70, 54-58 valid */
stw_raw(p + 63, 0x103); /* DMA modes XXX: may be incorrect */ put_le16(p + 63, 0x103); /* DMA modes XXX: may be incorrect */
stw_raw(p + 64, 1); /* PIO modes */ put_le16(p + 64, 1); /* PIO modes */
stw_raw(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */ put_le16(p + 65, 0xb4); /* minimum DMA multiword tx cycle time */
stw_raw(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */ put_le16(p + 66, 0xb4); /* recommended DMA multiword tx cycle time */
stw_raw(p + 67, 0x12c); /* minimum PIO cycle time without flow control */ put_le16(p + 67, 0x12c); /* minimum PIO cycle time without flow control */
stw_raw(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */ put_le16(p + 68, 0xb4); /* minimum PIO cycle time with IORDY flow control */
stw_raw(p + 71, 30); /* in ns */ put_le16(p + 71, 30); /* in ns */
stw_raw(p + 72, 30); /* in ns */ put_le16(p + 72, 30); /* in ns */
stw_raw(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */ put_le16(p + 80, 0x1e); /* support up to ATA/ATAPI-4 */
} }
static void ide_set_signature(IDEState *s) static void ide_set_signature(IDEState *s)

View File

@ -21,26 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * 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" #include "vl.h"
//#define DEBUG_CMOS //#define DEBUG_CMOS

View File

@ -21,26 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * 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" #include "vl.h"
/* debug NE2000 card */ /* debug NE2000 card */

26
hw/pc.c
View File

@ -21,26 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * 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" #include "vl.h"
/* output Bochs bios info messages */ /* output Bochs bios info messages */
@ -393,9 +373,13 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device,
bs_table[2 * i], bs_table[2 * i + 1]); bs_table[2 * i], bs_table[2 * i + 1]);
} }
kbd_init(); kbd_init();
AUD_init();
DMA_init(); DMA_init();
#ifndef _WIN32
/* no audio supported yet for win32 */
AUD_init();
SB16_init(); SB16_init();
#endif
floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);

View File

@ -21,26 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * 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" #include "vl.h"
/* debug PC keyboard */ /* debug PC keyboard */

View File

@ -21,11 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include "cpu.h"
#include "vl.h" #include "vl.h"
#define MIN(a, b) ((a)>(b)?(b):(a)) #define MIN(a, b) ((a)>(b)?(b):(a))

View File

@ -21,26 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * 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" #include "vl.h"
//#define DEBUG_SERIAL //#define DEBUG_SERIAL

View File

@ -21,28 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * 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 "exec-all.h"
#include "vl.h" #include "vl.h"
//#define DEBUG_VGA //#define DEBUG_VGA

View File

@ -21,25 +21,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * 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 <ctype.h>
#include "cpu.h"
#include "vl.h" #include "vl.h"
//#define DEBUG //#define DEBUG
@ -311,6 +292,7 @@ static void do_cont(int argc, const char **argv)
vm_start(); vm_start();
} }
#ifdef CONFIG_GDBSTUB
static void do_gdbserver(int argc, const char **argv) static void do_gdbserver(int argc, const char **argv)
{ {
int port; int port;
@ -324,6 +306,7 @@ static void do_gdbserver(int argc, const char **argv)
qemu_printf("Waiting gdb connection on port %d\n", port); qemu_printf("Waiting gdb connection on port %d\n", port);
} }
} }
#endif
static term_cmd_t term_cmds[] = { static term_cmd_t term_cmds[] = {
{ "help|?", do_help, { "help|?", do_help,
@ -348,7 +331,9 @@ static term_cmd_t term_cmds[] = {
"filename", "restore the whole virtual machine state from 'filename'" }, "filename", "restore the whole virtual machine state from 'filename'" },
{ "stop", do_stop, "", "stop emulation", }, { "stop", do_stop, "", "stop emulation", },
{ "c|cont", do_cont, "", "resume emulation", }, { "c|cont", do_cont, "", "resume emulation", },
#ifdef CONFIG_GDBSTUB
{ "gdbserver", do_gdbserver, "[port]", "start gdbserver session (default port=1234)", }, { "gdbserver", do_gdbserver, "[port]", "start gdbserver session (default port=1234)", },
#endif
{ NULL, NULL, }, { NULL, NULL, },
}; };

View File

@ -25,8 +25,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include <sys/mman.h>
#include <sys/ipc.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
@ -34,6 +32,9 @@
#if defined(__i386__) && !defined(CONFIG_SOFTMMU) && !defined(CONFIG_USER_ONLY) #if defined(__i386__) && !defined(CONFIG_SOFTMMU) && !defined(CONFIG_USER_ONLY)
#include <sys/mman.h>
#include <sys/ipc.h>
/* When not using soft mmu, libc independant functions are needed for /* When not using soft mmu, libc independant functions are needed for
the CPU core because it needs to use alternates stacks and the CPU core because it needs to use alternates stacks and
libc/thread incompatibles settings */ libc/thread incompatibles settings */

44
oss.c
View File

@ -21,6 +21,9 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include "vl.h"
#ifndef _WIN32
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
@ -33,7 +36,6 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <sys/soundcard.h> #include <sys/soundcard.h>
#include "vl.h"
/* http://www.df.lth.se/~john_e/gems/gem002d.html */ /* http://www.df.lth.se/~john_e/gems/gem002d.html */
/* http://www.multi-platforms.com/Tips/PopCount.htm */ /* http://www.multi-platforms.com/Tips/PopCount.htm */
@ -510,3 +512,43 @@ void AUD_init (void)
conf_fragsize = lsbindex (fsp); conf_fragsize = lsbindex (fsp);
} }
#else
void AUD_run (void)
{
}
int AUD_write (void *in_buf, int size)
{
return 0;
}
void AUD_reset (int rfreq, int rnchannels, audfmt_e rfmt)
{
}
void AUD_adjust_estimate (int _leftover)
{
}
int AUD_get_free (void)
{
return 0;
}
int AUD_get_live (void)
{
return 0;
}
int AUD_get_buffer_size (void)
{
return 0;
}
void AUD_init (void)
{
}
#endif

View File

@ -28,16 +28,11 @@
#include <getopt.h> #include <getopt.h>
#include <inttypes.h> #include <inttypes.h>
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
#include <time.h> #include <time.h>
#include <sys/time.h> #include <sys/time.h>
#include <malloc.h>
#include <termios.h>
#include <sys/poll.h>
#include <errno.h> #include <errno.h>
#include <sys/wait.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <netinet/in.h> #include <netinet/in.h>

29
sdl.c
View File

@ -21,31 +21,13 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include <stdlib.h> #include "vl.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 <SDL.h> #include <SDL.h>
#include "cpu.h" #ifndef _WIN32
#include "exec-all.h" #include <signal.h>
#endif
#include "vl.h"
static SDL_Surface *screen; static SDL_Surface *screen;
static int gui_grab; /* if true, all keyboard/mouse events are grabbed */ static int gui_grab; /* if true, all keyboard/mouse events are grabbed */
@ -291,9 +273,12 @@ void sdl_display_init(DisplayState *ds)
fprintf(stderr, "Could not initialize SDL - exiting\n"); fprintf(stderr, "Could not initialize SDL - exiting\n");
exit(1); exit(1);
} }
#ifndef _WIN32
/* NOTE: we still want Ctrl-C to work, so we undo the SDL redirections */ /* NOTE: we still want Ctrl-C to work, so we undo the SDL redirections */
signal(SIGINT, SIG_DFL); signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL); signal(SIGQUIT, SIG_DFL);
#endif
ds->dpy_update = sdl_update; ds->dpy_update = sdl_update;
ds->dpy_resize = sdl_resize; ds->dpy_resize = sdl_resize;

View File

@ -24,7 +24,6 @@
#include <inttypes.h> #include <inttypes.h>
#include <signal.h> #include <signal.h>
#include <assert.h> #include <assert.h>
#include <sys/mman.h>
#include "cpu.h" #include "cpu.h"
#include "exec-all.h" #include "exec-all.h"
@ -334,7 +333,7 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr,
if (!(env->cr[0] & CR0_PG_MASK)) { if (!(env->cr[0] & CR0_PG_MASK)) {
pte = addr; pte = addr;
virt_addr = addr & TARGET_PAGE_MASK; virt_addr = addr & TARGET_PAGE_MASK;
prot = PROT_READ | PROT_WRITE; prot = PAGE_READ | PAGE_WRITE;
page_size = 4096; page_size = 4096;
goto do_mapping; goto do_mapping;
} }
@ -409,17 +408,17 @@ int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr,
} }
/* the page can be put in the TLB */ /* the page can be put in the TLB */
prot = PROT_READ; prot = PAGE_READ;
if (pte & PG_DIRTY_MASK) { if (pte & PG_DIRTY_MASK) {
/* only set write access if already dirty... otherwise wait /* only set write access if already dirty... otherwise wait
for dirty access */ for dirty access */
if (is_user) { if (is_user) {
if (ptep & PG_RW_MASK) if (ptep & PG_RW_MASK)
prot |= PROT_WRITE; prot |= PAGE_WRITE;
} else { } else {
if (!(env->cr[0] & CR0_WP_MASK) || if (!(env->cr[0] & CR0_WP_MASK) ||
(ptep & PG_RW_MASK)) (ptep & PG_RW_MASK))
prot |= PROT_WRITE; prot |= PAGE_WRITE;
} }
} }

View File

@ -17,15 +17,14 @@
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "config.h"
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <inttypes.h> #include <inttypes.h>
#include <signal.h>
#include <assert.h> #include <assert.h>
#include <sys/mman.h>
#include <sys/ucontext.h>
#include "cpu.h" #include "cpu.h"
#include "exec-all.h" #include "exec-all.h"
@ -33,6 +32,10 @@
#ifdef USE_CODE_COPY #ifdef USE_CODE_COPY
#include <signal.h>
#include <sys/mman.h>
#include <sys/ucontext.h>
extern char exec_loop; extern char exec_loop;
/* operand size */ /* operand size */

View File

@ -24,7 +24,6 @@
#include <inttypes.h> #include <inttypes.h>
#include <signal.h> #include <signal.h>
#include <assert.h> #include <assert.h>
#include <sys/mman.h>
#include "cpu.h" #include "cpu.h"
#include "exec-all.h" #include "exec-all.h"

185
vl.c
View File

@ -21,35 +21,40 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE. * THE SOFTWARE.
*/ */
#include <stdlib.h> #include "vl.h"
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <getopt.h> #include <getopt.h>
#include <inttypes.h>
#include <unistd.h> #include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
#include <time.h> #include <time.h>
#include <sys/time.h>
#include <malloc.h> #include <malloc.h>
#include <termios.h>
#include <sys/poll.h>
#include <errno.h> #include <errno.h>
#include <sys/time.h>
#ifndef _WIN32
#include <sys/times.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <pty.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/ioctl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <linux/if.h> #include <linux/if.h>
#include <linux/if_tun.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 "disas.h"
#include "vl.h"
#include "exec-all.h" #include "exec-all.h"
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" #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; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
return tv.tv_sec * 1000000LL + tv.tv_usec; return tv.tv_sec * 1000000LL + tv.tv_usec;
#endif
} }
void cpu_calibrate_ticks(void) void cpu_calibrate_ticks(void)
@ -388,7 +399,11 @@ void cpu_calibrate_ticks(void)
usec = get_clock(); usec = get_clock();
ticks = cpu_get_real_ticks(); ticks = cpu_get_real_ticks();
#ifdef _WIN32
Sleep(50);
#else
usleep(50 * 1000); usleep(50 * 1000);
#endif
usec = get_clock() - usec; usec = get_clock() - usec;
ticks = cpu_get_real_ticks() - ticks; ticks = cpu_get_real_ticks() - ticks;
ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec; ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec;
@ -438,8 +453,10 @@ QEMUClock *rt_clock;
QEMUClock *vm_clock; QEMUClock *vm_clock;
static QEMUTimer *active_timers[2]; static QEMUTimer *active_timers[2];
#ifndef _WIN32
/* frequency of the times() clock tick */ /* frequency of the times() clock tick */
static int timer_freq; static int timer_freq;
#endif
QEMUClock *qemu_new_clock(int type) QEMUClock *qemu_new_clock(int type)
{ {
@ -550,12 +567,16 @@ int64_t qemu_get_clock(QEMUClock *clock)
{ {
switch(clock->type) { switch(clock->type) {
case QEMU_TIMER_REALTIME: case QEMU_TIMER_REALTIME:
#ifdef _WIN32
return GetTickCount();
#else
/* XXX: portability among Linux hosts */ /* XXX: portability among Linux hosts */
if (timer_freq == 100) { if (timer_freq == 100) {
return times(NULL) * 10; return times(NULL) * 10;
} else { } else {
return ((int64_t)times(NULL) * 1000) / timer_freq; return ((int64_t)times(NULL) * 1000) / timer_freq;
} }
#endif
default: default:
case QEMU_TIMER_VIRTUAL: case QEMU_TIMER_VIRTUAL:
return cpu_get_ticks(); return cpu_get_ticks();
@ -608,7 +629,12 @@ static int timer_load(QEMUFile *f, void *opaque, int version_id)
return 0; 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) static void host_alarm_handler(int host_signum)
#endif
{ {
if (qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL], if (qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],
qemu_get_clock(vm_clock)) || qemu_get_clock(vm_clock)) ||
@ -621,39 +647,66 @@ static void host_alarm_handler(int host_signum)
static void init_timers(void) 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); rt_clock = qemu_new_clock(QEMU_TIMER_REALTIME);
vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL); vm_clock = qemu_new_clock(QEMU_TIMER_VIRTUAL);
/* timer signal */ #ifdef _WIN32
sigfillset(&act.sa_mask); {
act.sa_flags = 0; 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) #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 #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 */ /* serial device */
#ifdef _WIN32
int serial_open_device(void)
{
return -1;
}
#else
int serial_open_device(void) int serial_open_device(void)
{ {
char slave_name[1024]; char slave_name[1024];
@ -672,9 +725,24 @@ int serial_open_device(void)
} }
} }
#endif
/***********************************************************/ /***********************************************************/
/* Linux network device redirector */ /* 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) static int tun_open(char *ifname, int ifname_size)
{ {
struct ifreq ifr; struct ifreq ifr;
@ -753,9 +821,23 @@ void net_send_packet(NetDriverState *nd, const uint8_t *buf, int size)
write(nd->fd, buf, size); write(nd->fd, buf, size);
} }
#endif
/***********************************************************/ /***********************************************************/
/* dumb display */ /* dumb display */
#ifdef _WIN32
static void term_exit(void)
{
}
static void term_init(void)
{
}
#else
/* init terminal so that we can grab keys */ /* init terminal so that we can grab keys */
static struct termios oldtty; static struct termios oldtty;
@ -790,6 +872,8 @@ static void term_init(void)
fcntl(0, F_SETFL, O_NONBLOCK); fcntl(0, F_SETFL, O_NONBLOCK);
} }
#endif
static void dumb_update(DisplayState *ds, int x, int y, int w, int h) 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) int main_loop(void)
{ {
#ifndef _WIN32
struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf; struct pollfd ufds[MAX_IO_HANDLERS + 1], *pf;
int ret, n, timeout, max_size;
uint8_t buf[4096];
IOHandlerRecord *ioh, *ioh_next; IOHandlerRecord *ioh, *ioh_next;
uint8_t buf[4096];
int n, max_size;
#endif
int ret, timeout;
CPUState *env = global_env; CPUState *env = global_env;
for(;;) { for(;;) {
@ -1422,6 +1509,7 @@ int main_loop(void)
timeout = 10; timeout = 10;
} }
#ifndef _WIN32
/* poll any events */ /* poll any events */
/* XXX: separate device handlers from system ones */ /* XXX: separate device handlers from system ones */
pf = ufds; pf = ufds;
@ -1471,6 +1559,7 @@ int main_loop(void)
} }
} }
} }
#endif
if (vm_running) { if (vm_running) {
qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL], qemu_run_timers(&active_timers[QEMU_TIMER_VIRTUAL],
@ -1592,7 +1681,10 @@ static uint8_t *signal_stack;
int main(int argc, char **argv) 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; int snapshot, linux_boot;
CPUState *env; CPUState *env;
const char *initrd_filename; const char *initrd_filename;
@ -1601,8 +1693,10 @@ int main(int argc, char **argv)
DisplayState *ds = &display_state; DisplayState *ds = &display_state;
int cyls, heads, secs; int cyls, heads, secs;
#if !defined(CONFIG_SOFTMMU)
/* we never want that malloc() uses mmap() */ /* we never want that malloc() uses mmap() */
mallopt(M_MMAP_THRESHOLD, 4096 * 1024); mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
#endif
initrd_filename = NULL; initrd_filename = NULL;
for(i = 0; i < MAX_FD; i++) for(i = 0; i < MAX_FD; i++)
fd_filename[i] = NULL; fd_filename[i] = NULL;
@ -1611,8 +1705,10 @@ int main(int argc, char **argv)
ram_size = 32 * 1024 * 1024; ram_size = 32 * 1024 * 1024;
vga_ram_size = VGA_RAM_SIZE; vga_ram_size = VGA_RAM_SIZE;
pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT); pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
#ifdef CONFIG_GDBSTUB
use_gdbstub = 0; use_gdbstub = 0;
gdbstub_port = DEFAULT_GDBSTUB_PORT; gdbstub_port = DEFAULT_GDBSTUB_PORT;
#endif
snapshot = 0; snapshot = 0;
nographic = 0; nographic = 0;
kernel_filename = NULL; kernel_filename = NULL;
@ -1773,12 +1869,14 @@ int main(int argc, char **argv)
case 'n': case 'n':
pstrcpy(network_script, sizeof(network_script), optarg); pstrcpy(network_script, sizeof(network_script), optarg);
break; break;
#ifdef CONFIG_GDBSTUB
case 's': case 's':
use_gdbstub = 1; use_gdbstub = 1;
break; break;
case 'p': case 'p':
gdbstub_port = atoi(optarg); gdbstub_port = atoi(optarg);
break; break;
#endif
case 'L': case 'L':
bios_dir = optarg; bios_dir = optarg;
break; break;
@ -1976,6 +2074,7 @@ int main(int argc, char **argv)
} }
#endif #endif
#ifndef _WIN32
{ {
struct sigaction act; struct sigaction act;
sigfillset(&act.sa_mask); sigfillset(&act.sa_mask);
@ -1983,10 +2082,12 @@ int main(int argc, char **argv)
act.sa_handler = SIG_IGN; act.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &act, NULL); sigaction(SIGPIPE, &act, NULL);
} }
#endif
gui_timer = qemu_new_timer(rt_clock, gui_update, NULL); gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock)); qemu_mod_timer(gui_timer, qemu_get_clock(rt_clock));
#ifdef CONFIG_GDBSTUB
if (use_gdbstub) { if (use_gdbstub) {
if (gdbserver_start(gdbstub_port) < 0) { if (gdbserver_start(gdbstub_port) < 0) {
fprintf(stderr, "Could not open gdbserver socket on port %d\n", fprintf(stderr, "Could not open gdbserver socket on port %d\n",
@ -1995,7 +2096,9 @@ int main(int argc, char **argv)
} else { } else {
printf("Waiting gdb connection on port %d\n", gdbstub_port); printf("Waiting gdb connection on port %d\n", gdbstub_port);
} }
} else { } else
#endif
{
vm_start(); vm_start();
} }
term_init(); term_init();

69
vl.h
View File

@ -24,10 +24,79 @@
#ifndef VL_H #ifndef VL_H
#define VL_H #define VL_H
/* we put basic includes here to avoid repeating them in device drivers */
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <inttypes.h>
#include <time.h> #include <time.h>
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
#ifdef _WIN32
#define lseek64 lseek
#endif
#include "cpu.h" #include "cpu.h"
#ifndef glue
#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
#define stringify(s) tostring(s)
#define tostring(s) #s
#endif
#if defined(WORDS_BIGENDIAN)
static inline uint32_t be32_to_cpu(uint32_t v)
{
return v;
}
static inline uint16_t be16_to_cpu(uint16_t v)
{
return v;
}
static inline uint32_t le32_to_cpu(uint32_t v)
{
return bswap32(v);
}
static inline uint16_t le16_to_cpu(uint16_t v)
{
return bswap16(v);
}
#else
static inline uint32_t be32_to_cpu(uint32_t v)
{
return bswap32(v);
}
static inline uint16_t be16_to_cpu(uint16_t v)
{
return bswap16(v);
}
static inline uint32_t le32_to_cpu(uint32_t v)
{
return v;
}
static inline uint16_t le16_to_cpu(uint16_t v)
{
return v;
}
#endif
/* vl.c */ /* vl.c */
extern int reset_requested; extern int reset_requested;