diff -ur qemu-0.12.1-org/block/vvfat.c qemu-0.12.1/block/vvfat.c --- qemu-0.12.1-org/block/vvfat.c Sun Dec 20 10:32:16 2009 +++ qemu-0.12.1/block/vvfat.c Sat Jan 16 23:34:49 2010 @@ -816,6 +816,9 @@ static inline uint32_t sector2cluster(BDRVVVFATState* s,off_t sector_num) { + if (sector_num < s->faked_sectors) { + return 0; + } return (sector_num-s->faked_sectors)/s->sectors_per_cluster; } diff -ur qemu-0.12.1-org/configure qemu-0.12.1/configure --- qemu-0.12.1-org/configure Sun Dec 20 10:32:16 2009 +++ qemu-0.12.1/configure Sat Jan 16 23:34:49 2010 @@ -275,13 +275,13 @@ CYGWIN*) mingw32="yes" QEMU_CFLAGS="-mno-cygwin $QEMU_CFLAGS" - audio_possible_drivers="winwave sdl" + audio_possible_drivers="winwave dsound sdl fmod" audio_drv_list="winwave" ;; MINGW32*) mingw32="yes" audio_possible_drivers="winwave dsound sdl fmod" - audio_drv_list="winwave" + audio_drv_list="winwave dsound sdl fmod" ;; GNU/kFreeBSD) bsd="yes" diff -ur qemu-0.12.1-org/hw/cirrus_vga.c qemu-0.12.1/hw/cirrus_vga.c --- qemu-0.12.1-org/hw/cirrus_vga.c Sun Dec 20 10:32:16 2009 +++ qemu-0.12.1/hw/cirrus_vga.c Sat Jan 16 23:34:49 2010 @@ -174,6 +174,7 @@ #define CIRRUS_PNPMMIO_SIZE 0x1000 +#if 0 #define ABS(a) ((signed)(a) > 0 ? a : -a) #define BLTUNSAFE(s) \ @@ -189,6 +190,7 @@ (s)->vga.vram_size \ ) \ ) +#endif struct CirrusVGAState; typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s, @@ -250,6 +252,56 @@ static uint8_t rop_to_index[256]; +inline static int ABS (int n) +{ + return n >= 0 ? n : -n; +} + +inline static int BLTUNSAFE_debug (CirrusVGAState *s, + const char *funcname, + int lineno) +{ + int is_unsafe; + int srccount, dstcount; + uint32_t srcaddr, dstaddr; + +#if defined(DEBUG_BITBLT) + if (!s) { + printf("BLTUNSAFE line %d (%s) - null pointer\n", lineno, funcname); + return !0; + } +#endif + + srccount = ABS(s->cirrus_blt_srcpitch) * s->cirrus_blt_height; + dstcount = ABS(s->cirrus_blt_dstpitch) * s->cirrus_blt_height; + srcaddr = s->cirrus_blt_srcaddr & s->cirrus_addr_mask; + dstaddr = s->cirrus_blt_dstaddr & s->cirrus_addr_mask; + + is_unsafe = dstaddr + dstcount > s->vga.vram_size || + srcaddr + srccount > s->vga.vram_size; + +#ifdef DEBUG_BITBLT + { +#else + if (is_unsafe) { +#endif + printf("BLTUNSAFE line %d (%s)", lineno, funcname); + printf(" - %ssafe\n", is_unsafe ? "un" : ""); + printf(" srcaddr=%08x srcpitch=%d dstaddr=%08x dstpitch=%d" + " blt_height=%d\n", + s->cirrus_blt_srcaddr, s->cirrus_blt_srcpitch, + s->cirrus_blt_dstaddr, s->cirrus_blt_dstpitch, + s->cirrus_blt_height ); + } + + return is_unsafe; +} +#if defined(__GNUC__) +#define BLTUNSAFE(s) BLTUNSAFE_debug(s, __FUNCTION__,__LINE__) +#else +#define BLTUNSAFE(s) BLTUNSAFE_debug(s,"???",__LINE__) +#endif + /*************************************** * * prototypes. @@ -679,7 +731,7 @@ int depth; int notify = 0; - depth = s->vga.get_bpp(&s->vga) / 8; + depth = (s->vga.get_bpp(&s->vga) + 7) / 8; s->vga.get_resolution(&s->vga, &width, &height); /* extra x, y */ @@ -882,7 +934,7 @@ s->cirrus_blt_width = (s->vga.gr[0x20] | (s->vga.gr[0x21] << 8)) + 1; s->cirrus_blt_height = (s->vga.gr[0x22] | (s->vga.gr[0x23] << 8)) + 1; s->cirrus_blt_dstpitch = (s->vga.gr[0x24] | (s->vga.gr[0x25] << 8)); - s->cirrus_blt_srcpitch = (s->vga.gr[0x26] | (s->vga.gr[0x27] << 8)); + // s->cirrus_blt_srcpitch = (s->vga.gr[0x26] | (s->vga.gr[0x27] << 8)); s->cirrus_blt_dstaddr = (s->vga.gr[0x28] | (s->vga.gr[0x29] << 8) | (s->vga.gr[0x2a] << 16)); s->cirrus_blt_srcaddr = @@ -891,6 +943,17 @@ s->cirrus_blt_modeext = s->vga.gr[0x33]; blt_rop = s->vga.gr[0x32]; + if ((s->cirrus_blt_mode & 0x80) == 0x80) { + /* special case (bitblt with color expantion) */ + /* source pitch (GR26, GR27) is 'don't care'. */ + int width, height, depth; + depth = (s->vga.get_bpp(&s->vga) + 7) / 8; + s->vga.get_resolution(&s->vga, &width, &height); + s->cirrus_blt_srcpitch = width * depth; + } else { + s->cirrus_blt_srcpitch = s->vga.gr[0x26] | (s->vga.gr[0x27] << 8); + } + #ifdef DEBUG_BITBLT printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n", blt_rop, @@ -1000,6 +1063,7 @@ } } // setup bitblt engine. + cirrus_update_memory_access(s); if (s->cirrus_blt_mode & CIRRUS_BLTMODE_MEMSYSSRC) { if (!cirrus_bitblt_cputovideo(s)) goto bitblt_ignore; @@ -2556,6 +2620,12 @@ s->vga.map_addr = s->vga.lfb_addr; s->vga.map_end = s->vga.lfb_end; cpu_register_physical_memory(s->vga.map_addr, s->vga.map_end - s->vga.map_addr, s->vga.vram_offset); + } else { + if (s->vga.lfb_addr && s->vga.lfb_end > s->vga.lfb_addr) { + cpu_register_physical_memory(s->vga.lfb_addr, + s->vga.lfb_end - s->vga.lfb_addr, + s->cirrus_linear_io_addr); + } } if (!s->vga.map_addr) @@ -2588,8 +2658,14 @@ if (s->vga.map_addr && s->vga.lfb_addr && s->vga.lfb_end) s->vga.map_addr = s->vga.map_end = 0; + s->vga.lfb_vram_mapped = 0; cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000, s->vga.vga_io_memory); + if (s->vga.lfb_addr && s->vga.lfb_end > s->vga.lfb_addr) { + cpu_register_physical_memory(s->vga.lfb_addr, + s->vga.lfb_end - s->vga.lfb_addr, + s->cirrus_linear_io_addr); + } } /* Compute the memory access functions */ diff -ur qemu-0.12.1-org/hw/cirrus_vga_rop.h qemu-0.12.1/hw/cirrus_vga_rop.h --- qemu-0.12.1-org/hw/cirrus_vga_rop.h Sun Dec 20 10:32:16 2009 +++ qemu-0.12.1/hw/cirrus_vga_rop.h Sat Jan 16 23:34:49 2010 @@ -32,10 +32,13 @@ dstpitch -= bltwidth; srcpitch -= bltwidth; + /* srcpitch and dstpitch could be nagative. */ +#if 0 if (dstpitch < 0 || srcpitch < 0) { /* is 0 valid? srcpitch == 0 could be useful */ return; } +#endif for (y = 0; y < bltheight; y++) { for (x = 0; x < bltwidth; x++) { diff -ur qemu-0.12.1-org/net/socket.c qemu-0.12.1/net/socket.c --- qemu-0.12.1-org/net/socket.c Sun Dec 20 10:32:24 2009 +++ qemu-0.12.1/net/socket.c Sat Jan 16 23:34:49 2010 @@ -40,6 +40,9 @@ unsigned int packet_len; uint8_t buf[4096]; struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */ +#ifdef _WIN32 + WSAEVENT hEvent; +#endif } NetSocketState; typedef struct NetSocketListenState { @@ -47,8 +50,66 @@ char *model; char *name; int fd; +#ifdef _WIN32 + WSAEVENT hEvent; +#endif } NetSocketListenState; +#ifdef _WIN32 +#define FD_NOEVENT FD_MAX_EVENTS + 1 /* used for already connected */ + +static int net_socket_set_event(SOCKET fd, WSAEVENT hEvent, int fd_events) +{ + int ret; + + ret = WSAEventSelect(fd, hEvent, fd_events); + if (ret == SOCKET_ERROR) { + perror("connect: EventSelect"); + return -1; + } + return 0; +} + +static int net_socket_enum_event(SOCKET fd, WSAEVENT hEvent) +{ + WSANETWORKEVENTS events; + int ret; + + ret = WSAEnumNetworkEvents(fd, hEvent, &events); + if (ret == SOCKET_ERROR) { + perror("EnumNetworkEvents"); + } else { + if (events.lNetworkEvents & FD_READ) { + if (events.iErrorCode[FD_READ_BIT] == 0) { + return FD_READ; + } else { + perror("fd_read: refused"); + return -1; + } + } else if (events.lNetworkEvents & FD_ACCEPT) { + if (events.iErrorCode[FD_ACCEPT_BIT] == 0) { + return FD_ACCEPT; + } else { + perror("fd_accept: refused"); + return -1; + } + } else if (events.lNetworkEvents & FD_CONNECT) { + if (events.iErrorCode[FD_CONNECT_BIT] == 0) { + return FD_CONNECT; + } else { + perror("fd_connect: refused"); + return -1; + } + } else if (events.lNetworkEvents & FD_CLOSE) { + return FD_CLOSE; + } else { + return FD_NOEVENT; + } + } + return -1; +} +#endif + /* XXX: we consider we can send the whole packet without blocking */ static ssize_t net_socket_receive(VLANClientState *nc, const uint8_t *buf, size_t size) { @@ -75,7 +136,18 @@ unsigned l; uint8_t buf1[4096]; const uint8_t *buf; +#ifdef _WIN32 + int ret; + ret = net_socket_enum_event(s->fd, s->hEvent); + if (ret == FD_CLOSE) { + qemu_del_wait_object(s->hEvent, NULL, NULL); + WSACloseEvent(s->hEvent); + closesocket(s->fd); + return; + } else if (ret != FD_READ) + return; +#endif size = recv(s->fd, (void *)buf1, sizeof(buf1), 0); if (size < 0) { err = socket_error(); @@ -137,7 +209,13 @@ { NetSocketState *s = opaque; int size; +#ifdef _WIN32 + int ret; + ret = net_socket_enum_event(s->fd, s->hEvent); + if (ret != FD_READ) + return; +#endif size = recv(s->fd, (void *)s->buf, sizeof(s->buf), 0); if (size < 0) return; @@ -153,7 +231,9 @@ { struct ip_mreq imr; int fd; - int val, ret; + int val, ret, err; + struct sockaddr_in addr; + if (!IN_MULTICAST(ntohl(mcastaddr->sin_addr.s_addr))) { fprintf(stderr, "qemu: error: specified mcastaddr \"%s\" (0x%08x) does not contain a multicast address\n", inet_ntoa(mcastaddr->sin_addr), @@ -161,7 +241,11 @@ return -1; } +#ifdef _WIN32 + fd = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); +#else fd = qemu_socket(PF_INET, SOCK_DGRAM, 0); +#endif if (fd < 0) { perror("socket(PF_INET, SOCK_DGRAM)"); return -1; @@ -177,8 +261,22 @@ ret = bind(fd, (struct sockaddr *)mcastaddr, sizeof(*mcastaddr)); if (ret < 0) { - perror("bind"); - goto fail; + err = socket_error(); + if (err == EADDRNOTAVAIL) { + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = mcastaddr->sin_port; + addr.sin_addr.s_addr = INADDR_ANY; + + ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (ret < 0) { + perror("bind"); + goto fail; + } + } else { + perror("bind"); + goto fail; + } } /* Add host to multicast group */ @@ -233,6 +331,9 @@ socklen_t saddr_len; VLANClientState *nc; NetSocketState *s; +#ifdef _WIN32 + int ret; +#endif /* fd passed: multicast: "learn" dgram_dst address from bound address and save it * Because this may be "shared" socket from a "master" process, datagrams would be recv() @@ -276,7 +377,23 @@ s->fd = fd; +#ifdef _WIN32 + s->hEvent = WSACreateEvent(); + if (s->hEvent == WSA_INVALID_EVENT) { + closesocket(fd); + return NULL; + } + ret = net_socket_set_event(s->fd, s->hEvent, FD_READ); + if (ret < 0) { + perror("dgram: set_event"); + WSACloseEvent(s->hEvent); + closesocket(fd); + return NULL; + } + qemu_add_wait_object(s->hEvent, net_socket_send_dgram, s); +#else qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s); +#endif /* mcast: save bound address as dst */ if (is_connected) s->dgram_dst=saddr; @@ -287,7 +404,21 @@ static void net_socket_connect(void *opaque) { NetSocketState *s = opaque; +#ifdef _WIN32 + int ret; + + ret = net_socket_enum_event(s->fd, s->hEvent); + if (ret != FD_CONNECT && ret != FD_NOEVENT) + return; + qemu_del_wait_object(s->hEvent, NULL, NULL); + WSAResetEvent(s->hEvent); + ret = net_socket_set_event(s->fd, s->hEvent, FD_READ | FD_CLOSE); + if (ret < 0) + return; + qemu_add_wait_object(s->hEvent, net_socket_send, s); +#else qemu_set_fd_handler(s->fd, net_socket_send, NULL, s); +#endif } static NetClientInfo net_socket_info = { @@ -300,7 +431,8 @@ static NetSocketState *net_socket_fd_init_stream(VLANState *vlan, const char *model, const char *name, - int fd, int is_connected) + int fd, int is_connected, + void *opaque) { VLANClientState *nc; NetSocketState *s; @@ -312,18 +444,27 @@ s = DO_UPCAST(NetSocketState, nc, nc); s->fd = fd; +#ifdef _WIN32 + if (opaque) + s->hEvent = *(WSAEVENT *)opaque; +#endif if (is_connected) { net_socket_connect(s); } else { +#ifdef _WIN32 + qemu_add_wait_object(s->hEvent, net_socket_connect, s); +#else qemu_set_fd_handler(s->fd, NULL, net_socket_connect, s); +#endif } return s; } static NetSocketState *net_socket_fd_init(VLANState *vlan, const char *model, const char *name, - int fd, int is_connected) + int fd, int is_connected, + void *opaque) { int so_type = -1, optlen=sizeof(so_type); @@ -336,11 +477,11 @@ case SOCK_DGRAM: return net_socket_fd_init_dgram(vlan, model, name, fd, is_connected); case SOCK_STREAM: - return net_socket_fd_init_stream(vlan, model, name, fd, is_connected); + return net_socket_fd_init_stream(vlan, model, name, fd, is_connected, opaque); default: /* who knows ... this could be a eg. a pty, do warn and continue as stream */ fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd); - return net_socket_fd_init_stream(vlan, model, name, fd, is_connected); + return net_socket_fd_init_stream(vlan, model, name, fd, is_connected, opaque); } return NULL; } @@ -352,17 +493,39 @@ struct sockaddr_in saddr; socklen_t len; int fd; +#ifdef _WIN32 + int ret; + WSAEVENT hEvent; + + ret = net_socket_enum_event(s->fd, s->hEvent); + if (ret != FD_ACCEPT) + return; +#endif for(;;) { len = sizeof(saddr); +#ifdef _WIN32 + fd = accept(s->fd, (struct sockaddr *)&saddr, &len); +#else fd = qemu_accept(s->fd, (struct sockaddr *)&saddr, &len); +#endif if (fd < 0 && errno != EINTR) { return; } else if (fd >= 0) { break; } } - s1 = net_socket_fd_init(s->vlan, s->model, s->name, fd, 1); +#ifdef _WIN32 + hEvent = WSACreateEvent(); + if (hEvent == WSA_INVALID_EVENT) { + perror("accept: CreateEvent"); + closesocket(fd); + return; + } + s1 = net_socket_fd_init(s->vlan, s->model, s->name, fd, 1, &hEvent); +#else + s1 = net_socket_fd_init(s->vlan, s->model, s->name, fd, 1, NULL); +#endif if (!s1) { closesocket(fd); } else { @@ -380,19 +543,41 @@ NetSocketListenState *s; int fd, val, ret; struct sockaddr_in saddr; +#ifdef _WIN32 + WSAEVENT hEvent; +#endif if (parse_host_port(&saddr, host_str) < 0) return -1; s = qemu_mallocz(sizeof(NetSocketListenState)); +#ifdef _WIN32 + fd = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); +#else fd = qemu_socket(PF_INET, SOCK_STREAM, 0); +#endif if (fd < 0) { perror("socket"); return -1; } socket_set_nonblock(fd); +#ifdef _WIN32 + hEvent = WSACreateEvent(); + if (hEvent == WSA_INVALID_EVENT) { + closesocket(fd); + return -1; + } + ret = net_socket_set_event(fd, hEvent, FD_ACCEPT); + if (ret < 0) { + perror("connect: set_event"); + WSACloseEvent(hEvent); + closesocket(fd); + return -1; + } +#endif + /* allow fast reuse */ val = 1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val)); @@ -411,7 +596,12 @@ s->model = qemu_strdup(model); s->name = name ? qemu_strdup(name) : NULL; s->fd = fd; +#ifdef _WIN32 + s->hEvent = hEvent; + qemu_add_wait_object(hEvent, net_socket_accept, s); +#else qemu_set_fd_handler(fd, net_socket_accept, NULL, s); +#endif return 0; } @@ -421,19 +611,45 @@ const char *host_str) { NetSocketState *s; +#ifdef _WIN32 + WSAEVENT hEvent; + int fd, connected, ret; +#else int fd, connected, ret, err; +#endif struct sockaddr_in saddr; if (parse_host_port(&saddr, host_str) < 0) return -1; +#ifdef _WIN32 + fd = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); +#else fd = qemu_socket(PF_INET, SOCK_STREAM, 0); +#endif if (fd < 0) { perror("socket"); return -1; } socket_set_nonblock(fd); +#ifdef _WIN32 + hEvent = WSACreateEvent(); + if (hEvent == WSA_INVALID_EVENT) { + closesocket(fd); + return -1; + } + ret = net_socket_set_event(fd, hEvent, FD_CONNECT); + if (ret < 0) { + perror("connect: set_event"); + WSACloseEvent(hEvent); + closesocket(fd); + return -1; + } + connected = 0; + ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); + s = net_socket_fd_init(vlan, model, name, fd, connected, &hEvent); +#else connected = 0; for(;;) { ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); @@ -442,10 +658,6 @@ if (err == EINTR || err == EWOULDBLOCK) { } else if (err == EINPROGRESS) { break; -#ifdef _WIN32 - } else if (err == WSAEALREADY) { - break; -#endif } else { perror("connect"); closesocket(fd); @@ -456,7 +668,9 @@ break; } } - s = net_socket_fd_init(vlan, model, name, fd, connected); + s = net_socket_fd_init(vlan, model, name, fd, connected, NULL); +#endif + if (!s) return -1; snprintf(s->nc.info_str, sizeof(s->nc.info_str), @@ -482,7 +696,7 @@ if (fd < 0) return -1; - s = net_socket_fd_init(vlan, model, name, fd, 0); + s = net_socket_fd_init(vlan, model, name, fd, 0, NULL); if (!s) return -1; @@ -515,7 +729,7 @@ return -1; } - if (!net_socket_fd_init(vlan, "socket", name, fd, 1)) { + if (!net_socket_fd_init(vlan, "socket", name, fd, 1, NULL)) { close(fd); return -1; } diff -ur qemu-0.12.1-org/osdep.c qemu-0.12.1/osdep.c --- qemu-0.12.1-org/osdep.c Sun Dec 20 10:32:24 2009 +++ qemu-0.12.1/osdep.c Sat Jan 16 23:34:49 2010 @@ -125,8 +125,10 @@ if (fd == -1) return -1; +#ifndef __CYGWIN__ if (lockf(fd, F_TLOCK, 0) == -1) return -1; +#endif len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid()); if (write(fd, buffer, len) != len) @@ -162,6 +164,16 @@ } #ifdef _WIN32 +int ffs(int i) +{ + int bit; + for(bit = 0; bit < 32; bit++) { + if(i & (1 << bit)) { + return bit + 1; + } + } + return 0; +} /* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */ #define _W32_FT_OFFSET (116444736000000000ULL) diff -ur qemu-0.12.1-org/qemu_socket.h qemu-0.12.1/qemu_socket.h --- qemu-0.12.1-org/qemu_socket.h Sun Dec 20 10:32:28 2009 +++ qemu-0.12.1/qemu_socket.h Sat Jan 16 23:34:49 2010 @@ -12,6 +12,7 @@ #define EWOULDBLOCK WSAEWOULDBLOCK #define EINTR WSAEINTR #define EINPROGRESS WSAEINPROGRESS +#define EADDRNOTAVAIL WSAEADDRNOTAVAIL int inet_aton(const char *cp, struct in_addr *ia); diff -ur qemu-0.12.1-org/x_keymap.c qemu-0.12.1/x_keymap.c --- qemu-0.12.1-org/x_keymap.c Sun Dec 20 10:32:34 2009 +++ qemu-0.12.1/x_keymap.c Sat Jan 16 23:36:23 2010 @@ -94,7 +94,7 @@ */ static const uint8_t evdev_keycode_to_pc_keycode[61] = { - 0, /* 97 EVDEV - RO ("Internet" Keyboards) */ + 0x73, /* 97 EVDEV - RO ("Internet" Keyboards) */ 0, /* 98 EVDEV - KATA (Katakana) */ 0, /* 99 EVDEV - HIRA (Hiragana) */ 0x79, /* 100 EVDEV - HENK (Henkan) */