diff options
Diffstat (limited to 'tools/ioemu')
-rw-r--r-- | tools/ioemu/Makefile.target | 43 | ||||
-rw-r--r-- | tools/ioemu/aes.c | 2 | ||||
-rw-r--r-- | tools/ioemu/block-raw.c | 33 | ||||
-rw-r--r-- | tools/ioemu/block-vbd.c | 345 | ||||
-rw-r--r-- | tools/ioemu/block.c | 3 | ||||
-rwxr-xr-x | tools/ioemu/configure | 22 | ||||
-rw-r--r-- | tools/ioemu/console.c | 6 | ||||
-rw-r--r-- | tools/ioemu/cpu-all.h | 10 | ||||
-rw-r--r-- | tools/ioemu/exec-all.h | 4 | ||||
-rw-r--r-- | tools/ioemu/hw/fdc.c | 7 | ||||
-rw-r--r-- | tools/ioemu/hw/ide.c | 4 | ||||
-rw-r--r-- | tools/ioemu/hw/pc.c | 11 | ||||
-rw-r--r-- | tools/ioemu/hw/scsi-disk.c | 8 | ||||
-rw-r--r-- | tools/ioemu/hw/usb-hid.c | 68 | ||||
-rw-r--r-- | tools/ioemu/hw/vga.c | 14 | ||||
-rw-r--r-- | tools/ioemu/hw/xen_console.c | 8 | ||||
-rw-r--r-- | tools/ioemu/hw/xen_machine_fv.c | 3 | ||||
-rw-r--r-- | tools/ioemu/hw/xenfb.c | 8 | ||||
-rw-r--r-- | tools/ioemu/osdep.c | 20 | ||||
-rw-r--r-- | tools/ioemu/osdep.h | 1 | ||||
-rw-r--r-- | tools/ioemu/sdl.c | 30 | ||||
-rw-r--r-- | tools/ioemu/target-i386-dm/cpu.h | 4 | ||||
-rw-r--r-- | tools/ioemu/target-i386-dm/helper2.c | 6 | ||||
-rw-r--r-- | tools/ioemu/vl.c | 161 | ||||
-rw-r--r-- | tools/ioemu/vl.h | 6 | ||||
-rw-r--r-- | tools/ioemu/vnc.c | 360 | ||||
-rw-r--r-- | tools/ioemu/vnchextile.h | 12 | ||||
-rw-r--r-- | tools/ioemu/xenstore.c | 19 |
28 files changed, 1012 insertions, 206 deletions
diff --git a/tools/ioemu/Makefile.target b/tools/ioemu/Makefile.target index ebd691b5f0..965d726adf 100644 --- a/tools/ioemu/Makefile.target +++ b/tools/ioemu/Makefile.target @@ -15,7 +15,7 @@ TARGET_BASE_ARCH:=sparc endif TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)$(TARGET_SUB) VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio -CPPFLAGS=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH) +CPPFLAGS+=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH) CPPFLAGS+= -I$(XEN_ROOT)/tools/libxc CPPFLAGS+= -I$(XEN_ROOT)/tools/xenstore CPPFLAGS+= -I$(XEN_ROOT)/tools/include @@ -66,7 +66,11 @@ else QEMU_SYSTEM=qemu-fast endif +ifdef CONFIG_STUBDOM +QEMU_SYSTEM=qemu.a +else QEMU_SYSTEM=qemu-dm +endif ifdef CONFIG_USER_ONLY PROGS=$(QEMU_USER) @@ -345,14 +349,25 @@ VL_OBJS=vl.o osdep.o readline.o monitor.o pci.o console.o isa_mmio.o VL_OBJS+=cutils.o VL_OBJS+=block.o block-raw.o VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o +ifdef CONFIG_STUBDOM +VL_OBJS+=block-vbd.o +endif ifdef CONFIG_WIN32 VL_OBJS+=tap-win32.o endif -ifeq (,$(wildcard /usr/include/pci)) +ifdef CONFIG_STUBDOM +CONFIG_PASSTHROUGH=1 +else + ifeq (,$(wildcard /usr/include/pci)) $(warning *** pciutils-devl package not found - missing /usr/include/pci) $(warning *** PCI passthrough capability has been disabled) -else + else +CONFIG_PASSTHROUGH=1 + endif +endif + +ifdef CONFIG_PASSTHROUGH LIBS+=-lpci VL_OBJS+= pass-through.o CFLAGS += -DCONFIG_PASSTHROUGH @@ -404,13 +419,13 @@ VL_OBJS+= ne2000.o rtl8139.o pcnet.o e100.o ifeq ($(TARGET_BASE_ARCH), i386) # Hardware support -VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) extboot.o +VL_OBJS+= ide.o pckbd.o ps2.o vga.o dma.o extboot.o ifeq ($(ARCH),ia64) VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o else VL_OBJS+= fdc.o serial.o pc.o endif -VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o +VL_OBJS+= cirrus_vga.o parallel.o acpi.o VL_OBJS+= usb-uhci.o smbus_eeprom.o VL_OBJS+= piix4acpi.o VL_OBJS+= xenstore.o @@ -419,22 +434,32 @@ VL_OBJS+= xen_machine_fv.o VL_OBJS+= xen_machine_pv.o VL_OBJS+= xenfb.o VL_OBJS+= xen_console.o +ifndef CONFIG_STUBDOM VL_OBJS+= tpm_tis.o +VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o +CPPFLAGS += -DHAS_TPM CPPFLAGS += -DHAS_AUDIO endif +endif ifeq ($(TARGET_BASE_ARCH), ppc) -VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) +VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o dma.o VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o +ifndef CONFIG_STUBDOM +VL_OBJS+= $(SOUND_HW) $(AUDIODRV) CPPFLAGS += -DHAS_AUDIO endif +endif ifeq ($(TARGET_ARCH), mips) VL_OBJS+= mips_r4k.o mips_malta.o mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o VL_OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o -VL_OBJS+= piix_pci.o parallel.o mixeng.o cirrus_vga.o $(SOUND_HW) $(AUDIODRV) +VL_OBJS+= piix_pci.o parallel.o mixeng.o cirrus_vga.o +ifndef CONFIG_STUBDOM +VL_OBJS+= $(SOUND_HW) $(AUDIODRV) DEFINES += -DHAS_AUDIO endif +endif ifeq ($(TARGET_BASE_ARCH), sparc) ifeq ($(TARGET_ARCH), sparc64) VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o apb_pci.o @@ -512,7 +537,11 @@ SDL_LIBS := $(filter-out -mwindows, $(SDL_LIBS)) -mconsole endif $(QEMU_SYSTEM): $(VL_OBJS) libqemu.a +ifdef CONFIG_STUBDOM + $(AR) rcs $@ $(VL_OBJS) +else $(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS) +endif cocoa.o: cocoa.m $(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $< diff --git a/tools/ioemu/aes.c b/tools/ioemu/aes.c index cd4484ff9b..e75b168a80 100644 --- a/tools/ioemu/aes.c +++ b/tools/ioemu/aes.c @@ -33,9 +33,11 @@ #define NDEBUG #include <assert.h> +#ifndef CONFIG_STUBDOM typedef uint32_t u32; typedef uint16_t u16; typedef uint8_t u8; +#endif #define MAXKC (256/32) #define MAXKB (256/8) diff --git a/tools/ioemu/block-raw.c b/tools/ioemu/block-raw.c index 68e8a370ca..182d2ec55e 100644 --- a/tools/ioemu/block-raw.c +++ b/tools/ioemu/block-raw.c @@ -25,7 +25,9 @@ #include "block_int.h" #include <assert.h> #ifndef _WIN32 +#ifndef NO_AIO #include <aio.h> +#endif #ifndef QEMU_TOOL #include "exec-all.h" @@ -167,10 +169,16 @@ static int raw_pread(BlockDriverState *bs, int64_t offset, } s->lseek_err_cnt=0; - ret = read(s->fd, buf, count); - if (ret == count) - goto label__raw_read__success; + uint64_t done; + for (done = 0; done < count; done += ret) { + ret = read(s->fd, buf + done, count - done); + if (ret == -1) + goto label__raw_read__error; + } + ret = count; + goto label__raw_read__success; +label__raw_read__error: DEBUG_BLOCK_PRINT("raw_read(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 "] read failed %d : %d = %s\n", s->fd, bs->filename, @@ -232,9 +240,16 @@ static int raw_pwrite(BlockDriverState *bs, int64_t offset, } s->lseek_err_cnt = 0; - ret = write(s->fd, buf, count); - if (ret == count) - goto label__raw_write__success; + uint64_t done; + for (done = 0; done < count; done += ret) { + ret = write(s->fd, buf + done, count - done); + if (ret == -1) + goto label__raw_write__error; + } + ret = count; + goto label__raw_write__success; + +label__raw_write__error: DEBUG_BLOCK_PRINT("raw_write(%d:%s, %" PRId64 ", %p, %d) [%" PRId64 "] write failed %d : %d = %s\n", s->fd, @@ -255,6 +270,7 @@ label__raw_write__success: /***********************************************************/ /* Unix AIO using POSIX AIO */ +#ifndef NO_AIO typedef struct RawAIOCB { BlockDriverAIOCB common; struct aiocb aiocb; @@ -480,6 +496,7 @@ static void raw_aio_cancel(BlockDriverAIOCB *blockacb) pacb = &acb->next; } } +#endif static void raw_close(BlockDriverState *bs) { @@ -600,10 +617,12 @@ BlockDriver bdrv_raw = { raw_create, raw_flush, +#ifndef NO_AIO .bdrv_aio_read = raw_aio_read, .bdrv_aio_write = raw_aio_write, .bdrv_aio_cancel = raw_aio_cancel, .aiocb_size = sizeof(RawAIOCB), +#endif .protocol_name = "file", .bdrv_pread = raw_pread, .bdrv_pwrite = raw_pwrite, @@ -936,10 +955,12 @@ BlockDriver bdrv_host_device = { NULL, raw_flush, +#ifndef NO_AIO .bdrv_aio_read = raw_aio_read, .bdrv_aio_write = raw_aio_write, .bdrv_aio_cancel = raw_aio_cancel, .aiocb_size = sizeof(RawAIOCB), +#endif .bdrv_pread = raw_pread, .bdrv_pwrite = raw_pwrite, .bdrv_getlength = raw_getlength, diff --git a/tools/ioemu/block-vbd.c b/tools/ioemu/block-vbd.c new file mode 100644 index 0000000000..937bb5e62d --- /dev/null +++ b/tools/ioemu/block-vbd.c @@ -0,0 +1,345 @@ +/* + * Block driver for Mini-os PV devices + * Based on block-raw.c + * + * Copyright (c) 2006 Fabrice Bellard, 2007 Samuel Thibault + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "vl.h" +#include "block_int.h" +#include <assert.h> +#include <xenbus.h> +#include <blkfront.h> +#include <malloc.h> + +#define SECTOR_SIZE 512 + +#ifndef QEMU_TOOL +#include "exec-all.h" +#endif + +#define DEBUG_BLOCK +#ifdef DEBUG_BLOCK +#define DEBUG_BLOCK_PRINT( formatCstr, args... ) fprintf( logfile, formatCstr, ##args ); fflush( logfile ) +#else +#define DEBUG_BLOCK_PRINT( formatCstr, args... ) +#endif + +#define FTYPE_FILE 0 +#define FTYPE_CD 1 +#define FTYPE_FD 2 + +typedef struct BDRVVbdState { + struct blkfront_dev *dev; + int fd; + int type; + int mode; + uint64_t sectors; + unsigned sector_size; + QEMU_LIST_ENTRY(BDRVVbdState) list; +} BDRVVbdState; + +QEMU_LIST_HEAD(, BDRVVbdState) vbds; + +static int vbd_probe(const uint8_t *buf, int buf_size, const char *filename) +{ + char *value; + if (xenbus_read(XBT_NIL, filename, &value)) + return 0; + free(value); + return 100; +} + +static void vbd_io_completed(void *opaque) +{ + BDRVVbdState *s = opaque; + blkfront_aio_poll(s->dev); +} + +static int vbd_open(BlockDriverState *bs, const char *filename, int flags) +{ + BDRVVbdState *s = bs->opaque; + + //handy to test posix access + //return -EIO; + + s->dev = init_blkfront((char *) filename, &s->sectors, &s->sector_size, &s->mode); + + if (!s->dev) + return -EIO; + + if (SECTOR_SIZE % s->sector_size) { + printf("sector size is %d, we only support sector sizes that divide %d\n", s->sector_size, SECTOR_SIZE); + return -EIO; + } + + s->fd = blkfront_open(s->dev); + qemu_set_fd_handler(s->fd, vbd_io_completed, NULL, s); + + QEMU_LIST_INSERT_HEAD(&vbds, s, list); + + return 0; +} + +typedef struct VbdAIOCB { + BlockDriverAIOCB common; + struct blkfront_aiocb aiocb; +} VbdAIOCB; + +void qemu_aio_init(void) +{ +} + +void qemu_aio_poll(void) +{ +} + +/* Wait for all IO requests to complete. */ +void qemu_aio_flush(void) +{ + BDRVVbdState *s; + for (s = vbds.lh_first; s; s = s->list.le_next) + blkfront_sync(s->dev); +} + +void qemu_aio_wait_start(void) +{ +} + +void qemu_aio_wait(void) +{ + int some = 0; + DEFINE_WAIT(w); + while (1) { + BDRVVbdState *s; + add_waiter(w, blkfront_queue); + for (s = vbds.lh_first; s; s = s->list.le_next) + if (blkfront_aio_poll(s->dev)) + some = 1; + if (some) + break; + schedule(); + } + remove_waiter(w); +} + +void qemu_aio_wait_end(void) +{ +} + +static void vbd_aio_callback(struct blkfront_aiocb *aiocbp, int ret) { + VbdAIOCB *acb = aiocbp->data; + + acb->common.cb(acb->common.opaque, ret); + qemu_aio_release(acb); +} + +static VbdAIOCB *vbd_aio_setup(BlockDriverState *bs, + int64_t sector_num, uint8_t *buf, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) +{ + BDRVVbdState *s = bs->opaque; + VbdAIOCB *acb; + + acb = qemu_aio_get(bs, cb, opaque); + if (!acb) + return NULL; + acb->aiocb.aio_dev = s->dev; + acb->aiocb.aio_buf = buf; + acb->aiocb.aio_nbytes = nb_sectors * SECTOR_SIZE; + acb->aiocb.aio_offset = sector_num * SECTOR_SIZE; + acb->aiocb.aio_cb = vbd_aio_callback; + acb->aiocb.data = acb; + + return acb; +} + +static BlockDriverAIOCB *vbd_aio_read(BlockDriverState *bs, + int64_t sector_num, uint8_t *buf, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) +{ + VbdAIOCB *acb; + + acb = vbd_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque); + if (!acb) + return NULL; + blkfront_aio(&acb->aiocb, 0); + return &acb->common; +} + +static BlockDriverAIOCB *vbd_aio_write(BlockDriverState *bs, + int64_t sector_num, const uint8_t *buf, int nb_sectors, + BlockDriverCompletionFunc *cb, void *opaque) +{ + VbdAIOCB *acb; + + acb = vbd_aio_setup(bs, sector_num, (uint8_t*) buf, nb_sectors, cb, opaque); + if (!acb) + return NULL; + blkfront_aio(&acb->aiocb, 1); + return &acb->common; +} + +static void vbd_cb(void *data, int ret) { + int *result = data; + result[0] = 1; + result[1] = ret; +} + +static int vbd_aligned_io(BlockDriverState *bs, + int64_t sector_num, uint8_t *buf, int nb_sectors, int write) +{ + VbdAIOCB *acb; + int result[2]; + result[0] = 0; + qemu_aio_wait_start(); + acb = vbd_aio_setup(bs, sector_num, (uint8_t*) buf, nb_sectors, vbd_cb, &result); + blkfront_aio(&acb->aiocb, write); + while (!result[0]) + qemu_aio_wait(); + qemu_aio_wait_end(); + return result[1]; +} + +static int vbd_read(BlockDriverState *bs, + int64_t sector_num, uint8_t *buf, int nb_sectors) +{ + uint8_t *iobuf; + int ret; + /* page alignment would be a bit better, but that's still fine compared to + * copying */ + if (!((uintptr_t)buf & (SECTOR_SIZE-1))) + return vbd_aligned_io(bs, sector_num, buf, nb_sectors, 0); + iobuf = qemu_memalign(PAGE_SIZE, nb_sectors * SECTOR_SIZE); + ret = vbd_aligned_io(bs, sector_num, iobuf, nb_sectors, 0); + memcpy(buf, iobuf, nb_sectors * SECTOR_SIZE); + free(iobuf); + if (ret < 0) + return ret; + else if (ret != nb_sectors * SECTOR_SIZE) + return -EINVAL; + else + return 0; +} + +static int vbd_write(BlockDriverState *bs, + int64_t sector_num, const uint8_t *buf, int nb_sectors) +{ + uint8_t *iobuf; + int ret; + if (!((uintptr_t)buf & (SECTOR_SIZE-1))) + return vbd_aligned_io(bs, sector_num, (uint8_t*) buf, nb_sectors, 1); + iobuf = qemu_memalign(PAGE_SIZE, nb_sectors * SECTOR_SIZE); + memcpy(iobuf, buf, nb_sectors * SECTOR_SIZE); + ret = vbd_aligned_io(bs, sector_num, iobuf, nb_sectors, 1); + free(iobuf); + if (ret < 0) + return ret; + else if (ret != nb_sectors * SECTOR_SIZE) + return -EINVAL; + else + return 0; +} + +static void vbd_aio_cancel(BlockDriverAIOCB *blockacb) +{ + /* TODO */ + //VbdAIOCB *acb = (VbdAIOCB *)blockacb; + + // Try to cancel. If can't, wait for it, drop the callback and call qemu_aio_release(acb) +} + +static void vbd_close(BlockDriverState *bs) +{ + BDRVVbdState *s = bs->opaque; + bs->total_sectors = 0; + if (s->fd >= 0) { + close(s->fd); + s->fd = -1; + } + QEMU_LIST_REMOVE(s, list); +} + +static int64_t vbd_getlength(BlockDriverState *bs) +{ + BDRVVbdState *s = bs->opaque; + return s->sectors * s->sector_size; +} + +static void vbd_flush(BlockDriverState *bs) +{ + BDRVVbdState *s = bs->opaque; + blkfront_sync(s->dev); +} + +/***********************************************/ +/* host device */ + +static int vbd_is_inserted(BlockDriverState *bs) +{ + /* TODO: monitor the backend */ + return 1; +} + +/* currently only used by fdc.c, but a CD version would be good too */ +static int vbd_media_changed(BlockDriverState *bs) +{ + /* TODO: monitor the backend */ + return -ENOTSUP; +} + +static int vbd_eject(BlockDriverState *bs, int eject_flag) +{ + /* TODO: Xen support needed */ + return -ENOTSUP; +} + +static int vbd_set_locked(BlockDriverState *bs, int locked) +{ + /* TODO: Xen support needed */ + return -ENOTSUP; +} + +BlockDriver bdrv_vbd = { + "vbd", + sizeof(BDRVVbdState), + vbd_probe, + vbd_open, + NULL, + NULL, + vbd_close, + NULL, + vbd_flush, + + .bdrv_aio_read = vbd_aio_read, + .bdrv_aio_write = vbd_aio_write, + .bdrv_aio_cancel = vbd_aio_cancel, + .aiocb_size = sizeof(VbdAIOCB), + .bdrv_read = vbd_read, + .bdrv_write = vbd_write, + .bdrv_getlength = vbd_getlength, + + /* removable device support */ + .bdrv_is_inserted = vbd_is_inserted, + .bdrv_media_changed = vbd_media_changed, + .bdrv_eject = vbd_eject, + .bdrv_set_locked = vbd_set_locked, +}; + diff --git a/tools/ioemu/block.c b/tools/ioemu/block.c index cf84e8ffbb..a43f3fe27b 100644 --- a/tools/ioemu/block.c +++ b/tools/ioemu/block.c @@ -1235,6 +1235,9 @@ void bdrv_init(void) { bdrv_register(&bdrv_raw); bdrv_register(&bdrv_host_device); +#ifdef CONFIG_STUBDOM + bdrv_register(&bdrv_vbd); +#endif #ifndef _WIN32 bdrv_register(&bdrv_cow); #endif diff --git a/tools/ioemu/configure b/tools/ioemu/configure index ef0bac1f8e..3e3b427b87 100755 --- a/tools/ioemu/configure +++ b/tools/ioemu/configure @@ -74,6 +74,7 @@ softmmu="yes" linux_user="no" darwin_user="no" build_docs="no" +stubdom="no" uname_release="" # OS specific @@ -231,6 +232,8 @@ for opt do ;; --enable-uname-release=*) uname_release="$optarg" ;; + --enable-stubdom) stubdom="yes" + ;; esac done @@ -416,7 +419,11 @@ if test -z "$target_list" ; then target_list="i386-darwin-user ppc-darwin-user $target_list" fi # the i386-dm target - target_list="i386-dm" + if test "$stubdom" = "yes"; then + target_list="i386-dm-stubdom" + else + target_list="i386-dm" + fi else target_list=`echo "$target_list" | sed -e 's/,/ /g'` fi @@ -575,6 +582,11 @@ bindir="$prefix/$libdir/xen/bin" configdir="/etc/xen" fi +if test "$stubdom" = "yes"; then + oss="no" + sdl="no" +fi + echo "Install prefix $prefix" echo "BIOS directory $datadir" echo "binary directory $bindir" @@ -943,6 +955,14 @@ if expr $target : '.*-dm' > /dev/null ; then echo "#define CONFIG_DM 1" >> $config_h fi +if test "$stubdom" = "yes" ; then + echo "CONFIG_STUBDOM=yes" >> $config_mak + echo "#define CONFIG_STUBDOM 1" >> $config_h + echo "#define NO_UNIX_SOCKETS 1" >> $config_h + echo "#define NO_DAEMONIZE 1" >> $config_h + echo "#define NO_AIO 1" >> $config_h +fi + if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" -o "$target_cpu" = "sparc" -o "$target_cpu" = "sparc64" -o "$target_cpu" = "m68k"; then echo "CONFIG_SOFTFLOAT=yes" >> $config_mak echo "#define CONFIG_SOFTFLOAT 1" >> $config_h diff --git a/tools/ioemu/console.c b/tools/ioemu/console.c index 634e3d85d0..dc904f6574 100644 --- a/tools/ioemu/console.c +++ b/tools/ioemu/console.c @@ -169,16 +169,12 @@ static unsigned int vga_get_color(DisplayState *ds, unsigned int rgba) unsigned int r, g, b, color; switch(ds->depth) { -#if 0 case 8: r = (rgba >> 16) & 0xff; g = (rgba >> 8) & 0xff; b = (rgba) & 0xff; - color = (rgb_to_index[r] * 6 * 6) + - (rgb_to_index[g] * 6) + - (rgb_to_index[b]); + color = ((r >> 5) << 5 | (g >> 5) << 2 | (b >> 6)); break; -#endif case 15: r = (rgba >> 16) & 0xff; g = (rgba >> 8) & 0xff; diff --git a/tools/ioemu/cpu-all.h b/tools/ioemu/cpu-all.h index 2f125b785d..9cc854ed7c 100644 --- a/tools/ioemu/cpu-all.h +++ b/tools/ioemu/cpu-all.h @@ -116,6 +116,7 @@ static inline void tswap64s(uint64_t *s) #define bswaptls(s) bswap64s(s) #endif +#ifdef CONFIG_SOFTFLOAT /* NOTE: arm FPA is horrible as double 32 bit words are stored in big endian ! */ typedef union { @@ -134,6 +135,7 @@ typedef union { #endif uint64_t ll; } CPU_DoubleU; +#endif /* CPU memory access without any memory or io remapping */ @@ -267,6 +269,7 @@ static inline void stq_le_p(void *ptr, uint64_t v) stl_le_p(p + 4, v >> 32); } +#ifdef CONFIG_SOFTFLOAT /* float access */ static inline float32 ldfl_le_p(void *ptr) @@ -304,6 +307,7 @@ static inline void stfq_le_p(void *ptr, float64 v) stl_le_p(ptr, u.l.lower); stl_le_p(ptr + 4, u.l.upper); } +#endif #else @@ -342,6 +346,7 @@ static inline void stq_le_p(void *ptr, uint64_t v) *(uint64_t *)ptr = v; } +#ifdef CONFIG_SOFTFLOAT /* float access */ static inline float32 ldfl_le_p(void *ptr) @@ -364,6 +369,7 @@ static inline void stfq_le_p(void *ptr, float64 v) *(float64 *)ptr = v; } #endif +#endif #if !defined(WORDS_BIGENDIAN) || defined(WORDS_ALIGNED) @@ -456,6 +462,7 @@ static inline void stq_be_p(void *ptr, uint64_t v) stl_be_p(ptr + 4, v); } +#ifdef CONFIG_SOFTFLOAT /* float access */ static inline float32 ldfl_be_p(void *ptr) @@ -493,6 +500,7 @@ static inline void stfq_be_p(void *ptr, float64 v) stl_be_p(ptr, u.l.upper); stl_be_p(ptr + 4, u.l.lower); } +#endif #else @@ -531,6 +539,7 @@ static inline void stq_be_p(void *ptr, uint64_t v) *(uint64_t *)ptr = v; } +#ifdef CONFIG_SOFTFLOAT /* float access */ static inline float32 ldfl_be_p(void *ptr) @@ -552,6 +561,7 @@ static inline void stfq_be_p(void *ptr, float64 v) { *(float64 *)ptr = v; } +#endif #endif diff --git a/tools/ioemu/exec-all.h b/tools/ioemu/exec-all.h index f6804b1a0a..28c120d4ca 100644 --- a/tools/ioemu/exec-all.h +++ b/tools/ioemu/exec-all.h @@ -481,6 +481,9 @@ static inline int testandset (int *p) } #endif +#ifdef CONFIG_STUBDOM +#include <spinlock.h> +#else typedef int spinlock_t; #define SPIN_LOCK_UNLOCKED 0 @@ -514,6 +517,7 @@ static inline int spin_trylock(spinlock_t *lock) return 1; } #endif +#endif extern spinlock_t tb_lock; diff --git a/tools/ioemu/hw/fdc.c b/tools/ioemu/hw/fdc.c index dc2ea6ebff..5989afd7d0 100644 --- a/tools/ioemu/hw/fdc.c +++ b/tools/ioemu/hw/fdc.c @@ -378,7 +378,7 @@ struct fdctrl_t { uint8_t cur_drv; uint8_t bootsel; /* Command FIFO */ - uint8_t fifo[FD_SECTOR_LEN]; + uint8_t *fifo; uint32_t data_pos; uint32_t data_len; uint8_t data_state; @@ -497,6 +497,11 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped, fdctrl = qemu_mallocz(sizeof(fdctrl_t)); if (!fdctrl) return NULL; + fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN); + if (fdctrl->fifo == NULL) { + qemu_free(fdctrl); + return NULL; + } fdctrl->result_timer = qemu_new_timer(vm_clock, fdctrl_result_timer, fdctrl); diff --git a/tools/ioemu/hw/ide.c b/tools/ioemu/hw/ide.c index 0e65141ec6..9dd9653aa9 100644 --- a/tools/ioemu/hw/ide.c +++ b/tools/ioemu/hw/ide.c @@ -22,6 +22,7 @@ * THE SOFTWARE. */ #include "vl.h" +#include <malloc.h> /* debug IDE devices */ //#define DEBUG_IDE @@ -347,7 +348,7 @@ typedef struct IDEState { EndTransferFunc *end_transfer_func; uint8_t *data_ptr; uint8_t *data_end; - uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; + uint8_t *io_buffer; QEMUTimer *sector_write_timer; /* only used for win2k instal hack */ uint32_t irq_count; /* counts IRQs when using win2k install hack */ } IDEState; @@ -2305,6 +2306,7 @@ static void ide_init2(IDEState *ide_state, for(i = 0; i < 2; i++) { s = ide_state + i; + s->io_buffer = qemu_memalign(getpagesize(), MAX_MULT_SECTORS*512 + 4); if (i == 0) s->bs = hd0; else diff --git a/tools/ioemu/hw/pc.c b/tools/ioemu/hw/pc.c index 5d982016a6..c6ebc6780d 100644 --- a/tools/ioemu/hw/pc.c +++ b/tools/ioemu/hw/pc.c @@ -361,6 +361,7 @@ void bochs_bios_init(void) register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL); } +#if defined(__i386__) || defined(__x86_64__) /* Generate an initial boot sector which sets state and jump to a specified vector */ static void generate_bootsect(uint32_t gpr[8], uint16_t segs[6], uint16_t ip) @@ -718,6 +719,14 @@ static void load_linux(const char *kernel_filename, generate_bootsect(gpr, seg, 0); } +#else /* __ia64__ */ +static void load_linux(const char *kernel_filename, + const char *initrd_filename, + const char *kernel_cmdline) +{ + /* Direct Linux boot is unsupported. */ +} +#endif static void main_cpu_reset(void *opaque) { @@ -1013,8 +1022,10 @@ static void pc_init1(uint64_t ram_size, int vga_ram_size, char *boot_device, } } +#ifdef HAS_TPM if (has_tpm_device()) tpm_tis_init(&pic_set_irq_new, isa_pic, 11); +#endif kbd_init(); DMA_init(0); diff --git a/tools/ioemu/hw/scsi-disk.c b/tools/ioemu/hw/scsi-disk.c index c6280fd559..acbe75fc98 100644 --- a/tools/ioemu/hw/scsi-disk.c +++ b/tools/ioemu/hw/scsi-disk.c @@ -26,13 +26,18 @@ do { printf("scsi-disk: " fmt , ##args); } while (0) do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0) #include "vl.h" +#include <malloc.h> #define SENSE_NO_SENSE 0 #define SENSE_NOT_READY 2 #define SENSE_HARDWARE_ERROR 4 #define SENSE_ILLEGAL_REQUEST 5 +#ifdef CONFIG_STUBDOM +#define SCSI_DMA_BUF_SIZE 32768 +#else #define SCSI_DMA_BUF_SIZE 65536 +#endif typedef struct SCSIRequest { SCSIDevice *dev; @@ -44,7 +49,7 @@ typedef struct SCSIRequest { int sector_count; /* The amounnt of data in the buffer. */ int buf_len; - uint8_t dma_buf[SCSI_DMA_BUF_SIZE]; + uint8_t *dma_buf; BlockDriverAIOCB *aiocb; struct SCSIRequest *next; } SCSIRequest; @@ -76,6 +81,7 @@ static SCSIRequest *scsi_new_request(SCSIDevice *s, uint32_t tag) free_requests = r->next; } else { r = qemu_malloc(sizeof(SCSIRequest)); + r->dma_buf = qemu_memalign(getpagesize(), SCSI_DMA_BUF_SIZE); } r->dev = s; r->tag = tag; diff --git a/tools/ioemu/hw/usb-hid.c b/tools/ioemu/hw/usb-hid.c index e947977313..78b48b8dbb 100644 --- a/tools/ioemu/hw/usb-hid.c +++ b/tools/ioemu/hw/usb-hid.c @@ -224,15 +224,37 @@ static const uint8_t qemu_tablet_hid_report_descriptor[] = { 0xC0, /* End Collection */ }; +static int currentbutton = 0; +typedef struct _mouseclick { + int button_state; + struct _mouseclick *next; +} mouseclick; +static mouseclick mousequeue[20]; +static mouseclick *head = mousequeue; +static mouseclick *tail = mousequeue; + static void usb_mouse_event(void *opaque, int dx1, int dy1, int dz1, int buttons_state) { USBMouseState *s = opaque; + if (s->status_changed == 1){ + //A mouse event is lost + if (buttons_state != currentbutton && tail->next != head) { + //A left click event is lost: let's add it to the queue + //counter++; + tail->button_state = buttons_state; + tail = tail->next; + } + } + else { + s->buttons_state = buttons_state; + } + s->dx += dx1; s->dy += dy1; s->dz += dz1; - s->buttons_state = buttons_state; + currentbutton = buttons_state; s->status_changed = 1; } @@ -240,11 +262,24 @@ static void usb_tablet_event(void *opaque, int x, int y, int dz, int buttons_state) { USBMouseState *s = opaque; + + if (s->status_changed == 1){ + //A mouse event is lost + if (buttons_state != currentbutton && tail->next != head) { + //A left click event is lost: let's add it to the queue + //counter++; + tail->button_state = buttons_state; + tail = tail->next; + } + } + else { + s->buttons_state = buttons_state; + } s->x = x; s->y = y; s->dz += dz; - s->buttons_state = buttons_state; + currentbutton = buttons_state; s->status_changed = 1; } @@ -493,10 +528,17 @@ static int usb_mouse_handle_data(USBDevice *dev, USBPacket *p) else if (s->kind == USB_TABLET) ret = usb_tablet_poll(s, p->data, p->len); - if (!s->status_changed) + if (!s->status_changed) { ret = USB_RET_NAK; - else - s->status_changed = 0; + } else { + if (head != tail) { + s->buttons_state = head->button_state; + head = head->next; + } + else { + s->status_changed = 0; + } + } } else { goto fail; @@ -567,6 +609,14 @@ int usb_mouse_load(QEMUFile *f, void *opaque, int version_id) USBDevice *usb_tablet_init(void) { USBMouseState *s; + int i; + + for (i = 0; i < 19; i++) { + mousequeue[i].button_state = 0; + mousequeue[i].next = &(mousequeue[i + 1]); + } + mousequeue[i].button_state = 0; + mousequeue[i].next = mousequeue; s = qemu_mallocz(sizeof(USBMouseState)); if (!s) @@ -591,6 +641,14 @@ USBDevice *usb_tablet_init(void) USBDevice *usb_mouse_init(void) { USBMouseState *s; + int i; + + for (i = 0; i < 19; i++) { + mousequeue[i].button_state = 0; + mousequeue[i].next = &(mousequeue[i + 1]); + } + mousequeue[i].button_state = 0; + mousequeue[i].next = mousequeue; s = qemu_mallocz(sizeof(USBMouseState)); if (!s) diff --git a/tools/ioemu/hw/vga.c b/tools/ioemu/hw/vga.c index 17538bbddc..4e2f9525a7 100644 --- a/tools/ioemu/hw/vga.c +++ b/tools/ioemu/hw/vga.c @@ -1071,7 +1071,7 @@ static const uint8_t cursor_glyph[32 * 4] = { */ static void vga_draw_text(VGAState *s, int full_update) { - int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr; + int cx, cy, cheight, cw, ch, cattr, height, width, ch_attr, depth; int cx_min, cx_max, linesize, x_incr; uint32_t offset, fgcol, bgcol, v, cursor_offset; uint8_t *d1, *d, *src, *s1, *dest, *cursor_ptr; @@ -1134,6 +1134,11 @@ static void vga_draw_text(VGAState *s, int full_update) return; } + depth = s->get_bpp(s); + if (depth == 24) + depth = 32; + if (s->ds->dpy_colourdepth != NULL && s->ds->depth != depth) + s->ds->dpy_colourdepth(s->ds, depth); if (width != s->last_width || height != s->last_height || cw != s->last_cw || cheight != s->last_ch) { s->last_scr_width = width * cw; @@ -1477,7 +1482,7 @@ void check_sse2(void) */ static void vga_draw_graphic(VGAState *s, int full_update) { - int y1, y, update, linesize, y_start, double_scan, mask; + int y1, y, update, linesize, y_start, double_scan, mask, depth; int width, height, shift_control, line_offset, bwidth; ram_addr_t page0, page1; int disp_width, multi_scan, multi_run; @@ -1551,6 +1556,11 @@ static void vga_draw_graphic(VGAState *s, int full_update) } vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)]; + depth = s->get_bpp(s); + if (depth == 24) + depth = 32; + if (s->ds->dpy_colourdepth != NULL && s->ds->depth != depth) + s->ds->dpy_colourdepth(s->ds, depth); if (disp_width != s->last_width || height != s->last_height) { dpy_resize(s->ds, disp_width, height); diff --git a/tools/ioemu/hw/xen_console.c b/tools/ioemu/hw/xen_console.c index 76aca8f3ee..44f8bcca48 100644 --- a/tools/ioemu/hw/xen_console.c +++ b/tools/ioemu/hw/xen_console.c @@ -75,7 +75,7 @@ static void buffer_append(struct domain *dom) cons = intf->out_cons; prod = intf->out_prod; - mb(); + xen_mb(); size = prod - cons; if ((size == 0) || (size > sizeof(intf->out))) @@ -94,7 +94,7 @@ static void buffer_append(struct domain *dom) buffer->data[buffer->size++] = intf->out[ MASK_XENCONS_IDX(cons++, intf->out)]; - mb(); + xen_mb(); intf->out_cons = cons; xc_evtchn_notify(dom->xce_handle, dom->local_port); @@ -289,7 +289,7 @@ static int ring_free_bytes(struct domain *dom) cons = intf->in_cons; prod = intf->in_prod; - mb(); + xen_mb(); space = prod - cons; if (space > sizeof(intf->in)) @@ -322,7 +322,7 @@ static void xencons_receive(void *opaque, const uint8_t *buf, int len) intf->in[MASK_XENCONS_IDX(prod++, intf->in)] = buf[i]; } - wmb(); + xen_wmb(); intf->in_prod = prod; xc_evtchn_notify(dom->xce_handle, dom->local_port); } diff --git a/tools/ioemu/hw/xen_machine_fv.c b/tools/ioemu/hw/xen_machine_fv.c index 22ba1dbc3f..272f67946f 100644 --- a/tools/ioemu/hw/xen_machine_fv.c +++ b/tools/ioemu/hw/xen_machine_fv.c @@ -24,6 +24,9 @@ */ #include "vl.h" +#ifdef CONFIG_STUBDOM +#include <xenbus.h> +#endif #include <xen/hvm/params.h> #include <sys/mman.h> diff --git a/tools/ioemu/hw/xenfb.c b/tools/ioemu/hw/xenfb.c index f0d7f7936e..5418986178 100644 --- a/tools/ioemu/hw/xenfb.c +++ b/tools/ioemu/hw/xenfb.c @@ -485,7 +485,7 @@ static void xenfb_on_fb_event(struct xenfb *xenfb) prod = page->out_prod; if (prod == page->out_cons) return; - rmb(); /* ensure we see ring contents up to prod */ + xen_rmb(); /* ensure we see ring contents up to prod */ for (cons = page->out_cons; cons != prod; cons++) { union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons); int x, y, w, h; @@ -512,7 +512,7 @@ static void xenfb_on_fb_event(struct xenfb *xenfb) break; } } - mb(); /* ensure we're done with ring contents */ + xen_mb(); /* ensure we're done with ring contents */ page->out_cons = cons; xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port); } @@ -571,9 +571,9 @@ static int xenfb_kbd_event(struct xenfb *xenfb, return -1; } - mb(); /* ensure ring space available */ + xen_mb(); /* ensure ring space available */ XENKBD_IN_RING_REF(page, prod) = *event; - wmb(); /* ensure ring contents visible */ + xen_wmb(); /* ensure ring contents visible */ page->in_prod = prod + 1; return xc_evtchn_notify(xenfb->evt_xch, xenfb->kbd.port); } diff --git a/tools/ioemu/osdep.c b/tools/ioemu/osdep.c index d1eff8deb5..5ec16b47da 100644 --- a/tools/ioemu/osdep.c +++ b/tools/ioemu/osdep.c @@ -61,6 +61,10 @@ void *qemu_malloc(size_t size) } #if defined(_WIN32) +void *qemu_memalign(size_t alignment, size_t size) +{ + return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); +} void *qemu_vmalloc(size_t size) { @@ -172,6 +176,22 @@ void kqemu_vfree(void *ptr) #endif +void *qemu_memalign(size_t alignment, size_t size) +{ +#if defined(_POSIX_C_SOURCE) + int ret; + void *ptr; + ret = posix_memalign(&ptr, alignment, size); + if (ret != 0) + return NULL; + return ptr; +#elif defined(_BSD) + return valloc(size); +#else + return memalign(alignment, size); +#endif +} + /* alloc shared memory pages */ void *qemu_vmalloc(size_t size) { diff --git a/tools/ioemu/osdep.h b/tools/ioemu/osdep.h index bd6ffc1713..6df1d87d12 100644 --- a/tools/ioemu/osdep.h +++ b/tools/ioemu/osdep.h @@ -14,6 +14,7 @@ void *qemu_mallocz(size_t size); void qemu_free(void *ptr); char *qemu_strdup(const char *str); +void *qemu_memalign(size_t alignment, size_t size); void *qemu_vmalloc(size_t size); void qemu_vfree(void *ptr); diff --git a/tools/ioemu/sdl.c b/tools/ioemu/sdl.c index 4d6d73a6a1..4d09469858 100644 --- a/tools/ioemu/sdl.c +++ b/tools/ioemu/sdl.c @@ -259,11 +259,9 @@ static void sdl_grab_end(void) sdl_update_caption(); } -static void sdl_send_mouse_event(int dz) +static void sdl_send_mouse_event(int dx, int dy, int dz, int state) { - int dx, dy, state, buttons; - state = SDL_GetRelativeMouseState(&dx, &dy); - buttons = 0; + int buttons = 0; if (state & SDL_BUTTON(SDL_BUTTON_LEFT)) buttons |= MOUSE_EVENT_LBUTTON; if (state & SDL_BUTTON(SDL_BUTTON_RIGHT)) @@ -425,11 +423,19 @@ static void sdl_refresh(DisplayState *ds) case SDL_MOUSEMOTION: if (gui_grab || kbd_mouse_is_absolute() || absolute_enabled) { - sdl_send_mouse_event(0); + int dx, dy, state; + state = SDL_GetRelativeMouseState(&dx, &dy); + sdl_send_mouse_event(dx, dy, 0, state); } break; - case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: + if (gui_grab || kbd_mouse_is_absolute()) { + int dx, dy, state; + state = SDL_GetRelativeMouseState(&dx, &dy); + sdl_send_mouse_event(dx, dy, 0, state); + } + break; + case SDL_MOUSEBUTTONDOWN: { SDL_MouseButtonEvent *bev = &ev->button; if (!gui_grab && !kbd_mouse_is_absolute()) { @@ -439,16 +445,19 @@ static void sdl_refresh(DisplayState *ds) sdl_grab_start(); } } else { - int dz; + int dx, dy, dz, state; dz = 0; + state = SDL_GetRelativeMouseState(&dx, &dy); #ifdef SDL_BUTTON_WHEELUP - if (bev->button == SDL_BUTTON_WHEELUP && ev->type == SDL_MOUSEBUTTONDOWN) { + if (bev->button == SDL_BUTTON_WHEELUP) { dz = -1; - } else if (bev->button == SDL_BUTTON_WHEELDOWN && ev->type == SDL_MOUSEBUTTONDOWN) { + } else if (bev->button == SDL_BUTTON_WHEELDOWN) { dz = 1; + } else { + state = bev->button | state; } #endif - sdl_send_mouse_event(dz); + sdl_send_mouse_event(dx, dy, dz, state); } } break; @@ -499,6 +508,7 @@ void sdl_display_init(DisplayState *ds, int full_screen) ds->dpy_update = sdl_update; ds->dpy_resize = sdl_resize; ds->dpy_refresh = sdl_refresh; + ds->dpy_colourdepth = NULL; sdl_resize(ds, 640, 400); sdl_update_caption(); diff --git a/tools/ioemu/target-i386-dm/cpu.h b/tools/ioemu/target-i386-dm/cpu.h index 017b8c021b..6071a8529e 100644 --- a/tools/ioemu/target-i386-dm/cpu.h +++ b/tools/ioemu/target-i386-dm/cpu.h @@ -37,17 +37,21 @@ #include "cpu-defs.h" +#ifdef CONFIG_SOFTFLOAT #include "softfloat.h" +#endif #if defined(__i386__) && !defined(CONFIG_SOFTMMU) #define USE_CODE_COPY #endif +#ifdef CONFIG_SOFTFLOAT #ifdef USE_X86LDOUBLE typedef floatx80 CPU86_LDouble; #else typedef float64 CPU86_LDouble; #endif +#endif /* Empty for now */ typedef struct CPUX86State { diff --git a/tools/ioemu/target-i386-dm/helper2.c b/tools/ioemu/target-i386-dm/helper2.c index d45ac7a999..4896b11ab8 100644 --- a/tools/ioemu/target-i386-dm/helper2.c +++ b/tools/ioemu/target-i386-dm/helper2.c @@ -218,7 +218,7 @@ static ioreq_t *__cpu_get_ioreq(int vcpu) return NULL; } - rmb(); /* see IOREQ_READY /then/ read contents of ioreq */ + xen_rmb(); /* see IOREQ_READY /then/ read contents of ioreq */ req->state = STATE_IOREQ_INPROCESS; return req; @@ -568,7 +568,7 @@ void __handle_buffered_iopage(CPUState *env) __handle_ioreq(env, &req); - mb(); + xen_mb(); buffered_io_page->read_pointer += qw ? 2 : 1; } } @@ -603,7 +603,7 @@ void cpu_handle_ioreq(void *opaque) return; } - wmb(); /* Update ioreq contents /then/ update state. */ + xen_wmb(); /* Update ioreq contents /then/ update state. */ /* * We do this before we send the response so that the tools diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c index fc81fd16e1..703f1bfd6d 100644 --- a/tools/ioemu/vl.c +++ b/tools/ioemu/vl.c @@ -36,22 +36,29 @@ #include <sys/times.h> #include <sys/wait.h> #include <termios.h> +#ifndef CONFIG_STUBDOM #include <sys/poll.h> +#endif #include <sys/mman.h> #include <sys/ioctl.h> #include <sys/resource.h> #include <sys/socket.h> #include <netinet/in.h> +#ifndef CONFIG_STUBDOM #include <net/if.h> +#endif #if defined(__NetBSD__) #include <net/if_tap.h> #endif #if defined(__linux__) || defined(__Linux__) #include <linux/if_tun.h> #endif +#ifndef CONFIG_STUBDOM #include <arpa/inet.h> #include <dirent.h> +#endif #include <netdb.h> +#ifndef CONFIG_STUBDOM #ifdef _BSD #include <sys/stat.h> #ifndef _BSD @@ -70,6 +77,7 @@ #include <stropts.h> #endif #endif +#endif #if defined(CONFIG_SLIRP) #include "libslirp.h" @@ -80,6 +88,7 @@ #include <windows.h> #define getopt_long_only getopt_long #define memalign(align, size) malloc(size) +#define NO_DAEMONIZE 1 #endif #include "qemu_socket.h" @@ -131,10 +140,9 @@ #define MAX_IOPORTS 65536 const char *bios_dir = CONFIG_QEMU_SHAREDIR; -char phys_ram_file[1024]; -void *ioport_opaque[MAX_IOPORTS]; -IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS]; -IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS]; +void **ioport_opaque; +IOPortReadFunc *(*ioport_read_table)[MAX_IOPORTS]; +IOPortWriteFunc *(*ioport_write_table)[MAX_IOPORTS]; /* Note: bs_table[MAX_DISKS] is a dummy block driver if none available to store the VM snapshots */ BlockDriverState *bs_table[MAX_DISKS + MAX_SCSI_DISKS + 1], *fd_table[MAX_FD]; @@ -186,7 +194,9 @@ const char *vnc_display; int acpi_enabled = 0; int fd_bootchk = 1; int no_reboot = 0; +#ifndef NO_DAEMONIZE int daemonize = 0; +#endif const char *option_rom[MAX_OPTION_ROMS]; int nb_option_roms; int semihosting_enabled = 0; @@ -224,17 +234,29 @@ void default_ioport_writeb(void *opaque, uint32_t address, uint32_t data) uint32_t default_ioport_readw(void *opaque, uint32_t address) { uint32_t data; - data = ioport_read_table[0][address](ioport_opaque[address], address); + IOPortReadFunc *func = ioport_read_table[0][address]; + if (!func) + func = default_ioport_readb; + data = func(ioport_opaque[address], address); address = (address + 1) & (MAX_IOPORTS - 1); - data |= ioport_read_table[0][address](ioport_opaque[address], address) << 8; + func = ioport_read_table[0][address]; + if (!func) + func = default_ioport_readb; + data |= func(ioport_opaque[address], address) << 8; return data; } void default_ioport_writew(void *opaque, uint32_t address, uint32_t data) { - ioport_write_table[0][address](ioport_opaque[address], address, data & 0xff); + IOPortWriteFunc *func = ioport_write_table[0][address]; + if (!func) + func = default_ioport_writeb; + func(ioport_opaque[address], address, data & 0xff); address = (address + 1) & (MAX_IOPORTS - 1); - ioport_write_table[0][address](ioport_opaque[address], address, (data >> 8) & 0xff); + func = ioport_write_table[0][address]; + if (!func) + func = default_ioport_writeb; + func(ioport_opaque[address], address, (data >> 8) & 0xff); } uint32_t default_ioport_readl(void *opaque, uint32_t address) @@ -254,16 +276,9 @@ void default_ioport_writel(void *opaque, uint32_t address, uint32_t data) void init_ioports(void) { - int i; - - for(i = 0; i < MAX_IOPORTS; i++) { - ioport_read_table[0][i] = default_ioport_readb; - ioport_write_table[0][i] = default_ioport_writeb; - ioport_read_table[1][i] = default_ioport_readw; - ioport_write_table[1][i] = default_ioport_writew; - ioport_read_table[2][i] = default_ioport_readl; - ioport_write_table[2][i] = default_ioport_writel; - } + ioport_opaque = malloc(MAX_IOPORTS * sizeof(*ioport_opaque)); + ioport_read_table = malloc(3 * MAX_IOPORTS * sizeof(**ioport_read_table)); + ioport_write_table = malloc(3 * MAX_IOPORTS * sizeof(**ioport_write_table)); } /* size is the word size in byte */ @@ -335,11 +350,14 @@ void isa_unassign_ioport(int start, int length) void cpu_outb(CPUState *env, int addr, int val) { + IOPortWriteFunc *func = ioport_write_table[0][addr]; + if (!func) + func = default_ioport_writeb; #ifdef DEBUG_IOPORT if (loglevel & CPU_LOG_IOPORT) fprintf(logfile, "outb: %04x %02x\n", addr, val); #endif - ioport_write_table[0][addr](ioport_opaque[addr], addr, val); + func(ioport_opaque[addr], addr, val); #ifdef USE_KQEMU if (env) env->last_io_time = cpu_get_time_fast(); @@ -348,11 +366,14 @@ void cpu_outb(CPUState *env, int addr, int val) void cpu_outw(CPUState *env, int addr, int val) { + IOPortWriteFunc *func = ioport_write_table[1][addr]; + if (!func) + func = default_ioport_writew; #ifdef DEBUG_IOPORT if (loglevel & CPU_LOG_IOPORT) fprintf(logfile, "outw: %04x %04x\n", addr, val); #endif - ioport_write_table[1][addr](ioport_opaque[addr], addr, val); + func(ioport_opaque[addr], addr, val); #ifdef USE_KQEMU if (env) env->last_io_time = cpu_get_time_fast(); @@ -361,11 +382,14 @@ void cpu_outw(CPUState *env, int addr, int val) void cpu_outl(CPUState *env, int addr, int val) { + IOPortWriteFunc *func = ioport_write_table[2][addr]; + if (!func) + func = default_ioport_writel; #ifdef DEBUG_IOPORT if (loglevel & CPU_LOG_IOPORT) fprintf(logfile, "outl: %04x %08x\n", addr, val); #endif - ioport_write_table[2][addr](ioport_opaque[addr], addr, val); + func(ioport_opaque[addr], addr, val); #ifdef USE_KQEMU if (env) env->last_io_time = cpu_get_time_fast(); @@ -375,7 +399,10 @@ void cpu_outl(CPUState *env, int addr, int val) int cpu_inb(CPUState *env, int addr) { int val; - val = ioport_read_table[0][addr](ioport_opaque[addr], addr); + IOPortReadFunc *func = ioport_read_table[0][addr]; + if (!func) + func = default_ioport_readb; + val = func(ioport_opaque[addr], addr); #ifdef DEBUG_IOPORT if (loglevel & CPU_LOG_IOPORT) fprintf(logfile, "inb : %04x %02x\n", addr, val); @@ -390,7 +417,10 @@ int cpu_inb(CPUState *env, int addr) int cpu_inw(CPUState *env, int addr) { int val; - val = ioport_read_table[1][addr](ioport_opaque[addr], addr); + IOPortReadFunc *func = ioport_read_table[1][addr]; + if (!func) + func = default_ioport_readw; + val = func(ioport_opaque[addr], addr); #ifdef DEBUG_IOPORT if (loglevel & CPU_LOG_IOPORT) fprintf(logfile, "inw : %04x %04x\n", addr, val); @@ -405,7 +435,10 @@ int cpu_inw(CPUState *env, int addr) int cpu_inl(CPUState *env, int addr) { int val; - val = ioport_read_table[2][addr](ioport_opaque[addr], addr); + IOPortReadFunc *func = ioport_read_table[2][addr]; + if (!func) + func = default_ioport_readl; + val = func(ioport_opaque[addr], addr); #ifdef DEBUG_IOPORT if (loglevel & CPU_LOG_IOPORT) fprintf(logfile, "inl : %04x %08x\n", addr, val); @@ -773,9 +806,6 @@ static QEMUTimer *active_timers[2]; static MMRESULT timerID; static HANDLE host_alarm = NULL; static unsigned int period = 1; -#else -/* frequency of the times() clock tick */ -static int timer_freq; #endif QEMUClock *qemu_new_clock(int type) @@ -1113,9 +1143,6 @@ static void init_timer_alarm(void) struct itimerval itv; #endif - /* get times() syscall frequency */ - timer_freq = sysconf(_SC_CLK_TCK); - #ifndef CONFIG_DM /* timer signal */ sigfillset(&act.sa_mask); @@ -1473,6 +1500,7 @@ static CharDriverState *qemu_chr_open_file_out(const char *file_out) return qemu_chr_open_fd(-1, fd_out); } +#ifndef CONFIG_STUBDOM static CharDriverState *qemu_chr_open_pipe(const char *filename) { int fd_in, fd_out; @@ -1718,6 +1746,7 @@ static CharDriverState *qemu_chr_open_stdio(void) } return chr; } +#endif /* * Create a store entry for a device (e.g., monitor, serial/parallel lines). @@ -1727,6 +1756,9 @@ static CharDriverState *qemu_chr_open_stdio(void) static int store_dev_info(char *devName, int domid, CharDriverState *cState, char *storeString) { +#ifdef CONFIG_STUBDOM + return 0; +#else int xc_handle; struct xs_handle *xs; char *path; @@ -1802,8 +1834,10 @@ static int store_dev_info(char *devName, int domid, close(xc_handle); return 0; +#endif } +#ifndef CONFIG_STUBDOM #ifdef __sun__ /* Once Solaris has openpty(), this is going to be removed. */ int openpty(int *amaster, int *aslave, char *name, @@ -2462,6 +2496,7 @@ static CharDriverState *qemu_chr_open_win_file_out(const char *file_out) return qemu_chr_open_win_file(fd_out); } #endif +#endif /***********************************************************/ /* UDP Net console */ @@ -2532,7 +2567,7 @@ static void udp_chr_update_read_handler(CharDriverState *chr) } int parse_host_port(struct sockaddr_in *saddr, const char *str); -#ifndef _WIN32 +#ifndef NO_UNIX_SOCKETS static int parse_unix_path(struct sockaddr_un *uaddr, const char *str); #endif int parse_host_src_port(struct sockaddr_in *haddr, @@ -2740,7 +2775,7 @@ static void tcp_chr_accept(void *opaque) CharDriverState *chr = opaque; TCPCharDriver *s = chr->opaque; struct sockaddr_in saddr; -#ifndef _WIN32 +#ifndef NO_UNIX_SOCKETS struct sockaddr_un uaddr; #endif struct sockaddr *addr; @@ -2748,7 +2783,7 @@ static void tcp_chr_accept(void *opaque) int fd; for(;;) { -#ifndef _WIN32 +#ifndef NO_UNIX_SOCKETS if (s->is_unix) { len = sizeof(uaddr); addr = (struct sockaddr *)&uaddr; @@ -2797,13 +2832,13 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, int do_nodelay = 0; const char *ptr; struct sockaddr_in saddr; -#ifndef _WIN32 +#ifndef NO_UNIX_SOCKETS struct sockaddr_un uaddr; #endif struct sockaddr *addr; socklen_t addrlen; -#ifndef _WIN32 +#ifndef NO_UNIX_SOCKETS if (is_unix) { addr = (struct sockaddr *)&uaddr; addrlen = sizeof(uaddr); @@ -2842,7 +2877,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, if (!s) goto fail; -#ifndef _WIN32 +#ifndef NO_UNIX_SOCKETS if (is_unix) fd = socket(PF_UNIX, SOCK_STREAM, 0); else @@ -2867,7 +2902,7 @@ static CharDriverState *qemu_chr_open_tcp(const char *host_str, if (is_listen) { /* allow fast reuse */ -#ifndef _WIN32 +#ifndef NO_UNIX_SOCKETS if (is_unix) { char path[109]; strncpy(path, uaddr.sun_path, 108); @@ -2954,12 +2989,14 @@ CharDriverState *qemu_chr_open(const char *filename) return qemu_chr_open_tcp(p, 0, 1); } else if (strstart(filename, "file:", &p)) { return qemu_chr_open_file_out(p); +#ifndef CONFIG_STUBDOM } else if (strstart(filename, "pipe:", &p)) { return qemu_chr_open_pipe(p); } else if (!strcmp(filename, "pty")) { return qemu_chr_open_pty(); } else if (!strcmp(filename, "stdio")) { return qemu_chr_open_stdio(); +#endif } else #endif #if defined(__linux__) @@ -3449,7 +3486,16 @@ static TAPState *net_tap_fd_init(VLANState *vlan, int fd) return s; } -#ifdef _BSD +#ifdef CONFIG_STUBDOM +#include <netfront.h> +static int tap_open(char *ifname, int ifname_size) +{ + char nodename[64]; + static int num = 1; // 0 is for our own TCP/IP networking + snprintf(nodename, sizeof(nodename), "device/vif/%d", num++); + return netfront_tap_open(nodename); +} +#elif defined(_BSD) static int tap_open(char *ifname, int ifname_size) { int fd; @@ -3537,6 +3583,7 @@ static int net_tap_init(VLANState *vlan, const char *ifname1, if (fd < 0) return -1; +#ifndef CONFIG_STUBDOM if (!setup_script || !strcmp(setup_script, "no")) setup_script = ""; if (setup_script[0] != '\0') { @@ -3569,6 +3616,7 @@ static int net_tap_init(VLANState *vlan, const char *ifname1, } } } +#endif s = net_tap_fd_init(vlan, fd); if (!s) return -1; @@ -4397,6 +4445,7 @@ void dumb_display_init(DisplayState *ds) ds->depth = 0; ds->dpy_update = dumb_update; ds->dpy_resize = dumb_resize; + ds->dpy_colourdepth = NULL; ds->dpy_refresh = dumb_refresh; } @@ -6510,7 +6559,7 @@ void help(void) "-vnc display start a VNC server on display\n" "-vncviewer start a vncviewer process for this domain\n" "-vncunused bind the VNC server to an unused port\n" -#ifndef _WIN32 +#ifndef NO_DAEMONIZE "-daemonize daemonize QEMU after initializing\n" #endif "-option-rom rom load a file, rom, into the option ROM space\n" @@ -6600,7 +6649,9 @@ enum { QEMU_OPTION_vnc, QEMU_OPTION_no_acpi, QEMU_OPTION_no_reboot, +#ifndef NO_DAEMONIZE QEMU_OPTION_daemonize, +#endif QEMU_OPTION_option_rom, QEMU_OPTION_semihosting , @@ -6698,7 +6749,9 @@ const QEMUOption qemu_options[] = { { "cirrusvga", 0, QEMU_OPTION_cirrusvga }, { "no-acpi", 0, QEMU_OPTION_no_acpi }, { "no-reboot", 0, QEMU_OPTION_no_reboot }, +#ifndef NO_DAEMONIZE { "daemonize", 0, QEMU_OPTION_daemonize }, +#endif { "option-rom", HAS_ARG, QEMU_OPTION_option_rom }, #if defined(TARGET_ARM) { "semihosting", 0, QEMU_OPTION_semihosting }, @@ -7009,12 +7062,14 @@ int main(int argc, char **argv) char usb_devices[MAX_USB_CMDLINE][128]; int usb_devices_index; int fds[2]; +#ifndef CONFIG_STUBDOM struct rlimit rl; +#endif sigset_t set; char qemu_dm_logfilename[128]; const char *direct_pci = NULL; -#ifndef __sun__ +#if !defined(__sun__) && !defined(CONFIG_STUBDOM) /* Maximise rlimits. Needed where default constraints are tight (*BSD). */ if (getrlimit(RLIMIT_STACK, &rl) != 0) { perror("getrlimit(RLIMIT_STACK)"); @@ -7040,6 +7095,7 @@ int main(int argc, char **argv) perror("setrlimit(RLIMIT_MEMLOCK)"); #endif +#ifndef CONFIG_STUBDOM /* Ensure that SIGUSR2 is blocked by default when a new thread is created, then only the threads that use the signal unblock it -- this fixes a race condition in Qcow support where the AIO signal is misdelivered. */ @@ -7082,6 +7138,7 @@ int main(int argc, char **argv) } } #endif +#endif register_machines(); machine = first_machine; @@ -7496,9 +7553,11 @@ int main(int argc, char **argv) case QEMU_OPTION_no_reboot: no_reboot = 1; break; +#ifndef NO_DAEMONIZE case QEMU_OPTION_daemonize: daemonize = 1; break; +#endif case QEMU_OPTION_option_rom: if (nb_option_roms >= MAX_OPTION_ROMS) { fprintf(stderr, "Too many option ROMs\n"); @@ -7542,7 +7601,7 @@ int main(int argc, char **argv) sprintf(qemu_dm_logfilename, "/var/log/xen/qemu-dm-%d.log", domid); cpu_set_log_filename(qemu_dm_logfilename); -#ifndef _WIN32 +#ifndef NO_DAEMONIZE if (daemonize && !nographic && vnc_display == NULL && vncunused == 0) { fprintf(stderr, "Can only daemonize if using -nographic or -vnc\n"); daemonize = 0; @@ -7593,7 +7652,15 @@ int main(int argc, char **argv) #ifdef CONFIG_DM bdrv_init(); xc_handle = xc_interface_open(); +#ifdef CONFIG_STUBDOM + char *domid_s, *msg; + if ((msg = xenbus_read(XBT_NIL, "domid", &domid_s))) + fprintf(stderr,"Can not read our own domid\n", msg); + else + xenstore_parse_domain_config(atoi(domid_s)); +#else /* CONFIG_STUBDOM */ xenstore_parse_domain_config(domid); +#endif /* CONFIG_STUBDOM */ #endif /* CONFIG_DM */ #ifdef USE_KQEMU @@ -7760,8 +7827,10 @@ int main(int argc, char **argv) vnc_display_password(ds, password); if ((vnc_display_port = vnc_display_open(ds, vnc_display, vncunused)) < 0) exit (0); +#ifndef CONFIG_STUBDOM if (vncviewer) vnc_start_viewer(vnc_display_port); +#endif xenstore_write_vncport(vnc_display_port); } else { #if defined(CONFIG_SDL) @@ -7863,6 +7932,7 @@ int main(int argc, char **argv) } } +#ifndef NO_DAEMONIZE if (daemonize) { uint8_t status = 0; ssize_t len; @@ -7886,12 +7956,17 @@ int main(int argc, char **argv) close(fd); } +#endif - /* Unblock SIGTERM, which may have been blocked by the caller */ +#ifndef CONFIG_STUBDOM + /* Unblock SIGTERM and SIGHUP, which may have been blocked by the caller */ + signal(SIGHUP, SIG_DFL); sigemptyset(&set); sigaddset(&set, SIGTERM); + sigaddset(&set, SIGHUP); if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1) - fprintf(stderr, "Failed to unblock SIGTERM\n"); + fprintf(stderr, "Failed to unblock SIGTERM and SIGHUP\n"); +#endif main_loop(); quit_timers(); diff --git a/tools/ioemu/vl.h b/tools/ioemu/vl.h index 9d78cd25d9..00f5c16333 100644 --- a/tools/ioemu/vl.h +++ b/tools/ioemu/vl.h @@ -574,6 +574,9 @@ typedef struct BlockDriver BlockDriver; extern BlockDriver bdrv_raw; extern BlockDriver bdrv_host_device; +#ifdef CONFIG_STUBDOM +extern BlockDriver bdrv_vbd; +#endif extern BlockDriver bdrv_cow; extern BlockDriver bdrv_qcow; extern BlockDriver bdrv_vmdk; @@ -912,8 +915,11 @@ struct DisplayState { int height; void *opaque; + int switchbpp; + void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h); void (*dpy_resize)(struct DisplayState *s, int w, int h); + void (*dpy_colourdepth)(struct DisplayState *s, int depth); void (*dpy_refresh)(struct DisplayState *s); void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y, int dst_x, int dst_y, int w, int h); }; diff --git a/tools/ioemu/vnc.c b/tools/ioemu/vnc.c index 0dd78dd4b4..7f87f8ed18 100644 --- a/tools/ioemu/vnc.c +++ b/tools/ioemu/vnc.c @@ -30,6 +30,9 @@ #include "vl.h" #include "qemu_socket.h" #include <assert.h> +#ifdef CONFIG_STUBDOM +#include <netfront.h> +#endif /* The refresh interval starts at BASE. If we scan the buffer and find no change, we increase by INC, up to MAX. If the mouse moves @@ -85,8 +88,8 @@ typedef void VncWritePixels(VncState *vs, void *data, int size); typedef void VncSendHextileTile(VncState *vs, int x, int y, int w, int h, - uint32_t *last_bg, - uint32_t *last_fg, + void *last_bg, + void *last_fg, int *has_bg, int *has_fg); #if 0 @@ -154,6 +157,7 @@ struct VncState int has_resize; int has_hextile; int has_pointer_type_change; + int has_WMVi; int absolute; int last_x; int last_y; @@ -187,9 +191,9 @@ struct VncState VncWritePixels *write_pixels; VncSendHextileTile *send_hextile_tile; int pix_bpp, pix_big_endian; - int red_shift, red_max, red_shift1; - int green_shift, green_max, green_shift1; - int blue_shift, blue_max, blue_shift1; + int red_shift, red_max, red_shift1, red_max1; + int green_shift, green_max, green_shift1, green_max1; + int blue_shift, blue_max, blue_shift1, blue_max1; VncReadEvent *read_handler; size_t read_handler_expect; @@ -379,54 +383,67 @@ static void vnc_write_pixels_copy(VncState *vs, void *pixels, int size) /* slowest but generic code. */ static void vnc_convert_pixel(VncState *vs, uint8_t *buf, uint32_t v) { - unsigned int r, g, b; + uint8_t r, g, b; - r = (v >> vs->red_shift1) & vs->red_max; - g = (v >> vs->green_shift1) & vs->green_max; - b = (v >> vs->blue_shift1) & vs->blue_max; - v = (r << vs->red_shift) | - (g << vs->green_shift) | - (b << vs->blue_shift); + r = ((v >> vs->red_shift1) & vs->red_max1) * (vs->red_max + 1) / (vs->red_max1 + 1); + g = ((v >> vs->green_shift1) & vs->green_max1) * (vs->green_max + 1) / (vs->green_max1 + 1); + b = ((v >> vs->blue_shift1) & vs->blue_max1) * (vs->blue_max + 1) / (vs->blue_max1 + 1); switch(vs->pix_bpp) { case 1: - buf[0] = v; + buf[0] = (r << vs->red_shift) | (g << vs->green_shift) | (b << vs->blue_shift); break; case 2: + { + uint16_t *p = (uint16_t *) buf; + *p = (r << vs->red_shift) | (g << vs->green_shift) | (b << vs->blue_shift); if (vs->pix_big_endian) { - buf[0] = v >> 8; - buf[1] = v; - } else { - buf[1] = v >> 8; - buf[0] = v; + *p = htons(*p); } + } break; default: case 4: + { + uint32_t *p = (uint32_t *) buf; + *p = (r << vs->red_shift) | (g << vs->green_shift) | (b << vs->blue_shift); if (vs->pix_big_endian) { - buf[0] = v >> 24; - buf[1] = v >> 16; - buf[2] = v >> 8; - buf[3] = v; - } else { - buf[3] = v >> 24; - buf[2] = v >> 16; - buf[1] = v >> 8; - buf[0] = v; + *p = htonl(*p); } break; } + } } static void vnc_write_pixels_generic(VncState *vs, void *pixels1, int size) { - uint32_t *pixels = pixels1; uint8_t buf[4]; - int n, i; - n = size >> 2; - for(i = 0; i < n; i++) { - vnc_convert_pixel(vs, buf, pixels[i]); - vnc_write(vs, buf, vs->pix_bpp); + if (vs->depth == 4) { + uint32_t *pixels = pixels1; + int n, i; + n = size >> 2; + for(i = 0; i < n; i++) { + vnc_convert_pixel(vs, buf, pixels[i]); + vnc_write(vs, buf, vs->pix_bpp); + } + } else if (vs->depth == 2) { + uint16_t *pixels = pixels1; + int n, i; + n = size >> 1; + for(i = 0; i < n; i++) { + vnc_convert_pixel(vs, buf, pixels[i]); + vnc_write(vs, buf, vs->pix_bpp); + } + } else if (vs->depth == 1) { + uint8_t *pixels = pixels1; + int n, i; + n = size; + for(i = 0; i < n; i++) { + vnc_convert_pixel(vs, buf, pixels[i]); + vnc_write(vs, buf, vs->pix_bpp); + } + } else { + fprintf(stderr, "vnc_write_pixels_generic: VncState color depth not supported\n"); } } @@ -463,6 +480,18 @@ static void hextile_enc_cord(uint8_t *ptr, int x, int y, int w, int h) #undef BPP #define GENERIC +#define BPP 8 +#include "vnchextile.h" +#undef BPP +#undef GENERIC + +#define GENERIC +#define BPP 16 +#include "vnchextile.h" +#undef BPP +#undef GENERIC + +#define GENERIC #define BPP 32 #include "vnchextile.h" #undef BPP @@ -472,18 +501,22 @@ static void send_framebuffer_update_hextile(VncState *vs, int x, int y, int w, i { int i, j; int has_fg, has_bg; - uint32_t last_fg32, last_bg32; + void *last_fg, *last_bg; vnc_framebuffer_update(vs, x, y, w, h, 5); + last_fg = (void *) malloc(vs->depth); + last_bg = (void *) malloc(vs->depth); has_fg = has_bg = 0; for (j = y; j < (y + h); j += 16) { for (i = x; i < (x + w); i += 16) { vs->send_hextile_tile(vs, i, j, MIN(16, x + w - i), MIN(16, y + h - j), - &last_bg32, &last_fg32, &has_bg, &has_fg); + last_bg, last_fg, &has_bg, &has_fg); } } + free(last_fg); + free(last_bg); } static void send_framebuffer_update(VncState *vs, int x, int y, int w, int h) @@ -1278,6 +1311,7 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) vs->has_hextile = 0; vs->has_resize = 0; vs->has_pointer_type_change = 0; + vs->has_WMVi = 0; vs->absolute = -1; vs->ds->dpy_copy = NULL; @@ -1298,6 +1332,8 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) case -257: vs->has_pointer_type_change = 1; break; + case 0x574D5669: + vs->has_WMVi = 1; default: break; } @@ -1306,17 +1342,6 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings) check_pointer_type_change(vs, kbd_mouse_is_absolute()); } -static int compute_nbits(unsigned int val) -{ - int n; - n = 0; - while (val != 0) { - n++; - val >>= 1; - } - return n; -} - static void set_pixel_format(VncState *vs, int bits_per_pixel, int depth, int big_endian_flag, int true_color_flag, @@ -1335,23 +1360,24 @@ static void set_pixel_format(VncState *vs, vnc_client_error(vs); return; } - if (bits_per_pixel == 32 && + if (bits_per_pixel == 32 && + bits_per_pixel == vs->depth * 8 && host_big_endian_flag == big_endian_flag && red_max == 0xff && green_max == 0xff && blue_max == 0xff && red_shift == 16 && green_shift == 8 && blue_shift == 0) { - vs->depth = 4; vs->write_pixels = vnc_write_pixels_copy; vs->send_hextile_tile = send_hextile_tile_32; } else - if (bits_per_pixel == 16 && + if (bits_per_pixel == 16 && + bits_per_pixel == vs->depth * 8 && host_big_endian_flag == big_endian_flag && red_max == 31 && green_max == 63 && blue_max == 31 && red_shift == 11 && green_shift == 5 && blue_shift == 0) { - vs->depth = 2; vs->write_pixels = vnc_write_pixels_copy; vs->send_hextile_tile = send_hextile_tile_16; } else if (bits_per_pixel == 8 && + bits_per_pixel == vs->depth * 8 && red_max == 7 && green_max == 7 && blue_max == 3 && red_shift == 5 && green_shift == 2 && blue_shift == 0) { vs->depth = 1; @@ -1364,28 +1390,170 @@ static void set_pixel_format(VncState *vs, bits_per_pixel != 16 && bits_per_pixel != 32) goto fail; - vs->depth = 4; - vs->red_shift = red_shift; - vs->red_max = red_max; - vs->red_shift1 = 24 - compute_nbits(red_max); - vs->green_shift = green_shift; - vs->green_max = green_max; - vs->green_shift1 = 16 - compute_nbits(green_max); - vs->blue_shift = blue_shift; - vs->blue_max = blue_max; - vs->blue_shift1 = 8 - compute_nbits(blue_max); - vs->pix_bpp = bits_per_pixel / 8; + if (vs->depth == 4) { + vs->send_hextile_tile = send_hextile_tile_generic_32; + } else if (vs->depth == 2) { + vs->send_hextile_tile = send_hextile_tile_generic_16; + } else { + vs->send_hextile_tile = send_hextile_tile_generic_8; + } + vs->pix_big_endian = big_endian_flag; vs->write_pixels = vnc_write_pixels_generic; - vs->send_hextile_tile = send_hextile_tile_generic; } - - vnc_dpy_resize(vs->ds, vs->ds->width, vs->ds->height); + + vs->red_shift = red_shift; + vs->red_max = red_max; + vs->green_shift = green_shift; + vs->green_max = green_max; + vs->blue_shift = blue_shift; + vs->blue_max = blue_max; + vs->pix_bpp = bits_per_pixel / 8; vga_hw_invalidate(); vga_hw_update(); } +static void pixel_format_message (VncState *vs) { + char pad[3] = { 0, 0, 0 }; + + vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */ + if (vs->depth == 4) vnc_write_u8(vs, 24); /* depth */ + else vnc_write_u8(vs, vs->depth * 8); /* depth */ + +#ifdef WORDS_BIGENDIAN + vnc_write_u8(vs, 1); /* big-endian-flag */ +#else + vnc_write_u8(vs, 0); /* big-endian-flag */ +#endif + vnc_write_u8(vs, 1); /* true-color-flag */ + if (vs->depth == 4) { + vnc_write_u16(vs, 0xFF); /* red-max */ + vnc_write_u16(vs, 0xFF); /* green-max */ + vnc_write_u16(vs, 0xFF); /* blue-max */ + vnc_write_u8(vs, 16); /* red-shift */ + vnc_write_u8(vs, 8); /* green-shift */ + vnc_write_u8(vs, 0); /* blue-shift */ + vs->send_hextile_tile = send_hextile_tile_32; + } else if (vs->depth == 2) { + vnc_write_u16(vs, 31); /* red-max */ + vnc_write_u16(vs, 63); /* green-max */ + vnc_write_u16(vs, 31); /* blue-max */ + vnc_write_u8(vs, 11); /* red-shift */ + vnc_write_u8(vs, 5); /* green-shift */ + vnc_write_u8(vs, 0); /* blue-shift */ + vs->send_hextile_tile = send_hextile_tile_16; + } else if (vs->depth == 1) { + /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */ + vnc_write_u16(vs, 7); /* red-max */ + vnc_write_u16(vs, 7); /* green-max */ + vnc_write_u16(vs, 3); /* blue-max */ + vnc_write_u8(vs, 5); /* red-shift */ + vnc_write_u8(vs, 2); /* green-shift */ + vnc_write_u8(vs, 0); /* blue-shift */ + vs->send_hextile_tile = send_hextile_tile_8; + } + vs->red_max = vs->red_max1; + vs->green_max = vs->green_max1; + vs->blue_max = vs->blue_max1; + vs->red_shift = vs->red_shift1; + vs->green_shift = vs->green_shift1; + vs->blue_shift = vs->blue_shift1; + vs->pix_bpp = vs->depth * 8; + vs->write_pixels = vnc_write_pixels_copy; + + vnc_write(vs, pad, 3); /* padding */ +} + +static void vnc_dpy_colourdepth(DisplayState *ds, int depth) +{ + int host_big_endian_flag; + struct VncState *vs; + + if (!depth) return; + +#ifdef WORDS_BIGENDIAN + host_big_endian_flag = 1; +#else + host_big_endian_flag = 0; +#endif + vs = ds->opaque; + + switch (depth) { + case 8: + vs->depth = depth / 8; + vs->red_max1 = 7; + vs->green_max1 = 7; + vs->blue_max1 = 3; + vs->red_shift1 = 5; + vs->green_shift1 = 2; + vs->blue_shift1 = 0; + break; + case 16: + vs->depth = depth / 8; + vs->red_max1 = 31; + vs->green_max1 = 63; + vs->blue_max1 = 31; + vs->red_shift1 = 11; + vs->green_shift1 = 5; + vs->blue_shift1 = 0; + break; + case 32: + vs->depth = 4; + vs->red_max1 = 255; + vs->green_max1 = 255; + vs->blue_max1 = 255; + vs->red_shift1 = 16; + vs->green_shift1 = 8; + vs->blue_shift1 = 0; + break; + default: + return; + } + if (ds->switchbpp) { + vnc_client_error(vs); + } else if (vs->csock != -1 && vs->has_WMVi) { + /* Sending a WMVi message to notify the client*/ + vnc_write_u8(vs, 0); /* msg id */ + vnc_write_u8(vs, 0); + vnc_write_u16(vs, 1); /* number of rects */ + vnc_framebuffer_update(vs, 0, 0, ds->width, ds->height, 0x574D5669); + pixel_format_message(vs); + vnc_flush(vs); + } else { + if (vs->pix_bpp == 4 && vs->depth == 4 && + host_big_endian_flag == vs->pix_big_endian && + vs->red_max == 0xff && vs->green_max == 0xff && vs->blue_max == 0xff && + vs->red_shift == 16 && vs->green_shift == 8 && vs->blue_shift == 0) { + vs->write_pixels = vnc_write_pixels_copy; + vs->send_hextile_tile = send_hextile_tile_32; + } else if (vs->pix_bpp == 2 && vs->depth == 2 && + host_big_endian_flag == vs->pix_big_endian && + vs->red_max == 31 && vs->green_max == 63 && vs->blue_max == 31 && + vs->red_shift == 11 && vs->green_shift == 5 && vs->blue_shift == 0) { + vs->write_pixels = vnc_write_pixels_copy; + vs->send_hextile_tile = send_hextile_tile_16; + } else if (vs->pix_bpp == 1 && vs->depth == 1 && + host_big_endian_flag == vs->pix_big_endian && + vs->red_max == 7 && vs->green_max == 7 && vs->blue_max == 3 && + vs->red_shift == 5 && vs->green_shift == 2 && vs->blue_shift == 0) { + vs->write_pixels = vnc_write_pixels_copy; + vs->send_hextile_tile = send_hextile_tile_8; + } else { + if (vs->depth == 4) { + vs->send_hextile_tile = send_hextile_tile_generic_32; + } else if (vs->depth == 2) { + vs->send_hextile_tile = send_hextile_tile_generic_16; + } else { + vs->send_hextile_tile = send_hextile_tile_generic_8; + } + vs->write_pixels = vnc_write_pixels_generic; + } + } + + vnc_dpy_resize(ds, ds->width, ds->height); +} + static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) { int i; @@ -1473,7 +1641,6 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) { size_t l; - char pad[3] = { 0, 0, 0 }; vga_hw_update(); @@ -1482,43 +1649,7 @@ static int protocol_client_init(VncState *vs, uint8_t *data, size_t len) vnc_write_u16(vs, vs->ds->width); vnc_write_u16(vs, vs->ds->height); - vnc_write_u8(vs, vs->depth * 8); /* bits-per-pixel */ - vnc_write_u8(vs, vs->depth * 8); /* depth */ -#ifdef WORDS_BIGENDIAN - vnc_write_u8(vs, 1); /* big-endian-flag */ -#else - vnc_write_u8(vs, 0); /* big-endian-flag */ -#endif - vnc_write_u8(vs, 1); /* true-color-flag */ - if (vs->depth == 4) { - vnc_write_u16(vs, 0xFF); /* red-max */ - vnc_write_u16(vs, 0xFF); /* green-max */ - vnc_write_u16(vs, 0xFF); /* blue-max */ - vnc_write_u8(vs, 16); /* red-shift */ - vnc_write_u8(vs, 8); /* green-shift */ - vnc_write_u8(vs, 0); /* blue-shift */ - vs->send_hextile_tile = send_hextile_tile_32; - } else if (vs->depth == 2) { - vnc_write_u16(vs, 31); /* red-max */ - vnc_write_u16(vs, 63); /* green-max */ - vnc_write_u16(vs, 31); /* blue-max */ - vnc_write_u8(vs, 11); /* red-shift */ - vnc_write_u8(vs, 5); /* green-shift */ - vnc_write_u8(vs, 0); /* blue-shift */ - vs->send_hextile_tile = send_hextile_tile_16; - } else if (vs->depth == 1) { - /* XXX: change QEMU pixel 8 bit pixel format to match the VNC one ? */ - vnc_write_u16(vs, 7); /* red-max */ - vnc_write_u16(vs, 7); /* green-max */ - vnc_write_u16(vs, 3); /* blue-max */ - vnc_write_u8(vs, 5); /* red-shift */ - vnc_write_u8(vs, 2); /* green-shift */ - vnc_write_u8(vs, 0); /* blue-shift */ - vs->send_hextile_tile = send_hextile_tile_8; - } - vs->write_pixels = vnc_write_pixels_copy; - - vnc_write(vs, pad, 3); /* padding */ + pixel_format_message(vs); l = strlen(domain_name); vnc_write_u32(vs, l); @@ -2160,7 +2291,6 @@ void vnc_display_init(DisplayState *ds) vs->lsock = -1; vs->csock = -1; - vs->depth = 4; vs->last_x = -1; vs->last_y = -1; @@ -2177,9 +2307,12 @@ void vnc_display_init(DisplayState *ds) vs->ds->data = NULL; vs->ds->dpy_update = vnc_dpy_update; vs->ds->dpy_resize = vnc_dpy_resize; + vs->ds->dpy_colourdepth = vnc_dpy_colourdepth; vs->ds->dpy_refresh = vnc_dpy_refresh; - vnc_dpy_resize(vs->ds, 640, 400); + vs->ds->width = 640; + vs->ds->height = 400; + vnc_dpy_colourdepth(vs->ds, 32); } #if CONFIG_VNC_TLS @@ -2297,10 +2430,12 @@ int vnc_display_open(DisplayState *ds, const char *display, int find_unused) { struct sockaddr *addr; struct sockaddr_in iaddr; -#ifndef _WIN32 +#ifndef NO_UNIX_SOCKETS struct sockaddr_un uaddr; #endif +#ifndef CONFIG_STUBDOM int reuse_addr, ret; +#endif socklen_t addrlen; const char *p; VncState *vs = ds ? (VncState *)ds->opaque : vnc_state; @@ -2325,6 +2460,8 @@ int vnc_display_open(DisplayState *ds, const char *display, int find_unused) options++; if (strncmp(options, "password", 8) == 0) { password = 1; /* Require password auth */ + } else if (strncmp(options, "switchbpp", 9) == 0) { + ds->switchbpp = 1; #if CONFIG_VNC_TLS } else if (strncmp(options, "tls", 3) == 0) { tls = 1; /* Require TLS */ @@ -2432,6 +2569,15 @@ int vnc_display_open(DisplayState *ds, const char *display, int find_unused) return -1; } +#ifdef CONFIG_STUBDOM + { + struct ip_addr ipaddr = { iaddr.sin_addr.s_addr }; + struct ip_addr netmask = { 0 }; + struct ip_addr gw = { 0 }; + networking_set_addr(&ipaddr, &netmask, &gw); + } +#endif + iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900); vs->lsock = socket(PF_INET, SOCK_STREAM, 0); @@ -2442,6 +2588,7 @@ int vnc_display_open(DisplayState *ds, const char *display, int find_unused) return -1; } +#ifndef CONFIG_STUBDOM reuse_addr = 1; ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuse_addr, sizeof(reuse_addr)); @@ -2453,6 +2600,7 @@ int vnc_display_open(DisplayState *ds, const char *display, int find_unused) vs->display = NULL; return -1; } +#endif } while (bind(vs->lsock, addr, addrlen) == -1) { @@ -2483,6 +2631,7 @@ int vnc_display_open(DisplayState *ds, const char *display, int find_unused) return ntohs(iaddr.sin_port); } +#ifndef CONFIG_STUBDOM int vnc_start_viewer(int port) { int pid, i, open_max; @@ -2510,4 +2659,5 @@ int vnc_start_viewer(int port) return pid; } } +#endif diff --git a/tools/ioemu/vnchextile.h b/tools/ioemu/vnchextile.h index 3d894cd574..29b74840f5 100644 --- a/tools/ioemu/vnchextile.h +++ b/tools/ioemu/vnchextile.h @@ -2,29 +2,29 @@ #define CONCAT(a, b) CONCAT_I(a, b) #define pixel_t CONCAT(uint, CONCAT(BPP, _t)) #ifdef GENERIC -#define NAME generic +#define NAME CONCAT(generic_, BPP) #else #define NAME BPP #endif static void CONCAT(send_hextile_tile_, NAME)(VncState *vs, int x, int y, int w, int h, - uint32_t *last_bg32, - uint32_t *last_fg32, + void *last_bg_, + void *last_fg_, int *has_bg, int *has_fg) { uint8_t *row = (vs->ds->data + y * vs->ds->linesize + x * vs->depth); pixel_t *irow = (pixel_t *)row; int j, i; - pixel_t *last_bg = (pixel_t *)last_bg32; - pixel_t *last_fg = (pixel_t *)last_fg32; + pixel_t *last_bg = (pixel_t *)last_bg_; + pixel_t *last_fg = (pixel_t *)last_fg_; pixel_t bg = 0; pixel_t fg = 0; int n_colors = 0; int bg_count = 0; int fg_count = 0; int flags = 0; - uint8_t data[(sizeof(pixel_t) + 2) * 16 * 16]; + uint8_t data[(vs->pix_bpp + 2) * 16 * 16]; int n_data = 0; int n_subtiles = 0; diff --git a/tools/ioemu/xenstore.c b/tools/ioemu/xenstore.c index 9d33237cb3..8cad6bda2d 100644 --- a/tools/ioemu/xenstore.c +++ b/tools/ioemu/xenstore.c @@ -11,8 +11,10 @@ #include "vl.h" #include "block_int.h" #include <unistd.h> +#ifndef CONFIG_STUBDOM #include <sys/ipc.h> #include <sys/shm.h> +#endif #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -219,10 +221,18 @@ void xenstore_parse_domain_config(int domid) } /* open device now if media present */ +#ifdef CONFIG_STUBDOM + if (pasprintf(&buf, "%s/device/vbd/%s", path, e[i]) == -1) + continue; + if (bdrv_open2(bs, buf, 0 /* snapshot */, &bdrv_vbd) == 0) { + pstrcpy(bs->filename, sizeof(bs->filename), params); + continue; + } +#endif + if (params[0]) { if (bdrv_open(bs, params, 0 /* snapshot */) < 0) - fprintf(stderr, "qemu: could not open hard disk image '%s'\n", - params); + fprintf(stderr, "qemu: could not open vbd '%s' or hard disk image '%s'\n", buf, params); } } @@ -265,6 +275,10 @@ extern int vga_ram_size, bios_size; void xenstore_process_logdirty_event(void) { +#ifdef CONFIG_STUBDOM + /* XXX we just can't use shm. */ + return; +#else char *act; static char *active_path = NULL; static char *next_active_path = NULL; @@ -367,6 +381,7 @@ void xenstore_process_logdirty_event(void) /* Ack that we've switched */ xs_write(xsh, XBT_NULL, active_path, act, len); free(act); +#endif } |