aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-02-12 14:35:39 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-02-12 14:35:39 +0000
commit0243b256d6187ea610174531607366945e489605 (patch)
treefd2de9267b7493642626f8c84d7c81ebcd336bed /tools
parent67bfbd67d1311a1a590b47e568a07622d4492873 (diff)
downloadxen-0243b256d6187ea610174531607366945e489605.tar.gz
xen-0243b256d6187ea610174531607366945e489605.tar.bz2
xen-0243b256d6187ea610174531607366945e489605.zip
Add stubdomain support. See stubdom/README for usage details.
- Move PAGE_SIZE and STACK_SIZE into __PAGE_SIZE and __STACK_SIZE in arch_limits.h so as to permit getting them from there without pulling all the internal Mini-OS defines. - Setup a xen-elf cross-compilation environment in stubdom/cross-root - Add a POSIX layer on top of Mini-OS by linking against the newlib C library and lwIP, and implementing the Unixish part in mini-os/lib/sys.c - Cross-compile zlib and libpci too. - Add an xs.h-compatible layer on top of Mini-OS' xenbus. - Cross-compile libxc with an additional xc_minios.c and a few things disabled. - Cross-compile ioemu with an additional block-vbd, but without sound, tpm and other details. A few hacks are needed: - Align ide and scsi buffers at least on sector size to permit direct transmission to the block backend. While we are at it, just page-align it to possibly save a segment. Also, limit the scsi buffer size because of limitations of the block paravirtualization protocol. - Allocate big tables dynamically rather that letting them go to bss: when Mini-OS gets installed in memory, bss is not lazily allocated, and doing so during Mini-OS is unnecessarily trick while we can simply use malloc. - Had to change the Mini-OS compilation somehow, so as to export Mini-OS compilation flags to the Makefiles of libxc and ioemu. Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/ioemu/Makefile.target42
-rw-r--r--tools/ioemu/aes.c2
-rw-r--r--tools/ioemu/block-vbd.c341
-rw-r--r--tools/ioemu/block.c3
-rwxr-xr-xtools/ioemu/configure22
-rw-r--r--tools/ioemu/exec-all.h4
-rw-r--r--tools/ioemu/hw/ide.c4
-rw-r--r--tools/ioemu/hw/scsi-disk.c8
-rw-r--r--tools/ioemu/hw/xen_machine_fv.c3
-rw-r--r--tools/ioemu/vl.c65
-rw-r--r--tools/ioemu/vl.h3
-rw-r--r--tools/ioemu/vnc.c19
-rw-r--r--tools/ioemu/xenstore.c19
-rw-r--r--tools/libxc/Makefile23
-rw-r--r--tools/libxc/ia64/Makefile2
-rw-r--r--tools/libxc/xc_minios.c313
16 files changed, 846 insertions, 27 deletions
diff --git a/tools/ioemu/Makefile.target b/tools/ioemu/Makefile.target
index 2b1bc6bb13..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,23 +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
@@ -513,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-vbd.c b/tools/ioemu/block-vbd.c
new file mode 100644
index 0000000000..9cb97255e6
--- /dev/null
+++ b/tools/ioemu/block-vbd.c
@@ -0,0 +1,341 @@
+/*
+ * 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 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_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)
+{
+ BDRVVbdState *s;
+ for (s = vbds.lh_first; s; s = s->list.le_next)
+ blkfront_aio_poll(s->dev);
+}
+
+/* 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 = 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 = 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/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/ide.c b/tools/ioemu/hw/ide.c
index 0e65141ec6..cba064bd10 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 = memalign(getpagesize(), MAX_MULT_SECTORS*512 + 4);
if (i == 0)
s->bs = hd0;
else
diff --git a/tools/ioemu/hw/scsi-disk.c b/tools/ioemu/hw/scsi-disk.c
index c6280fd559..d62d4d0d95 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 = memalign(getpagesize(), SCSI_DMA_BUF_SIZE);
}
r->dev = s;
r->tag = tag;
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/vl.c b/tools/ioemu/vl.c
index 452bfcc555..6841f07848 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"
@@ -132,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];
@@ -270,6 +277,9 @@ void default_ioport_writel(void *opaque, uint32_t address, uint32_t data)
void init_ioports(void)
{
+ 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 */
@@ -797,9 +807,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)
@@ -1137,9 +1144,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);
@@ -1497,6 +1501,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;
@@ -1742,6 +1747,7 @@ static CharDriverState *qemu_chr_open_stdio(void)
}
return chr;
}
+#endif
/*
* Create a store entry for a device (e.g., monitor, serial/parallel lines).
@@ -1751,6 +1757,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;
@@ -1826,8 +1835,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,
@@ -2486,6 +2497,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 */
@@ -2978,12 +2990,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__)
@@ -3473,7 +3487,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;
@@ -3561,6 +3584,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') {
@@ -3593,6 +3617,7 @@ static int net_tap_init(VLANState *vlan, const char *ifname1,
}
}
}
+#endif
s = net_tap_fd_init(vlan, fd);
if (!s)
return -1;
@@ -7041,12 +7066,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)");
@@ -7072,6 +7099,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. */
@@ -7114,6 +7142,7 @@ int main(int argc, char **argv)
}
}
#endif
+#endif
register_machines();
machine = first_machine;
@@ -7631,7 +7660,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
@@ -7799,8 +7836,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)
@@ -7928,6 +7967,7 @@ int main(int argc, char **argv)
}
#endif
+#ifndef CONFIG_STUBDOM
/* Unblock SIGTERM and SIGHUP, which may have been blocked by the caller */
signal(SIGHUP, SIG_DFL);
sigemptyset(&set);
@@ -7935,6 +7975,7 @@ int main(int argc, char **argv)
sigaddset(&set, SIGHUP);
if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1)
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 04d04845c5..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;
diff --git a/tools/ioemu/vnc.c b/tools/ioemu/vnc.c
index 7b6e633f7a..f07ce8ca34 100644
--- a/tools/ioemu/vnc.c
+++ b/tools/ioemu/vnc.c
@@ -27,10 +27,12 @@
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
-#include <arpa/inet.h>
#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
@@ -2407,7 +2409,9 @@ int vnc_display_open(DisplayState *ds, const char *display, int find_unused)
#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;
@@ -2539,6 +2543,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);
@@ -2549,6 +2562,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));
@@ -2560,6 +2574,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) {
@@ -2590,6 +2605,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;
@@ -2617,4 +2633,5 @@ int vnc_start_viewer(int port)
return pid;
}
}
+#endif
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
}
diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index ffc5662052..41dcbab808 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -5,10 +5,12 @@ MAJOR = 3.2
MINOR = 0
CTRL_SRCS-y :=
+ifneq ($(stubdom),y)
CTRL_SRCS-y += xc_core.c
CTRL_SRCS-$(CONFIG_X86) += xc_core_x86.c
CTRL_SRCS-$(CONFIG_IA64) += xc_core_ia64.c
CTRL_SRCS-$(CONFIG_POWERPC) += xc_core_powerpc.c
+endif
CTRL_SRCS-y += xc_domain.c
CTRL_SRCS-y += xc_evtchn.c
CTRL_SRCS-y += xc_misc.c
@@ -19,21 +21,29 @@ CTRL_SRCS-y += xc_private.c
CTRL_SRCS-y += xc_sedf.c
CTRL_SRCS-y += xc_csched.c
CTRL_SRCS-y += xc_tbuf.c
+ifneq ($(stubdom),y)
CTRL_SRCS-y += xc_resume.c
+endif
CTRL_SRCS-$(CONFIG_X86) += xc_pagetab.c
+ifneq ($(stubdom),y)
CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c
CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.c
CTRL_SRCS-$(CONFIG_X86_Linux) += xc_ptrace.c xc_ptrace_core.c
CTRL_SRCS-$(CONFIG_NetBSD) += xc_netbsd.c
+endif
+CTRL_SRCS-$(stubdom) += xc_minios.c
GUEST_SRCS-y :=
GUEST_SRCS-y += xg_private.c
+ifneq ($(stubdom),y)
GUEST_SRCS-$(CONFIG_MIGRATE) += xc_domain_restore.c xc_domain_save.c
GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
+endif
VPATH = ../../xen/common/libelf
CFLAGS += -I../../xen/common/libelf
+ifneq ($(stubdom),y)
GUEST_SRCS-y += libelf-tools.c libelf-loader.c
GUEST_SRCS-y += libelf-dominfo.c libelf-relocate.c
@@ -46,6 +56,7 @@ GUEST_SRCS-y += xc_dom_compat_linux.c
GUEST_SRCS-$(CONFIG_X86) += xc_dom_x86.c
GUEST_SRCS-$(CONFIG_IA64) += xc_dom_ia64.c
GUEST_SRCS-$(CONFIG_POWERPC) += xc_dom_powerpc.c
+endif
-include $(XEN_TARGET_ARCH)/Makefile
@@ -64,6 +75,10 @@ CFLAGS += -Wp,-MD,.$(@F).d
LDFLAGS += -L.
DEPS = .*.d
+ifneq ($(stubdom),y)
+LDLIBS = -lpthread
+endif
+
CTRL_LIB_OBJS := $(patsubst %.c,%.o,$(CTRL_SRCS-y))
CTRL_PIC_OBJS := $(patsubst %.c,%.opic,$(CTRL_SRCS-y))
@@ -71,10 +86,14 @@ GUEST_LIB_OBJS := $(patsubst %.c,%.o,$(GUEST_SRCS-y))
GUEST_PIC_OBJS := $(patsubst %.c,%.opic,$(GUEST_SRCS-y))
LIB := libxenctrl.a
+ifneq ($(stubdom),y)
LIB += libxenctrl.so libxenctrl.so.$(MAJOR) libxenctrl.so.$(MAJOR).$(MINOR)
+endif
LIB += libxenguest.a
+ifneq ($(stubdom),y)
LIB += libxenguest.so libxenguest.so.$(MAJOR) libxenguest.so.$(MAJOR).$(MINOR)
+endif
.PHONY: all
all: build
@@ -133,7 +152,7 @@ libxenctrl.so.$(MAJOR): libxenctrl.so.$(MAJOR).$(MINOR)
ln -sf $< $@
libxenctrl.so.$(MAJOR).$(MINOR): $(CTRL_PIC_OBJS)
- $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ -lpthread
+ $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ $(LDLIBS)
# libxenguest
@@ -146,7 +165,7 @@ libxenguest.so.$(MAJOR): libxenguest.so.$(MAJOR).$(MINOR)
ln -sf $< $@
libxenguest.so.$(MAJOR).$(MINOR): $(GUEST_PIC_OBJS) libxenctrl.so
- $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $(GUEST_PIC_OBJS) -lz -lxenctrl -lpthread
+ $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $(GUEST_PIC_OBJS) -lz -lxenctrl $(LDLIBS)
-include $(DEPS)
diff --git a/tools/libxc/ia64/Makefile b/tools/libxc/ia64/Makefile
index 8a23024b24..4fd4fbbe86 100644
--- a/tools/libxc/ia64/Makefile
+++ b/tools/libxc/ia64/Makefile
@@ -1,3 +1,4 @@
+ifneq ($(stubdom),y)
CTRL_SRCS-y += ia64/xc_ia64_stubs.c
GUEST_SRCS-y += ia64/xc_ia64_hvm_build.c
@@ -8,6 +9,7 @@ GUEST_SRCS-y += ia64/xc_dom_ia64_util.c
GUEST_SRCS-y += ia64/dom_fw_acpi.c
DOMFW_SRCS_BASE := dom_fw_common.c dom_fw_domu.c dom_fw_asm.S
+endif
DOMFW_SRCS := $(addprefix ia64/, $(DOMFW_SRCS_BASE))
$(DOMFW_SRCS):
ln -sf ../$(XEN_ROOT)/xen/arch/ia64/xen/$(@F) $@
diff --git a/tools/libxc/xc_minios.c b/tools/libxc/xc_minios.c
new file mode 100644
index 0000000000..53f7a148da
--- /dev/null
+++ b/tools/libxc/xc_minios.c
@@ -0,0 +1,313 @@
+/******************************************************************************
+ *
+ * Copyright 2007-2008 Samuel Thibault <samuel.thibault@eu.citrix.com>.
+ * All rights reserved.
+ * Use is subject to license terms.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ */
+
+#undef NDEBUG
+#include <types.h>
+#include <os.h>
+#include <mm.h>
+#include <lib.h>
+#include <events.h>
+#include <wait.h>
+#include <sys/mman.h>
+#include <errno.h>
+
+#include <xen/memory.h>
+#include <xen/sys/evtchn.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <assert.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include "xc_private.h"
+
+extern struct wait_queue_head event_queue;
+
+int xc_interface_open(void)
+{
+ return 0;
+}
+
+int xc_interface_close(int xc_handle)
+{
+ return 0;
+}
+
+void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
+ xen_pfn_t *arr, int num)
+{
+ unsigned long pt_prot = 0;
+#ifdef __ia64__
+ /* TODO */
+#else
+ if (prot & PROT_READ)
+ pt_prot = L1_PROT_RO;
+ if (prot & PROT_WRITE)
+ pt_prot = L1_PROT;
+#endif
+ return map_frames_ex(arr, num, 1, 0, 1, dom, 1, pt_prot);
+}
+
+void *xc_map_foreign_range(int xc_handle, uint32_t dom,
+ int size, int prot,
+ unsigned long mfn)
+{
+ unsigned long pt_prot = 0;
+ printf("xc_map_foreign_range(%lx, %d)\n", mfn, size);
+#ifdef __ia64__
+ /* TODO */
+#else
+ if (prot & PROT_READ)
+ pt_prot = L1_PROT_RO;
+ if (prot & PROT_WRITE)
+ pt_prot = L1_PROT;
+#endif
+ assert(!(size % getpagesize()));
+ return map_frames_ex(&mfn, size / getpagesize(), 0, 1, 1, dom, 0, pt_prot);
+}
+
+int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
+ privcmd_mmap_entry_t *entries, int nr)
+{
+ printf("xc_map_foreign_ranges, TODO\n");
+ do_exit();
+}
+
+int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
+{
+ multicall_entry_t call;
+ int i, ret;
+
+ call.op = hypercall->op;
+ for (i = 0; i < sizeof(hypercall->arg) / sizeof(*hypercall->arg); i++)
+ call.args[i] = hypercall->arg[i];
+
+ ret = HYPERVISOR_multicall(&call, 1);
+
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ if (call.result < 0) {
+ errno = -call.result;
+ return -1;
+ }
+ return call.result;
+}
+
+int xc_find_device_number(const char *name)
+{
+ printf("xc_find_device_number(%s)\n", name);
+ do_exit();
+}
+
+int xc_evtchn_open(void)
+{
+ int fd = alloc_fd(FTYPE_EVTCHN), i;
+ for (i = 0; i < MAX_EVTCHN_PORTS; i++) {
+ files[fd].evtchn.ports[i].port = -1;
+ files[fd].evtchn.ports[i].bound = 0;
+ }
+ printf("evtchn_open() -> %d\n", fd);
+ return fd;
+}
+
+int xc_evtchn_close(int xce_handle)
+{
+ int i;
+ for (i = 0; i < MAX_EVTCHN_PORTS; i++)
+ if (files[xce_handle].evtchn.ports[i].bound)
+ unbind_evtchn(files[xce_handle].evtchn.ports[i].port);
+ files[xce_handle].type = FTYPE_NONE;
+ return 0;
+}
+
+int xc_evtchn_fd(int xce_handle)
+{
+ return xce_handle;
+}
+
+int xc_evtchn_notify(int xce_handle, evtchn_port_t port)
+{
+ int ret;
+
+ ret = notify_remote_via_evtchn(port);
+
+ if (ret < 0) {
+ errno = -ret;
+ ret = -1;
+ }
+ return ret;
+}
+
+/* XXX Note: This is not threadsafe */
+static int port_alloc(int xce_handle) {
+ int i;
+ for (i= 0; i < MAX_EVTCHN_PORTS; i++)
+ if (files[xce_handle].evtchn.ports[i].port == -1)
+ break;
+ if (i == MAX_EVTCHN_PORTS) {
+ printf("Too many ports in xc handle\n");
+ errno = EMFILE;
+ return -1;
+ }
+ files[xce_handle].evtchn.ports[i].pending = 0;
+ return i;
+}
+
+static void poke_port(int xce_handle, evtchn_port_t port)
+{
+ shared_info_t *s = HYPERVISOR_shared_info;
+ printk("poking port %d\n", port);
+ synch_set_bit(port, &s->evtchn_pending[0]);
+ xc_evtchn_unmask(xce_handle, port);
+}
+
+static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
+{
+ int xce_handle = (intptr_t) data;
+ int i;
+ assert(files[xce_handle].type == FTYPE_EVTCHN);
+ mask_evtchn(port);
+ for (i= 0; i < MAX_EVTCHN_PORTS; i++)
+ if (files[xce_handle].evtchn.ports[i].port == port)
+ break;
+ if (i == MAX_EVTCHN_PORTS) {
+ printk("Unknown port for handle %d\n", xce_handle);
+ return;
+ }
+ files[xce_handle].evtchn.ports[i].pending++;
+ files[xce_handle].read = 1;
+ wake_up(&event_queue);
+}
+
+evtchn_port_or_error_t xc_evtchn_bind_unbound_port(int xce_handle, int domid)
+{
+ int ret, i;
+ evtchn_port_t port;
+
+ assert(get_current() == main_thread);
+ i = port_alloc(xce_handle);
+ if (i == -1)
+ return -1;
+
+ printf("xc_evtchn_bind_unbound_port(%d)", domid);
+ ret = evtchn_alloc_unbound(domid, evtchn_handler, (void*)(intptr_t)xce_handle, &port);
+ printf(" = %d\n", ret);
+
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ files[xce_handle].evtchn.ports[i].bound = 1;
+ files[xce_handle].evtchn.ports[i].port = port;
+ return port;
+}
+
+evtchn_port_or_error_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
+ evtchn_port_t remote_port)
+{
+ evtchn_port_t local_port;
+ int ret, i;
+
+ assert(get_current() == main_thread);
+ i = port_alloc(xce_handle);
+ if (i == -1)
+ return -1;
+
+ printf("xc_evtchn_bind_interdomain(%d, %"PRId32")", domid, remote_port);
+ ret = evtchn_bind_interdomain(domid, remote_port, evtchn_handler, (void*)(intptr_t)xce_handle, &local_port);
+ printf(" = %d\n", ret);
+
+ if (ret < 0) {
+ errno = -ret;
+ return -1;
+ }
+ files[xce_handle].evtchn.ports[i].bound = 1;
+ files[xce_handle].evtchn.ports[i].port = local_port;
+/* Poke port on start: HVM won't send an event for the very first request since
+ * we were not ready yet */
+ poke_port(xce_handle, local_port);
+ return local_port;
+}
+
+int xc_evtchn_unbind(int xce_handle, evtchn_port_t port)
+{
+ int i;
+ for (i = 0; i < MAX_EVTCHN_PORTS; i++)
+ if (files[xce_handle].evtchn.ports[i].port == port) {
+ files[xce_handle].evtchn.ports[i].port = -1;
+ break;
+ }
+ if (i == MAX_EVTCHN_PORTS)
+ printf("Warning: couldn't find port %"PRId32" for xc handle %x\n", port, xce_handle);
+ files[xce_handle].evtchn.ports[i].bound = 0;
+ unbind_evtchn(port);
+ return 0;
+}
+
+evtchn_port_or_error_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq)
+{
+ evtchn_port_t port;
+ int i;
+
+ assert(get_current() == main_thread);
+ i = port_alloc(xce_handle);
+ if (i == -1)
+ return -1;
+
+ printf("xc_evtchn_bind_virq(%d)", virq);
+ port = bind_virq(virq, evtchn_handler, (void*)(intptr_t)xce_handle);
+
+ if (port < 0) {
+ errno = -port;
+ return -1;
+ }
+ files[xce_handle].evtchn.ports[i].bound = 1;
+ files[xce_handle].evtchn.ports[i].port = port;
+ return port;
+}
+
+evtchn_port_or_error_t xc_evtchn_pending(int xce_handle)
+{
+ int i;
+ unsigned long flags;
+ local_irq_save(flags);
+ for (i = 0; i < MAX_EVTCHN_PORTS; i++) {
+ evtchn_port_t port = files[xce_handle].evtchn.ports[i].port;
+ if (port != -1 && files[xce_handle].evtchn.ports[i].pending) {
+ files[xce_handle].evtchn.ports[i].pending--;
+ local_irq_restore(flags);
+ return port;
+ }
+ }
+ files[xce_handle].read = 0;
+ local_irq_restore(flags);
+ return -1;
+}
+
+int xc_evtchn_unmask(int xce_handle, evtchn_port_t port)
+{
+ unmask_evtchn(port);
+ return 0;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */