ia64/xen-unstable

changeset 17042:a905c582a406

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>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Feb 12 14:35:39 2008 +0000 (2008-02-12)
parents 88818d55e95a
children 319a54d5c804
files .hgignore Config.mk extras/mini-os/Config.mk extras/mini-os/Makefile extras/mini-os/arch/ia64/Makefile extras/mini-os/arch/ia64/minios-ia64.lds extras/mini-os/arch/ia64/mm.c extras/mini-os/arch/x86/Makefile extras/mini-os/arch/x86/arch.mk extras/mini-os/arch/x86/minios-x86_32.lds extras/mini-os/arch/x86/minios-x86_64.lds extras/mini-os/arch/x86/mm.c extras/mini-os/arch/x86/x86_32.S extras/mini-os/arch/x86/x86_64.S extras/mini-os/blkfront.c extras/mini-os/include/arch/cc.h extras/mini-os/include/byteswap.h extras/mini-os/include/console.h extras/mini-os/include/errno.h extras/mini-os/include/fcntl.h extras/mini-os/include/fs.h extras/mini-os/include/ia64/arch_limits.h extras/mini-os/include/ia64/arch_mm.h extras/mini-os/include/ia64/page.h extras/mini-os/include/lib.h extras/mini-os/include/linux/types.h extras/mini-os/include/mm.h extras/mini-os/include/netfront.h extras/mini-os/include/posix/dirent.h extras/mini-os/include/posix/limits.h extras/mini-os/include/posix/netdb.h extras/mini-os/include/posix/netinet/in.h extras/mini-os/include/posix/netinet/tcp.h extras/mini-os/include/posix/pthread.h extras/mini-os/include/posix/stdlib.h extras/mini-os/include/posix/strings.h extras/mini-os/include/posix/sys/ioctl.h extras/mini-os/include/posix/sys/mman.h extras/mini-os/include/posix/sys/select.h extras/mini-os/include/posix/sys/socket.h extras/mini-os/include/posix/termios.h extras/mini-os/include/posix/time.h extras/mini-os/include/posix/unistd.h extras/mini-os/include/sched.h extras/mini-os/include/sys/time.h extras/mini-os/include/time.h extras/mini-os/include/x86/arch_limits.h extras/mini-os/include/x86/arch_mm.h extras/mini-os/include/x86/arch_sched.h extras/mini-os/include/x86/arch_spinlock.h extras/mini-os/include/x86/os.h extras/mini-os/lib/sys.c extras/mini-os/lib/xs.c extras/mini-os/main-caml.c extras/mini-os/main.c extras/mini-os/minios.mk extras/mini-os/mm.c extras/mini-os/netfront.c extras/mini-os/sched.c stubdom/Makefile stubdom/README stubdom/caml/Makefile stubdom/caml/hello.ml stubdom/libpci.config.h stubdom/libpci.config.mak stubdom/stubdom-dm tools/ioemu/Makefile.target tools/ioemu/aes.c tools/ioemu/block-vbd.c tools/ioemu/block.c tools/ioemu/configure tools/ioemu/exec-all.h tools/ioemu/hw/ide.c tools/ioemu/hw/scsi-disk.c tools/ioemu/hw/xen_machine_fv.c tools/ioemu/vl.c tools/ioemu/vl.h tools/ioemu/vnc.c tools/ioemu/xenstore.c tools/libxc/Makefile tools/libxc/ia64/Makefile tools/libxc/xc_minios.c
line diff
     1.1 --- a/.hgignore	Tue Feb 12 11:37:45 2008 +0000
     1.2 +++ b/.hgignore	Tue Feb 12 14:35:39 2008 +0000
     1.3 @@ -80,6 +80,17 @@
     1.4  ^pristine-.*$
     1.5  ^ref-.*$
     1.6  ^tmp-.*$
     1.7 +^stubdom/binutils.*$
     1.8 +^stubdom/cross-root.*$
     1.9 +^stubdom/gcc.*$
    1.10 +^stubdom/include.*$
    1.11 +^stubdom/ioemu.*$
    1.12 +^stubdom/libxc.*$
    1.13 +^stubdom/lwip.*$
    1.14 +^stubdom/mini-os.*$
    1.15 +^stubdom/newlib.*$
    1.16 +^stubdom/pciutils.*$
    1.17 +^stubdom/zlib.*$
    1.18  ^tools/.*/TAGS$
    1.19  ^tools/.*/build/lib.*/.*\.py$
    1.20  ^tools/blktap/Makefile\.smh$
     2.1 --- a/Config.mk	Tue Feb 12 11:37:45 2008 +0000
     2.2 +++ b/Config.mk	Tue Feb 12 14:35:39 2008 +0000
     2.3 @@ -28,6 +28,14 @@ DESTDIR     ?= /
     2.4  include $(XEN_ROOT)/config/$(XEN_OS).mk
     2.5  include $(XEN_ROOT)/config/$(XEN_TARGET_ARCH).mk
     2.6  
     2.7 +ifeq ($(stubdom),y)
     2.8 +include $(XEN_ROOT)/extras/mini-os/Config.mk
     2.9 +CFLAGS += $(DEF_CFLAGS) $(ARCH_CFLAGS)
    2.10 +CPPFLAGS += $(DEF_CPPFLAGS) $(ARCH_CPPFLAGS) $(extra_incl)
    2.11 +ASFLAGS += $(DEF_ASFLAGS) $(ARCH_ASFLAGS)
    2.12 +LDFLAGS += $(DEF_LDFLAGS) $(ARCH_LDFLAGS)
    2.13 +endif
    2.14 +
    2.15  ifneq ($(EXTRA_PREFIX),)
    2.16  EXTRA_INCLUDES += $(EXTRA_PREFIX)/include
    2.17  EXTRA_LIB += $(EXTRA_PREFIX)/$(LIBLEAFDIR)
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/extras/mini-os/Config.mk	Tue Feb 12 14:35:39 2008 +0000
     3.3 @@ -0,0 +1,76 @@
     3.4 +# Set mini-os root path, used in mini-os.mk.
     3.5 +MINI-OS_ROOT=$(XEN_ROOT)/extras/mini-os
     3.6 +export MINI-OS_ROOT
     3.7 +
     3.8 +ifeq ($(XEN_TARGET_ARCH),x86_32)
     3.9 +export pae ?= y
    3.10 +endif
    3.11 +libc = $(stubdom)
    3.12 +
    3.13 +XEN_INTERFACE_VERSION := 0x00030205
    3.14 +export XEN_INTERFACE_VERSION
    3.15 +
    3.16 +# Try to find out the architecture family TARGET_ARCH_FAM.
    3.17 +# First check whether x86_... is contained (for x86_32, x86_32y, x86_64).
    3.18 +# If not x86 then use $(XEN_TARGET_ARCH) -> for ia64, ...
    3.19 +ifeq ($(findstring x86_,$(XEN_TARGET_ARCH)),x86_)
    3.20 +TARGET_ARCH_FAM = x86
    3.21 +else
    3.22 +TARGET_ARCH_FAM = $(XEN_TARGET_ARCH)
    3.23 +endif
    3.24 +
    3.25 +# The architecture family directory below mini-os.
    3.26 +TARGET_ARCH_DIR := arch/$(TARGET_ARCH_FAM)
    3.27 +
    3.28 +# Export these variables for possible use in architecture dependent makefiles.
    3.29 +export TARGET_ARCH_DIR
    3.30 +export TARGET_ARCH_FAM
    3.31 +export XEN_TARGET_X86_PAE 
    3.32 +
    3.33 +# This is used for architecture specific links.
    3.34 +# This can be overwritten from arch specific rules.
    3.35 +ARCH_LINKS =
    3.36 +
    3.37 +# The path pointing to the architecture specific header files.
    3.38 +ARCH_INC := $(TARGET_ARCH_FAM)
    3.39 +
    3.40 +# For possible special header directories.
    3.41 +# This can be overwritten from arch specific rules.
    3.42 +EXTRA_INC = $(ARCH_INC)	
    3.43 +
    3.44 +# Include the architecture family's special makerules.
    3.45 +# This must be before include minios.mk!
    3.46 +include $(MINI-OS_ROOT)/$(TARGET_ARCH_DIR)/arch.mk
    3.47 +
    3.48 +extra_incl := $(foreach dir,$(EXTRA_INC),-I$(MINI-OS_ROOT)/include/$(dir))
    3.49 +
    3.50 +DEF_CPPFLAGS += -I$(MINI-OS_ROOT)/include
    3.51 +
    3.52 +ifeq ($(stubdom),y)
    3.53 +DEF_CPPFLAGS += -DCONFIG_STUBDOM
    3.54 +endif
    3.55 +
    3.56 +ifeq ($(libc),y)
    3.57 +DEF_CPPFLAGS += -DHAVE_LIBC
    3.58 +DEF_CPPFLAGS += -I$(MINI-OS_ROOT)/include/posix
    3.59 +DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/xenstore
    3.60 +endif
    3.61 +
    3.62 +ifneq ($(LWIPDIR),)
    3.63 +lwip=y
    3.64 +DEF_CPPFLAGS += -DHAVE_LWIP
    3.65 +DEF_CPPFLAGS += -I$(LWIPDIR)/src/include
    3.66 +DEF_CPPFLAGS += -I$(LWIPDIR)/src/include/ipv4
    3.67 +endif
    3.68 +
    3.69 +ifneq ($(QEMUDIR),)
    3.70 +qemu=y
    3.71 +endif
    3.72 +
    3.73 +ifneq ($(CAMLDIR),)
    3.74 +caml=y
    3.75 +endif
    3.76 +
    3.77 +ifeq ($(pae),y)
    3.78 +DEF_CPPFLAGS += -DCONFIG_X86_PAE
    3.79 +endif
     4.1 --- a/extras/mini-os/Makefile	Tue Feb 12 11:37:45 2008 +0000
     4.2 +++ b/extras/mini-os/Makefile	Tue Feb 12 14:35:39 2008 +0000
     4.3 @@ -4,54 +4,11 @@
     4.4  # Makefile and a arch.mk.
     4.5  #
     4.6  
     4.7 -XEN_ROOT = ../..
     4.8 +export XEN_ROOT = ../..
     4.9  include $(XEN_ROOT)/Config.mk
    4.10  
    4.11 -XEN_INTERFACE_VERSION := 0x00030205
    4.12 -export XEN_INTERFACE_VERSION
    4.13 -
    4.14 -# Set TARGET_ARCH
    4.15 -override TARGET_ARCH := $(XEN_TARGET_ARCH)
    4.16 -
    4.17 -# Set mini-os root path, used in mini-os.mk.
    4.18 -MINI-OS_ROOT=$(PWD)
    4.19 -export MINI-OS_ROOT
    4.20 -
    4.21 -# Try to find out the architecture family TARGET_ARCH_FAM.
    4.22 -# First check whether x86_... is contained (for x86_32, x86_32y, x86_64).
    4.23 -# If not x86 then use $(TARGET_ARCH) -> for ia64, ...
    4.24 -ifeq ($(findstring x86_,$(TARGET_ARCH)),x86_)
    4.25 -TARGET_ARCH_FAM = x86
    4.26 -else
    4.27 -TARGET_ARCH_FAM = $(TARGET_ARCH)
    4.28 -endif
    4.29 -
    4.30 -# The architecture family directory below mini-os.
    4.31 -TARGET_ARCH_DIR := arch/$(TARGET_ARCH_FAM)
    4.32 -
    4.33 -# Export these variables for possible use in architecture dependent makefiles.
    4.34 -export TARGET_ARCH
    4.35 -export TARGET_ARCH_DIR
    4.36 -export TARGET_ARCH_FAM
    4.37 -export XEN_TARGET_X86_PAE 
    4.38 -
    4.39 -# This is used for architecture specific links.
    4.40 -# This can be overwritten from arch specific rules.
    4.41 -ARCH_LINKS =
    4.42 -
    4.43 -# For possible special header directories.
    4.44 -# This can be overwritten from arch specific rules.
    4.45 -EXTRA_INC =
    4.46 -
    4.47 -# Include the architecture family's special makerules.
    4.48 -# This must be before include minios.mk!
    4.49 -include $(TARGET_ARCH_DIR)/arch.mk
    4.50 -
    4.51 -ifneq ($(LWIPDIR),)
    4.52 -lwip=y
    4.53 -DEF_CFLAGS += -DHAVE_LWIP
    4.54 -DEF_CFLAGS += -I$(LWIPDIR)/src/include
    4.55 -DEF_CFLAGS += -I$(LWIPDIR)/src/include/ipv4
    4.56 +ifneq ($(stubdom),y)
    4.57 +include Config.mk
    4.58  endif
    4.59  
    4.60  # Include common mini-os makerules.
    4.61 @@ -63,7 +20,7 @@ include minios.mk
    4.62  # Define some default flags for linking.
    4.63  LDLIBS := 
    4.64  LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
    4.65 -LDFLAGS_FINAL := -T $(TARGET_ARCH_DIR)/minios-$(TARGET_ARCH).lds
    4.66 +LDFLAGS_FINAL := -T $(TARGET_ARCH_DIR)/minios-$(XEN_TARGET_ARCH).lds
    4.67  
    4.68  # Prefix for global API names. All other symbols are localised before
    4.69  # linking with EXTRA_OBJS.
    4.70 @@ -112,14 +69,38 @@ lwip.a: $(LWO)
    4.71  	$(AR) cqs $@ $^
    4.72  
    4.73  OBJS += lwip.a
    4.74 +endif
    4.75  
    4.76 -OBJS := $(filter-out $(LWO), $(OBJS))
    4.77 +OBJS := $(filter-out lwip%.o $(LWO), $(OBJS))
    4.78 +
    4.79 +ifeq ($(caml),y)
    4.80 +CAMLLIB = $(shell ocamlc -where)
    4.81 +OBJS += $(CAMLDIR)/caml.o
    4.82 +OBJS += $(CAMLLIB)/libasmrun.a
    4.83 +CFLAGS += -I$(CAMLLIB)
    4.84 +LDLIBS += -lm
    4.85  else
    4.86 -OBJS := $(filter-out daytime.o lwip%.o, $(OBJS))
    4.87 +OBJS := $(filter-out main-caml.o, $(OBJS))
    4.88 +endif
    4.89 +
    4.90 +ifeq ($(qemu),y)
    4.91 +OBJS += $(QEMUDIR)/i386-dm-stubdom/qemu.a $(QEMUDIR)/i386-dm-stubdom/libqemu.a
    4.92 +CFLAGS += -DCONFIG_QEMU
    4.93 +endif
    4.94 +
    4.95 +ifeq ($(libc),y)
    4.96 +LDLIBS += -L$(XEN_ROOT)/stubdom/libxc -lxenctrl -lxenguest
    4.97 +LDLIBS += -lpci
    4.98 +LDLIBS += -lz
    4.99 +LDLIBS += -lc
   4.100 +endif
   4.101 +
   4.102 +ifneq ($(caml)-$(qemu)-$(lwip),--y)
   4.103 +OBJS := $(filter-out daytime.o, $(OBJS))
   4.104  endif
   4.105  
   4.106  $(TARGET): links $(OBJS) arch_lib
   4.107 -	$(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJS) $(LDARCHLIB) -o $@.o
   4.108 +	$(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o $@.o
   4.109  	$(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o
   4.110  	$(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@
   4.111  	gzip -f -9 -c $@ >$@.gz
     5.1 --- a/extras/mini-os/arch/ia64/Makefile	Tue Feb 12 11:37:45 2008 +0000
     5.2 +++ b/extras/mini-os/arch/ia64/Makefile	Tue Feb 12 14:35:39 2008 +0000
     5.3 @@ -5,6 +5,8 @@
     5.4  XEN_ROOT = ../../../..
     5.5  include $(XEN_ROOT)/Config.mk
     5.6  
     5.7 +include ../../Config.mk
     5.8 +
     5.9  include arch.mk
    5.10  include ../../minios.mk
    5.11  
    5.12 @@ -41,7 +43,7 @@ ARCH_OBJS += __divdi3.o
    5.13  
    5.14  GEN_OFF_SRC := gen_off.c
    5.15  GEN_OFF_ASM := gen_off.s
    5.16 -GEN_OFF_H   := $(ARCH_INC)/offsets.h
    5.17 +GEN_OFF_H   := $(MINI-OS_ROOT)/include/$(ARCH_INC)/offsets.h
    5.18  
    5.19  all: $(ARCH_LIB)
    5.20  
     6.1 --- a/extras/mini-os/arch/ia64/minios-ia64.lds	Tue Feb 12 11:37:45 2008 +0000
     6.2 +++ b/extras/mini-os/arch/ia64/minios-ia64.lds	Tue Feb 12 14:35:39 2008 +0000
     6.3 @@ -40,6 +40,18 @@ SECTIONS
     6.4    .rodata.str1.8 : AT(ADDR(.rodata.str1.8) - (((5<<(61))+0x100000000) - (1 << 20)))
     6.5    { *(.rodata.str1.8) }
     6.6  
     6.7 +  /* newlib initialization functions */
     6.8 +  . = ALIGN(64 / 8);
     6.9 +  PROVIDE (__preinit_array_start = .);
    6.10 +  .preinit_array     : { *(.preinit_array) }
    6.11 +  PROVIDE (__preinit_array_end = .);
    6.12 +  PROVIDE (__init_array_start = .);
    6.13 +  .init_array     : { *(.init_array) }
    6.14 +  PROVIDE (__init_array_end = .);
    6.15 +  PROVIDE (__fini_array_start = .);
    6.16 +  .fini_array     : { *(.fini_array) }
    6.17 +  PROVIDE (__fini_array_end = .);
    6.18 +
    6.19    .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - (((5<<(61))+0x100000000) - (1 << 20)))
    6.20    { *(.IA_64.unwind_info) }
    6.21  
     7.1 --- a/extras/mini-os/arch/ia64/mm.c	Tue Feb 12 11:37:45 2008 +0000
     7.2 +++ b/extras/mini-os/arch/ia64/mm.c	Tue Feb 12 14:35:39 2008 +0000
     7.3 @@ -43,6 +43,14 @@ extern uint64_t _text[], _etext[], _end[
     7.4  
     7.5  uint64_t kernstart, kernend, kernsize, kernpstart, kernpend;
     7.6  
     7.7 +#ifdef HAVE_LIBC
     7.8 +uint8_t _heap[512 * 1024];
     7.9 +unsigned long heap = (unsigned long)_heap,
    7.10 +              brk = (unsigned long)_heap,
    7.11 +              heap_mapped = (unsigned long)_heap + sizeof(_heap),
    7.12 +              heap_end = (unsigned long)_heap + sizeof(_heap);
    7.13 +#endif
    7.14 +
    7.15  /* Print the available memory chunks. */
    7.16  static void
    7.17  print_phys_avail(void)
     8.1 --- a/extras/mini-os/arch/x86/Makefile	Tue Feb 12 11:37:45 2008 +0000
     8.2 +++ b/extras/mini-os/arch/x86/Makefile	Tue Feb 12 14:35:39 2008 +0000
     8.3 @@ -5,13 +5,14 @@
     8.4  
     8.5  XEN_ROOT = ../../../..
     8.6  include $(XEN_ROOT)/Config.mk
     8.7 +include ../../Config.mk
     8.8  
     8.9  # include arch.mk has to be before mini-os.mk!
    8.10  
    8.11  include arch.mk
    8.12  include ../../minios.mk
    8.13  
    8.14 -# Sources here are all *.c *.S without $(TARGET_ARCH).S
    8.15 +# Sources here are all *.c *.S without $(XEN_TARGET_ARCH).S
    8.16  # This is handled in $(HEAD_ARCH_OBJ)
    8.17  ARCH_SRCS := $(wildcard *.c)
    8.18  
     9.1 --- a/extras/mini-os/arch/x86/arch.mk	Tue Feb 12 11:37:45 2008 +0000
     9.2 +++ b/extras/mini-os/arch/x86/arch.mk	Tue Feb 12 14:35:39 2008 +0000
     9.3 @@ -3,11 +3,11 @@
     9.4  # (including x86_32, x86_32y and x86_64).
     9.5  #
     9.6  
     9.7 -ifeq ($(TARGET_ARCH),x86_32)
     9.8 +ifeq ($(XEN_TARGET_ARCH),x86_32)
     9.9  ARCH_CFLAGS  := -m32 -march=i686
    9.10  ARCH_LDFLAGS := -m elf_i386
    9.11  ARCH_ASFLAGS := -m32
    9.12 -EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH)
    9.13 +EXTRA_INC += $(TARGET_ARCH_FAM)/$(XEN_TARGET_ARCH)
    9.14  EXTRA_SRC += arch/$(EXTRA_INC)
    9.15  
    9.16  ifeq ($(XEN_TARGET_X86_PAE),y)
    9.17 @@ -16,12 +16,12 @@ ARCH_ASFLAGS += -DCONFIG_X86_PAE=1
    9.18  endif
    9.19  endif
    9.20  
    9.21 -ifeq ($(TARGET_ARCH),x86_64)
    9.22 +ifeq ($(XEN_TARGET_ARCH),x86_64)
    9.23  ARCH_CFLAGS := -m64 -mno-red-zone -fno-reorder-blocks
    9.24  ARCH_CFLAGS += -fno-asynchronous-unwind-tables
    9.25  ARCH_ASFLAGS := -m64
    9.26  ARCH_LDFLAGS := -m elf_x86_64
    9.27 -EXTRA_INC += $(TARGET_ARCH_FAM)/$(TARGET_ARCH)
    9.28 +EXTRA_INC += $(TARGET_ARCH_FAM)/$(XEN_TARGET_ARCH)
    9.29  EXTRA_SRC += arch/$(EXTRA_INC)
    9.30  endif
    9.31  
    10.1 --- a/extras/mini-os/arch/x86/minios-x86_32.lds	Tue Feb 12 11:37:45 2008 +0000
    10.2 +++ b/extras/mini-os/arch/x86/minios-x86_32.lds	Tue Feb 12 14:35:39 2008 +0000
    10.3 @@ -16,6 +16,18 @@ SECTIONS
    10.4    . = ALIGN(4096);
    10.5    _erodata = .;
    10.6  
    10.7 +  /* newlib initialization functions */
    10.8 +  . = ALIGN(32 / 8);
    10.9 +  PROVIDE (__preinit_array_start = .);
   10.10 +  .preinit_array     : { *(.preinit_array) }
   10.11 +  PROVIDE (__preinit_array_end = .);
   10.12 +  PROVIDE (__init_array_start = .);
   10.13 +  .init_array     : { *(.init_array) }
   10.14 +  PROVIDE (__init_array_end = .);
   10.15 +  PROVIDE (__fini_array_start = .);
   10.16 +  .fini_array     : { *(.fini_array) }
   10.17 +  PROVIDE (__fini_array_end = .);
   10.18 +
   10.19    .data : {			/* Data */
   10.20  	*(.data)
   10.21  	CONSTRUCTORS
    11.1 --- a/extras/mini-os/arch/x86/minios-x86_64.lds	Tue Feb 12 11:37:45 2008 +0000
    11.2 +++ b/extras/mini-os/arch/x86/minios-x86_64.lds	Tue Feb 12 14:35:39 2008 +0000
    11.3 @@ -16,6 +16,18 @@ SECTIONS
    11.4    . = ALIGN(4096);
    11.5    _erodata = .;
    11.6  
    11.7 +  /* newlib initialization functions */
    11.8 +  . = ALIGN(64 / 8);
    11.9 +  PROVIDE (__preinit_array_start = .);
   11.10 +  .preinit_array     : { *(.preinit_array) }
   11.11 +  PROVIDE (__preinit_array_end = .);
   11.12 +  PROVIDE (__init_array_start = .);
   11.13 +  .init_array     : { *(.init_array) }
   11.14 +  PROVIDE (__init_array_end = .);
   11.15 +  PROVIDE (__fini_array_start = .);
   11.16 +  .fini_array     : { *(.fini_array) }
   11.17 +  PROVIDE (__fini_array_end = .);
   11.18 +
   11.19    .data : {			/* Data */
   11.20  	*(.data)
   11.21  	CONSTRUCTORS
    12.1 --- a/extras/mini-os/arch/x86/mm.c	Tue Feb 12 11:37:45 2008 +0000
    12.2 +++ b/extras/mini-os/arch/x86/mm.c	Tue Feb 12 14:35:39 2008 +0000
    12.3 @@ -448,6 +448,15 @@ static unsigned long demand_map_area_sta
    12.4  #define DEMAND_MAP_PAGES ((2ULL << 30) / PAGE_SIZE)
    12.5  #endif
    12.6  
    12.7 +#ifdef HAVE_LIBC
    12.8 +unsigned long heap, brk, heap_mapped, heap_end;
    12.9 +#ifdef __x86_64__
   12.10 +#define HEAP_PAGES ((128ULL << 30) / PAGE_SIZE)
   12.11 +#else
   12.12 +#define HEAP_PAGES ((1ULL << 30) / PAGE_SIZE)
   12.13 +#endif
   12.14 +#endif
   12.15 +
   12.16  void arch_init_demand_mapping_area(unsigned long cur_pfn)
   12.17  {
   12.18      cur_pfn++;
   12.19 @@ -455,6 +464,14 @@ void arch_init_demand_mapping_area(unsig
   12.20      demand_map_area_start = (unsigned long) pfn_to_virt(cur_pfn);
   12.21      cur_pfn += DEMAND_MAP_PAGES;
   12.22      printk("Demand map pfns at %lx-%lx.\n", demand_map_area_start, pfn_to_virt(cur_pfn));
   12.23 +
   12.24 +#ifdef HAVE_LIBC
   12.25 +    cur_pfn++;
   12.26 +    heap_mapped = brk = heap = (unsigned long) pfn_to_virt(cur_pfn);
   12.27 +    cur_pfn += HEAP_PAGES;
   12.28 +    heap_end = (unsigned long) pfn_to_virt(cur_pfn);
   12.29 +    printk("Heap resides at %lx-%lx.\n", brk, heap_end);
   12.30 +#endif
   12.31  }
   12.32  
   12.33  #define MAP_BATCH ((STACK_SIZE / 2) / sizeof(mmu_update_t))
    13.1 --- a/extras/mini-os/arch/x86/x86_32.S	Tue Feb 12 11:37:45 2008 +0000
    13.2 +++ b/extras/mini-os/arch/x86/x86_32.S	Tue Feb 12 14:35:39 2008 +0000
    13.3 @@ -1,5 +1,5 @@
    13.4  #include <os.h>
    13.5 -#include <arch_mm.h>
    13.6 +#include <arch_limits.h>
    13.7  #include <xen/arch-x86_32.h>
    13.8  
    13.9  .section __xen_guest
   13.10 @@ -22,12 +22,12 @@
   13.11  _start:
   13.12          cld
   13.13          lss stack_start,%esp
   13.14 -        andl $(~(STACK_SIZE-1)), %esp
   13.15 +        andl $(~(__STACK_SIZE-1)), %esp
   13.16          push %esi 
   13.17          call start_kernel
   13.18  
   13.19  stack_start:
   13.20 -	.long stack+(2*STACK_SIZE), __KERNEL_SS
   13.21 +	.long stack+(2*__STACK_SIZE), __KERNEL_SS
   13.22  
   13.23          /* Unpleasant -- the PTE that maps this page is actually overwritten */
   13.24          /* to map the real shared-info page! :-)                             */
    14.1 --- a/extras/mini-os/arch/x86/x86_64.S	Tue Feb 12 11:37:45 2008 +0000
    14.2 +++ b/extras/mini-os/arch/x86/x86_64.S	Tue Feb 12 14:35:39 2008 +0000
    14.3 @@ -1,5 +1,5 @@
    14.4  #include <os.h>
    14.5 -#include <arch_mm.h>
    14.6 +#include <arch_limits.h>
    14.7  #include <xen/features.h>
    14.8  
    14.9  .section __xen_guest
   14.10 @@ -19,12 +19,12 @@
   14.11  _start:
   14.12          cld
   14.13          movq stack_start(%rip),%rsp
   14.14 -        andq $(~(STACK_SIZE-1)), %rsp
   14.15 +        andq $(~(__STACK_SIZE-1)), %rsp
   14.16          movq %rsi,%rdi
   14.17          call start_kernel
   14.18  
   14.19  stack_start:
   14.20 -        .quad stack+(2*STACK_SIZE)
   14.21 +        .quad stack+(2*__STACK_SIZE)
   14.22  
   14.23          /* Unpleasant -- the PTE that maps this page is actually overwritten */
   14.24          /* to map the real shared-info page! :-)                             */
    15.1 --- a/extras/mini-os/blkfront.c	Tue Feb 12 11:37:45 2008 +0000
    15.2 +++ b/extras/mini-os/blkfront.c	Tue Feb 12 14:35:39 2008 +0000
    15.3 @@ -15,6 +15,10 @@
    15.4  #include <lib.h>
    15.5  #include <fcntl.h>
    15.6  
    15.7 +#ifndef HAVE_LIBC
    15.8 +#define strtoul simple_strtoul
    15.9 +#endif
   15.10 +
   15.11  /* Note: we generally don't need to disable IRQs since we hardly do anything in
   15.12   * the interrupt handler.  */
   15.13  
   15.14 @@ -49,6 +53,10 @@ struct blkfront_dev {
   15.15      int mode;
   15.16      int barrier;
   15.17      int flush;
   15.18 +
   15.19 +#ifdef HAVE_LIBC
   15.20 +    int fd;
   15.21 +#endif
   15.22  };
   15.23  
   15.24  static inline int xenblk_rxidx(RING_IDX idx)
   15.25 @@ -58,6 +66,12 @@ static inline int xenblk_rxidx(RING_IDX 
   15.26  
   15.27  void blkfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
   15.28  {
   15.29 +#ifdef HAVE_LIBC
   15.30 +    struct blkfront_dev *dev = data;
   15.31 +    int fd = dev->fd;
   15.32 +
   15.33 +    files[fd].read = 1;
   15.34 +#endif
   15.35      wake_up(&blkfront_queue);
   15.36  }
   15.37  
   15.38 @@ -148,7 +162,7 @@ done:
   15.39  
   15.40      printk("backend at %s\n", dev->backend);
   15.41  
   15.42 -    dev->handle = simple_strtoul(strrchr(nodename, '/')+1, NULL, 0);
   15.43 +    dev->handle = strtoul(strrchr(nodename, '/')+1, NULL, 0);
   15.44  
   15.45      {
   15.46          char path[strlen(dev->backend) + 1 + 19 + 1];
   15.47 @@ -322,12 +336,16 @@ moretodo:
   15.48      {
   15.49  	rsp = RING_GET_RESPONSE(&dev->ring, cons);
   15.50  
   15.51 +        if (rsp->status != BLKIF_RSP_OKAY)
   15.52 +            printk("block error %d for op %d\n", rsp->status, rsp->operation);
   15.53 +
   15.54          switch (rsp->operation) {
   15.55          case BLKIF_OP_READ:
   15.56          case BLKIF_OP_WRITE:
   15.57          {
   15.58              struct blkfront_aiocb *aiocbp = (void*) (uintptr_t) rsp->id;
   15.59              int j;
   15.60 +
   15.61              for (j = 0; j < aiocbp->n; j++)
   15.62                  gnttab_end_access(aiocbp->gref[j]);
   15.63  
   15.64 @@ -365,6 +383,12 @@ static void blkfront_push_operation(stru
   15.65      i = dev->ring.req_prod_pvt;
   15.66      req = RING_GET_REQUEST(&dev->ring, i);
   15.67      req->operation = op;
   15.68 +    req->nr_segments = 0;
   15.69 +    req->handle = dev->handle;
   15.70 +    /* Not used */
   15.71 +    req->id = 0;
   15.72 +    /* Not needed anyway, but the backend will check it */
   15.73 +    req->sector_number = 0;
   15.74      dev->ring.req_prod_pvt = i + 1;
   15.75      wmb();
   15.76      RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->ring, notify);
   15.77 @@ -375,11 +399,13 @@ void blkfront_sync(struct blkfront_dev *
   15.78  {
   15.79      unsigned long flags;
   15.80  
   15.81 -    if (dev->barrier == 1)
   15.82 -        blkfront_push_operation(dev, BLKIF_OP_WRITE_BARRIER);
   15.83 +    if (dev->mode == O_RDWR) {
   15.84 +        if (dev->barrier == 1)
   15.85 +            blkfront_push_operation(dev, BLKIF_OP_WRITE_BARRIER);
   15.86  
   15.87 -    if (dev->flush == 1)
   15.88 -        blkfront_push_operation(dev, BLKIF_OP_FLUSH_DISKCACHE);
   15.89 +        if (dev->flush == 1)
   15.90 +            blkfront_push_operation(dev, BLKIF_OP_FLUSH_DISKCACHE);
   15.91 +    }
   15.92  
   15.93      /* Note: This won't finish if another thread enqueues requests.  */
   15.94      local_irq_save(flags);
   15.95 @@ -397,3 +423,13 @@ void blkfront_sync(struct blkfront_dev *
   15.96      remove_waiter(w);
   15.97      local_irq_restore(flags);
   15.98  }
   15.99 +
  15.100 +#ifdef HAVE_LIBC
  15.101 +int blkfront_open(struct blkfront_dev *dev)
  15.102 +{
  15.103 +    dev->fd = alloc_fd(FTYPE_BLK);
  15.104 +    printk("blk_open(%s) -> %d\n", dev->nodename, dev->fd);
  15.105 +    files[dev->fd].blk.dev = dev;
  15.106 +    return dev->fd;
  15.107 +}
  15.108 +#endif
    16.1 --- a/extras/mini-os/include/arch/cc.h	Tue Feb 12 11:37:45 2008 +0000
    16.2 +++ b/extras/mini-os/include/arch/cc.h	Tue Feb 12 14:35:39 2008 +0000
    16.3 @@ -54,7 +54,14 @@ extern void lwip_die(char *fmt, ...);
    16.4  #include <errno.h>
    16.5  
    16.6  /*   Not required by the docs, but needed for network-order calculations */
    16.7 +#ifdef HAVE_LIBC
    16.8 +#include <machine/endian.h>
    16.9 +#ifndef BIG_ENDIAN
   16.10 +#error endian.h does not define byte order
   16.11 +#endif
   16.12 +#else
   16.13  #include <endian.h>
   16.14 +#endif
   16.15  
   16.16  #include <inttypes.h>
   16.17  #define S16_F PRIi16
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/extras/mini-os/include/byteswap.h	Tue Feb 12 14:35:39 2008 +0000
    17.3 @@ -0,0 +1,22 @@
    17.4 +#ifndef _BYTESWAP_H_
    17.5 +#define _BYTESWAP_H_
    17.6 +
    17.7 +/* Unfortunately not provided by newlib.  */
    17.8 +#define bswap_16(x) \
    17.9 +    ((((x) & 0xff00) >> 8) | (((x) & 0xff) << 8))
   17.10 +
   17.11 +#define bswap_32(x) \
   17.12 +    ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) | \
   17.13 +     (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
   17.14 +
   17.15 +#define bswap_64(x) \
   17.16 +    ((((x) & 0xff00000000000000ULL) >> 56) | \
   17.17 +     (((x) & 0x00ff000000000000ULL) >> 40) | \
   17.18 +     (((x) & 0x0000ff0000000000ULL) >> 24) | \
   17.19 +     (((x) & 0x000000ff00000000ULL) >>  8) | \
   17.20 +     (((x) & 0x00000000ff000000ULL) <<  8) | \
   17.21 +     (((x) & 0x0000000000ff0000ULL) << 24) | \
   17.22 +     (((x) & 0x000000000000ff00ULL) << 40) | \
   17.23 +     (((x) & 0x00000000000000ffULL) << 56))
   17.24 +
   17.25 +#endif /* _BYTESWAP_H */
    18.1 --- a/extras/mini-os/include/console.h	Tue Feb 12 11:37:45 2008 +0000
    18.2 +++ b/extras/mini-os/include/console.h	Tue Feb 12 14:35:39 2008 +0000
    18.3 @@ -36,7 +36,9 @@
    18.4  #ifndef _LIB_CONSOLE_H_
    18.5  #define _LIB_CONSOLE_H_
    18.6  
    18.7 +#include<os.h>
    18.8  #include<traps.h>
    18.9 +#include<stdarg.h>
   18.10  
   18.11  void print(int direct, const char *fmt, va_list args);
   18.12  void printk(const char *fmt, ...);
   18.13 @@ -48,5 +50,6 @@ void xencons_rx(char *buf, unsigned len,
   18.14  void xencons_tx(void);
   18.15  
   18.16  void init_console(void);
   18.17 +void console_print(char *data, int length);
   18.18  
   18.19  #endif /* _LIB_CONSOLE_H_ */
    19.1 --- a/extras/mini-os/include/errno.h	Tue Feb 12 11:37:45 2008 +0000
    19.2 +++ b/extras/mini-os/include/errno.h	Tue Feb 12 14:35:39 2008 +0000
    19.3 @@ -107,4 +107,11 @@
    19.4  #define	EOWNERDEAD	130	/* Owner died */
    19.5  #define	ENOTRECOVERABLE	131	/* State not recoverable */
    19.6  
    19.7 +#ifdef HAVE_LIBC
    19.8 +#include <sched.h>
    19.9 +extern int errno;
   19.10 +#define ERRNO
   19.11 +#define errno (get_current()->reent._errno)
   19.12  #endif
   19.13 +
   19.14 +#endif
    20.1 --- a/extras/mini-os/include/fcntl.h	Tue Feb 12 11:37:45 2008 +0000
    20.2 +++ b/extras/mini-os/include/fcntl.h	Tue Feb 12 14:35:39 2008 +0000
    20.3 @@ -86,4 +86,7 @@ struct flock64 {
    20.4  
    20.5  #define F_LINUX_SPECIFIC_BASE	1024
    20.6  */
    20.7 +
    20.8 +int open(const char *path, int flags, ...);
    20.9 +int fcntl(int fd, int cmd, ...);
   20.10  #endif
    21.1 --- a/extras/mini-os/include/fs.h	Tue Feb 12 11:37:45 2008 +0000
    21.2 +++ b/extras/mini-os/include/fs.h	Tue Feb 12 14:35:39 2008 +0000
    21.3 @@ -22,6 +22,7 @@ struct fs_import
    21.4      struct semaphore reqs_sem;      /* Accounts requests resource           */
    21.5  };
    21.6  
    21.7 +extern struct fs_import *fs_import;
    21.8  
    21.9  void init_fs_frontend(void);
   21.10  
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/extras/mini-os/include/ia64/arch_limits.h	Tue Feb 12 14:35:39 2008 +0000
    22.3 @@ -0,0 +1,12 @@
    22.4 +
    22.5 +#ifndef __ARCH_LIMITS_H__
    22.6 +#define __ARCH_LIMITS_H__
    22.7 +
    22.8 +/* Commonly 16K pages are used. */
    22.9 +#define __PAGE_SHIFT	14	/* 16K pages */
   22.10 +#define __PAGE_SIZE	(1<<(__PAGE_SHIFT))
   22.11 +
   22.12 +#define __STACK_SIZE_PAGE_ORDER   2
   22.13 +#define __STACK_SIZE              (__PAGE_SIZE * (1 << __STACK_SIZE_PAGE_ORDER))
   22.14 +          
   22.15 +#endif /* __ARCH_LIMITS_H__ */
    23.1 --- a/extras/mini-os/include/ia64/arch_mm.h	Tue Feb 12 11:37:45 2008 +0000
    23.2 +++ b/extras/mini-os/include/ia64/arch_mm.h	Tue Feb 12 14:35:39 2008 +0000
    23.3 @@ -35,11 +35,9 @@
    23.4  #define virt_to_mfn(x)	virt_to_pfn(x)
    23.5  #define virtual_to_mfn(x)      (ia64_tpa((uint64_t)(x)) >> PAGE_SHIFT)
    23.6  
    23.7 -#define STACK_SIZE_PAGE_ORDER   1
    23.8 -#define STACK_SIZE              (PAGE_SIZE * (1 << STACK_SIZE_PAGE_ORDER))
    23.9 -
   23.10  #define map_frames(f, n) map_frames_ex(f, n, 1, 0, 1, DOMID_SELF, 0, 0)
   23.11  /* TODO */
   23.12  #define map_zero(n, a) map_frames_ex(NULL, n, 0, 0, a, DOMID_SELF, 0, 0)
   23.13 +#define do_map_zero(start, n) ((void)0)
   23.14  
   23.15  #endif /* __ARCH_MM_H__ */
    24.1 --- a/extras/mini-os/include/ia64/page.h	Tue Feb 12 11:37:45 2008 +0000
    24.2 +++ b/extras/mini-os/include/ia64/page.h	Tue Feb 12 14:35:39 2008 +0000
    24.3 @@ -43,9 +43,9 @@
    24.4  /* The efi-pal page size for text and data. */
    24.5  #define PAL_TR_PAGE_SIZE	PTE_PS_1M
    24.6  
    24.7 -/* Commonly 16K pages are used. */
    24.8 -#define PAGE_SHIFT	14	/* 16K pages */
    24.9 -#define PAGE_SIZE	(1<<(PAGE_SHIFT))
   24.10 +#include "arch_limits.h"
   24.11 +#define PAGE_SHIFT	__PAGE_SHIFT
   24.12 +#define PAGE_SIZE	__PAGE_SIZE
   24.13  #define PAGE_MASK	(~(PAGE_SIZE-1))
   24.14  
   24.15  #define KSTACK_PAGES	4	/* 4 pages for the kernel stack + bsp */
    25.1 --- a/extras/mini-os/include/lib.h	Tue Feb 12 11:37:45 2008 +0000
    25.2 +++ b/extras/mini-os/include/lib.h	Tue Feb 12 14:35:39 2008 +0000
    25.3 @@ -57,6 +57,8 @@
    25.4  
    25.5  #include <stdarg.h>
    25.6  #include <stddef.h>
    25.7 +#include <xen/xen.h>
    25.8 +#include <xen/event_channel.h>
    25.9  
   25.10  #ifdef HAVE_LIBC
   25.11  #include <stdio.h>
   25.12 @@ -103,6 +105,8 @@ char  *strdup(const char *s);
   25.13  
   25.14  int rand(void);
   25.15  
   25.16 +#include <xenbus.h>
   25.17 +
   25.18  #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
   25.19  
   25.20  struct kvec {
   25.21 @@ -126,4 +130,59 @@ do {                                    
   25.22  /* Consistency check as much as possible. */
   25.23  void sanity_check(void);
   25.24  
   25.25 +#ifdef HAVE_LIBC
   25.26 +enum fd_type {
   25.27 +    FTYPE_NONE = 0,
   25.28 +    FTYPE_CONSOLE,
   25.29 +    FTYPE_FILE,
   25.30 +    FTYPE_XENBUS,
   25.31 +    FTYPE_EVTCHN,
   25.32 +    FTYPE_SOCKET,
   25.33 +    FTYPE_TAP,
   25.34 +    FTYPE_BLK,
   25.35 +};
   25.36 +
   25.37 +#define MAX_EVTCHN_PORTS 16
   25.38 +
   25.39 +extern struct file {
   25.40 +    enum fd_type type;
   25.41 +    union {
   25.42 +	struct {
   25.43 +            /* lwIP fd */
   25.44 +	    int fd;
   25.45 +	} socket;
   25.46 +	struct {
   25.47 +            /* FS import fd */
   25.48 +	    int fd;
   25.49 +	    off_t offset;
   25.50 +	} file;
   25.51 +	struct {
   25.52 +            /* To each event channel FD is associated a series of ports which
   25.53 +             * wakes select for this FD. */
   25.54 +            struct {
   25.55 +                evtchn_port_t port;
   25.56 +                volatile unsigned long pending;
   25.57 +                int bound;
   25.58 +            } ports[MAX_EVTCHN_PORTS];
   25.59 +	} evtchn;
   25.60 +	struct {
   25.61 +	    struct netfront_dev *dev;
   25.62 +	} tap;
   25.63 +	struct {
   25.64 +	    struct blkfront_dev *dev;
   25.65 +	} blk;
   25.66 +        struct {
   25.67 +            /* To each xenbus FD is associated a queue of watch events for this
   25.68 +             * FD.  */
   25.69 +            struct xenbus_event *volatile events;
   25.70 +        } xenbus;
   25.71 +    };
   25.72 +    volatile int read;	/* maybe available for read */
   25.73 +} files[];
   25.74 +
   25.75 +int alloc_fd(enum fd_type type);
   25.76 +void close_all_files(void);
   25.77 +extern struct thread *main_thread;
   25.78 +#endif
   25.79 +
   25.80  #endif /* _LIB_H_ */
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/extras/mini-os/include/linux/types.h	Tue Feb 12 14:35:39 2008 +0000
    26.3 @@ -0,0 +1,5 @@
    26.4 +#ifndef _LINUX_TYPES_H_
    26.5 +#define _LINUX_TYPES_H_
    26.6 +#include <types.h>
    26.7 +typedef u64 __u64;
    26.8 +#endif /* _LINUX_TYPES_H_ */
    27.1 --- a/extras/mini-os/include/mm.h	Tue Feb 12 11:37:45 2008 +0000
    27.2 +++ b/extras/mini-os/include/mm.h	Tue Feb 12 14:35:39 2008 +0000
    27.3 @@ -36,8 +36,13 @@
    27.4  #endif
    27.5  
    27.6  #include <lib.h>
    27.7 +
    27.8 +#include <arch_limits.h>
    27.9  #include <arch_mm.h>
   27.10  
   27.11 +#define STACK_SIZE_PAGE_ORDER __STACK_SIZE_PAGE_ORDER
   27.12 +#define STACK_SIZE __STACK_SIZE
   27.13 +
   27.14  
   27.15  void init_mm(void);
   27.16  unsigned long alloc_pages(int order);
   27.17 @@ -61,5 +66,8 @@ void arch_init_p2m(unsigned long max_pfn
   27.18  void *map_frames_ex(unsigned long *f, unsigned long n, unsigned long stride,
   27.19  	unsigned long increment, unsigned long alignment, domid_t id,
   27.20  	int may_fail, unsigned long prot);
   27.21 +#ifdef HAVE_LIBC
   27.22 +extern unsigned long heap, brk, heap_mapped, heap_end;
   27.23 +#endif
   27.24  
   27.25  #endif /* _MM_H_ */
    28.1 --- a/extras/mini-os/include/netfront.h	Tue Feb 12 11:37:45 2008 +0000
    28.2 +++ b/extras/mini-os/include/netfront.h	Tue Feb 12 14:35:39 2008 +0000
    28.3 @@ -6,6 +6,10 @@ struct netfront_dev;
    28.4  struct netfront_dev *init_netfront(char *nodename, void (*netif_rx)(unsigned char *data, int len), unsigned char rawmac[6]);
    28.5  void netfront_xmit(struct netfront_dev *dev, unsigned char* data,int len);
    28.6  void shutdown_netfront(struct netfront_dev *dev);
    28.7 +#ifdef HAVE_LIBC
    28.8 +int netfront_tap_open(char *nodename);
    28.9 +ssize_t netfront_receive(struct netfront_dev *dev, unsigned char *data, size_t len);
   28.10 +#endif
   28.11  
   28.12  extern struct wait_queue_head netfront_queue;
   28.13  
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/extras/mini-os/include/posix/dirent.h	Tue Feb 12 14:35:39 2008 +0000
    29.3 @@ -0,0 +1,24 @@
    29.4 +#ifndef _POSIX_DIRENT_H
    29.5 +#define _POSIX_DIRENT_H
    29.6 +
    29.7 +#include <sys/types.h>
    29.8 +
    29.9 +struct dirent {
   29.10 +        char *d_name;
   29.11 +};
   29.12 +
   29.13 +typedef struct {
   29.14 +        struct dirent dirent;
   29.15 +        char *name;
   29.16 +        int32_t offset;
   29.17 +        char **entries;
   29.18 +        int32_t curentry;
   29.19 +        int32_t nbentries;
   29.20 +        int has_more;
   29.21 +} DIR;
   29.22 +
   29.23 +DIR *opendir(const char *name);
   29.24 +struct dirent *readdir(DIR *dir);
   29.25 +int closedir(DIR *dir);
   29.26 +
   29.27 +#endif /* _POSIX_DIRENT_H */
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/extras/mini-os/include/posix/limits.h	Tue Feb 12 14:35:39 2008 +0000
    30.3 @@ -0,0 +1,9 @@
    30.4 +#ifndef _POSIX_LIMITS_H
    30.5 +#define _POSIX_LIMITS_H
    30.6 +
    30.7 +#include_next <limits.h>
    30.8 +#include <arch_limits.h>
    30.9 +
   30.10 +#define PATH_MAX __PAGE_SIZE
   30.11 +
   30.12 +#endif /* _POSIX_LIMITS_H */
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/extras/mini-os/include/posix/netdb.h	Tue Feb 12 14:35:39 2008 +0000
    31.3 @@ -0,0 +1,9 @@
    31.4 +#ifndef _POSIX_NETDB_H_
    31.5 +#define _POSIX_NETDB_H_
    31.6 +
    31.7 +struct hostent {
    31.8 +    char *h_addr;
    31.9 +};
   31.10 +#define gethostbyname(buf) NULL
   31.11 +
   31.12 +#endif /* _POSIX_NETDB_H_ */
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/extras/mini-os/include/posix/netinet/in.h	Tue Feb 12 14:35:39 2008 +0000
    32.3 @@ -0,0 +1,7 @@
    32.4 +#ifndef _POSIX_SYS_IN_H_
    32.5 +#define _POSIX_SYS_IN_H_
    32.6 +
    32.7 +#include <fcntl.h>
    32.8 +#include <lwip/sockets.h>
    32.9 +
   32.10 +#endif /* _POSIX_SYS_IN_H_ */
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/extras/mini-os/include/posix/netinet/tcp.h	Tue Feb 12 14:35:39 2008 +0000
    33.3 @@ -0,0 +1,6 @@
    33.4 +#ifndef _POSIX_SYS_TCP_H_
    33.5 +#define _POSIX_SYS_TCP_H_
    33.6 +
    33.7 +#include <lwip/tcp.h>
    33.8 +
    33.9 +#endif /* _POSIX_SYS_TCP_H_ */
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/extras/mini-os/include/posix/pthread.h	Tue Feb 12 14:35:39 2008 +0000
    34.3 @@ -0,0 +1,19 @@
    34.4 +#ifndef _POSIX_PTHREAD_H
    34.5 +#define _POSIX_PTHREAD_H
    34.6 +
    34.7 +/* Let's be single-threaded for now.  */
    34.8 +
    34.9 +typedef void *pthread_key_t;
   34.10 +typedef struct {} pthread_mutex_t, pthread_once_t;
   34.11 +#define PTHREAD_MUTEX_INITIALIZER {}
   34.12 +#define PTHREAD_ONCE_INIT {}
   34.13 +static inline int pthread_mutex_lock(pthread_mutex_t *mutex) { return 0; }
   34.14 +static inline int pthread_mutex_unlock(pthread_mutex_t *mutex) { return 0; }
   34.15 +static inline int pthread_key_create(pthread_key_t *key, void (*destr_function)(void*)) { *key = NULL; return 0; }
   34.16 +static inline int pthread_setspecific(pthread_key_t *key, const void *pointer) { *key = (void*) pointer; return 0; }
   34.17 +static inline void *pthread_getspecific(pthread_key_t *key) { return *key; }
   34.18 +static inline int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) { init_routine(); return 0; }
   34.19 +
   34.20 +#define __thread
   34.21 +
   34.22 +#endif /* _POSIX_PTHREAD_H */
    35.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.2 +++ b/extras/mini-os/include/posix/stdlib.h	Tue Feb 12 14:35:39 2008 +0000
    35.3 @@ -0,0 +1,8 @@
    35.4 +#ifndef _POSIX_STDLIB_H
    35.5 +#define _POSIX_STDLIB_H
    35.6 +
    35.7 +#include_next <stdlib.h>
    35.8 +
    35.9 +#define realpath(p,r) strcpy(r,p)
   35.10 +
   35.11 +#endif /* _POSIX_STDLIB_H */
    36.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.2 +++ b/extras/mini-os/include/posix/strings.h	Tue Feb 12 14:35:39 2008 +0000
    36.3 @@ -0,0 +1,8 @@
    36.4 +#ifndef _POSIX_STRINGS_H
    36.5 +#define _POSIX_STRINGS_H
    36.6 +
    36.7 +#include <string.h>
    36.8 +
    36.9 +#define bzero(ptr, size) (memset((ptr), '\0', (size)), (void) 0)
   36.10 +
   36.11 +#endif /* _POSIX_STRINGS_H */
    37.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.2 +++ b/extras/mini-os/include/posix/sys/ioctl.h	Tue Feb 12 14:35:39 2008 +0000
    37.3 @@ -0,0 +1,16 @@
    37.4 +#ifndef _POSIX_SYS_IOCTL_H
    37.5 +#define _POSIX_SYS_IOCTL_H
    37.6 +
    37.7 +int ioctl(int fd, int request, ...);
    37.8 +
    37.9 +#define _IOC_NONE 0
   37.10 +#define _IOC_WRITE 1
   37.11 +#define _IOC_READ 2
   37.12 +
   37.13 +#define _IOC(rw, class, n, size) \
   37.14 +    	(((rw   ) << 30) | \
   37.15 +	 ((class) << 22) | \
   37.16 +	 ((n    ) << 14) | \
   37.17 +	 ((size ) << 0))
   37.18 +
   37.19 +#endif /* _POSIX_SYS_IOCTL_H */
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/extras/mini-os/include/posix/sys/mman.h	Tue Feb 12 14:35:39 2008 +0000
    38.3 @@ -0,0 +1,19 @@
    38.4 +#ifndef _POSIX_SYS_MMAN_H
    38.5 +#define _POSIX_SYS_MMAN_H
    38.6 +
    38.7 +#define PROT_READ	0x1
    38.8 +#define PROT_WRITE	0x2
    38.9 +#define PROT_EXEC	0x4
   38.10 +
   38.11 +#define MAP_SHARED	0x01
   38.12 +#define MAP_PRIVATE	0x02
   38.13 +#define MAP_ANON	0x20
   38.14 +
   38.15 +#define MAP_FAILED	((void*)0)
   38.16 +
   38.17 +void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
   38.18 +int munmap(void *start, size_t length);
   38.19 +#define munlock(addr, len) ((void)addr, (void)len, 0)
   38.20 +#define mlock(addr, len) ((void)addr, (void)len, 0)
   38.21 +
   38.22 +#endif /* _POSIX_SYS_MMAN_H */
    39.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.2 +++ b/extras/mini-os/include/posix/sys/select.h	Tue Feb 12 14:35:39 2008 +0000
    39.3 @@ -0,0 +1,7 @@
    39.4 +#ifndef _POSIX_SELECT_H
    39.5 +#define _POSIX_SELECT_H
    39.6 +
    39.7 +#include <sys/time.h>
    39.8 +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
    39.9 +
   39.10 +#endif /* _POSIX_SELECT_H */
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/extras/mini-os/include/posix/sys/socket.h	Tue Feb 12 14:35:39 2008 +0000
    40.3 @@ -0,0 +1,31 @@
    40.4 +#ifndef _POSIX_SYS_SOCKET_H_
    40.5 +#define _POSIX_SYS_SOCKET_H_
    40.6 +
    40.7 +#include <fcntl.h>
    40.8 +#include <lwip/sockets.h>
    40.9 +
   40.10 +int accept(int s, struct sockaddr *addr, socklen_t *addrlen);
   40.11 +int bind(int s, struct sockaddr *name, socklen_t namelen);
   40.12 +int shutdown(int s, int how);
   40.13 +int getpeername (int s, struct sockaddr *name, socklen_t *namelen);
   40.14 +int getsockname (int s, struct sockaddr *name, socklen_t *namelen);
   40.15 +int getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen);
   40.16 +int setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen);
   40.17 +int close(int s);
   40.18 +int connect(int s, struct sockaddr *name, socklen_t namelen);
   40.19 +int listen(int s, int backlog);
   40.20 +int recv(int s, void *mem, int len, unsigned int flags);
   40.21 +//int read(int s, void *mem, int len);
   40.22 +int recvfrom(int s, void *mem, int len, unsigned int flags,
   40.23 +      struct sockaddr *from, socklen_t *fromlen);
   40.24 +int send(int s, void *dataptr, int size, unsigned int flags);
   40.25 +int sendto(int s, void *dataptr, int size, unsigned int flags,
   40.26 +    struct sockaddr *to, socklen_t tolen);
   40.27 +int socket(int domain, int type, int protocol);
   40.28 +//int write(int s, void *dataptr, int size);
   40.29 +int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
   40.30 +                struct timeval *timeout);
   40.31 +//int ioctl(int s, long cmd, void *argp);
   40.32 +int getsockname(int s, struct sockaddr *name, socklen_t *namelen);
   40.33 +
   40.34 +#endif /* _POSIX_SYS_SOCKET_H_ */
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/extras/mini-os/include/posix/termios.h	Tue Feb 12 14:35:39 2008 +0000
    41.3 @@ -0,0 +1,87 @@
    41.4 +#ifndef _POSIX_TERMIOS_H
    41.5 +#define _POSIX_TERMIOS_H
    41.6 +
    41.7 +#define NCC 32
    41.8 +
    41.9 +struct termios {
   41.10 +    unsigned long c_iflag;
   41.11 +    unsigned long c_oflag;
   41.12 +    unsigned long c_lflag;
   41.13 +    unsigned long c_cflag;
   41.14 +    unsigned char c_cc[NCC];
   41.15 +};
   41.16 +
   41.17 +/* modem lines */
   41.18 +#define TIOCM_DTR	0x002
   41.19 +#define TIOCM_RTS	0x004
   41.20 +#define TIOCM_CTS	0x020
   41.21 +#define TIOCM_CAR	0x040
   41.22 +#define TIOCM_RI	0x080
   41.23 +#define TIOCM_DSR	0x100
   41.24 +
   41.25 +/* c_iflag */
   41.26 +#define IGNBRK	0x00000001
   41.27 +#define BRKINT	0x00000002
   41.28 +#define IGNPAR	0x00000004
   41.29 +#define PARMRK	0x00000008
   41.30 +#define INPCK	0x00000010
   41.31 +#define ISTRIP	0x00000020
   41.32 +#define INLCR	0x00000040
   41.33 +#define IGNCR	0x00000080
   41.34 +#define ICRNL	0x00000100
   41.35 +#define IUCLC	0x00000200
   41.36 +#define IXON	0x00000400
   41.37 +#define IXANY	0x00000800
   41.38 +#define IXOFF	0x00001000
   41.39 +#define IMAXBEL	0x00002000
   41.40 +#define IUTF8	0x00004000
   41.41 +
   41.42 +/* c_oflag */
   41.43 +#define OPOST	0x00000001
   41.44 +#define OLCUC	0x00000002
   41.45 +#define ONLCR	0x00000004
   41.46 +#define OCRNL	0x00000008
   41.47 +#define ONOCR	0x00000010
   41.48 +#define ONLRET	0x00000020
   41.49 +#define OFILL	0x00000040
   41.50 +#define OFDEL	0x00000080
   41.51 +
   41.52 +/* c_lflag */
   41.53 +#define ISIG	0x00000001
   41.54 +#define ICANON	0x00000002
   41.55 +#define XCASE	0x00000004
   41.56 +#define ECHO	0x00000008
   41.57 +#define ECHOE	0x00000010
   41.58 +#define ECHOK	0x00000020
   41.59 +#define ECHONL	0x00000040
   41.60 +#define NOFLSH	0x00000080
   41.61 +#define TOSTOP	0x00000100
   41.62 +#define ECHOCTL	0x00000200
   41.63 +#define ECHOPRT	0x00000400
   41.64 +#define ECHOKE	0x00000800
   41.65 +#define FLUSHO	0x00002000
   41.66 +#define PENDIN	0x00004000
   41.67 +#define IEXTEN	0x00008000
   41.68 +
   41.69 +/* c_cflag */
   41.70 +#define CSIZE	0x00000030
   41.71 +#define CS8	0x00000030
   41.72 +#define CSTOPB	0x00000040
   41.73 +#define CREAD	0x00000080
   41.74 +#define PARENB	0x00000100
   41.75 +#define PARODD	0x00000200
   41.76 +#define HUPCL	0x00000400
   41.77 +#define CLOCAL	0x00000800
   41.78 +
   41.79 +/* c_cc */
   41.80 +#define VTIME	5
   41.81 +#define VMIN	6
   41.82 +
   41.83 +#define TCSANOW		0
   41.84 +#define TCSADRAIN	1
   41.85 +#define TCSAFLUSH	2
   41.86 +
   41.87 +int tcsetattr(int fildes, int action, const struct termios *tios);
   41.88 +int tcgetattr(int fildes, struct termios *tios);
   41.89 +
   41.90 +#endif /* _POSIX_TERMIOS_H */
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/extras/mini-os/include/posix/time.h	Tue Feb 12 14:35:39 2008 +0000
    42.3 @@ -0,0 +1,10 @@
    42.4 +#ifndef _POSIX_TIME_H
    42.5 +#define _POSIX_TIME_H
    42.6 +
    42.7 +#include <sys/time.h>
    42.8 +#define CLOCK_MONOTONIC	2
    42.9 +#include_next <time.h>
   42.10 +
   42.11 +int nanosleep(const struct timespec *req, struct timespec *rem);
   42.12 +
   42.13 +#endif /* _POSIX_TIME_H */
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/extras/mini-os/include/posix/unistd.h	Tue Feb 12 14:35:39 2008 +0000
    43.3 @@ -0,0 +1,12 @@
    43.4 +#ifndef _POSIX_UNISTD_H
    43.5 +#define _POSIX_UNISTD_H
    43.6 +
    43.7 +#include_next <unistd.h>
    43.8 +#include <sys/select.h>
    43.9 +#include <arch_limits.h>
   43.10 +
   43.11 +#define getpagesize() __PAGE_SIZE
   43.12 +
   43.13 +int ftruncate(int fd, off_t length);
   43.14 +
   43.15 +#endif /* _POSIX_UNISTD_H */
    44.1 --- a/extras/mini-os/include/sched.h	Tue Feb 12 11:37:45 2008 +0000
    44.2 +++ b/extras/mini-os/include/sched.h	Tue Feb 12 14:35:39 2008 +0000
    44.3 @@ -19,6 +19,9 @@ struct thread
    44.4      struct list_head thread_list;
    44.5      u32 flags;
    44.6      s_time_t wakeup_time;
    44.7 +#ifdef HAVE_LIBC
    44.8 +    struct _reent reent;
    44.9 +#endif
   44.10  };
   44.11  
   44.12  extern struct thread *idle_thread;
    45.1 --- a/extras/mini-os/include/sys/time.h	Tue Feb 12 11:37:45 2008 +0000
    45.2 +++ b/extras/mini-os/include/sys/time.h	Tue Feb 12 14:35:39 2008 +0000
    45.3 @@ -20,6 +20,9 @@
    45.4  #ifndef _MINIOS_SYS_TIME_H_
    45.5  #define _MINIOS_SYS_TIME_H_
    45.6  
    45.7 +#ifdef HAVE_LIBC
    45.8 +#include_next <sys/time.h>
    45.9 +#else
   45.10  struct timespec {
   45.11      time_t      tv_sec;
   45.12      long        tv_nsec;
   45.13 @@ -34,5 +37,6 @@ struct timeval {
   45.14  };
   45.15  
   45.16  int      gettimeofday(struct timeval *tv, void *tz);
   45.17 +#endif
   45.18  
   45.19  #endif /* _MINIOS_SYS_TIME_H_ */
    46.1 --- a/extras/mini-os/include/time.h	Tue Feb 12 11:37:45 2008 +0000
    46.2 +++ b/extras/mini-os/include/time.h	Tue Feb 12 14:35:39 2008 +0000
    46.3 @@ -17,8 +17,9 @@
    46.4   ****************************************************************************
    46.5   */
    46.6  
    46.7 -#ifndef _TIME_H_
    46.8 -#define _TIME_H_
    46.9 +#ifndef _MINIOS_TIME_H_
   46.10 +#define _MINIOS_TIME_H_
   46.11 +#include <types.h>
   46.12  
   46.13  /*
   46.14   * System Time
   46.15 @@ -44,8 +45,12 @@ typedef s64 s_time_t;
   46.16  /* wall clock time  */
   46.17  typedef long time_t;
   46.18  typedef long suseconds_t;
   46.19 +
   46.20  #include <sys/time.h>
   46.21  
   46.22 +#ifdef HAVE_LIBC
   46.23 +#include_next <time.h>
   46.24 +#endif
   46.25  
   46.26  /* prototypes */
   46.27  void     init_time(void);
   46.28 @@ -54,4 +59,4 @@ s_time_t get_v_time(void);
   46.29  u64      monotonic_clock(void);
   46.30  void     block_domain(s_time_t until);
   46.31  
   46.32 -#endif /* _TIME_H_ */
   46.33 +#endif /* _MINIOS_TIME_H_ */
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/extras/mini-os/include/x86/arch_limits.h	Tue Feb 12 14:35:39 2008 +0000
    47.3 @@ -0,0 +1,20 @@
    47.4 +
    47.5 +#ifndef __ARCH_LIMITS_H__
    47.6 +#define __ARCH_LIMITS_H__
    47.7 +
    47.8 +#define __PAGE_SHIFT      12
    47.9 +
   47.10 +#ifdef __ASSEMBLY__
   47.11 +#define __PAGE_SIZE       (1 << __PAGE_SHIFT)
   47.12 +#else
   47.13 +#ifndef CONFIG_X86_PAE
   47.14 +#define __PAGE_SIZE       (1UL << __PAGE_SHIFT)
   47.15 +#else
   47.16 +#define __PAGE_SIZE       (1ULL << __PAGE_SHIFT)
   47.17 +#endif
   47.18 +#endif
   47.19 +
   47.20 +#define __STACK_SIZE_PAGE_ORDER  4
   47.21 +#define __STACK_SIZE             (__PAGE_SIZE * (1 << __STACK_SIZE_PAGE_ORDER))
   47.22 +          
   47.23 +#endif /* __ARCH_LIMITS_H__ */
    48.1 --- a/extras/mini-os/include/x86/arch_mm.h	Tue Feb 12 11:37:45 2008 +0000
    48.2 +++ b/extras/mini-os/include/x86/arch_mm.h	Tue Feb 12 14:35:39 2008 +0000
    48.3 @@ -157,16 +157,9 @@ typedef unsigned long pgentry_t;
    48.4  #define L4_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER)
    48.5  #endif /* __i386__ || __x86_64__ */
    48.6  
    48.7 -#ifdef __ASSEMBLY__
    48.8 -#define PAGE_SIZE       (1 << L1_PAGETABLE_SHIFT)
    48.9 -#else
   48.10 -#ifndef CONFIG_X86_PAE
   48.11 -#define PAGE_SIZE       (1UL << L1_PAGETABLE_SHIFT)
   48.12 -#else
   48.13 -#define PAGE_SIZE       (1ULL << L1_PAGETABLE_SHIFT)
   48.14 -#endif
   48.15 -#endif
   48.16 -#define PAGE_SHIFT      L1_PAGETABLE_SHIFT
   48.17 +#include "arch_limits.h"
   48.18 +#define PAGE_SIZE       __PAGE_SIZE
   48.19 +#define PAGE_SHIFT      __PAGE_SHIFT
   48.20  #define PAGE_MASK       (~(PAGE_SIZE-1))
   48.21  
   48.22  #define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
   48.23 @@ -177,9 +170,6 @@ typedef unsigned long pgentry_t;
   48.24  /* to align the pointer to the (next) page boundary */
   48.25  #define PAGE_ALIGN(addr)        (((addr)+PAGE_SIZE-1)&PAGE_MASK)
   48.26  
   48.27 -#define STACK_SIZE_PAGE_ORDER  1
   48.28 -#define STACK_SIZE             (PAGE_SIZE * (1 << STACK_SIZE_PAGE_ORDER))
   48.29 -
   48.30  #ifndef __ASSEMBLY__
   48.31  /* Definitions for machine and pseudophysical addresses. */
   48.32  #ifdef CONFIG_X86_PAE
   48.33 @@ -257,5 +247,11 @@ static __inline__ paddr_t machine_to_phy
   48.34  
   48.35  #define map_frames(f, n) map_frames_ex(f, n, 1, 0, 1, DOMID_SELF, 0, L1_PROT)
   48.36  #define map_zero(n, a) map_frames_ex(&mfn_zero, n, 0, 0, a, DOMID_SELF, 0, L1_PROT_RO)
   48.37 +#ifndef __ASSEMBLY__
   48.38 +void do_map_frames(unsigned long addr,
   48.39 +        unsigned long *f, unsigned long n, unsigned long stride,
   48.40 +	unsigned long increment, domid_t id, int may_fail, unsigned long prot);
   48.41 +#endif
   48.42 +#define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0, DOMID_SELF, 0, L1_PROT_RO)
   48.43  
   48.44  #endif /* _ARCH_MM_H_ */
    49.1 --- a/extras/mini-os/include/x86/arch_sched.h	Tue Feb 12 11:37:45 2008 +0000
    49.2 +++ b/extras/mini-os/include/x86/arch_sched.h	Tue Feb 12 14:35:39 2008 +0000
    49.3 @@ -2,7 +2,7 @@
    49.4  #ifndef __ARCH_SCHED_H__
    49.5  #define __ARCH_SCHED_H__
    49.6  
    49.7 -#include <arch_mm.h>
    49.8 +#include <arch_limits.h>
    49.9  
   49.10  static inline struct thread* get_current(void)
   49.11  {
   49.12 @@ -12,7 +12,7 @@ static inline struct thread* get_current
   49.13  #else
   49.14      register unsigned long sp asm("rsp");
   49.15  #endif 
   49.16 -    current = (void *)(unsigned long)(sp & ~(STACK_SIZE-1));
   49.17 +    current = (void *)(unsigned long)(sp & ~(__STACK_SIZE-1));
   49.18      return *current;
   49.19  }
   49.20  
    50.1 --- a/extras/mini-os/include/x86/arch_spinlock.h	Tue Feb 12 11:37:45 2008 +0000
    50.2 +++ b/extras/mini-os/include/x86/arch_spinlock.h	Tue Feb 12 14:35:39 2008 +0000
    50.3 @@ -4,6 +4,7 @@
    50.4  #define __ARCH_ASM_SPINLOCK_H
    50.5  
    50.6  #include <lib.h>
    50.7 +#include "os.h"
    50.8  
    50.9  
   50.10  #define ARCH_SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }
    51.1 --- a/extras/mini-os/include/x86/os.h	Tue Feb 12 11:37:45 2008 +0000
    51.2 +++ b/extras/mini-os/include/x86/os.h	Tue Feb 12 14:35:39 2008 +0000
    51.3 @@ -563,6 +563,7 @@ static __inline__ int synch_var_test_bit
    51.4   synch_var_test_bit((nr),(addr)))
    51.5  
    51.6  
    51.7 +#undef ADDR
    51.8  
    51.9  #endif /* not assembly */
   51.10  #endif /* _OS_H_ */
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/extras/mini-os/lib/sys.c	Tue Feb 12 14:35:39 2008 +0000
    52.3 @@ -0,0 +1,1083 @@
    52.4 +/*
    52.5 + * POSIX-compatible libc layer
    52.6 + *
    52.7 + * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, October 2007
    52.8 + *
    52.9 + * Provides the UNIXish part of the standard libc function.
   52.10 + *
   52.11 + * Relatively straight-forward: just multiplex the file descriptor operations
   52.12 + * among the various file types (console, FS, network, ...)
   52.13 + */
   52.14 +
   52.15 +//#define LIBC_VERBOSE
   52.16 +//#define LIBC_DEBUG
   52.17 +
   52.18 +#ifdef LIBC_DEBUG
   52.19 +#define DEBUG(fmt,...) printk(fmt, ##__VA_ARGS__)
   52.20 +#else
   52.21 +#define DEBUG(fmt,...)
   52.22 +#endif
   52.23 +
   52.24 +#ifdef HAVE_LIBC
   52.25 +#include <os.h>
   52.26 +#include <console.h>
   52.27 +#include <sched.h>
   52.28 +#include <events.h>
   52.29 +#include <wait.h>
   52.30 +#include <netfront.h>
   52.31 +#include <blkfront.h>
   52.32 +#include <xenbus.h>
   52.33 +#include <xs.h>
   52.34 +
   52.35 +#include <sys/types.h>
   52.36 +#include <sys/unistd.h>
   52.37 +#include <sys/stat.h>
   52.38 +#include <sys/mman.h>
   52.39 +#include <time.h>
   52.40 +#include <errno.h>
   52.41 +#include <fcntl.h>
   52.42 +#include <pthread.h>
   52.43 +#include <assert.h>
   52.44 +#include <dirent.h>
   52.45 +#include <stdlib.h>
   52.46 +#include <math.h>
   52.47 +
   52.48 +#include <lwip/sockets.h>
   52.49 +#include <fs.h>
   52.50 +
   52.51 +#define debug(fmt, ...) \
   52.52 +
   52.53 +#define print_unsupported(fmt, ...) \
   52.54 +    printk("Unsupported function "fmt" called in Mini-OS kernel\n", ## __VA_ARGS__);
   52.55 +
   52.56 +/* Crash on function call */
   52.57 +#define unsupported_function_crash(function) \
   52.58 +    int __unsup_##function(void) asm(#function); \
   52.59 +    int __unsup_##function(void) \
   52.60 +    { \
   52.61 +	print_unsupported(#function); \
   52.62 +	do_exit(); \
   52.63 +    }
   52.64 +
   52.65 +/* Log and err out on function call */
   52.66 +#define unsupported_function_log(type, function, ret) \
   52.67 +    type __unsup_##function(void) asm(#function); \
   52.68 +    type __unsup_##function(void) \
   52.69 +    { \
   52.70 +	print_unsupported(#function); \
   52.71 +	errno = ENOSYS; \
   52.72 +	return ret; \
   52.73 +    }
   52.74 +
   52.75 +/* Err out on function call */
   52.76 +#define unsupported_function(type, function, ret) \
   52.77 +    type __unsup_##function(void) asm(#function); \
   52.78 +    type __unsup_##function(void) \
   52.79 +    { \
   52.80 +	errno = ENOSYS; \
   52.81 +	return ret; \
   52.82 +    }
   52.83 +
   52.84 +#define NOFILE 32
   52.85 +extern int xc_evtchn_close(int fd);
   52.86 +
   52.87 +pthread_mutex_t fd_lock = PTHREAD_MUTEX_INITIALIZER;
   52.88 +struct file files[NOFILE] = {
   52.89 +    { .type = FTYPE_CONSOLE }, /* stdin */
   52.90 +    { .type = FTYPE_CONSOLE }, /* stdout */
   52.91 +    { .type = FTYPE_CONSOLE }, /* stderr */
   52.92 +};
   52.93 +
   52.94 +DECLARE_WAIT_QUEUE_HEAD(event_queue);
   52.95 +
   52.96 +int alloc_fd(enum fd_type type)
   52.97 +{
   52.98 +    int i;
   52.99 +    pthread_mutex_lock(&fd_lock);
  52.100 +    for (i=0; i<NOFILE; i++) {
  52.101 +	if (files[i].type == FTYPE_NONE) {
  52.102 +	    files[i].type = type;
  52.103 +	    pthread_mutex_unlock(&fd_lock);
  52.104 +	    return i;
  52.105 +	}
  52.106 +    }
  52.107 +    pthread_mutex_unlock(&fd_lock);
  52.108 +    printk("Too many opened files\n");
  52.109 +    do_exit();
  52.110 +}
  52.111 +
  52.112 +void close_all_files(void)
  52.113 +{
  52.114 +    int i;
  52.115 +    pthread_mutex_lock(&fd_lock);
  52.116 +    for (i=NOFILE - 1; i > 0; i--)
  52.117 +	if (files[i].type != FTYPE_NONE)
  52.118 +            close(i);
  52.119 +    pthread_mutex_unlock(&fd_lock);
  52.120 +}
  52.121 +
  52.122 +int dup2(int oldfd, int newfd)
  52.123 +{
  52.124 +    pthread_mutex_lock(&fd_lock);
  52.125 +    if (files[newfd].type != FTYPE_NONE)
  52.126 +	close(newfd);
  52.127 +    // XXX: this is a bit bogus, as we are supposed to share the offset etc
  52.128 +    files[newfd] = files[oldfd];
  52.129 +    pthread_mutex_unlock(&fd_lock);
  52.130 +    return 0;
  52.131 +}
  52.132 +
  52.133 +pid_t getpid(void)
  52.134 +{
  52.135 +    return 1;
  52.136 +}
  52.137 +
  52.138 +pid_t getppid(void)
  52.139 +{
  52.140 +    return 1;
  52.141 +}
  52.142 +
  52.143 +pid_t setsid(void)
  52.144 +{
  52.145 +    return 1;
  52.146 +}
  52.147 +
  52.148 +char *getcwd(char *buf, size_t size)
  52.149 +{
  52.150 +    snprintf(buf, size, "/");
  52.151 +    return buf;
  52.152 +}
  52.153 +
  52.154 +#define LOG_PATH "/var/log/"
  52.155 +
  52.156 +int mkdir(const char *pathname, mode_t mode)
  52.157 +{
  52.158 +    int ret;
  52.159 +    ret = fs_create(fs_import, (char *) pathname, 1, mode);
  52.160 +    if (ret < 0) {
  52.161 +        errno = EIO;
  52.162 +        return -1;
  52.163 +    }
  52.164 +    return 0;
  52.165 +}
  52.166 +
  52.167 +int open(const char *pathname, int flags, ...)
  52.168 +{
  52.169 +    int fs_fd, fd;
  52.170 +    /* Ugly, but fine.  */
  52.171 +    if (!strncmp(pathname,LOG_PATH,strlen(LOG_PATH))) {
  52.172 +	fd = alloc_fd(FTYPE_CONSOLE);
  52.173 +        printk("open(%s) -> %d\n", pathname, fd);
  52.174 +        return fd;
  52.175 +    }
  52.176 +    printk("open(%s)", pathname);
  52.177 +    fs_fd = fs_open(fs_import, (void *) pathname);
  52.178 +    if (fs_fd < 0) {
  52.179 +	errno = EIO;
  52.180 +	return -1;
  52.181 +    }
  52.182 +    fd = alloc_fd(FTYPE_FILE);
  52.183 +    printk("-> %d\n", fd);
  52.184 +    files[fd].file.fd = fs_fd;
  52.185 +    files[fd].file.offset = 0;
  52.186 +    return fd;
  52.187 +}
  52.188 +#if defined(__x86_64__) || defined(__ia64__)
  52.189 +__typeof__(open) open64 __attribute__((__alias__("open")));
  52.190 +#endif
  52.191 +
  52.192 +int isatty(int fd)
  52.193 +{
  52.194 +    return files[fd].type == FTYPE_CONSOLE;
  52.195 +}
  52.196 +
  52.197 +int read(int fd, void *buf, size_t nbytes)
  52.198 +{
  52.199 +    switch (files[fd].type) {
  52.200 +	case FTYPE_CONSOLE:
  52.201 +	    return 0;
  52.202 +	case FTYPE_FILE: {
  52.203 +	    ssize_t ret;
  52.204 +	    if (nbytes > PAGE_SIZE)
  52.205 +		nbytes = PAGE_SIZE;
  52.206 +	    ret = fs_read(fs_import, files[fd].file.fd, buf, nbytes, files[fd].file.offset);
  52.207 +	    if (ret > 0) {
  52.208 +		files[fd].file.offset += ret;
  52.209 +		return ret;
  52.210 +	    } else if (ret < 0) {
  52.211 +		errno = EIO;
  52.212 +		return -1;
  52.213 +	    }
  52.214 +	    return 0;
  52.215 +	}
  52.216 +	case FTYPE_SOCKET:
  52.217 +	    return lwip_read(files[fd].socket.fd, buf, nbytes);
  52.218 +	case FTYPE_TAP: {
  52.219 +	    ssize_t ret;
  52.220 +	    ret = netfront_receive(files[fd].tap.dev, buf, nbytes);
  52.221 +	    if (ret <= 0) {
  52.222 +		errno = EAGAIN;
  52.223 +		return -1;
  52.224 +	    }
  52.225 +	    return ret;
  52.226 +	}
  52.227 +	case FTYPE_NONE:
  52.228 +	case FTYPE_XENBUS:
  52.229 +	case FTYPE_EVTCHN:
  52.230 +	case FTYPE_BLK:
  52.231 +	    break;
  52.232 +    }
  52.233 +    printk("read(%d): Bad descriptor\n", fd);
  52.234 +    errno = EBADF;
  52.235 +    return -1;
  52.236 +}
  52.237 +
  52.238 +int write(int fd, const void *buf, size_t nbytes)
  52.239 +{
  52.240 +    switch (files[fd].type) {
  52.241 +	case FTYPE_CONSOLE:
  52.242 +	    console_print((char *)buf, nbytes);
  52.243 +	    return nbytes;
  52.244 +	case FTYPE_FILE: {
  52.245 +	    ssize_t ret;
  52.246 +	    if (nbytes > PAGE_SIZE)
  52.247 +		nbytes = PAGE_SIZE;
  52.248 +	    ret = fs_write(fs_import, files[fd].file.fd, (void *) buf, nbytes, files[fd].file.offset);
  52.249 +	    if (ret > 0) {
  52.250 +		files[fd].file.offset += ret;
  52.251 +		return ret;
  52.252 +	    } else if (ret < 0) {
  52.253 +		errno = EIO;
  52.254 +		return -1;
  52.255 +	    }
  52.256 +	    return 0;
  52.257 +	}
  52.258 +	case FTYPE_SOCKET:
  52.259 +	    return lwip_write(files[fd].socket.fd, (void*) buf, nbytes);
  52.260 +	case FTYPE_TAP:
  52.261 +	    netfront_xmit(files[fd].tap.dev, (void*) buf, nbytes);
  52.262 +	    return nbytes;
  52.263 +	case FTYPE_NONE:
  52.264 +	case FTYPE_XENBUS:
  52.265 +	case FTYPE_EVTCHN:
  52.266 +	case FTYPE_BLK:
  52.267 +	    break;
  52.268 +    }
  52.269 +    printk("write(%d): Bad descriptor\n", fd);
  52.270 +    errno = EBADF;
  52.271 +    return -1;
  52.272 +}
  52.273 +
  52.274 +off_t lseek(int fd, off_t offset, int whence)
  52.275 +{
  52.276 +    if (files[fd].type != FTYPE_FILE) {
  52.277 +	errno = ESPIPE;
  52.278 +	return (off_t) -1;
  52.279 +    }
  52.280 +    switch (whence) {
  52.281 +	case SEEK_SET:
  52.282 +	    files[fd].file.offset = offset;
  52.283 +	    break;
  52.284 +	case SEEK_CUR:
  52.285 +	    files[fd].file.offset += offset;
  52.286 +	    break;
  52.287 +	case SEEK_END: {
  52.288 +	    struct stat st;
  52.289 +	    int ret;
  52.290 +	    ret = fstat(fd, &st);
  52.291 +	    if (ret)
  52.292 +		return -1;
  52.293 +	    files[fd].file.offset = st.st_size + offset;
  52.294 +	    break;
  52.295 +	}
  52.296 +	default:
  52.297 +	    errno = EINVAL;
  52.298 +	    return -1;
  52.299 +    }
  52.300 +    return files[fd].file.offset;
  52.301 +}
  52.302 +#if defined(__x86_64__) || defined(__ia64__)
  52.303 +__typeof__(lseek) lseek64 __attribute__((__alias__("lseek")));
  52.304 +#endif
  52.305 +
  52.306 +int fsync(int fd) {
  52.307 +    switch (files[fd].type) {
  52.308 +	case FTYPE_FILE: {
  52.309 +	    int ret;
  52.310 +	    ret = fs_sync(fs_import, files[fd].file.fd);
  52.311 +	    if (ret < 0) {
  52.312 +		errno = EIO;
  52.313 +		return -1;
  52.314 +	    }
  52.315 +	    return 0;
  52.316 +	}
  52.317 +	case FTYPE_NONE:
  52.318 +	case FTYPE_CONSOLE:
  52.319 +	case FTYPE_SOCKET:
  52.320 +	case FTYPE_XENBUS:
  52.321 +	case FTYPE_EVTCHN:
  52.322 +	case FTYPE_TAP:
  52.323 +	case FTYPE_BLK:
  52.324 +	    break;
  52.325 +    }
  52.326 +    printk("fsync(%d): Bad descriptor\n", fd);
  52.327 +    errno = EBADF;
  52.328 +    return -1;
  52.329 +}
  52.330 +
  52.331 +int close(int fd)
  52.332 +{
  52.333 +    printk("close(%d)\n", fd);
  52.334 +    switch (files[fd].type) {
  52.335 +	case FTYPE_CONSOLE:
  52.336 +	    files[fd].type = FTYPE_NONE;
  52.337 +	    return 0;
  52.338 +	case FTYPE_FILE: {
  52.339 +	    int ret = fs_close(fs_import, files[fd].file.fd);
  52.340 +	    files[fd].type = FTYPE_NONE;
  52.341 +	    if (ret < 0) {
  52.342 +		errno = EIO;
  52.343 +		return -1;
  52.344 +	    }
  52.345 +	    return 0;
  52.346 +	}
  52.347 +	case FTYPE_XENBUS:
  52.348 +            xs_daemon_close((void*)(intptr_t) fd);
  52.349 +            return 0;
  52.350 +	case FTYPE_SOCKET: {
  52.351 +	    int res = lwip_close(files[fd].socket.fd);
  52.352 +	    files[fd].type = FTYPE_NONE;
  52.353 +	    return res;
  52.354 +	}
  52.355 +	case FTYPE_EVTCHN:
  52.356 +            xc_evtchn_close(fd);
  52.357 +            return 0;
  52.358 +	case FTYPE_TAP:
  52.359 +	    shutdown_netfront(files[fd].tap.dev);
  52.360 +	    files[fd].type = FTYPE_NONE;
  52.361 +	    return 0;
  52.362 +	case FTYPE_BLK:
  52.363 +            shutdown_blkfront(files[fd].blk.dev);
  52.364 +	    files[fd].type = FTYPE_NONE;
  52.365 +	    return 0;
  52.366 +	case FTYPE_NONE:
  52.367 +	    break;
  52.368 +    }
  52.369 +    printk("close(%d): Bad descriptor\n", fd);
  52.370 +    errno = EBADF;
  52.371 +    return -1;
  52.372 +}
  52.373 +
  52.374 +static void init_stat(struct stat *buf)
  52.375 +{
  52.376 +    memset(buf, 0, sizeof(*buf));
  52.377 +    buf->st_dev = 0;
  52.378 +    buf->st_ino = 0;
  52.379 +    buf->st_nlink = 1;
  52.380 +    buf->st_rdev = 0;
  52.381 +    buf->st_blksize = 4096;
  52.382 +    buf->st_blocks = 0;
  52.383 +}
  52.384 +
  52.385 +static void stat_from_fs(struct stat *buf, struct fsif_stat_response *stat)
  52.386 +{
  52.387 +    buf->st_mode = stat->stat_mode;
  52.388 +    buf->st_uid = stat->stat_uid;
  52.389 +    buf->st_gid = stat->stat_gid;
  52.390 +    buf->st_size = stat->stat_size;
  52.391 +    buf->st_atime = stat->stat_atime;
  52.392 +    buf->st_mtime = stat->stat_mtime;
  52.393 +    buf->st_ctime = stat->stat_ctime;
  52.394 +}
  52.395 +
  52.396 +int stat(const char *path, struct stat *buf)
  52.397 +{
  52.398 +    struct fsif_stat_response stat;
  52.399 +    int ret;
  52.400 +    int fs_fd;
  52.401 +    printk("stat(%s)\n", path);
  52.402 +    fs_fd = fs_open(fs_import, (char*) path);
  52.403 +    if (fs_fd < 0) {
  52.404 +	errno = EIO;
  52.405 +	ret = -1;
  52.406 +	goto out;
  52.407 +    }
  52.408 +    ret = fs_stat(fs_import, fs_fd, &stat);
  52.409 +    if (ret < 0) {
  52.410 +	errno = EIO;
  52.411 +	ret = -1;
  52.412 +	goto outfd;
  52.413 +    }
  52.414 +    init_stat(buf);
  52.415 +    stat_from_fs(buf, &stat);
  52.416 +    ret = 0;
  52.417 +
  52.418 +outfd:
  52.419 +    fs_close(fs_import, fs_fd);
  52.420 +out:
  52.421 +    return ret;
  52.422 +}
  52.423 +
  52.424 +int fstat(int fd, struct stat *buf)
  52.425 +{
  52.426 +    init_stat(buf);
  52.427 +    switch (files[fd].type) {
  52.428 +	case FTYPE_CONSOLE:
  52.429 +	case FTYPE_SOCKET: {
  52.430 +	    buf->st_mode = (files[fd].type == FTYPE_CONSOLE?S_IFCHR:S_IFSOCK) | S_IRUSR|S_IWUSR;
  52.431 +	    buf->st_uid = 0;
  52.432 +	    buf->st_gid = 0;
  52.433 +	    buf->st_size = 0;
  52.434 +	    buf->st_atime = 
  52.435 +	    buf->st_mtime = 
  52.436 +	    buf->st_ctime = time(NULL);
  52.437 +	    return 0;
  52.438 +	}
  52.439 +	case FTYPE_FILE: {
  52.440 +	    struct fsif_stat_response stat;
  52.441 +	    int ret;
  52.442 +	    ret = fs_stat(fs_import, files[fd].file.fd, &stat);
  52.443 +	    if (ret < 0) {
  52.444 +		errno = EIO;
  52.445 +		return -1;
  52.446 +	    }
  52.447 +	    /* The protocol is a bit evasive about this value */
  52.448 +	    stat_from_fs(buf, &stat);
  52.449 +	    return 0;
  52.450 +	}
  52.451 +	case FTYPE_NONE:
  52.452 +	case FTYPE_XENBUS:
  52.453 +	case FTYPE_EVTCHN:
  52.454 +	case FTYPE_TAP:
  52.455 +	case FTYPE_BLK:
  52.456 +	    break;
  52.457 +    }
  52.458 +
  52.459 +    printk("statf(%d): Bad descriptor\n", fd);
  52.460 +    errno = EBADF;
  52.461 +    return -1;
  52.462 +}
  52.463 +
  52.464 +int ftruncate(int fd, off_t length)
  52.465 +{
  52.466 +    switch (files[fd].type) {
  52.467 +	case FTYPE_FILE: {
  52.468 +            int ret;
  52.469 +            ret = fs_truncate(fs_import, files[fd].file.fd, length);
  52.470 +	    if (ret < 0) {
  52.471 +		errno = EIO;
  52.472 +		return -1;
  52.473 +	    }
  52.474 +	    return 0;
  52.475 +	}
  52.476 +	case FTYPE_NONE:
  52.477 +	case FTYPE_CONSOLE:
  52.478 +	case FTYPE_SOCKET:
  52.479 +	case FTYPE_XENBUS:
  52.480 +	case FTYPE_EVTCHN:
  52.481 +	case FTYPE_TAP:
  52.482 +	case FTYPE_BLK:
  52.483 +	    break;
  52.484 +    }
  52.485 +
  52.486 +    printk("ftruncate(%d): Bad descriptor\n", fd);
  52.487 +    errno = EBADF;
  52.488 +    return -1;
  52.489 +}
  52.490 +
  52.491 +int remove(const char *pathname)
  52.492 +{
  52.493 +    int ret;
  52.494 +    printk("remove(%s)", pathname);
  52.495 +    ret = fs_remove(fs_import, (char*) pathname);
  52.496 +    if (ret < 0) {
  52.497 +        errno = EIO;
  52.498 +        return -1;
  52.499 +    }
  52.500 +    return 0;
  52.501 +}
  52.502 +
  52.503 +int unlink(const char *pathname)
  52.504 +{
  52.505 +    return remove(pathname);
  52.506 +}
  52.507 +
  52.508 +int rmdir(const char *pathname)
  52.509 +{
  52.510 +    return remove(pathname);
  52.511 +}
  52.512 +
  52.513 +int fcntl(int fd, int cmd, ...)
  52.514 +{
  52.515 +    long arg;
  52.516 +    va_list ap;
  52.517 +    va_start(ap, cmd);
  52.518 +    arg = va_arg(ap, long);
  52.519 +    va_end(ap);
  52.520 +
  52.521 +    switch (cmd) {
  52.522 +	case F_SETFL:
  52.523 +	    if (files[fd].type == FTYPE_SOCKET && !(arg & ~O_NONBLOCK)) {
  52.524 +		/* Only flag supported: non-blocking mode */
  52.525 +		uint32_t nblock = !!(arg & O_NONBLOCK);
  52.526 +		return lwip_ioctl(files[fd].socket.fd, FIONBIO, &nblock);
  52.527 +	    }
  52.528 +	    /* Fallthrough */
  52.529 +	default:
  52.530 +	    printk("fcntl(%d, %d, %lx/%lo)\n", fd, cmd, arg, arg);
  52.531 +	    errno = ENOSYS;
  52.532 +	    return -1;
  52.533 +    }
  52.534 +}
  52.535 +
  52.536 +DIR *opendir(const char *name)
  52.537 +{
  52.538 +    DIR *ret;
  52.539 +    ret = malloc(sizeof(*ret));
  52.540 +    ret->name = strdup(name);
  52.541 +    ret->offset = 0;
  52.542 +    ret->entries = NULL;
  52.543 +    ret->curentry = -1;
  52.544 +    ret->nbentries = 0;
  52.545 +    ret->has_more = 1;
  52.546 +    return ret;
  52.547 +}
  52.548 +
  52.549 +struct dirent *readdir(DIR *dir)
  52.550 +{
  52.551 +    if (dir->curentry >= 0) {
  52.552 +        free(dir->entries[dir->curentry]);
  52.553 +        dir->entries[dir->curentry] = NULL;
  52.554 +    }
  52.555 +    dir->curentry++;
  52.556 +    if (dir->curentry >= dir->nbentries) {
  52.557 +        dir->offset += dir->nbentries;
  52.558 +        free(dir->entries);
  52.559 +        dir->curentry = -1;
  52.560 +        dir->nbentries = 0;
  52.561 +        if (!dir->has_more)
  52.562 +            return NULL;
  52.563 +        dir->entries = fs_list(fs_import, dir->name, dir->offset, &dir->nbentries, &dir->has_more);
  52.564 +        if (!dir->entries || !dir->nbentries)
  52.565 +            return NULL;
  52.566 +        dir->curentry = 0;
  52.567 +    }
  52.568 +    dir->dirent.d_name = dir->entries[dir->curentry];
  52.569 +    return &dir->dirent;
  52.570 +} 
  52.571 +int closedir(DIR *dir)
  52.572 +{
  52.573 +    int i;
  52.574 +    for (i=0; i<dir->nbentries; i++)
  52.575 +        free(dir->entries[i]);
  52.576 +    free(dir->entries);
  52.577 +    free(dir->name);
  52.578 +    free(dir);
  52.579 +    return 0;
  52.580 +}
  52.581 +
  52.582 +/* We assume that only the main thread calls select(). */
  52.583 +
  52.584 +static const char file_types[] = {
  52.585 +    [FTYPE_NONE]	= 'N',
  52.586 +    [FTYPE_CONSOLE]	= 'C',
  52.587 +    [FTYPE_FILE]	= 'F',
  52.588 +    [FTYPE_XENBUS]	= 'X',
  52.589 +    [FTYPE_EVTCHN]	= 'E',
  52.590 +    [FTYPE_SOCKET]	= 'S',
  52.591 +    [FTYPE_TAP]		= 'T',
  52.592 +    [FTYPE_BLK]		= 'B',
  52.593 +};
  52.594 +#ifdef LIBC_DEBUG
  52.595 +static void dump_set(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
  52.596 +{
  52.597 +    int i, comma;
  52.598 +#define printfds(set) do {\
  52.599 +    comma = 0; \
  52.600 +    for (i = 0; i < nfds; i++) { \
  52.601 +	if (FD_ISSET(i, set)) { \
  52.602 +	    if (comma) \
  52.603 +		printk(", "); \
  52.604 +	    printk("%d(%c)", i, file_types[files[i].type]); \
  52.605 +	    comma = 1; \
  52.606 +	} \
  52.607 +    } \
  52.608 +} while (0)
  52.609 +
  52.610 +    printk("[");
  52.611 +    if (readfds)
  52.612 +	printfds(readfds);
  52.613 +    printk("], [");
  52.614 +    if (writefds)
  52.615 +	printfds(writefds);
  52.616 +    printk("], [");
  52.617 +    if (exceptfds)
  52.618 +	printfds(exceptfds);
  52.619 +    printk("], ");
  52.620 +    if (timeout)
  52.621 +	printk("{ %ld, %ld }", timeout->tv_sec, timeout->tv_usec);
  52.622 +}
  52.623 +#else
  52.624 +#define dump_set(nfds, readfds, writefds, exceptfds, timeout)
  52.625 +#endif
  52.626 +
  52.627 +/* Just poll without blocking */
  52.628 +static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
  52.629 +{
  52.630 +    int i, n = 0, sock_n, sock_nfds = 0;
  52.631 +    fd_set sock_readfds, sock_writefds, sock_exceptfds;
  52.632 +    struct timeval timeout = { .tv_sec = 0, .tv_usec = 0};
  52.633 +
  52.634 +#ifdef LIBC_VERBOSE
  52.635 +    static int nb;
  52.636 +    static int nbread[NOFILE], nbwrite[NOFILE], nbexcept[NOFILE];
  52.637 +    static s64_t lastshown;
  52.638 +
  52.639 +    nb++;
  52.640 +#endif
  52.641 +
  52.642 +    /* first poll network */
  52.643 +    FD_ZERO(&sock_readfds);
  52.644 +    FD_ZERO(&sock_writefds);
  52.645 +    FD_ZERO(&sock_exceptfds);
  52.646 +    for (i = 0; i < nfds; i++) {
  52.647 +	if (files[i].type == FTYPE_SOCKET) {
  52.648 +	    if (FD_ISSET(i, readfds)) {
  52.649 +		FD_SET(files[i].socket.fd, &sock_readfds);
  52.650 +		sock_nfds = i+1;
  52.651 +	    }
  52.652 +	    if (FD_ISSET(i, writefds)) {
  52.653 +		FD_SET(files[i].socket.fd, &sock_writefds);
  52.654 +		sock_nfds = i+1;
  52.655 +	    }
  52.656 +	    if (FD_ISSET(i, exceptfds)) {
  52.657 +		FD_SET(files[i].socket.fd, &sock_exceptfds);
  52.658 +		sock_nfds = i+1;
  52.659 +	    }
  52.660 +	}
  52.661 +    }
  52.662 +    DEBUG("lwip_select(");
  52.663 +    dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
  52.664 +    DEBUG("); -> ");
  52.665 +    sock_n = lwip_select(sock_nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
  52.666 +    dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
  52.667 +    DEBUG("\n");
  52.668 +
  52.669 +    /* Then see others as well. */
  52.670 +    for (i = 0; i < nfds; i++) {
  52.671 +	switch(files[i].type) {
  52.672 +	case FTYPE_NONE:
  52.673 +	    if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, exceptfds))
  52.674 +		printk("bogus fd %d in select\n", i);
  52.675 +	    /* Fallthrough.  */
  52.676 +	case FTYPE_FILE:
  52.677 +	    FD_CLR(i, readfds);
  52.678 +	    FD_CLR(i, writefds);
  52.679 +	    FD_CLR(i, exceptfds);
  52.680 +	    break;
  52.681 +	case FTYPE_CONSOLE:
  52.682 +	    FD_CLR(i, readfds);
  52.683 +	    if (FD_ISSET(i, writefds))
  52.684 +                n++;
  52.685 +	    FD_CLR(i, exceptfds);
  52.686 +	    break;
  52.687 +	case FTYPE_XENBUS:
  52.688 +	    if (FD_ISSET(i, readfds)) {
  52.689 +                if (files[i].xenbus.events)
  52.690 +		    n++;
  52.691 +		else
  52.692 +		    FD_CLR(i, readfds);
  52.693 +	    }
  52.694 +	    FD_CLR(i, writefds);
  52.695 +	    FD_CLR(i, exceptfds);
  52.696 +	    break;
  52.697 +	case FTYPE_EVTCHN:
  52.698 +	case FTYPE_TAP:
  52.699 +	case FTYPE_BLK:
  52.700 +	    if (FD_ISSET(i, readfds)) {
  52.701 +		if (files[i].read)
  52.702 +		    n++;
  52.703 +		else
  52.704 +		    FD_CLR(i, readfds);
  52.705 +	    }
  52.706 +	    FD_CLR(i, writefds);
  52.707 +	    FD_CLR(i, exceptfds);
  52.708 +	    break;
  52.709 +	case FTYPE_SOCKET:
  52.710 +	    if (FD_ISSET(i, readfds)) {
  52.711 +	        /* Optimize no-network-packet case.  */
  52.712 +		if (sock_n && FD_ISSET(files[i].socket.fd, &sock_readfds))
  52.713 +		    n++;
  52.714 +		else
  52.715 +		    FD_CLR(i, readfds);
  52.716 +	    }
  52.717 +            if (FD_ISSET(i, writefds)) {
  52.718 +		if (sock_n && FD_ISSET(files[i].socket.fd, &sock_writefds))
  52.719 +		    n++;
  52.720 +		else
  52.721 +		    FD_CLR(i, writefds);
  52.722 +            }
  52.723 +            if (FD_ISSET(i, exceptfds)) {
  52.724 +		if (sock_n && FD_ISSET(files[i].socket.fd, &sock_exceptfds))
  52.725 +		    n++;
  52.726 +		else
  52.727 +		    FD_CLR(i, exceptfds);
  52.728 +            }
  52.729 +	    break;
  52.730 +	}
  52.731 +#ifdef LIBC_VERBOSE
  52.732 +	if (FD_ISSET(i, readfds))
  52.733 +	    nbread[i]++;
  52.734 +	if (FD_ISSET(i, writefds))
  52.735 +	    nbwrite[i]++;
  52.736 +	if (FD_ISSET(i, exceptfds))
  52.737 +	    nbexcept[i]++;
  52.738 +#endif
  52.739 +    }
  52.740 +#ifdef LIBC_VERBOSE
  52.741 +    if (NOW() > lastshown + 1000000000ull) {
  52.742 +	lastshown = NOW();
  52.743 +	printk("%lu MB free, ", num_free_pages() / ((1 << 20) / PAGE_SIZE));
  52.744 +	printk("%d(%d): ", nb, sock_n);
  52.745 +	for (i = 0; i < nfds; i++) {
  52.746 +	    if (nbread[i] || nbwrite[i] || nbexcept[i])
  52.747 +		printk(" %d(%c):", i, file_types[files[i].type]);
  52.748 +	    if (nbread[i])
  52.749 +	    	printk(" %dR", nbread[i]);
  52.750 +	    if (nbwrite[i])
  52.751 +		printk(" %dW", nbwrite[i]);
  52.752 +	    if (nbexcept[i])
  52.753 +		printk(" %dE", nbexcept[i]);
  52.754 +	}
  52.755 +	printk("\n");
  52.756 +	memset(nbread, 0, sizeof(nbread));
  52.757 +	memset(nbwrite, 0, sizeof(nbwrite));
  52.758 +	memset(nbexcept, 0, sizeof(nbexcept));
  52.759 +	nb = 0;
  52.760 +    }
  52.761 +#endif
  52.762 +    return n;
  52.763 +}
  52.764 +
  52.765 +/* The strategy is to
  52.766 + * - announce that we will maybe sleep
  52.767 + * - poll a bit ; if successful, return
  52.768 + * - if timeout, return
  52.769 + * - really sleep (except if somebody woke us in the meanwhile) */
  52.770 +int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
  52.771 +	struct timeval *timeout)
  52.772 +{
  52.773 +    int n, ret;
  52.774 +    fd_set myread, mywrite, myexcept;
  52.775 +    struct thread *thread = get_current();
  52.776 +    s_time_t start = NOW(), stop;
  52.777 +    DEFINE_WAIT(w1);
  52.778 +    DEFINE_WAIT(w2);
  52.779 +    DEFINE_WAIT(w3);
  52.780 +    DEFINE_WAIT(w4);
  52.781 +
  52.782 +    assert(thread == main_thread);
  52.783 +
  52.784 +    DEBUG("select(%d, ", nfds);
  52.785 +    dump_set(nfds, readfds, writefds, exceptfds, timeout);
  52.786 +    DEBUG(");\n");
  52.787 +
  52.788 +    if (timeout)
  52.789 +	stop = start + SECONDS(timeout->tv_sec) + timeout->tv_usec * 1000;
  52.790 +    else
  52.791 +	/* just make gcc happy */
  52.792 +	stop = start;
  52.793 +
  52.794 +    /* Tell people we're going to sleep before looking at what they are
  52.795 +     * saying, hence letting them wake us if events happen between here and
  52.796 +     * schedule() */
  52.797 +    add_waiter(w1, netfront_queue);
  52.798 +    add_waiter(w2, event_queue);
  52.799 +    add_waiter(w3, blkfront_queue);
  52.800 +    add_waiter(w4, xenbus_watch_queue);
  52.801 +
  52.802 +    myread = *readfds;
  52.803 +    mywrite = *writefds;
  52.804 +    myexcept = *exceptfds;
  52.805 +    DEBUG("polling ");
  52.806 +    dump_set(nfds, &myread, &mywrite, &myexcept, timeout);
  52.807 +    DEBUG("\n");
  52.808 +    n = select_poll(nfds, &myread, &mywrite, &myexcept);
  52.809 +
  52.810 +    if (n) {
  52.811 +	dump_set(nfds, readfds, writefds, exceptfds, timeout);
  52.812 +	if (readfds)
  52.813 +	    *readfds = myread;
  52.814 +	if (writefds)
  52.815 +	    *writefds = mywrite;
  52.816 +	if (exceptfds)
  52.817 +	    *exceptfds = myexcept;
  52.818 +	DEBUG(" -> ");
  52.819 +	dump_set(nfds, readfds, writefds, exceptfds, timeout);
  52.820 +	DEBUG("\n");
  52.821 +	wake(thread);
  52.822 +	ret = n;
  52.823 +	goto out;
  52.824 +    }
  52.825 +    if (timeout && NOW() >= stop) {
  52.826 +	if (readfds)
  52.827 +	    FD_ZERO(readfds);
  52.828 +	if (writefds)
  52.829 +	    FD_ZERO(writefds);
  52.830 +	if (exceptfds)
  52.831 +	    FD_ZERO(exceptfds);
  52.832 +	timeout->tv_sec = 0;
  52.833 +	timeout->tv_usec = 0;
  52.834 +	wake(thread);
  52.835 +	ret = 0;
  52.836 +	goto out;
  52.837 +    }
  52.838 +
  52.839 +    if (timeout)
  52.840 +	thread->wakeup_time = stop;
  52.841 +    schedule();
  52.842 +
  52.843 +    myread = *readfds;
  52.844 +    mywrite = *writefds;
  52.845 +    myexcept = *exceptfds;
  52.846 +    n = select_poll(nfds, &myread, &mywrite, &myexcept);
  52.847 +
  52.848 +    if (n) {
  52.849 +	if (readfds)
  52.850 +	    *readfds = myread;
  52.851 +	if (writefds)
  52.852 +	    *writefds = mywrite;
  52.853 +	if (exceptfds)
  52.854 +	    *exceptfds = myexcept;
  52.855 +	ret = n;
  52.856 +	goto out;
  52.857 +    }
  52.858 +    errno = EINTR;
  52.859 +    ret = -1;
  52.860 +
  52.861 +out:
  52.862 +    remove_waiter(w1);
  52.863 +    remove_waiter(w2);
  52.864 +    remove_waiter(w3);
  52.865 +    remove_waiter(w4);
  52.866 +    return ret;
  52.867 +}
  52.868 +
  52.869 +int socket(int domain, int type, int protocol)
  52.870 +{
  52.871 +    int fd, res;
  52.872 +    fd = lwip_socket(domain, type, protocol);
  52.873 +    if (fd < 0)
  52.874 +	return -1;
  52.875 +    res = alloc_fd(FTYPE_SOCKET);
  52.876 +    printk("socket -> %d\n", res);
  52.877 +    files[res].socket.fd = fd;
  52.878 +    return res;
  52.879 +}
  52.880 +
  52.881 +int accept(int s, struct sockaddr *addr, socklen_t *addrlen)
  52.882 +{
  52.883 +    int fd, res;
  52.884 +    if (files[s].type != FTYPE_SOCKET) {
  52.885 +	printk("accept(%d): Bad descriptor\n", s);
  52.886 +	errno = EBADF;
  52.887 +	return -1;
  52.888 +    }
  52.889 +    fd = lwip_accept(files[s].socket.fd, addr, addrlen);
  52.890 +    if (fd < 0)
  52.891 +	return -1;
  52.892 +    res = alloc_fd(FTYPE_SOCKET);
  52.893 +    files[res].socket.fd = fd;
  52.894 +    printk("accepted on %d -> %d\n", s, res);
  52.895 +    return res;
  52.896 +}
  52.897 +
  52.898 +#define LWIP_STUB(ret, name, proto, args) \
  52.899 +ret name proto \
  52.900 +{ \
  52.901 +    if (files[s].type != FTYPE_SOCKET) { \
  52.902 +	printk(#name "(%d): Bad descriptor\n", s); \
  52.903 +	errno = EBADF; \
  52.904 +	return -1; \
  52.905 +    } \
  52.906 +    s = files[s].socket.fd; \
  52.907 +    return lwip_##name args; \
  52.908 +}
  52.909 +
  52.910 +LWIP_STUB(int, bind, (int s, struct sockaddr *my_addr, socklen_t addrlen), (s, my_addr, addrlen))
  52.911 +LWIP_STUB(int, getsockopt, (int s, int level, int optname, void *optval, socklen_t *optlen), (s, level, optname, optval, optlen))
  52.912 +LWIP_STUB(int, setsockopt, (int s, int level, int optname, void *optval, socklen_t optlen), (s, level, optname, optval, optlen))
  52.913 +LWIP_STUB(int, connect, (int s, struct sockaddr *serv_addr, socklen_t addrlen), (s, serv_addr, addrlen))
  52.914 +LWIP_STUB(int, listen, (int s, int backlog), (s, backlog));
  52.915 +LWIP_STUB(ssize_t, recv, (int s, void *buf, size_t len, int flags), (s, buf, len, flags))
  52.916 +LWIP_STUB(ssize_t, recvfrom, (int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen), (s, buf, len, flags, from, fromlen))
  52.917 +LWIP_STUB(ssize_t, send, (int s, void *buf, size_t len, int flags), (s, buf, len, flags))
  52.918 +LWIP_STUB(ssize_t, sendto, (int s, void *buf, size_t len, int flags, struct sockaddr *to, socklen_t tolen), (s, buf, len, flags, to, tolen))
  52.919 +LWIP_STUB(int, getsockname, (int s, struct sockaddr *name, socklen_t *namelen), (s, name, namelen))
  52.920 +
  52.921 +int nanosleep(const struct timespec *req, struct timespec *rem)
  52.922 +{
  52.923 +    s_time_t start = NOW();
  52.924 +    s_time_t stop = start + SECONDS(req->tv_sec) + req->tv_nsec;
  52.925 +    s_time_t stopped;
  52.926 +    struct thread *thread = get_current();
  52.927 +
  52.928 +    thread->wakeup_time = stop;
  52.929 +    clear_runnable(thread);
  52.930 +    schedule();
  52.931 +    stopped = NOW();
  52.932 +
  52.933 +    if (rem)
  52.934 +    {
  52.935 +	s_time_t remaining = stop - stopped;
  52.936 +	if (remaining > 0)
  52.937 +	{
  52.938 +	    rem->tv_nsec = remaining % 1000000000ULL;
  52.939 +	    rem->tv_sec  = remaining / 1000000000ULL;
  52.940 +	} else memset(rem, 0, sizeof(*rem));
  52.941 +    }
  52.942 +
  52.943 +    return 0;
  52.944 +}
  52.945 +
  52.946 +int usleep(useconds_t usec)
  52.947 +{
  52.948 +    /* "usec shall be less than one million."  */
  52.949 +    struct timespec req;
  52.950 +    req.tv_nsec = usec * 1000;
  52.951 +    req.tv_sec = 0;
  52.952 +
  52.953 +    if (nanosleep(&req, NULL))
  52.954 +	return -1;
  52.955 +
  52.956 +    return 0;
  52.957 +}
  52.958 +
  52.959 +unsigned int sleep(unsigned int seconds)
  52.960 +{
  52.961 +    struct timespec req, rem;
  52.962 +    req.tv_sec = seconds;
  52.963 +    req.tv_nsec = 0;
  52.964 +
  52.965 +    if (nanosleep(&req, &rem))
  52.966 +	return -1;
  52.967 +
  52.968 +    if (rem.tv_nsec > 0)
  52.969 +	rem.tv_sec++;
  52.970 +
  52.971 +    return rem.tv_sec;
  52.972 +}
  52.973 +
  52.974 +int clock_gettime(clockid_t clk_id, struct timespec *tp)
  52.975 +{
  52.976 +    switch (clk_id) {
  52.977 +	case CLOCK_MONOTONIC:
  52.978 +	{
  52.979 +	    struct timeval tv;
  52.980 +
  52.981 +	    gettimeofday(&tv, NULL);
  52.982 +
  52.983 +	    tp->tv_sec = tv.tv_sec;
  52.984 +	    tp->tv_nsec = tv.tv_usec * 1000;
  52.985 +
  52.986 +	    break;
  52.987 +	}
  52.988 +	case CLOCK_REALTIME:
  52.989 +	{
  52.990 +	    u64 nsec = monotonic_clock();
  52.991 +
  52.992 +	    tp->tv_sec = nsec / 1000000000ULL;
  52.993 +	    tp->tv_nsec = nsec % 1000000000ULL;
  52.994 +
  52.995 +	    break;
  52.996 +	}
  52.997 +	default:
  52.998 +	    print_unsupported("clock_gettime(%d)", clk_id);
  52.999 +	    errno = EINVAL;
 52.1000 +	    return -1;
 52.1001 +    }
 52.1002 +
 52.1003 +    return 0;
 52.1004 +}
 52.1005 +
 52.1006 +void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
 52.1007 +{
 52.1008 +    ASSERT(!start);
 52.1009 +    length = (length + PAGE_SIZE - 1) & PAGE_MASK;
 52.1010 +    ASSERT(prot == (PROT_READ|PROT_WRITE));
 52.1011 +    ASSERT(flags == (MAP_SHARED|MAP_ANON) || flags == (MAP_PRIVATE|MAP_ANON));
 52.1012 +    ASSERT(fd == -1);
 52.1013 +    ASSERT(offset == 0);
 52.1014 +
 52.1015 +    return map_zero(length / PAGE_SIZE, 1);
 52.1016 +}
 52.1017 +#if defined(__x86_64__) || defined(__ia64__)
 52.1018 +__typeof__(mmap) mmap64 __attribute__((__alias__("mmap")));
 52.1019 +#endif
 52.1020 +
 52.1021 +int munmap(void *start, size_t length)
 52.1022 +{
 52.1023 +    int i, n = length / PAGE_SIZE;
 52.1024 +    multicall_entry_t call[n];
 52.1025 +    unsigned char (*data)[PAGE_SIZE] = start;
 52.1026 +    int ret;
 52.1027 +    ASSERT(!((unsigned long)start & ~PAGE_MASK));
 52.1028 +    ASSERT(!(length & ~PAGE_MASK));
 52.1029 +
 52.1030 +    for (i = 0; i < n; i++) {
 52.1031 +	call[i].op = __HYPERVISOR_update_va_mapping;
 52.1032 +	call[i].args[0] = (unsigned long) &data[i];
 52.1033 +	call[i].args[1] = 0;
 52.1034 +	call[i].args[2] = 0;
 52.1035 +	call[i].args[3] = UVMF_INVLPG | UVMF_ALL;
 52.1036 +    }
 52.1037 +
 52.1038 +    ret = HYPERVISOR_multicall(call, n);
 52.1039 +    if (ret) {
 52.1040 +	errno = -ret;
 52.1041 +	return -1;
 52.1042 +    }
 52.1043 +
 52.1044 +    for (i = 0; i < n; i++) {
 52.1045 +	if (call[i].result) {
 52.1046 +	    errno = call[i].result;
 52.1047 +	    return -1;
 52.1048 +	}
 52.1049 +    }
 52.1050 +    return 0;
 52.1051 +}
 52.1052 +
 52.1053 +/* Not supported by FS yet.  */
 52.1054 +unsupported_function_crash(link);
 52.1055 +unsupported_function(int, readlink, -1);
 52.1056 +
 52.1057 +/* We could support that.  */
 52.1058 +unsupported_function_log(int, chdir, -1);
 52.1059 +
 52.1060 +/* No dynamic library support.  */ 
 52.1061 +unsupported_function_log(void *, dlopen, NULL);
 52.1062 +unsupported_function_log(void *, dlsym, NULL);
 52.1063 +unsupported_function_log(char *, dlerror, NULL);
 52.1064 +unsupported_function_log(int, dlclose, -1);
 52.1065 +
 52.1066 +/* We don't raise signals anyway.  */
 52.1067 +unsupported_function(int, sigemptyset, -1);
 52.1068 +unsupported_function(int, sigfillset, -1);
 52.1069 +unsupported_function(int, sigaddset, -1);
 52.1070 +unsupported_function(int, sigdelset, -1);
 52.1071 +unsupported_function(int, sigismember, -1);
 52.1072 +unsupported_function(int, sigprocmask, -1);
 52.1073 +unsupported_function(int, sigaction, -1);
 52.1074 +unsupported_function(int, __sigsetjmp, 0);
 52.1075 +unsupported_function(int, sigaltstack, -1);
 52.1076 +unsupported_function_crash(kill);
 52.1077 +
 52.1078 +/* Linuxish abi for the Caml runtime, don't support */
 52.1079 +unsupported_function_log(struct dirent *, readdir64, NULL);
 52.1080 +unsupported_function_log(int, getrusage, -1);
 52.1081 +unsupported_function_log(int, getrlimit, -1);
 52.1082 +unsupported_function_log(int, getrlimit64, -1);
 52.1083 +unsupported_function_log(int, __xstat64, -1);
 52.1084 +unsupported_function_log(long, __strtol_internal, LONG_MIN);
 52.1085 +unsupported_function_log(double, __strtod_internal, HUGE_VAL);
 52.1086 +#endif
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/extras/mini-os/lib/xs.c	Tue Feb 12 14:35:39 2008 +0000
    53.3 @@ -0,0 +1,187 @@
    53.4 +/*
    53.5 + * libxs-compatible layer
    53.6 + *
    53.7 + * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, 2007-2008
    53.8 + *
    53.9 + * Mere wrapper around xenbus_*
   53.10 + */
   53.11 +
   53.12 +#ifdef HAVE_LIBC
   53.13 +#include <os.h>
   53.14 +#include <lib.h>
   53.15 +#include <xs.h>
   53.16 +#include <xenbus.h>
   53.17 +#include <stdlib.h>
   53.18 +#include <unistd.h>
   53.19 +
   53.20 +static inline int _xs_fileno(struct xs_handle *h) {
   53.21 +    return (intptr_t) h;
   53.22 +}
   53.23 +
   53.24 +struct xs_handle *xs_daemon_open()
   53.25 +{
   53.26 +    int fd = alloc_fd(FTYPE_XENBUS);
   53.27 +    files[fd].xenbus.events = NULL;
   53.28 +    printk("xs_daemon_open -> %d, %p\n", fd, &files[fd].xenbus.events);
   53.29 +    return (void*)(intptr_t) fd;
   53.30 +}
   53.31 +
   53.32 +void xs_daemon_close(struct xs_handle *h)
   53.33 +{
   53.34 +    int fd = _xs_fileno(h);
   53.35 +    struct xenbus_event *event;
   53.36 +    for (event = files[fd].xenbus.events; event; event = event->next)
   53.37 +        free(event);
   53.38 +    files[fd].type = FTYPE_NONE;
   53.39 +}
   53.40 +
   53.41 +int xs_fileno(struct xs_handle *h)
   53.42 +{
   53.43 +    return _xs_fileno(h);
   53.44 +}
   53.45 +
   53.46 +void *xs_read(struct xs_handle *h, xs_transaction_t t,
   53.47 +	     const char *path, unsigned int *len)
   53.48 +{
   53.49 +    char *value;
   53.50 +    char *msg;
   53.51 +
   53.52 +    msg = xenbus_read(t, path, &value);
   53.53 +    if (msg) {
   53.54 +	printk("xs_read(%s): %s\n", path, msg);
   53.55 +	return NULL;
   53.56 +    }
   53.57 +
   53.58 +    if (len)
   53.59 +	*len = strlen(value);
   53.60 +    return value;
   53.61 +}
   53.62 +
   53.63 +bool xs_write(struct xs_handle *h, xs_transaction_t t,
   53.64 +	      const char *path, const void *data, unsigned int len)
   53.65 +{
   53.66 +    char value[len + 1];
   53.67 +    char *msg;
   53.68 +
   53.69 +    memcpy(value, data, len);
   53.70 +    value[len] = 0;
   53.71 +
   53.72 +    msg = xenbus_write(t, path, value);
   53.73 +    if (msg) {
   53.74 +	printk("xs_write(%s): %s\n", path, msg);
   53.75 +	return false;
   53.76 +    }
   53.77 +    return true;
   53.78 +}
   53.79 +
   53.80 +static bool xs_bool(char *reply)
   53.81 +{
   53.82 +    if (!reply)
   53.83 +	return true;
   53.84 +    free(reply);
   53.85 +    return false;
   53.86 +}
   53.87 +
   53.88 +bool xs_rm(struct xs_handle *h, xs_transaction_t t, const char *path)
   53.89 +{
   53.90 +    return xs_bool(xenbus_rm(t, path));
   53.91 +}
   53.92 +
   53.93 +static void *xs_talkv(struct xs_handle *h, xs_transaction_t t,
   53.94 +		enum xsd_sockmsg_type type,
   53.95 +		struct write_req *iovec,
   53.96 +		unsigned int num_vecs,
   53.97 +		unsigned int *len)
   53.98 +{
   53.99 +    struct xsd_sockmsg *msg;
  53.100 +    void *ret;
  53.101 +
  53.102 +    msg = xenbus_msg_reply(type, t, iovec, num_vecs);
  53.103 +    ret = malloc(msg->len);
  53.104 +    memcpy(ret, (char*) msg + sizeof(*msg), msg->len);
  53.105 +    if (len)
  53.106 +	*len = msg->len - 1;
  53.107 +    free(msg);
  53.108 +    return ret;
  53.109 +}
  53.110 +
  53.111 +static void *xs_single(struct xs_handle *h, xs_transaction_t t,
  53.112 +		enum xsd_sockmsg_type type,
  53.113 +		const char *string,
  53.114 +		unsigned int *len)
  53.115 +{
  53.116 +    struct write_req iovec;
  53.117 +
  53.118 +    iovec.data = (void *)string;
  53.119 +    iovec.len = strlen(string) + 1;
  53.120 +
  53.121 +    return xs_talkv(h, t, type, &iovec, 1, len);
  53.122 +}
  53.123 +
  53.124 +char *xs_get_domain_path(struct xs_handle *h, unsigned int domid)
  53.125 +{
  53.126 +    char domid_str[MAX_STRLEN(domid)];
  53.127 +
  53.128 +    sprintf(domid_str, "%u", domid);
  53.129 +
  53.130 +    return xs_single(h, XBT_NULL, XS_GET_DOMAIN_PATH, domid_str, NULL);
  53.131 +}
  53.132 +
  53.133 +char **xs_directory(struct xs_handle *h, xs_transaction_t t,
  53.134 +		    const char *path, unsigned int *num)
  53.135 +{
  53.136 +    char *msg;
  53.137 +    char **entries, **res;
  53.138 +    char *entry;
  53.139 +    int i, n;
  53.140 +    int size;
  53.141 +
  53.142 +    msg = xenbus_ls(t, path, &res);
  53.143 +    if (msg) {
  53.144 +	printk("xs_directory(%s): %s\n", path, msg);
  53.145 +	return NULL;
  53.146 +    }
  53.147 +
  53.148 +    size = 0;
  53.149 +    for (n = 0; res[n]; n++)
  53.150 +	size += strlen(res[n]) + 1;
  53.151 +
  53.152 +    entries = malloc(n * sizeof(char *) + size);
  53.153 +    entry = (char *) (&entries[n]);
  53.154 +
  53.155 +    for (i = 0; i < n; i++) {
  53.156 +	int l = strlen(res[i]) + 1;
  53.157 +	memcpy(entry, res[i], l);
  53.158 +	free(res[i]);
  53.159 +	entries[i] = entry;
  53.160 +	entry += l;
  53.161 +    }
  53.162 +
  53.163 +    *num = n;
  53.164 +    return entries;
  53.165 +}
  53.166 +
  53.167 +bool xs_watch(struct xs_handle *h, const char *path, const char *token)
  53.168 +{
  53.169 +    int fd = _xs_fileno(h);
  53.170 +    printk("xs_watch(%s, %s)\n", path, token);
  53.171 +    return xs_bool(xenbus_watch_path_token(XBT_NULL, path, token, &files[fd].xenbus.events));
  53.172 +}
  53.173 +
  53.174 +char **xs_read_watch(struct xs_handle *h, unsigned int *num)
  53.175 +{
  53.176 +    int fd = _xs_fileno(h);
  53.177 +    struct xenbus_event *event;
  53.178 +    event = files[fd].xenbus.events;
  53.179 +    files[fd].xenbus.events = event->next;
  53.180 +    printk("xs_read_watch() -> %s %s\n", event->path, event->token);
  53.181 +    *num = 2;
  53.182 +    return (char **) &event->path;
  53.183 +}
  53.184 +
  53.185 +bool xs_unwatch(struct xs_handle *h, const char *path, const char *token)
  53.186 +{
  53.187 +    printk("xs_unwatch(%s, %s)\n", path, token);
  53.188 +    return xs_bool(xenbus_unwatch_path_token(XBT_NULL, path, token));
  53.189 +}
  53.190 +#endif
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/extras/mini-os/main-caml.c	Tue Feb 12 14:35:39 2008 +0000
    54.3 @@ -0,0 +1,42 @@
    54.4 +/*
    54.5 + * Caml bootstrap
    54.6 + *
    54.7 + * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, January 2008
    54.8 + */
    54.9 +
   54.10 +#include <stdio.h>
   54.11 +#include <errno.h>
   54.12 +
   54.13 +#include <caml/mlvalues.h>
   54.14 +#include <caml/callback.h>
   54.15 +#include <unistd.h>
   54.16 +
   54.17 +/* Ugly binary compatibility with Linux */
   54.18 +FILE *_stderr asm("stderr");
   54.19 +int *__errno_location;
   54.20 +/* Will probably break everything, probably need to fetch from glibc */
   54.21 +void *__ctype_b_loc;
   54.22 +
   54.23 +int main(int argc, char *argv[], char *envp[])
   54.24 +{
   54.25 +    value *val;
   54.26 +
   54.27 +    /* Get current thread's value */
   54.28 +    _stderr = stderr;
   54.29 +    __errno_location = &errno;
   54.30 +
   54.31 +    printf("starting caml\n");
   54.32 +
   54.33 +    /* Wait before things might hang up */
   54.34 +    sleep(1);
   54.35 +
   54.36 +    caml_startup(argv);
   54.37 +    val = caml_named_value("main");
   54.38 +    if (!val) {
   54.39 +        printf("Couldn't find Caml main");
   54.40 +        return 1;
   54.41 +    }
   54.42 +    caml_callback(*val, Val_int(0));
   54.43 +    printf("callback returned\n");
   54.44 +    return 0;
   54.45 +}
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/extras/mini-os/main.c	Tue Feb 12 14:35:39 2008 +0000
    55.3 @@ -0,0 +1,167 @@
    55.4 +/*
    55.5 + * POSIX-compatible main layer
    55.6 + *
    55.7 + * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, October 2007
    55.8 + */
    55.9 +
   55.10 +#ifdef HAVE_LIBC
   55.11 +#include <os.h>
   55.12 +#include <sched.h>
   55.13 +#include <console.h>
   55.14 +#include <netfront.h>
   55.15 +#include <time.h>
   55.16 +#include <stdlib.h>
   55.17 +#include <unistd.h>
   55.18 +#include <fs.h>
   55.19 +#include <xenbus.h>
   55.20 +#include <events.h>
   55.21 +
   55.22 +extern int main(int argc, char *argv[], char *envp[]);
   55.23 +extern void __libc_init_array(void);
   55.24 +extern void __libc_fini_array(void);
   55.25 +
   55.26 +struct thread *main_thread;
   55.27 +
   55.28 +#if 0
   55.29 +#include <stdio.h>
   55.30 +int main(int argc, char *argv[], char *envp[])
   55.31 +{
   55.32 +    printf("Hello, World!\n");
   55.33 +    return 1;
   55.34 +}
   55.35 +#endif
   55.36 +
   55.37 +void _init(void)
   55.38 +{
   55.39 +}
   55.40 +
   55.41 +void _fini(void)
   55.42 +{
   55.43 +}
   55.44 +
   55.45 +static void call_main(void *p)
   55.46 +{
   55.47 +    char *args, /**path,*/ *msg, *c;
   55.48 +    int argc;
   55.49 +    char **argv;
   55.50 +    char *envp[] = { NULL };
   55.51 +    char *vm;
   55.52 +    int i;
   55.53 +    char path[128];
   55.54 +
   55.55 +    /* Let other parts initialize (including console output) before maybe
   55.56 +     * crashing. */
   55.57 +    //sleep(1);
   55.58 +
   55.59 +    start_networking();
   55.60 +    init_fs_frontend();
   55.61 +
   55.62 +#ifdef CONFIG_QEMU
   55.63 +    if (!fs_import) {
   55.64 +        printk("No FS backend found, is it running?\n");
   55.65 +        do_exit();
   55.66 +    }
   55.67 +
   55.68 +    /* Fetch argc, argv from XenStore */
   55.69 +    char domid_s[10];
   55.70 +    int domid;
   55.71 +    domid = xenbus_read_integer("target");
   55.72 +    if (domid == -1) {
   55.73 +        printk("Couldn't read target\n");
   55.74 +        do_exit();
   55.75 +    }
   55.76 +    snprintf(domid_s, sizeof(domid_s), "%d", domid);
   55.77 +
   55.78 +    snprintf(path, sizeof(path), "/local/domain/%d/vm", domid);
   55.79 +    msg = xenbus_read(XBT_NIL, path, &vm);
   55.80 +    if (msg) {
   55.81 +        printk("Couldn't read vm path\n");
   55.82 +        do_exit();
   55.83 +    }
   55.84 +    printk("vm is at %s\n", vm);
   55.85 +#else
   55.86 +    msg = xenbus_read(XBT_NIL, "vm", &vm);
   55.87 +    if (msg) {
   55.88 +        printk("Couldn't read vm path\n");
   55.89 +        do_exit();
   55.90 +    }
   55.91 +#endif
   55.92 +
   55.93 +    snprintf(path, sizeof(path), "%s/image/dmargs", vm);
   55.94 +    free(vm);
   55.95 +    msg = xenbus_read(XBT_NIL, path, &args);
   55.96 +
   55.97 +    if (msg) {
   55.98 +        printk("Couldn't get stubdom args: %s\n", msg);
   55.99 +        args = strdup("");
  55.100 +    }
  55.101 +
  55.102 +    argc = 1;
  55.103 +#ifdef CONFIG_QEMU
  55.104 +    argc += 2;
  55.105 +#endif
  55.106 +    c = args;
  55.107 +    while (*c) {
  55.108 +	if (*c != ' ') {
  55.109 +	    argc++;
  55.110 +	    while (*c && *c != ' ')
  55.111 +		c++;
  55.112 +	} else {
  55.113 +	    while (*c == ' ')
  55.114 +		c++;
  55.115 +	}
  55.116 +    }
  55.117 +    argv = alloca((argc + 1) * sizeof(char *));
  55.118 +    argv[0] = "main";
  55.119 +    argc = 1;
  55.120 +#ifdef CONFIG_QEMU
  55.121 +    argv[1] = "-d";
  55.122 +    argv[2] = domid_s;
  55.123 +    argc += 2;
  55.124 +#endif
  55.125 +    c = args;
  55.126 +    while (*c) {
  55.127 +	if (*c != ' ') {
  55.128 +	    argv[argc++] = c;
  55.129 +	    while (*c && *c != ' ')
  55.130 +		c++;
  55.131 +	} else {
  55.132 +	    *c++ = 0;
  55.133 +	    while (*c == ' ')
  55.134 +		c++;
  55.135 +	}
  55.136 +    }
  55.137 +    argv[argc] = NULL;
  55.138 +
  55.139 +    for (i = 0; i < argc; i++)
  55.140 +	printf("\"%s\" ", argv[i]);
  55.141 +    printf("\n");
  55.142 +
  55.143 +    __libc_init_array();
  55.144 +    environ = envp;
  55.145 +    tzset();
  55.146 +
  55.147 +    exit(main(argc, argv, envp));
  55.148 +}
  55.149 +
  55.150 +void _exit(int ret)
  55.151 +{
  55.152 +    close_all_files();
  55.153 +    __libc_fini_array();
  55.154 +    printk("main returned %d\n", ret);
  55.155 +    unbind_all_ports();
  55.156 +    if (!ret) {
  55.157 +	/* No problem, just shutdown.  */
  55.158 +        struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff };
  55.159 +        HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
  55.160 +    }
  55.161 +    do_exit();
  55.162 +}
  55.163 +
  55.164 +int app_main(start_info_t *si)
  55.165 +{
  55.166 +    printk("Dummy main: start_info=%p\n", si);
  55.167 +    main_thread = create_thread("main", call_main, si);
  55.168 +    return 0;
  55.169 +}
  55.170 +#endif
    56.1 --- a/extras/mini-os/minios.mk	Tue Feb 12 11:37:45 2008 +0000
    56.2 +++ b/extras/mini-os/minios.mk	Tue Feb 12 14:35:39 2008 +0000
    56.3 @@ -9,7 +9,7 @@ debug = y
    56.4  DEF_CFLAGS += -fno-builtin -Wall -Werror -Wredundant-decls -Wno-format
    56.5  DEF_CFLAGS += $(call cc-option,$(CC),-fno-stack-protector,)
    56.6  DEF_CFLAGS += -Wstrict-prototypes -Wnested-externs -Wpointer-arith -Winline
    56.7 -DEF_CFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION)
    56.8 +DEF_CPPFLAGS += -D__XEN_INTERFACE_VERSION__=$(XEN_INTERFACE_VERSION)
    56.9  
   56.10  DEF_ASFLAGS = -D__ASSEMBLY__
   56.11  DEF_LDFLAGS =
   56.12 @@ -24,12 +24,10 @@ endif
   56.13  # DEF_... flags are the common mini-os flags,
   56.14  # ARCH_... flags may be defined in arch/$(TARGET_ARCH_FAM/rules.mk
   56.15  CFLAGS := $(DEF_CFLAGS) $(ARCH_CFLAGS)
   56.16 +CPPFLAGS := $(DEF_CPPFLAGS) $(ARCH_CPPFLAGS)
   56.17  ASFLAGS := $(DEF_ASFLAGS) $(ARCH_ASFLAGS)
   56.18  LDFLAGS := $(DEF_LDFLAGS) $(ARCH_LDFLAGS)
   56.19  
   56.20 -# The path pointing to the architecture specific header files.
   56.21 -ARCH_INC := $(MINI-OS_ROOT)/include/$(TARGET_ARCH_FAM)
   56.22 -
   56.23  # Special build dependencies.
   56.24  # Rebuild all after touching this/these file(s)
   56.25  EXTRA_DEPS = $(MINI-OS_ROOT)/minios.mk \
   56.26 @@ -44,18 +42,17 @@ extra_heads := $(foreach dir,$(EXTRA_INC
   56.27  HDRS += $(extra_heads)
   56.28  
   56.29  # Add the special header directories to the include paths.
   56.30 -extra_incl := $(foreach dir,$(EXTRA_INC),-I$(MINI-OS_ROOT)/include/$(dir))
   56.31 -override CPPFLAGS := -I$(MINI-OS_ROOT)/include $(CPPFLAGS) -I$(ARCH_INC)	$(extra_incl)
   56.32 +override CPPFLAGS := $(CPPFLAGS) $(extra_incl)
   56.33  
   56.34  # The name of the architecture specific library.
   56.35  # This is on x86_32: libx86_32.a
   56.36  # $(ARCH_LIB) has to built in the architecture specific directory.
   56.37 -ARCH_LIB_NAME = $(TARGET_ARCH)
   56.38 +ARCH_LIB_NAME = $(XEN_TARGET_ARCH)
   56.39  ARCH_LIB := lib$(ARCH_LIB_NAME).a
   56.40  
   56.41  # This object contains the entrypoint for startup from Xen.
   56.42  # $(HEAD_ARCH_OBJ) has to be built in the architecture specific directory.
   56.43 -HEAD_ARCH_OBJ := $(TARGET_ARCH).o
   56.44 +HEAD_ARCH_OBJ := $(XEN_TARGET_ARCH).o
   56.45  HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ)
   56.46  
   56.47  
    57.1 --- a/extras/mini-os/mm.c	Tue Feb 12 11:37:45 2008 +0000
    57.2 +++ b/extras/mini-os/mm.c	Tue Feb 12 14:35:39 2008 +0000
    57.3 @@ -360,6 +360,29 @@ void free_pages(void *pointer, int order
    57.4     
    57.5  }
    57.6  
    57.7 +#ifdef HAVE_LIBC
    57.8 +void *sbrk(ptrdiff_t increment)
    57.9 +{
   57.10 +    unsigned long old_brk = brk;
   57.11 +    unsigned long new_brk = old_brk + increment;
   57.12 +
   57.13 +    if (new_brk > heap_end) {
   57.14 +	printk("Heap exhausted: %p + %lx = %p > %p\n", old_brk, increment, new_brk, heap_end);
   57.15 +	return NULL;
   57.16 +    }
   57.17 +    
   57.18 +    if (new_brk > heap_mapped) {
   57.19 +        unsigned long n = (new_brk - heap_mapped + PAGE_SIZE - 1) / PAGE_SIZE;
   57.20 +        do_map_zero(heap_mapped, n);
   57.21 +        heap_mapped += n * PAGE_SIZE;
   57.22 +    }
   57.23 +
   57.24 +    brk = new_brk;
   57.25 +
   57.26 +    return (void *) old_brk;
   57.27 +}
   57.28 +#endif
   57.29 +
   57.30  
   57.31  
   57.32  void init_mm(void)
    58.1 --- a/extras/mini-os/netfront.c	Tue Feb 12 11:37:45 2008 +0000
    58.2 +++ b/extras/mini-os/netfront.c	Tue Feb 12 14:35:39 2008 +0000
    58.3 @@ -19,7 +19,10 @@
    58.4  
    58.5  DECLARE_WAIT_QUEUE_HEAD(netfront_queue);
    58.6  
    58.7 +#ifdef HAVE_LIBC
    58.8  #define NETIF_SELECT_RX ((void*)-1)
    58.9 +#endif
   58.10 +
   58.11  
   58.12  
   58.13  #define NET_TX_RING_SIZE __RING_SIZE((struct netif_tx_sring *)0, PAGE_SIZE)
   58.14 @@ -50,6 +53,13 @@ struct netfront_dev {
   58.15      char *nodename;
   58.16      char *backend;
   58.17  
   58.18 +#ifdef HAVE_LIBC
   58.19 +    int fd;
   58.20 +    unsigned char *data;
   58.21 +    size_t len;
   58.22 +    size_t rlen;
   58.23 +#endif
   58.24 +
   58.25      void (*netif_rx)(unsigned char* data, int len);
   58.26  };
   58.27  
   58.28 @@ -92,7 +102,8 @@ moretodo:
   58.29      cons = dev->rx.rsp_cons;
   58.30  
   58.31      int nr_consumed=0;
   58.32 -    while ((cons != rp))
   58.33 +    int some = 0;
   58.34 +    while ((cons != rp) && !some)
   58.35      {
   58.36          struct net_buffer* buf;
   58.37          unsigned char* page;
   58.38 @@ -116,7 +127,18 @@ moretodo:
   58.39  
   58.40          if(rx->status>0)
   58.41          {
   58.42 -            dev->netif_rx(page+rx->offset,rx->status);
   58.43 +#ifdef HAVE_LIBC
   58.44 +	    if (dev->netif_rx == NETIF_SELECT_RX) {
   58.45 +		int len = rx->status;
   58.46 +		ASSERT(current == main_thread);
   58.47 +		if (len > dev->len)
   58.48 +		    len = dev->len;
   58.49 +		memcpy(dev->data, page+rx->offset, len);
   58.50 +		dev->rlen = len;
   58.51 +		some = 1;
   58.52 +	    } else
   58.53 +#endif
   58.54 +		dev->netif_rx(page+rx->offset,rx->status);
   58.55          }
   58.56  
   58.57          nr_consumed++;
   58.58 @@ -127,7 +149,7 @@ moretodo:
   58.59  
   58.60      int more;
   58.61      RING_FINAL_CHECK_FOR_RESPONSES(&dev->rx,more);
   58.62 -    if(more) goto moretodo;
   58.63 +    if(more && !some) goto moretodo;
   58.64  
   58.65      RING_IDX req_prod = dev->rx.req_prod_pvt;
   58.66  
   58.67 @@ -178,6 +200,9 @@ void network_tx_buf_gc(struct netfront_d
   58.68              if (txrsp->status == NETIF_RSP_NULL)
   58.69                  continue;
   58.70  
   58.71 +            if (txrsp->status == NETIF_RSP_ERROR)
   58.72 +                printk("packet error\n");
   58.73 +
   58.74              id  = txrsp->id;
   58.75              struct net_buffer* buf = &dev->tx_buffers[id];
   58.76              gnttab_end_access(buf->gref);
   58.77 @@ -218,6 +243,22 @@ void netfront_handler(evtchn_port_t port
   58.78      local_irq_restore(flags);
   58.79  }
   58.80  
   58.81 +#ifdef HAVE_LIBC
   58.82 +void netfront_select_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
   58.83 +{
   58.84 +    int flags;
   58.85 +    struct netfront_dev *dev = data;
   58.86 +    int fd = dev->fd;
   58.87 +
   58.88 +    local_irq_save(flags);
   58.89 +    network_tx_buf_gc(dev);
   58.90 +    local_irq_restore(flags);
   58.91 +
   58.92 +    files[fd].read = 1;
   58.93 +    wake_up(&netfront_queue);
   58.94 +}
   58.95 +#endif
   58.96 +
   58.97  struct netfront_dev *init_netfront(char *nodename, void (*thenetif_rx)(unsigned char* data, int len), unsigned char rawmac[6])
   58.98  {
   58.99      xenbus_transaction_t xbt;
  58.100 @@ -266,7 +307,12 @@ struct netfront_dev *init_netfront(char 
  58.101      dev->dom = op.remote_dom = xenbus_read_integer(path);
  58.102      HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound, &op);
  58.103      clear_evtchn(op.port);        /* Without, handler gets invoked now! */
  58.104 -    dev->local_port = bind_evtchn(op.port, netfront_handler, dev);
  58.105 +#ifdef HAVE_LIBC
  58.106 +    if (thenetif_rx == NETIF_SELECT_RX)
  58.107 +	dev->local_port = bind_evtchn(op.port, netfront_select_handler, dev);
  58.108 +    else
  58.109 +#endif
  58.110 +	dev->local_port = bind_evtchn(op.port, netfront_handler, dev);
  58.111      dev->evtchn=op.port;
  58.112  
  58.113      txs = (struct netif_tx_sring*) alloc_page();
  58.114 @@ -381,6 +427,23 @@ done:
  58.115      return dev;
  58.116  }
  58.117  
  58.118 +#ifdef HAVE_LIBC
  58.119 +int netfront_tap_open(char *nodename) {
  58.120 +    struct netfront_dev *dev;
  58.121 +
  58.122 +    dev = init_netfront(nodename, NETIF_SELECT_RX, NULL);
  58.123 +    if (!dev) {
  58.124 +	printk("TAP open failed\n");
  58.125 +	errno = EIO;
  58.126 +	return -1;
  58.127 +    }
  58.128 +    dev->fd = alloc_fd(FTYPE_TAP);
  58.129 +    printk("tap_open(%s) -> %d\n", nodename, dev->fd);
  58.130 +    files[dev->fd].tap.dev = dev;
  58.131 +    return dev->fd;
  58.132 +}
  58.133 +#endif
  58.134 +
  58.135  void shutdown_netfront(struct netfront_dev *dev)
  58.136  {
  58.137      char* err;
  58.138 @@ -481,3 +544,30 @@ void netfront_xmit(struct netfront_dev *
  58.139      network_tx_buf_gc(dev);
  58.140      local_irq_restore(flags);
  58.141  }
  58.142 +
  58.143 +#ifdef HAVE_LIBC
  58.144 +ssize_t netfront_receive(struct netfront_dev *dev, unsigned char *data, size_t len)
  58.145 +{
  58.146 +    unsigned long flags;
  58.147 +    int fd = dev->fd;
  58.148 +    ASSERT(current == main_thread);
  58.149 +
  58.150 +    dev->rlen = 0;
  58.151 +    dev->data = data;
  58.152 +    dev->len = len;
  58.153 +
  58.154 +    local_irq_save(flags);
  58.155 +    network_rx(dev);
  58.156 +    if (!dev->rlen)
  58.157 +	/* No data for us, make select stop returning */
  58.158 +	files[fd].read = 0;
  58.159 +    /* Before re-enabling the interrupts, in case a packet just arrived in the
  58.160 +     * meanwhile. */
  58.161 +    local_irq_restore(flags);
  58.162 +
  58.163 +    dev->data = NULL;
  58.164 +    dev->len = 0;
  58.165 +
  58.166 +    return dev->rlen;
  58.167 +}
  58.168 +#endif
    59.1 --- a/extras/mini-os/sched.c	Tue Feb 12 11:37:45 2008 +0000
    59.2 +++ b/extras/mini-os/sched.c	Tue Feb 12 14:35:39 2008 +0000
    59.3 @@ -56,6 +56,7 @@
    59.4  
    59.5  struct thread *idle_thread = NULL;
    59.6  LIST_HEAD(exited_threads);
    59.7 +static int threads_started;
    59.8  
    59.9  void inline print_runqueue(void)
   59.10  {
   59.11 @@ -172,6 +173,9 @@ struct thread* create_thread(char *name,
   59.12      /* Not runable, not exited, not sleeping */
   59.13      thread->flags = 0;
   59.14      thread->wakeup_time = 0LL;
   59.15 +#ifdef HAVE_LIBC
   59.16 +    _REENT_INIT_PTR((&thread->reent))
   59.17 +#endif
   59.18      set_runnable(thread);
   59.19      local_irq_save(flags);
   59.20      if(idle_thread != NULL) {
   59.21 @@ -185,6 +189,42 @@ struct thread* create_thread(char *name,
   59.22      return thread;
   59.23  }
   59.24  
   59.25 +#ifdef HAVE_LIBC
   59.26 +static struct _reent callback_reent;
   59.27 +struct _reent *__getreent(void)
   59.28 +{
   59.29 +    struct _reent *_reent;
   59.30 +
   59.31 +    if (!threads_started)
   59.32 +	_reent = _impure_ptr;
   59.33 +    else if (in_callback)
   59.34 +	_reent = &callback_reent;
   59.35 +    else
   59.36 +	_reent = &get_current()->reent;
   59.37 +
   59.38 +#ifndef NDEBUG
   59.39 +#if defined(__x86_64__) || defined(__x86__)
   59.40 +    {
   59.41 +#ifdef __x86_64__
   59.42 +	register unsigned long sp asm ("rsp");
   59.43 +#else
   59.44 +	register unsigned long sp asm ("esp");
   59.45 +#endif
   59.46 +	if ((sp & (STACK_SIZE-1)) < STACK_SIZE / 16) {
   59.47 +	    static int overflowing;
   59.48 +	    if (!overflowing) {
   59.49 +		overflowing = 1;
   59.50 +		printk("stack overflow\n");
   59.51 +		BUG();
   59.52 +	    }
   59.53 +	}
   59.54 +    }
   59.55 +#endif
   59.56 +#endif
   59.57 +    return _reent;
   59.58 +}
   59.59 +#endif
   59.60 +
   59.61  void exit_thread(void)
   59.62  {
   59.63      unsigned long flags;
   59.64 @@ -228,6 +268,7 @@ void wake(struct thread *thread)
   59.65  void idle_thread_fn(void *unused)
   59.66  {
   59.67      s_time_t until;
   59.68 +    threads_started = 1;
   59.69      unsigned long flags;
   59.70      struct list_head *iterator;
   59.71      struct thread *next, *thread;
   59.72 @@ -297,6 +338,9 @@ void init_sched(void)
   59.73  {
   59.74      printk("Initialising scheduler\n");
   59.75  
   59.76 +#ifdef HAVE_LIBC
   59.77 +    _REENT_INIT_PTR((&callback_reent))
   59.78 +#endif
   59.79      idle_thread = create_thread("Idle", idle_thread_fn, NULL);
   59.80      INIT_LIST_HEAD(&idle_thread->thread_list);
   59.81  }
    60.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.2 +++ b/stubdom/Makefile	Tue Feb 12 14:35:39 2008 +0000
    60.3 @@ -0,0 +1,256 @@
    60.4 +XEN_ROOT = ..
    60.5 +
    60.6 +include $(XEN_ROOT)/Config.mk
    60.7 +export stubdom=y
    60.8 +export debug=y
    60.9 +
   60.10 +IOEMU_OPTIONS=--disable-vnc-tls 
   60.11 +BINUTILS_VERSION=2.18
   60.12 +GCC_VERSION=4.2.2
   60.13 +ZLIB_VERSION=1.2.3
   60.14 +LIBPCI_VERSION=2.2.9
   60.15 +NEWLIB_DATE=2008-01-01
   60.16 +LWIP_DATE=2008-02-08
   60.17 +
   60.18 +WGET=wget -c
   60.19 +
   60.20 +GNU_TARGET_ARCH:=$(XEN_TARGET_ARCH)
   60.21 +ifeq ($(XEN_TARGET_ARCH),x86_32)
   60.22 +GNU_TARGET_ARCH:=i686
   60.23 +endif
   60.24 +
   60.25 +ifeq ($(GNU_TARGET_ARCH), i686)
   60.26 +TARGET_CFLAGS=
   60.27 +endif
   60.28 +ifeq ($(GNU_TARGET_ARCH), x86_64)
   60.29 +TARGET_CFLAGS=-mno-red-zone
   60.30 +endif
   60.31 +ifeq ($(GNU_TARGET_ARCH), ia64)
   60.32 +TARGET_CFLAGS=-mconstant-gp
   60.33 +endif
   60.34 +
   60.35 +CROSS_ROOT=cross-root-$(GNU_TARGET_ARCH)
   60.36 +CROSS_PREFIX=$(CURDIR)/$(CROSS_ROOT)
   60.37 +export CROSS_COMPILE=$(GNU_TARGET_ARCH)-xen-elf-
   60.38 +export PATH:=$(CROSS_PREFIX)/bin:$(PATH)
   60.39 +
   60.40 +.PHONY: all
   60.41 +all: qemu-stubdom
   60.42 +
   60.43 +################
   60.44 +# Cross-binutils
   60.45 +################
   60.46 +
   60.47 +binutils-$(BINUTILS_VERSION).tar.bz2:
   60.48 +	$(WGET) http://ftp.gnu.org/gnu/binutils/$@
   60.49 +binutils-$(BINUTILS_VERSION): binutils-$(BINUTILS_VERSION).tar.bz2
   60.50 +	tar xjf $@.tar.bz2
   60.51 +	( cd binutils-$(BINUTILS_VERSION) && patch -p1 < ../binutils.patch )
   60.52 +	touch $@
   60.53 +
   60.54 +BINUTILS_STAMPFILE=$(CROSS_ROOT)/bin/$(GNU_TARGET_ARCH)-xen-elf-ar
   60.55 +.PHONY: cross-binutils
   60.56 +cross-binutils: $(BINUTILS_STAMPFILE)
   60.57 +$(BINUTILS_STAMPFILE): binutils-$(BINUTILS_VERSION)
   60.58 +	mkdir -p binutils.build
   60.59 +	( cd binutils.build && \
   60.60 +	  ../binutils-$(BINUTILS_VERSION)/configure --prefix=$(CROSS_PREFIX) --verbose --target=$(GNU_TARGET_ARCH)-xen-elf && \
   60.61 +	  $(MAKE) && \
   60.62 +	  $(MAKE) check && \
   60.63 +	  $(MAKE) install )
   60.64 +
   60.65 +###########
   60.66 +# Cross-gcc
   60.67 +###########
   60.68 +
   60.69 +gcc-$(GCC_VERSION).tar.bz2:
   60.70 +	$(WGET) http://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)/gcc-$(GCC_VERSION).tar.bz2
   60.71 +gcc-$(GCC_VERSION): gcc-$(GCC_VERSION).tar.bz2
   60.72 +	tar xjf gcc-$(GCC_VERSION).tar.bz2
   60.73 +	( cd gcc-$(GCC_VERSION) && patch -p1 < ../gcc.patch )
   60.74 +	touch $@
   60.75 +	
   60.76 +GCC_STAMPFILE=$(CROSS_ROOT)/bin/$(GNU_TARGET_ARCH)-xen-elf-gcc-$(GCC_VERSION)
   60.77 +.PHONY: cross-gcc
   60.78 +cross-gcc: $(GCC_STAMPFILE)
   60.79 +$(GCC_STAMPFILE): gcc-$(GCC_VERSION) $(BINUTILS_STAMPFILE)
   60.80 +	mkdir -p gcc.build
   60.81 +	( cd gcc.build && \
   60.82 +	  ../gcc-$(GCC_VERSION)/configure --prefix=$(CROSS_PREFIX) --verbose --target=$(GNU_TARGET_ARCH)-xen-elf --enable-languages=c --disable-libssp --with-gnu-as --with-gnu-ld && \
   60.83 +	  $(MAKE) GCC_FOR_TARGET='$$$$r/gcc/xgcc -B$$$$r/gcc/ '"$(TARGET_CFLAGS)"' $$(FLAGS_FOR_TARGET)' && \
   60.84 +	  $(MAKE) install )
   60.85 +
   60.86 +##############
   60.87 +# Cross-newlib
   60.88 +##############
   60.89 +
   60.90 +newlib:
   60.91 +	cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/src co -D $(NEWLIB_DATE) newlib
   60.92 +	mv src newlib
   60.93 +	( cd newlib && patch -p0 < ../newlib.patch)
   60.94 +
   60.95 +NEWLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libc.a
   60.96 +.PHONY: cross-newlib
   60.97 +cross-newlib: $(NEWLIB_STAMPFILE)
   60.98 +$(NEWLIB_STAMPFILE): newlib $(GCC_STAMPFILE)
   60.99 +	mkdir -p newlib.build
  60.100 +	( cd newlib.build && \
  60.101 +	  CC_FOR_TARGET="$(GNU_TARGET_ARCH)-xen-elf-gcc $(TARGET_CFLAGS)" ../newlib/configure --prefix=$(CROSS_PREFIX) --verbose --target=$(GNU_TARGET_ARCH)-xen-elf --enable-newlib-io-long-long && \
  60.102 +	  $(MAKE) && \
  60.103 +	  $(MAKE) install )
  60.104 +
  60.105 +############
  60.106 +# Cross-zlib
  60.107 +############
  60.108 +
  60.109 +zlib-$(ZLIB_VERSION).tar.gz:
  60.110 +	$(WGET) http://www.zlib.net/zlib-$(ZLIB_VERSION).tar.gz
  60.111 +
  60.112 +ZLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libz.a
  60.113 +.PHONY: cross-zlib
  60.114 +cross-zlib: $(ZLIB_STAMPFILE)
  60.115 +$(ZLIB_STAMPFILE): zlib-$(ZLIB_VERSION).tar.gz $(NEWLIB_STAMPFILE)
  60.116 +	tar xzf $<
  60.117 +	( cd zlib-$(ZLIB_VERSION) && \
  60.118 +	  CFLAGS="$(TARGET_CFLAGS)" CC=$(GNU_TARGET_ARCH)-xen-elf-gcc ./configure --prefix=$(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf && \
  60.119 +	  $(MAKE) libz.a && \
  60.120 +	  $(MAKE) install )
  60.121 +
  60.122 +##############
  60.123 +# Cross-libpci
  60.124 +##############
  60.125 +
  60.126 +pciutils-$(LIBPCI_VERSION).tar.bz2:
  60.127 +	$(WGET) http://www.kernel.org/pub/software/utils/pciutils/pciutils-$(LIBPCI_VERSION).tar.bz2
  60.128 +
  60.129 +LIBPCI_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libpci.a
  60.130 +.PHONY: cross-libpci
  60.131 +cross-libpci: $(LIBPCI_STAMPFILE)
  60.132 +$(LIBPCI_STAMPFILE): pciutils-$(LIBPCI_VERSION).tar.bz2 $(NEWLIB_STAMPFILE) $(ZLIB_STAMPFILE)
  60.133 +	tar xjf $<
  60.134 +	( cd pciutils-$(LIBPCI_VERSION) && \
  60.135 +	  cp ../libpci.config.h lib/config.h && \
  60.136 +	  echo '#define PCILIB_VERSION "$(LIBPCI_VERSION)"' >> lib/config.h && \
  60.137 +	  cp ../libpci.config.mak lib/config.mk && \
  60.138 +	  $(MAKE) CC="$(GNU_TARGET_ARCH)-xen-elf-gcc $(TARGET_CFLAGS)" lib/libpci.a && \
  60.139 +	  $(INSTALL_DATA) lib/libpci.a $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/lib/ && \
  60.140 +	  $(INSTALL_DIR) $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/include/pci && \
  60.141 +	  $(INSTALL_DATA) lib/{config,header,pci,types}.h $(CROSS_PREFIX)/$(GNU_TARGET_ARCH)-xen-elf/include/pci/ \
  60.142 +	)
  60.143 +
  60.144 +######
  60.145 +# lwIP
  60.146 +######
  60.147 +
  60.148 +lwip:
  60.149 +	cvs -z 9 -d :pserver:anonymous@cvs.savannah.nongnu.org:/sources/lwip co -D $(LWIP_DATE) lwip
  60.150 +
  60.151 +#######
  60.152 +# Links
  60.153 +#######
  60.154 +
  60.155 +.PHONY: $(CROSS_ROOT)
  60.156 +$(CROSS_ROOT): cross-newlib cross-zlib cross-libpci
  60.157 +
  60.158 +.PHONY: mk-symlinks
  60.159 +mk-symlinks:
  60.160 +	[ -h include ] || ln -sf ../tools/include .
  60.161 +	mkdir -p libxc
  60.162 +	[ -h libxc/Makefile ] || ( cd libxc && \
  60.163 +	  ln -sf ../../tools/libxc/*.h . && \
  60.164 +	  ln -sf ../../tools/libxc/*.c . && \
  60.165 +	  ln -sf ../../tools/libxc/Makefile . )
  60.166 +	mkdir -p libxc/$(XEN_TARGET_ARCH)
  60.167 +	[ -h libxc/$(XEN_TARGET_ARCH) ] || ( cd libxc/$(XEN_TARGET_ARCH) && \
  60.168 +	  ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/*.c . && \
  60.169 +	  ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/*.h . && \
  60.170 +	  ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/Makefile . )
  60.171 +	mkdir -p ioemu
  60.172 +	[ -h ioemu/Makefile ] || ( cd ioemu && \
  60.173 +	  ln -sf ../../tools/ioemu/* . && \
  60.174 +	  ([ ! -h config-host.h ] || rm -f config-host.h) && \
  60.175 +	  ([ ! -h config-host.mak ] || rm -f config-host.mak) )
  60.176 +	[ -h mini-os ] || ln -sf ../extras/mini-os .
  60.177 +
  60.178 +#######
  60.179 +# libxc
  60.180 +#######
  60.181 +
  60.182 +.PHONY: libxc
  60.183 +libxc: cross-zlib mk-symlinks
  60.184 +	$(MAKE) -C $@
  60.185 +
  60.186 +#######
  60.187 +# ioemu
  60.188 +#######
  60.189 +
  60.190 +.PHONY: ioemu
  60.191 +ioemu: cross-zlib cross-libpci mk-symlinks libxc
  60.192 +	[ -f ioemu/config-host.mak ] || \
  60.193 +	  ( cd ioemu ; XEN_TARGET_ARCH=$(XEN_TARGET_ARCH) sh configure --prefix=/usr --enable-stubdom $(IOEMU_OPTIONS))
  60.194 +	$(MAKE) -C ioemu LWIPDIR=$(CURDIR)/lwip
  60.195 +
  60.196 +######
  60.197 +# caml
  60.198 +######
  60.199 +
  60.200 +.PHONY: caml
  60.201 +caml:
  60.202 +	$(MAKE) -C $@
  60.203 +
  60.204 +########
  60.205 +# minios
  60.206 +########
  60.207 +
  60.208 +.PHONY: qemu-stubdom
  60.209 +qemu-stubdom: mk-symlinks lwip libxc ioemu
  60.210 +	$(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip QEMUDIR=$(CURDIR)/ioemu
  60.211 +
  60.212 +.PHONY: caml-stubdom
  60.213 +caml-stubdom: mk-symlinks lwip libxc cross-libpci caml
  60.214 +	$(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip CAMLDIR=$(CURDIR)/caml
  60.215 +
  60.216 +#########
  60.217 +# install
  60.218 +#########
  60.219 +
  60.220 +install: mini-os/mini-os.gz
  60.221 +	$(INSTALL_PROG) stubdom-dm "$(DESTDIR)/usr/lib/xen/bin"
  60.222 +	$(INSTALL_PROG) mini-os/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/stubdom.gz"
  60.223 +
  60.224 +#######
  60.225 +# clean
  60.226 +#######
  60.227 +
  60.228 +# Only clean the libxc/ioemu/mini-os part
  60.229 +.PHONY: clean
  60.230 +clean:
  60.231 +	-$(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip clean
  60.232 +	$(MAKE) -C caml clean
  60.233 +	rm -fr libxc ioemu mini-os include
  60.234 +
  60.235 +# clean the cross-compilation result
  60.236 +.PHONY: crossclean
  60.237 +crossclean: clean
  60.238 +	rm -fr $(CROSS_ROOT)
  60.239 +	rm -fr binutils.build gcc.build newlib.build
  60.240 +	rm -fr zlib-$(ZLIB_VERSION) pciutils-$(LIBPCI_VERSION)
  60.241 +
  60.242 +# clean patched sources
  60.243 +.PHONY: patchclean
  60.244 +patchclean: crossclean
  60.245 +	rm -fr binutils-$(BINUTILS_VERSION)
  60.246 +	rm -fr gcc-$(GCC_VERSION)
  60.247 +	rm -fr newlib
  60.248 +	rm -fr lwip
  60.249 +
  60.250 +# clean downloads
  60.251 +.PHONY: downloadclean
  60.252 +downloadclean: patchclean
  60.253 +	rm -f binutils-$(BINUTILS_VERSION).tar.bz2
  60.254 +	rm -f gcc-$(GCC_VERSION).tar.bz2
  60.255 +	rm -f zlib-$(ZLIB_VERSION).tar.gz
  60.256 +	rm -f pciutils-$(LIBPCI_VERSION).tar.bz2
  60.257 +
  60.258 +.PHONY: distclean
  60.259 +distclean: downloadclean
    61.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.2 +++ b/stubdom/README	Tue Feb 12 14:35:39 2008 +0000
    61.3 @@ -0,0 +1,41 @@
    61.4 +To compile
    61.5 +==========
    61.6 +
    61.7 +Just run make -j 4, that will download / patch / compile
    61.8 +Then make install to install the result.
    61.9 +
   61.10 +Also, run make and make install in $XEN_ROOT/tools/fs-back
   61.11 +
   61.12 +To run
   61.13 +======
   61.14 +
   61.15 +mkdir -p /exports/usr/share/qemu
   61.16 +ln -s /usr/share/qemu/keymaps /exports/usr/share/qemu
   61.17 +/usr/sbin/fs-backend &
   61.18 +
   61.19 +
   61.20 +In your HVM config "hvmconfig",
   61.21 +
   61.22 +- use VNC, set vnclisten to "172.30.206.1" for instance:
   61.23 +
   61.24 +vnc=1 
   61.25 +vnclisten="172.30.206.1" 
   61.26 +
   61.27 +- use /usr/lib/xen/bin/stubdom-dm as dm script
   61.28 +
   61.29 +device_model = '/usr/lib/xen/bin/stubdom-dm'
   61.30 +
   61.31 +- comment the disk statement:
   61.32 +#disk = [  'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ]
   61.33 +
   61.34 +Create /etc/xen/stubdom-hvmconfig ("hvmconfig" must match your main config file)
   61.35 +with
   61.36 +
   61.37 +kernel="/usr/lib/xen/boot/stubdom.gz"
   61.38 +vif=[ 'ip=172.30.206.1', 'ip=10.0.1.1,mac=aa:00:00:12:23:34']
   61.39 +disk = [  'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ]
   61.40 +
   61.41 +where
   61.42 +- 172.30.206.1 is the IP for vnc,
   61.43 +- 'ip=10.0.1.1,mac=' is the same net configuration as in the hvmconfig script,
   61.44 +- and disk = is the same block configuration as in the hvmconfig script.
    62.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.2 +++ b/stubdom/caml/Makefile	Tue Feb 12 14:35:39 2008 +0000
    62.3 @@ -0,0 +1,18 @@
    62.4 +XEN_ROOT = ../..
    62.5 +
    62.6 +include $(XEN_ROOT)/Config.mk
    62.7 +
    62.8 +OCAMLFIND=ocamlfind
    62.9 +OCAMLOPT=ocamlopt
   62.10 +
   62.11 +OBJS := hello.cmx
   62.12 +LIBS := 
   62.13 +
   62.14 +%.cmx: %.ml
   62.15 +	$(OCAMLFIND) $(OCAMLOPT) -c $< -o $@
   62.16 +
   62.17 +caml.o: $(OBJS)
   62.18 +	$(OCAMLFIND) $(OCAMLOPT) $(LIBS) $^ -output-obj -o $@
   62.19 +
   62.20 +clean:
   62.21 +	rm -f *.o *.cmx *.cmi
    63.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.2 +++ b/stubdom/caml/hello.ml	Tue Feb 12 14:35:39 2008 +0000
    63.3 @@ -0,0 +1,4 @@
    63.4 +let main arg =
    63.5 +  Printf.printf "Hello, world!\n%!."
    63.6 +
    63.7 +let _ = Callback.register "main" main
    64.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.2 +++ b/stubdom/libpci.config.h	Tue Feb 12 14:35:39 2008 +0000
    64.3 @@ -0,0 +1,5 @@
    64.4 +#define PCI_OS_STUBDOM
    64.5 +#define PCI_HAVE_STDINT_H
    64.6 +#define PCI_PATH_IDS_DIR "."
    64.7 +#define PCI_COMPRESSED_IDS
    64.8 +#define PCI_IDS "pci.ids.gz"
    65.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.2 +++ b/stubdom/libpci.config.mak	Tue Feb 12 14:35:39 2008 +0000
    65.3 @@ -0,0 +1,2 @@
    65.4 +LIBZ=-lz
    65.5 +LDLIBS+=$(LIBZ)
    66.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.2 +++ b/stubdom/stubdom-dm	Tue Feb 12 14:35:39 2008 +0000
    66.3 @@ -0,0 +1,97 @@
    66.4 +#!/bin/bash
    66.5 +#
    66.6 +# Copyright 2007-2008 Samuel Thibault <samuel.thibault@eu.citrix.net>
    66.7 +#
    66.8 +# dm script around stubdomains.
    66.9 +#
   66.10 +
   66.11 +# To fit xterms nicely
   66.12 +height=339
   66.13 +
   66.14 +# Parse arguments
   66.15 +
   66.16 +domid=
   66.17 +domname=
   66.18 +vncviewer=0
   66.19 +vncpid=
   66.20 +while [ "$#" -gt 0 ];
   66.21 +do
   66.22 +    if [ "$#" -ge 2 ];
   66.23 +    then
   66.24 +	case "$1" in
   66.25 +	    -d) domid=$2; shift ;;
   66.26 +	    -domain-name) domname=$2; shift ;;
   66.27 +	    -vnc)
   66.28 +		ip=${2%:*};
   66.29 +		vnc_port=${2#*:};
   66.30 +		shift
   66.31 +		;;
   66.32 +	esac
   66.33 +    fi
   66.34 +    case "$1" in
   66.35 +	-vncviewer) vncviewer=1 ;;
   66.36 +    esac
   66.37 +    shift
   66.38 +done
   66.39 +
   66.40 +[ -z "$domid"   ] && ( echo "couldn't find domain ID" ; exit 1 )
   66.41 +[ -z "$domname" ] && ( echo "couldn't find domain name" ; exit 1 )
   66.42 +
   66.43 +# Termination handler
   66.44 +
   66.45 +term() {
   66.46 +    kill %1
   66.47 +    (
   66.48 +	[ -n "$vncpid" ] && kill -9 $vncpid
   66.49 +	xm destroy stubdom-$domname
   66.50 +	#xm destroy $domname
   66.51 +    ) &
   66.52 +    # We need to exit immediately so as to let xend do the commands above
   66.53 +    exit 0
   66.54 +}
   66.55 +
   66.56 +trap term SIGHUP
   66.57 +
   66.58 +############
   66.59 +# stubdomain
   66.60 +# Wait for any previous stubdom to terminate
   66.61 +while xm list | grep stubdom-$domname
   66.62 +do
   66.63 +	sleep 1
   66.64 +done
   66.65 +
   66.66 +creation="xm create -c stubdom-$domname target=$domid memory=32"
   66.67 +
   66.68 +(while true ; do sleep 60 ; done) | $creation &
   66.69 +#xterm -geometry +0+0 -e /bin/sh -c "$creation ; echo ; echo press ENTER to shut down ; read" &
   66.70 +consolepid=$!
   66.71 +
   66.72 +
   66.73 +while ! vnc_port=`xenstore-read /local/domain/$domid/console/vnc-port`
   66.74 +do
   66.75 +        # Check that the stubdom job is still alive
   66.76 +        kill -0 $consolepid || term
   66.77 +	sleep 1
   66.78 +done
   66.79 +
   66.80 +################
   66.81 +# DEBUG: tcpdump
   66.82 +#while ! stubdomid=`xm domid stubdom-$domname`
   66.83 +#do
   66.84 +#        sleep 1
   66.85 +#done
   66.86 +#xterm -geometry 160x25+0+$height -e /bin/sh -c "tcpdump -n -i vif$stubdomid.0" &
   66.87 +#xterm -geometry 160x25+0+$((2 * $height)) -e /bin/sh -c "tcpdump -n -i vif$stubdomid.1" &
   66.88 +
   66.89 +###########
   66.90 +# vncviewer
   66.91 +if [ "$vncviewer" = 1 ]
   66.92 +then
   66.93 +    vncviewer $ip:$vnc_port &
   66.94 +    vncpid=$!
   66.95 +fi
   66.96 +
   66.97 +# wait for SIGHUP or stubdom termination
   66.98 +wait $consolepid
   66.99 +
  66.100 +term
    67.1 --- a/tools/ioemu/Makefile.target	Tue Feb 12 11:37:45 2008 +0000
    67.2 +++ b/tools/ioemu/Makefile.target	Tue Feb 12 14:35:39 2008 +0000
    67.3 @@ -15,7 +15,7 @@ TARGET_BASE_ARCH:=sparc
    67.4  endif
    67.5  TARGET_PATH=$(SRC_PATH)/target-$(TARGET_BASE_ARCH)$(TARGET_SUB)
    67.6  VPATH=$(SRC_PATH):$(TARGET_PATH):$(SRC_PATH)/hw:$(SRC_PATH)/audio
    67.7 -CPPFLAGS=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH)
    67.8 +CPPFLAGS+=-I. -I.. -I$(TARGET_PATH) -I$(SRC_PATH)
    67.9  CPPFLAGS+= -I$(XEN_ROOT)/tools/libxc
   67.10  CPPFLAGS+= -I$(XEN_ROOT)/tools/xenstore
   67.11  CPPFLAGS+= -I$(XEN_ROOT)/tools/include
   67.12 @@ -66,7 +66,11 @@ else
   67.13  QEMU_SYSTEM=qemu-fast
   67.14  endif
   67.15  
   67.16 +ifdef CONFIG_STUBDOM
   67.17 +QEMU_SYSTEM=qemu.a
   67.18 +else
   67.19  QEMU_SYSTEM=qemu-dm
   67.20 +endif
   67.21  
   67.22  ifdef CONFIG_USER_ONLY
   67.23  PROGS=$(QEMU_USER)
   67.24 @@ -345,14 +349,25 @@ VL_OBJS=vl.o osdep.o readline.o monitor.
   67.25  VL_OBJS+=cutils.o
   67.26  VL_OBJS+=block.o block-raw.o
   67.27  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
   67.28 +ifdef CONFIG_STUBDOM
   67.29 +VL_OBJS+=block-vbd.o
   67.30 +endif
   67.31  ifdef CONFIG_WIN32
   67.32  VL_OBJS+=tap-win32.o
   67.33  endif
   67.34  
   67.35 -ifeq (,$(wildcard /usr/include/pci))
   67.36 +ifdef CONFIG_STUBDOM
   67.37 +CONFIG_PASSTHROUGH=1
   67.38 +else
   67.39 +  ifeq (,$(wildcard /usr/include/pci))
   67.40  $(warning *** pciutils-devl package not found - missing /usr/include/pci)
   67.41  $(warning *** PCI passthrough capability has been disabled)
   67.42 -else
   67.43 +  else
   67.44 +CONFIG_PASSTHROUGH=1
   67.45 +  endif
   67.46 +endif
   67.47 +
   67.48 +ifdef CONFIG_PASSTHROUGH
   67.49  LIBS+=-lpci
   67.50  VL_OBJS+= pass-through.o
   67.51  CFLAGS += -DCONFIG_PASSTHROUGH
   67.52 @@ -404,13 +419,13 @@ VL_OBJS+= ne2000.o rtl8139.o pcnet.o e10
   67.53  
   67.54  ifeq ($(TARGET_BASE_ARCH), i386)
   67.55  # Hardware support
   67.56 -VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) extboot.o
   67.57 +VL_OBJS+= ide.o pckbd.o ps2.o vga.o dma.o extboot.o
   67.58  ifeq ($(ARCH),ia64)
   67.59  VL_OBJS+= fdc.o mc146818rtc.o serial.o pc.o
   67.60  else
   67.61  VL_OBJS+= fdc.o serial.o pc.o
   67.62  endif
   67.63 -VL_OBJS+= cirrus_vga.o mixeng.o parallel.o acpi.o
   67.64 +VL_OBJS+= cirrus_vga.o parallel.o acpi.o
   67.65  VL_OBJS+= usb-uhci.o smbus_eeprom.o
   67.66  VL_OBJS+= piix4acpi.o
   67.67  VL_OBJS+= xenstore.o
   67.68 @@ -419,23 +434,32 @@ VL_OBJS+= xen_machine_fv.o
   67.69  VL_OBJS+= xen_machine_pv.o
   67.70  VL_OBJS+= xenfb.o
   67.71  VL_OBJS+= xen_console.o
   67.72 +ifndef CONFIG_STUBDOM
   67.73  VL_OBJS+= tpm_tis.o
   67.74 +VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o 
   67.75  CPPFLAGS += -DHAS_TPM
   67.76  CPPFLAGS += -DHAS_AUDIO
   67.77  endif
   67.78 +endif
   67.79  ifeq ($(TARGET_BASE_ARCH), ppc)
   67.80 -VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
   67.81 +VL_OBJS+= ppc.o ide.o pckbd.o ps2.o vga.o dma.o
   67.82  VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
   67.83  VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o heathrow_pic.o mixeng.o
   67.84  VL_OBJS+= grackle_pci.o prep_pci.o unin_pci.o
   67.85 +ifndef CONFIG_STUBDOM
   67.86 +VL_OBJS+= $(SOUND_HW) $(AUDIODRV) 
   67.87  CPPFLAGS += -DHAS_AUDIO
   67.88  endif
   67.89 +endif
   67.90  ifeq ($(TARGET_ARCH), mips)
   67.91  VL_OBJS+= mips_r4k.o mips_malta.o mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o
   67.92  VL_OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o
   67.93 -VL_OBJS+= piix_pci.o parallel.o mixeng.o cirrus_vga.o $(SOUND_HW) $(AUDIODRV)
   67.94 +VL_OBJS+= piix_pci.o parallel.o mixeng.o cirrus_vga.o
   67.95 +ifndef CONFIG_STUBDOM
   67.96 +VL_OBJS+= $(SOUND_HW) $(AUDIODRV) 
   67.97  DEFINES += -DHAS_AUDIO
   67.98  endif
   67.99 +endif
  67.100  ifeq ($(TARGET_BASE_ARCH), sparc)
  67.101  ifeq ($(TARGET_ARCH), sparc64)
  67.102  VL_OBJS+= sun4u.o ide.o pckbd.o ps2.o vga.o apb_pci.o
  67.103 @@ -513,7 +537,11 @@ SDL_LIBS := $(filter-out -mwindows, $(SD
  67.104  endif
  67.105  
  67.106  $(QEMU_SYSTEM): $(VL_OBJS) libqemu.a
  67.107 +ifdef CONFIG_STUBDOM
  67.108 +	$(AR) rcs $@ $(VL_OBJS)
  67.109 +else
  67.110  	$(CC) $(VL_LDFLAGS) -o $@ $^ $(LIBS) $(SDL_LIBS) $(COCOA_LIBS) $(VL_LIBS)
  67.111 +endif
  67.112  
  67.113  cocoa.o: cocoa.m
  67.114  	$(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
    68.1 --- a/tools/ioemu/aes.c	Tue Feb 12 11:37:45 2008 +0000
    68.2 +++ b/tools/ioemu/aes.c	Tue Feb 12 14:35:39 2008 +0000
    68.3 @@ -33,9 +33,11 @@
    68.4  #define NDEBUG
    68.5  #include <assert.h>
    68.6  
    68.7 +#ifndef CONFIG_STUBDOM
    68.8  typedef uint32_t u32;
    68.9  typedef uint16_t u16;
   68.10  typedef uint8_t u8;
   68.11 +#endif
   68.12  
   68.13  #define MAXKC   (256/32)
   68.14  #define MAXKB   (256/8)
    69.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.2 +++ b/tools/ioemu/block-vbd.c	Tue Feb 12 14:35:39 2008 +0000
    69.3 @@ -0,0 +1,341 @@
    69.4 +/*
    69.5 + * Block driver for Mini-os PV devices
    69.6 + * Based on block-raw.c
    69.7 + * 
    69.8 + * Copyright (c) 2006 Fabrice Bellard, 2007 Samuel Thibault
    69.9 + * 
   69.10 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   69.11 + * of this software and associated documentation files (the "Software"), to deal
   69.12 + * in the Software without restriction, including without limitation the rights
   69.13 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   69.14 + * copies of the Software, and to permit persons to whom the Software is
   69.15 + * furnished to do so, subject to the following conditions:
   69.16 + *
   69.17 + * The above copyright notice and this permission notice shall be included in
   69.18 + * all copies or substantial portions of the Software.
   69.19 + *
   69.20 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   69.21 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   69.22 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   69.23 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   69.24 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   69.25 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   69.26 + * THE SOFTWARE.
   69.27 + */
   69.28 +#include "vl.h"
   69.29 +#include "block_int.h"
   69.30 +#include <assert.h>
   69.31 +#include <xenbus.h>
   69.32 +#include <blkfront.h>
   69.33 +#include <malloc.h>
   69.34 +
   69.35 +#define SECTOR_SIZE 512
   69.36 +
   69.37 +#ifndef QEMU_TOOL
   69.38 +#include "exec-all.h"
   69.39 +#endif
   69.40 +
   69.41 +#define DEBUG_BLOCK
   69.42 +#ifdef  DEBUG_BLOCK
   69.43 +#define DEBUG_BLOCK_PRINT( formatCstr, args... ) fprintf( logfile, formatCstr, ##args ); fflush( logfile )
   69.44 +#else
   69.45 +#define DEBUG_BLOCK_PRINT( formatCstr, args... )
   69.46 +#endif
   69.47 +
   69.48 +#define FTYPE_FILE   0
   69.49 +#define FTYPE_CD     1
   69.50 +#define FTYPE_FD     2
   69.51 +
   69.52 +typedef struct BDRVVbdState {
   69.53 +    struct blkfront_dev *dev;
   69.54 +    int fd;
   69.55 +    int type;
   69.56 +    int mode;
   69.57 +    uint64_t sectors;
   69.58 +    unsigned sector_size;
   69.59 +    QEMU_LIST_ENTRY(BDRVVbdState) list;
   69.60 +} BDRVVbdState;
   69.61 +
   69.62 +QEMU_LIST_HEAD(, BDRVVbdState) vbds;
   69.63 +
   69.64 +static int vbd_probe(const uint8_t *buf, int buf_size, const char *filename)
   69.65 +{
   69.66 +    char *value;
   69.67 +    if (xenbus_read(XBT_NIL, filename, &value))
   69.68 +	return 0;
   69.69 +    free(value);
   69.70 +    return 100;
   69.71 +}
   69.72 +
   69.73 +static int vbd_open(BlockDriverState *bs, const char *filename, int flags)
   69.74 +{
   69.75 +    BDRVVbdState *s = bs->opaque;
   69.76 +
   69.77 +    //handy to test posix access
   69.78 +    //return -EIO;
   69.79 +
   69.80 +    s->dev = init_blkfront((char *) filename, &s->sectors, &s->sector_size, &s->mode);
   69.81 +
   69.82 +    if (!s->dev)
   69.83 +	return -EIO;
   69.84 +
   69.85 +    if (SECTOR_SIZE % s->sector_size) {
   69.86 +	printf("sector size is %d, we only support sector sizes that divide %d\n", s->sector_size, SECTOR_SIZE);
   69.87 +	return -EIO;
   69.88 +    }
   69.89 +
   69.90 +    s->fd = blkfront_open(s->dev);
   69.91 +
   69.92 +    QEMU_LIST_INSERT_HEAD(&vbds, s, list);
   69.93 +
   69.94 +    return 0;
   69.95 +}
   69.96 +
   69.97 +typedef struct VbdAIOCB {
   69.98 +    BlockDriverAIOCB common;
   69.99 +    struct blkfront_aiocb aiocb;
  69.100 +} VbdAIOCB;
  69.101 +
  69.102 +void qemu_aio_init(void)
  69.103 +{
  69.104 +}
  69.105 +
  69.106 +void qemu_aio_poll(void)
  69.107 +{
  69.108 +    BDRVVbdState *s;
  69.109 +    for (s = vbds.lh_first; s; s = s->list.le_next)
  69.110 +	blkfront_aio_poll(s->dev);
  69.111 +}
  69.112 +
  69.113 +/* Wait for all IO requests to complete.  */
  69.114 +void qemu_aio_flush(void)
  69.115 +{
  69.116 +    BDRVVbdState *s;
  69.117 +    for (s = vbds.lh_first; s; s = s->list.le_next)
  69.118 +	blkfront_sync(s->dev);
  69.119 +}
  69.120 +
  69.121 +void qemu_aio_wait_start(void)
  69.122 +{
  69.123 +}
  69.124 +
  69.125 +void qemu_aio_wait(void)
  69.126 +{
  69.127 +    int some = 0;
  69.128 +    DEFINE_WAIT(w);
  69.129 +    while (1) {
  69.130 +	BDRVVbdState *s;
  69.131 +	add_waiter(w, blkfront_queue);
  69.132 +        for (s = vbds.lh_first; s; s = s->list.le_next)
  69.133 +	    if (blkfront_aio_poll(s->dev))
  69.134 +		some = 1;
  69.135 +	if (some)
  69.136 +	    break;
  69.137 +	schedule();
  69.138 +    }
  69.139 +    remove_waiter(w);
  69.140 +}
  69.141 +
  69.142 +void qemu_aio_wait_end(void)
  69.143 +{
  69.144 +}
  69.145 +
  69.146 +static void vbd_aio_callback(struct blkfront_aiocb *aiocbp, int ret) {
  69.147 +    VbdAIOCB *acb = aiocbp->data;
  69.148 +
  69.149 +    acb->common.cb(acb->common.opaque, ret);
  69.150 +    qemu_aio_release(acb);
  69.151 +}
  69.152 +
  69.153 +static VbdAIOCB *vbd_aio_setup(BlockDriverState *bs,
  69.154 +        int64_t sector_num, uint8_t *buf, int nb_sectors,
  69.155 +        BlockDriverCompletionFunc *cb, void *opaque)
  69.156 +{
  69.157 +    BDRVVbdState *s = bs->opaque;
  69.158 +    VbdAIOCB *acb;
  69.159 +
  69.160 +    acb = qemu_aio_get(bs, cb, opaque);
  69.161 +    if (!acb)
  69.162 +	return NULL;
  69.163 +    acb->aiocb.aio_dev = s->dev;
  69.164 +    acb->aiocb.aio_buf = buf;
  69.165 +    acb->aiocb.aio_nbytes = nb_sectors * SECTOR_SIZE;
  69.166 +    acb->aiocb.aio_offset = sector_num * SECTOR_SIZE;
  69.167 +    acb->aiocb.aio_cb = vbd_aio_callback;
  69.168 +    acb->aiocb.data = acb;
  69.169 +
  69.170 +    return acb;
  69.171 +}
  69.172 +
  69.173 +static BlockDriverAIOCB *vbd_aio_read(BlockDriverState *bs,
  69.174 +        int64_t sector_num, uint8_t *buf, int nb_sectors,
  69.175 +        BlockDriverCompletionFunc *cb, void *opaque)
  69.176 +{
  69.177 +    VbdAIOCB *acb;
  69.178 +
  69.179 +    acb = vbd_aio_setup(bs, sector_num, buf, nb_sectors, cb, opaque);
  69.180 +    if (!acb)
  69.181 +	return NULL;
  69.182 +    blkfront_aio(&acb->aiocb, 0);
  69.183 +    return &acb->common;
  69.184 +}
  69.185 +
  69.186 +static BlockDriverAIOCB *vbd_aio_write(BlockDriverState *bs,
  69.187 +        int64_t sector_num, const uint8_t *buf, int nb_sectors,
  69.188 +        BlockDriverCompletionFunc *cb, void *opaque)
  69.189 +{
  69.190 +    VbdAIOCB *acb;
  69.191 +
  69.192 +    acb = vbd_aio_setup(bs, sector_num, (uint8_t*) buf, nb_sectors, cb, opaque);
  69.193 +    if (!acb)
  69.194 +	return NULL;
  69.195 +    blkfront_aio(&acb->aiocb, 1);
  69.196 +    return &acb->common;
  69.197 +}
  69.198 +
  69.199 +static void vbd_cb(void *data, int ret) {
  69.200 +    int *result = data;
  69.201 +    result[0] = 1;
  69.202 +    result[1] = ret;
  69.203 +}
  69.204 +
  69.205 +static int vbd_aligned_io(BlockDriverState *bs,
  69.206 +	int64_t sector_num, uint8_t *buf, int nb_sectors, int write)
  69.207 +{
  69.208 +    VbdAIOCB *acb;
  69.209 +    int result[2];
  69.210 +    result[0] = 0;
  69.211 +    qemu_aio_wait_start();
  69.212 +    acb = vbd_aio_setup(bs, sector_num, (uint8_t*) buf, nb_sectors, vbd_cb, &result);
  69.213 +    blkfront_aio(&acb->aiocb, write);
  69.214 +    while (!result[0])
  69.215 +	qemu_aio_wait();
  69.216 +    qemu_aio_wait_end();
  69.217 +    return result[1];
  69.218 +}
  69.219 +
  69.220 +static int vbd_read(BlockDriverState *bs,
  69.221 +	int64_t sector_num, uint8_t *buf, int nb_sectors)
  69.222 +{
  69.223 +    uint8_t *iobuf;
  69.224 +    int ret;
  69.225 +    /* page alignment would be a bit better, but that's still fine compared to
  69.226 +     * copying */
  69.227 +    if (!((uintptr_t)buf & (SECTOR_SIZE-1)))
  69.228 +	return vbd_aligned_io(bs, sector_num, buf, nb_sectors, 0);
  69.229 +    iobuf = memalign(PAGE_SIZE, nb_sectors * SECTOR_SIZE);
  69.230 +    ret = vbd_aligned_io(bs, sector_num, iobuf, nb_sectors, 0);
  69.231 +    memcpy(buf, iobuf, nb_sectors * SECTOR_SIZE);
  69.232 +    free(iobuf);
  69.233 +    if (ret < 0)
  69.234 +	return ret;
  69.235 +    else if (ret != nb_sectors * SECTOR_SIZE)
  69.236 +	return -EINVAL;
  69.237 +    else
  69.238 +	return 0;
  69.239 +}
  69.240 +
  69.241 +static int vbd_write(BlockDriverState *bs,
  69.242 +	int64_t sector_num, const uint8_t *buf, int nb_sectors)
  69.243 +{
  69.244 +    uint8_t *iobuf;
  69.245 +    int ret;
  69.246 +    if (!((uintptr_t)buf & (SECTOR_SIZE-1)))
  69.247 +	return vbd_aligned_io(bs, sector_num, (uint8_t*) buf, nb_sectors, 1);
  69.248 +    iobuf = memalign(PAGE_SIZE, nb_sectors * SECTOR_SIZE);
  69.249 +    memcpy(iobuf, buf, nb_sectors * SECTOR_SIZE);
  69.250 +    ret = vbd_aligned_io(bs, sector_num, iobuf, nb_sectors, 1);
  69.251 +    free(iobuf);
  69.252 +    if (ret < 0)
  69.253 +	return ret;
  69.254 +    else if (ret != nb_sectors * SECTOR_SIZE)
  69.255 +	return -EINVAL;
  69.256 +    else
  69.257 +	return 0;
  69.258 +}
  69.259 +
  69.260 +static void vbd_aio_cancel(BlockDriverAIOCB *blockacb)
  69.261 +{
  69.262 +    /* TODO */
  69.263 +    //VbdAIOCB *acb = (VbdAIOCB *)blockacb;
  69.264 +
  69.265 +    // Try to cancel. If can't, wait for it, drop the callback and call qemu_aio_release(acb)
  69.266 +}
  69.267 +
  69.268 +static void vbd_close(BlockDriverState *bs)
  69.269 +{
  69.270 +    BDRVVbdState *s = bs->opaque;
  69.271 +    bs->total_sectors = 0;
  69.272 +    if (s->fd >= 0) {
  69.273 +        close(s->fd);
  69.274 +        s->fd = -1;
  69.275 +    }
  69.276 +    QEMU_LIST_REMOVE(s, list);
  69.277 +}
  69.278 +
  69.279 +static int64_t  vbd_getlength(BlockDriverState *bs)
  69.280 +{
  69.281 +    BDRVVbdState *s = bs->opaque;
  69.282 +    return s->sectors * s->sector_size;
  69.283 +}
  69.284 +
  69.285 +static void vbd_flush(BlockDriverState *bs)
  69.286 +{
  69.287 +    BDRVVbdState *s = bs->opaque;
  69.288 +    blkfront_sync(s->dev);
  69.289 +}
  69.290 +
  69.291 +/***********************************************/
  69.292 +/* host device */
  69.293 +
  69.294 +static int vbd_is_inserted(BlockDriverState *bs)
  69.295 +{
  69.296 +    /* TODO: monitor the backend */
  69.297 +    return 1;
  69.298 +}
  69.299 +
  69.300 +/* currently only used by fdc.c, but a CD version would be good too */
  69.301 +static int vbd_media_changed(BlockDriverState *bs)
  69.302 +{
  69.303 +    /* TODO: monitor the backend */
  69.304 +    return -ENOTSUP;
  69.305 +}
  69.306 +
  69.307 +static int vbd_eject(BlockDriverState *bs, int eject_flag)
  69.308 +{
  69.309 +    /* TODO: Xen support needed */
  69.310 +    return -ENOTSUP;
  69.311 +}
  69.312 +
  69.313 +static int vbd_set_locked(BlockDriverState *bs, int locked)
  69.314 +{
  69.315 +    /* TODO: Xen support needed */
  69.316 +    return -ENOTSUP;
  69.317 +}
  69.318 +
  69.319 +BlockDriver bdrv_vbd = {
  69.320 +    "vbd",
  69.321 +    sizeof(BDRVVbdState),
  69.322 +    vbd_probe,
  69.323 +    vbd_open,
  69.324 +    NULL,
  69.325 +    NULL,
  69.326 +    vbd_close,
  69.327 +    NULL,
  69.328 +    vbd_flush,
  69.329 +    
  69.330 +    .bdrv_aio_read = vbd_aio_read,
  69.331 +    .bdrv_aio_write = vbd_aio_write,
  69.332 +    .bdrv_aio_cancel = vbd_aio_cancel,
  69.333 +    .aiocb_size = sizeof(VbdAIOCB),
  69.334 +    .bdrv_read = vbd_read,
  69.335 +    .bdrv_write = vbd_write,
  69.336 +    .bdrv_getlength = vbd_getlength,
  69.337 +
  69.338 +    /* removable device support */
  69.339 +    .bdrv_is_inserted = vbd_is_inserted,
  69.340 +    .bdrv_media_changed = vbd_media_changed,
  69.341 +    .bdrv_eject = vbd_eject,
  69.342 +    .bdrv_set_locked = vbd_set_locked,
  69.343 +};
  69.344 +
    70.1 --- a/tools/ioemu/block.c	Tue Feb 12 11:37:45 2008 +0000
    70.2 +++ b/tools/ioemu/block.c	Tue Feb 12 14:35:39 2008 +0000
    70.3 @@ -1235,6 +1235,9 @@ void bdrv_init(void)
    70.4  {
    70.5      bdrv_register(&bdrv_raw);
    70.6      bdrv_register(&bdrv_host_device);
    70.7 +#ifdef CONFIG_STUBDOM
    70.8 +    bdrv_register(&bdrv_vbd);
    70.9 +#endif
   70.10  #ifndef _WIN32
   70.11      bdrv_register(&bdrv_cow);
   70.12  #endif
    71.1 --- a/tools/ioemu/configure	Tue Feb 12 11:37:45 2008 +0000
    71.2 +++ b/tools/ioemu/configure	Tue Feb 12 14:35:39 2008 +0000
    71.3 @@ -74,6 +74,7 @@ softmmu="yes"
    71.4  linux_user="no"
    71.5  darwin_user="no"
    71.6  build_docs="no"
    71.7 +stubdom="no"
    71.8  uname_release=""
    71.9  
   71.10  # OS specific
   71.11 @@ -231,6 +232,8 @@ for opt do
   71.12    ;;
   71.13    --enable-uname-release=*) uname_release="$optarg"
   71.14    ;;
   71.15 +  --enable-stubdom) stubdom="yes"
   71.16 +  ;;
   71.17    esac
   71.18  done
   71.19  
   71.20 @@ -416,7 +419,11 @@ if test -z "$target_list" ; then
   71.21          target_list="i386-darwin-user ppc-darwin-user $target_list"
   71.22      fi
   71.23  # the i386-dm target
   71.24 -    target_list="i386-dm"
   71.25 +    if test "$stubdom" = "yes"; then
   71.26 +        target_list="i386-dm-stubdom"
   71.27 +    else
   71.28 +        target_list="i386-dm"
   71.29 +    fi
   71.30  else
   71.31      target_list=`echo "$target_list" | sed -e 's/,/ /g'`
   71.32  fi
   71.33 @@ -575,6 +582,11 @@ bindir="$prefix/$libdir/xen/bin"
   71.34  configdir="/etc/xen"
   71.35  fi
   71.36  
   71.37 +if test "$stubdom" = "yes"; then
   71.38 +    oss="no"
   71.39 +    sdl="no"
   71.40 +fi
   71.41 +
   71.42  echo "Install prefix    $prefix"
   71.43  echo "BIOS directory    $datadir"
   71.44  echo "binary directory  $bindir"
   71.45 @@ -943,6 +955,14 @@ if expr $target : '.*-dm' > /dev/null ; 
   71.46    echo "#define CONFIG_DM 1" >> $config_h
   71.47  fi
   71.48  
   71.49 +if test "$stubdom" = "yes" ; then
   71.50 +  echo "CONFIG_STUBDOM=yes" >> $config_mak
   71.51 +  echo "#define CONFIG_STUBDOM 1" >> $config_h
   71.52 +  echo "#define NO_UNIX_SOCKETS 1" >> $config_h
   71.53 +  echo "#define NO_DAEMONIZE 1" >> $config_h
   71.54 +  echo "#define NO_AIO 1" >> $config_h
   71.55 +fi
   71.56 +
   71.57  if test "$target_cpu" = "arm" -o "$target_cpu" = "armeb" -o "$target_cpu" = "sparc" -o "$target_cpu" = "sparc64" -o "$target_cpu" = "m68k"; then
   71.58    echo "CONFIG_SOFTFLOAT=yes" >> $config_mak
   71.59    echo "#define CONFIG_SOFTFLOAT 1" >> $config_h
    72.1 --- a/tools/ioemu/exec-all.h	Tue Feb 12 11:37:45 2008 +0000
    72.2 +++ b/tools/ioemu/exec-all.h	Tue Feb 12 14:35:39 2008 +0000
    72.3 @@ -481,6 +481,9 @@ static inline int testandset (int *p)
    72.4  }
    72.5  #endif
    72.6  
    72.7 +#ifdef CONFIG_STUBDOM
    72.8 +#include <spinlock.h>
    72.9 +#else
   72.10  typedef int spinlock_t;
   72.11  
   72.12  #define SPIN_LOCK_UNLOCKED 0
   72.13 @@ -514,6 +517,7 @@ static inline int spin_trylock(spinlock_
   72.14      return 1;
   72.15  }
   72.16  #endif
   72.17 +#endif
   72.18  
   72.19  extern spinlock_t tb_lock;
   72.20  
    73.1 --- a/tools/ioemu/hw/ide.c	Tue Feb 12 11:37:45 2008 +0000
    73.2 +++ b/tools/ioemu/hw/ide.c	Tue Feb 12 14:35:39 2008 +0000
    73.3 @@ -22,6 +22,7 @@
    73.4   * THE SOFTWARE.
    73.5   */
    73.6  #include "vl.h"
    73.7 +#include <malloc.h>
    73.8  
    73.9  /* debug IDE devices */
   73.10  //#define DEBUG_IDE
   73.11 @@ -347,7 +348,7 @@ typedef struct IDEState {
   73.12      EndTransferFunc *end_transfer_func;
   73.13      uint8_t *data_ptr;
   73.14      uint8_t *data_end;
   73.15 -    uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
   73.16 +    uint8_t *io_buffer;
   73.17      QEMUTimer *sector_write_timer; /* only used for win2k instal hack */
   73.18      uint32_t irq_count; /* counts IRQs when using win2k install hack */
   73.19  } IDEState;
   73.20 @@ -2305,6 +2306,7 @@ static void ide_init2(IDEState *ide_stat
   73.21  
   73.22      for(i = 0; i < 2; i++) {
   73.23          s = ide_state + i;
   73.24 +        s->io_buffer = memalign(getpagesize(), MAX_MULT_SECTORS*512 + 4);
   73.25          if (i == 0)
   73.26              s->bs = hd0;
   73.27          else
    74.1 --- a/tools/ioemu/hw/scsi-disk.c	Tue Feb 12 11:37:45 2008 +0000
    74.2 +++ b/tools/ioemu/hw/scsi-disk.c	Tue Feb 12 14:35:39 2008 +0000
    74.3 @@ -26,13 +26,18 @@ do { printf("scsi-disk: " fmt , ##args);
    74.4  do { fprintf(stderr, "scsi-disk: " fmt , ##args); } while (0)
    74.5  
    74.6  #include "vl.h"
    74.7 +#include <malloc.h>
    74.8  
    74.9  #define SENSE_NO_SENSE        0
   74.10  #define SENSE_NOT_READY       2
   74.11  #define SENSE_HARDWARE_ERROR  4
   74.12  #define SENSE_ILLEGAL_REQUEST 5
   74.13  
   74.14 +#ifdef CONFIG_STUBDOM
   74.15 +#define SCSI_DMA_BUF_SIZE    32768
   74.16 +#else
   74.17  #define SCSI_DMA_BUF_SIZE    65536
   74.18 +#endif
   74.19  
   74.20  typedef struct SCSIRequest {
   74.21      SCSIDevice *dev;
   74.22 @@ -44,7 +49,7 @@ typedef struct SCSIRequest {
   74.23      int sector_count;
   74.24      /* The amounnt of data in the buffer.  */
   74.25      int buf_len;
   74.26 -    uint8_t dma_buf[SCSI_DMA_BUF_SIZE];
   74.27 +    uint8_t *dma_buf;
   74.28      BlockDriverAIOCB *aiocb;
   74.29      struct SCSIRequest *next;
   74.30  } SCSIRequest;
   74.31 @@ -76,6 +81,7 @@ static SCSIRequest *scsi_new_request(SCS
   74.32          free_requests = r->next;
   74.33      } else {
   74.34          r = qemu_malloc(sizeof(SCSIRequest));
   74.35 +	r->dma_buf = memalign(getpagesize(), SCSI_DMA_BUF_SIZE);
   74.36      }
   74.37      r->dev = s;
   74.38      r->tag = tag;
    75.1 --- a/tools/ioemu/hw/xen_machine_fv.c	Tue Feb 12 11:37:45 2008 +0000
    75.2 +++ b/tools/ioemu/hw/xen_machine_fv.c	Tue Feb 12 14:35:39 2008 +0000
    75.3 @@ -24,6 +24,9 @@
    75.4   */
    75.5  
    75.6  #include "vl.h"
    75.7 +#ifdef CONFIG_STUBDOM
    75.8 +#include <xenbus.h>
    75.9 +#endif
   75.10  #include <xen/hvm/params.h>
   75.11  #include <sys/mman.h>
   75.12  
    76.1 --- a/tools/ioemu/vl.c	Tue Feb 12 11:37:45 2008 +0000
    76.2 +++ b/tools/ioemu/vl.c	Tue Feb 12 14:35:39 2008 +0000
    76.3 @@ -36,22 +36,29 @@
    76.4  #include <sys/times.h>
    76.5  #include <sys/wait.h>
    76.6  #include <termios.h>
    76.7 +#ifndef CONFIG_STUBDOM
    76.8  #include <sys/poll.h>
    76.9 +#endif
   76.10  #include <sys/mman.h>
   76.11  #include <sys/ioctl.h>
   76.12  #include <sys/resource.h>
   76.13  #include <sys/socket.h>
   76.14  #include <netinet/in.h>
   76.15 +#ifndef CONFIG_STUBDOM
   76.16  #include <net/if.h>
   76.17 +#endif
   76.18  #if defined(__NetBSD__)
   76.19  #include <net/if_tap.h>
   76.20  #endif
   76.21  #if defined(__linux__) || defined(__Linux__)
   76.22  #include <linux/if_tun.h>
   76.23  #endif
   76.24 +#ifndef CONFIG_STUBDOM
   76.25  #include <arpa/inet.h>
   76.26  #include <dirent.h>
   76.27 +#endif
   76.28  #include <netdb.h>
   76.29 +#ifndef CONFIG_STUBDOM
   76.30  #ifdef _BSD
   76.31  #include <sys/stat.h>
   76.32  #ifndef _BSD
   76.33 @@ -70,6 +77,7 @@
   76.34  #include <stropts.h>
   76.35  #endif
   76.36  #endif
   76.37 +#endif
   76.38  
   76.39  #if defined(CONFIG_SLIRP)
   76.40  #include "libslirp.h"
   76.41 @@ -132,10 +140,9 @@
   76.42  #define MAX_IOPORTS 65536
   76.43  
   76.44  const char *bios_dir = CONFIG_QEMU_SHAREDIR;
   76.45 -char phys_ram_file[1024];
   76.46 -void *ioport_opaque[MAX_IOPORTS];
   76.47 -IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
   76.48 -IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
   76.49 +void **ioport_opaque;
   76.50 +IOPortReadFunc *(*ioport_read_table)[MAX_IOPORTS];
   76.51 +IOPortWriteFunc *(*ioport_write_table)[MAX_IOPORTS];
   76.52  /* Note: bs_table[MAX_DISKS] is a dummy block driver if none available
   76.53     to store the VM snapshots */
   76.54  BlockDriverState *bs_table[MAX_DISKS + MAX_SCSI_DISKS + 1], *fd_table[MAX_FD];
   76.55 @@ -270,6 +277,9 @@ void default_ioport_writel(void *opaque,
   76.56  
   76.57  void init_ioports(void)
   76.58  {
   76.59 +    ioport_opaque = malloc(MAX_IOPORTS * sizeof(*ioport_opaque));
   76.60 +    ioport_read_table = malloc(3 * MAX_IOPORTS * sizeof(**ioport_read_table));
   76.61 +    ioport_write_table = malloc(3 * MAX_IOPORTS * sizeof(**ioport_write_table));
   76.62  }
   76.63  
   76.64  /* size is the word size in byte */
   76.65 @@ -797,9 +807,6 @@ static QEMUTimer *active_timers[2];
   76.66  static MMRESULT timerID;
   76.67  static HANDLE host_alarm = NULL;
   76.68  static unsigned int period = 1;
   76.69 -#else
   76.70 -/* frequency of the times() clock tick */
   76.71 -static int timer_freq;
   76.72  #endif
   76.73  
   76.74  QEMUClock *qemu_new_clock(int type)
   76.75 @@ -1137,9 +1144,6 @@ static void init_timer_alarm(void)
   76.76          struct itimerval itv;
   76.77  #endif
   76.78          
   76.79 -        /* get times() syscall frequency */
   76.80 -        timer_freq = sysconf(_SC_CLK_TCK);
   76.81 -        
   76.82  #ifndef CONFIG_DM
   76.83          /* timer signal */
   76.84          sigfillset(&act.sa_mask);
   76.85 @@ -1497,6 +1501,7 @@ static CharDriverState *qemu_chr_open_fi
   76.86      return qemu_chr_open_fd(-1, fd_out);
   76.87  }
   76.88  
   76.89 +#ifndef CONFIG_STUBDOM
   76.90  static CharDriverState *qemu_chr_open_pipe(const char *filename)
   76.91  {
   76.92      int fd_in, fd_out;
   76.93 @@ -1742,6 +1747,7 @@ static CharDriverState *qemu_chr_open_st
   76.94      }
   76.95      return chr;
   76.96  }
   76.97 +#endif
   76.98  
   76.99  /*
  76.100   * Create a store entry for a device (e.g., monitor, serial/parallel lines).
  76.101 @@ -1751,6 +1757,9 @@ static CharDriverState *qemu_chr_open_st
  76.102  static int store_dev_info(char *devName, int domid,
  76.103                            CharDriverState *cState, char *storeString)
  76.104  {
  76.105 +#ifdef CONFIG_STUBDOM
  76.106 +    return 0;
  76.107 +#else
  76.108      int xc_handle;
  76.109      struct xs_handle *xs;
  76.110      char *path;
  76.111 @@ -1826,8 +1835,10 @@ static int store_dev_info(char *devName,
  76.112      close(xc_handle);
  76.113  
  76.114      return 0;
  76.115 -}
  76.116 -
  76.117 +#endif
  76.118 +}
  76.119 +
  76.120 +#ifndef CONFIG_STUBDOM
  76.121  #ifdef __sun__
  76.122  /* Once Solaris has openpty(), this is going to be removed. */
  76.123  int openpty(int *amaster, int *aslave, char *name,
  76.124 @@ -2486,6 +2497,7 @@ static CharDriverState *qemu_chr_open_wi
  76.125      return qemu_chr_open_win_file(fd_out);
  76.126  }
  76.127  #endif
  76.128 +#endif
  76.129  
  76.130  /***********************************************************/
  76.131  /* UDP Net console */
  76.132 @@ -2978,12 +2990,14 @@ CharDriverState *qemu_chr_open(const cha
  76.133  	return qemu_chr_open_tcp(p, 0, 1);
  76.134      } else if (strstart(filename, "file:", &p)) {
  76.135          return qemu_chr_open_file_out(p);
  76.136 +#ifndef CONFIG_STUBDOM
  76.137      } else if (strstart(filename, "pipe:", &p)) {
  76.138          return qemu_chr_open_pipe(p);
  76.139      } else if (!strcmp(filename, "pty")) {
  76.140          return qemu_chr_open_pty();
  76.141      } else if (!strcmp(filename, "stdio")) {
  76.142          return qemu_chr_open_stdio();
  76.143 +#endif
  76.144      } else 
  76.145  #endif
  76.146  #if defined(__linux__)
  76.147 @@ -3473,7 +3487,16 @@ static TAPState *net_tap_fd_init(VLANSta
  76.148      return s;
  76.149  }
  76.150  
  76.151 -#ifdef _BSD
  76.152 +#ifdef CONFIG_STUBDOM
  76.153 +#include <netfront.h>
  76.154 +static int tap_open(char *ifname, int ifname_size)
  76.155 +{
  76.156 +    char nodename[64];
  76.157 +    static int num = 1; // 0 is for our own TCP/IP networking
  76.158 +    snprintf(nodename, sizeof(nodename), "device/vif/%d", num++);
  76.159 +    return netfront_tap_open(nodename);
  76.160 +}
  76.161 +#elif defined(_BSD)
  76.162  static int tap_open(char *ifname, int ifname_size)
  76.163  {
  76.164      int fd;
  76.165 @@ -3561,6 +3584,7 @@ static int net_tap_init(VLANState *vlan,
  76.166      if (fd < 0)
  76.167          return -1;
  76.168  
  76.169 +#ifndef CONFIG_STUBDOM
  76.170      if (!setup_script || !strcmp(setup_script, "no"))
  76.171          setup_script = "";
  76.172      if (setup_script[0] != '\0') {
  76.173 @@ -3593,6 +3617,7 @@ static int net_tap_init(VLANState *vlan,
  76.174              }
  76.175          }
  76.176      }
  76.177 +#endif
  76.178      s = net_tap_fd_init(vlan, fd);
  76.179      if (!s)
  76.180          return -1;
  76.181 @@ -7041,12 +7066,14 @@ int main(int argc, char **argv)
  76.182      char usb_devices[MAX_USB_CMDLINE][128];
  76.183      int usb_devices_index;
  76.184      int fds[2];
  76.185 +#ifndef CONFIG_STUBDOM
  76.186      struct rlimit rl;
  76.187 +#endif
  76.188      sigset_t set;
  76.189      char qemu_dm_logfilename[128];
  76.190      const char *direct_pci = NULL;
  76.191  
  76.192 -#ifndef __sun__
  76.193 +#if !defined(__sun__) && !defined(CONFIG_STUBDOM)
  76.194      /* Maximise rlimits. Needed where default constraints are tight (*BSD). */
  76.195      if (getrlimit(RLIMIT_STACK, &rl) != 0) {
  76.196         perror("getrlimit(RLIMIT_STACK)");
  76.197 @@ -7072,6 +7099,7 @@ int main(int argc, char **argv)
  76.198         perror("setrlimit(RLIMIT_MEMLOCK)");
  76.199  #endif
  76.200  
  76.201 +#ifndef CONFIG_STUBDOM
  76.202      /* Ensure that SIGUSR2 is blocked by default when a new thread is created,
  76.203         then only the threads that use the signal unblock it -- this fixes a
  76.204         race condition in Qcow support where the AIO signal is misdelivered.  */
  76.205 @@ -7114,6 +7142,7 @@ int main(int argc, char **argv)
  76.206          }
  76.207      }
  76.208  #endif
  76.209 +#endif
  76.210  
  76.211      register_machines();
  76.212      machine = first_machine;
  76.213 @@ -7631,7 +7660,15 @@ int main(int argc, char **argv)
  76.214  #ifdef CONFIG_DM
  76.215      bdrv_init();
  76.216      xc_handle = xc_interface_open();
  76.217 +#ifdef CONFIG_STUBDOM
  76.218 +    char *domid_s, *msg;
  76.219 +    if ((msg = xenbus_read(XBT_NIL, "domid", &domid_s)))
  76.220 +        fprintf(stderr,"Can not read our own domid\n", msg);
  76.221 +    else
  76.222 +        xenstore_parse_domain_config(atoi(domid_s));
  76.223 +#else /* CONFIG_STUBDOM */
  76.224      xenstore_parse_domain_config(domid);
  76.225 +#endif /* CONFIG_STUBDOM */
  76.226  #endif /* CONFIG_DM */
  76.227  
  76.228  #ifdef USE_KQEMU
  76.229 @@ -7799,8 +7836,10 @@ int main(int argc, char **argv)
  76.230  	vnc_display_password(ds, password);
  76.231  	if ((vnc_display_port = vnc_display_open(ds, vnc_display, vncunused)) < 0) 
  76.232  	    exit (0);
  76.233 +#ifndef CONFIG_STUBDOM	    
  76.234   	if (vncviewer)
  76.235  	    vnc_start_viewer(vnc_display_port);
  76.236 +#endif
  76.237  	xenstore_write_vncport(vnc_display_port);
  76.238      } else {
  76.239  #if defined(CONFIG_SDL)
  76.240 @@ -7928,6 +7967,7 @@ int main(int argc, char **argv)
  76.241      }
  76.242  #endif
  76.243  
  76.244 +#ifndef CONFIG_STUBDOM
  76.245      /* Unblock SIGTERM and SIGHUP, which may have been blocked by the caller */
  76.246      signal(SIGHUP, SIG_DFL);
  76.247      sigemptyset(&set);
  76.248 @@ -7935,6 +7975,7 @@ int main(int argc, char **argv)
  76.249      sigaddset(&set, SIGHUP);
  76.250      if (sigprocmask(SIG_UNBLOCK, &set, NULL) == -1)
  76.251          fprintf(stderr, "Failed to unblock SIGTERM and SIGHUP\n");
  76.252 +#endif
  76.253  
  76.254      main_loop();
  76.255      quit_timers();
    77.1 --- a/tools/ioemu/vl.h	Tue Feb 12 11:37:45 2008 +0000
    77.2 +++ b/tools/ioemu/vl.h	Tue Feb 12 14:35:39 2008 +0000
    77.3 @@ -574,6 +574,9 @@ typedef struct BlockDriver BlockDriver;
    77.4  
    77.5  extern BlockDriver bdrv_raw;
    77.6  extern BlockDriver bdrv_host_device;
    77.7 +#ifdef CONFIG_STUBDOM
    77.8 +extern BlockDriver bdrv_vbd;
    77.9 +#endif
   77.10  extern BlockDriver bdrv_cow;
   77.11  extern BlockDriver bdrv_qcow;
   77.12  extern BlockDriver bdrv_vmdk;
    78.1 --- a/tools/ioemu/vnc.c	Tue Feb 12 11:37:45 2008 +0000
    78.2 +++ b/tools/ioemu/vnc.c	Tue Feb 12 14:35:39 2008 +0000
    78.3 @@ -27,10 +27,12 @@
    78.4  #include <sys/stat.h>
    78.5  #include <sys/socket.h>
    78.6  #include <netinet/in.h>
    78.7 -#include <arpa/inet.h>
    78.8  #include "vl.h"
    78.9  #include "qemu_socket.h"
   78.10  #include <assert.h>
   78.11 +#ifdef CONFIG_STUBDOM
   78.12 +#include <netfront.h>
   78.13 +#endif
   78.14  
   78.15  /* The refresh interval starts at BASE.  If we scan the buffer and
   78.16     find no change, we increase by INC, up to MAX.  If the mouse moves
   78.17 @@ -2407,7 +2409,9 @@ int vnc_display_open(DisplayState *ds, c
   78.18  #ifndef NO_UNIX_SOCKETS
   78.19      struct sockaddr_un uaddr;
   78.20  #endif
   78.21 +#ifndef CONFIG_STUBDOM
   78.22      int reuse_addr, ret;
   78.23 +#endif
   78.24      socklen_t addrlen;
   78.25      const char *p;
   78.26      VncState *vs = ds ? (VncState *)ds->opaque : vnc_state;
   78.27 @@ -2539,6 +2543,15 @@ int vnc_display_open(DisplayState *ds, c
   78.28  	    return -1;
   78.29  	}
   78.30  
   78.31 +#ifdef CONFIG_STUBDOM
   78.32 +        {
   78.33 +            struct ip_addr ipaddr = { iaddr.sin_addr.s_addr };
   78.34 +            struct ip_addr netmask = { 0 };
   78.35 +            struct ip_addr gw = { 0 };
   78.36 +            networking_set_addr(&ipaddr, &netmask, &gw);
   78.37 +        }
   78.38 +#endif
   78.39 +
   78.40  	iaddr.sin_port = htons(ntohs(iaddr.sin_port) + 5900);
   78.41  
   78.42  	vs->lsock = socket(PF_INET, SOCK_STREAM, 0);
   78.43 @@ -2549,6 +2562,7 @@ int vnc_display_open(DisplayState *ds, c
   78.44  	    return -1;
   78.45  	}
   78.46  
   78.47 +#ifndef CONFIG_STUBDOM
   78.48  	reuse_addr = 1;
   78.49  	ret = setsockopt(vs->lsock, SOL_SOCKET, SO_REUSEADDR,
   78.50  			 (const char *)&reuse_addr, sizeof(reuse_addr));
   78.51 @@ -2560,6 +2574,7 @@ int vnc_display_open(DisplayState *ds, c
   78.52  	    vs->display = NULL;
   78.53  	    return -1;
   78.54  	}
   78.55 +#endif
   78.56      }
   78.57  
   78.58      while (bind(vs->lsock, addr, addrlen) == -1) {
   78.59 @@ -2590,6 +2605,7 @@ int vnc_display_open(DisplayState *ds, c
   78.60      return ntohs(iaddr.sin_port);
   78.61  }
   78.62  
   78.63 +#ifndef CONFIG_STUBDOM
   78.64  int vnc_start_viewer(int port)
   78.65  {
   78.66      int pid, i, open_max;
   78.67 @@ -2617,4 +2633,5 @@ int vnc_start_viewer(int port)
   78.68  	return pid;
   78.69      }
   78.70  }
   78.71 +#endif
   78.72  
    79.1 --- a/tools/ioemu/xenstore.c	Tue Feb 12 11:37:45 2008 +0000
    79.2 +++ b/tools/ioemu/xenstore.c	Tue Feb 12 14:35:39 2008 +0000
    79.3 @@ -11,8 +11,10 @@
    79.4  #include "vl.h"
    79.5  #include "block_int.h"
    79.6  #include <unistd.h>
    79.7 +#ifndef CONFIG_STUBDOM
    79.8  #include <sys/ipc.h>
    79.9  #include <sys/shm.h>
   79.10 +#endif
   79.11  #include <sys/types.h>
   79.12  #include <sys/stat.h>
   79.13  #include <fcntl.h>
   79.14 @@ -219,10 +221,18 @@ void xenstore_parse_domain_config(int do
   79.15          }
   79.16  
   79.17          /* open device now if media present */
   79.18 +#ifdef CONFIG_STUBDOM
   79.19 +        if (pasprintf(&buf, "%s/device/vbd/%s", path, e[i]) == -1)
   79.20 +            continue;
   79.21 +	if (bdrv_open2(bs, buf, 0 /* snapshot */, &bdrv_vbd) == 0) {
   79.22 +	    pstrcpy(bs->filename, sizeof(bs->filename), params);
   79.23 +	    continue;
   79.24 +	}
   79.25 +#endif
   79.26 +
   79.27          if (params[0]) {
   79.28              if (bdrv_open(bs, params, 0 /* snapshot */) < 0)
   79.29 -                fprintf(stderr, "qemu: could not open hard disk image '%s'\n",
   79.30 -                        params);
   79.31 +                fprintf(stderr, "qemu: could not open vbd '%s' or hard disk image '%s'\n", buf, params);
   79.32          }
   79.33      }
   79.34  
   79.35 @@ -265,6 +275,10 @@ extern int vga_ram_size, bios_size;
   79.36  
   79.37  void xenstore_process_logdirty_event(void)
   79.38  {
   79.39 +#ifdef CONFIG_STUBDOM
   79.40 +    /* XXX we just can't use shm. */
   79.41 +    return;
   79.42 +#else
   79.43      char *act;
   79.44      static char *active_path = NULL;
   79.45      static char *next_active_path = NULL;
   79.46 @@ -367,6 +381,7 @@ void xenstore_process_logdirty_event(voi
   79.47      /* Ack that we've switched */
   79.48      xs_write(xsh, XBT_NULL, active_path, act, len);
   79.49      free(act);
   79.50 +#endif
   79.51  }
   79.52  
   79.53  
    80.1 --- a/tools/libxc/Makefile	Tue Feb 12 11:37:45 2008 +0000
    80.2 +++ b/tools/libxc/Makefile	Tue Feb 12 14:35:39 2008 +0000
    80.3 @@ -5,10 +5,12 @@ MAJOR    = 3.2
    80.4  MINOR    = 0
    80.5  
    80.6  CTRL_SRCS-y       :=
    80.7 +ifneq ($(stubdom),y)
    80.8  CTRL_SRCS-y       += xc_core.c
    80.9  CTRL_SRCS-$(CONFIG_X86) += xc_core_x86.c
   80.10  CTRL_SRCS-$(CONFIG_IA64) += xc_core_ia64.c
   80.11  CTRL_SRCS-$(CONFIG_POWERPC) += xc_core_powerpc.c
   80.12 +endif
   80.13  CTRL_SRCS-y       += xc_domain.c
   80.14  CTRL_SRCS-y       += xc_evtchn.c
   80.15  CTRL_SRCS-y       += xc_misc.c
   80.16 @@ -19,21 +21,29 @@ CTRL_SRCS-y       += xc_private.c
   80.17  CTRL_SRCS-y       += xc_sedf.c
   80.18  CTRL_SRCS-y       += xc_csched.c
   80.19  CTRL_SRCS-y       += xc_tbuf.c
   80.20 +ifneq ($(stubdom),y)
   80.21  CTRL_SRCS-y       += xc_resume.c
   80.22 +endif
   80.23  CTRL_SRCS-$(CONFIG_X86) += xc_pagetab.c
   80.24 +ifneq ($(stubdom),y)
   80.25  CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c
   80.26  CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.c
   80.27  CTRL_SRCS-$(CONFIG_X86_Linux) += xc_ptrace.c xc_ptrace_core.c
   80.28  CTRL_SRCS-$(CONFIG_NetBSD) += xc_netbsd.c
   80.29 +endif
   80.30 +CTRL_SRCS-$(stubdom) += xc_minios.c
   80.31  
   80.32  GUEST_SRCS-y :=
   80.33  GUEST_SRCS-y += xg_private.c
   80.34 +ifneq ($(stubdom),y)
   80.35  GUEST_SRCS-$(CONFIG_MIGRATE) += xc_domain_restore.c xc_domain_save.c
   80.36  GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
   80.37 +endif
   80.38  
   80.39  VPATH = ../../xen/common/libelf
   80.40  CFLAGS += -I../../xen/common/libelf
   80.41  
   80.42 +ifneq ($(stubdom),y)
   80.43  GUEST_SRCS-y += libelf-tools.c libelf-loader.c
   80.44  GUEST_SRCS-y += libelf-dominfo.c libelf-relocate.c
   80.45  
   80.46 @@ -46,6 +56,7 @@ GUEST_SRCS-y += xc_dom_compat_linux.c
   80.47  GUEST_SRCS-$(CONFIG_X86)     += xc_dom_x86.c
   80.48  GUEST_SRCS-$(CONFIG_IA64)    += xc_dom_ia64.c
   80.49  GUEST_SRCS-$(CONFIG_POWERPC) += xc_dom_powerpc.c
   80.50 +endif
   80.51  
   80.52  -include $(XEN_TARGET_ARCH)/Makefile
   80.53  
   80.54 @@ -64,6 +75,10 @@ CFLAGS   += -Wp,-MD,.$(@F).d
   80.55  LDFLAGS  += -L.
   80.56  DEPS     = .*.d
   80.57  
   80.58 +ifneq ($(stubdom),y)
   80.59 +LDLIBS   = -lpthread
   80.60 +endif
   80.61 +
   80.62  CTRL_LIB_OBJS := $(patsubst %.c,%.o,$(CTRL_SRCS-y))
   80.63  CTRL_PIC_OBJS := $(patsubst %.c,%.opic,$(CTRL_SRCS-y))
   80.64  
   80.65 @@ -71,10 +86,14 @@ GUEST_LIB_OBJS := $(patsubst %.c,%.o,$(G
   80.66  GUEST_PIC_OBJS := $(patsubst %.c,%.opic,$(GUEST_SRCS-y))
   80.67  
   80.68  LIB := libxenctrl.a
   80.69 +ifneq ($(stubdom),y)
   80.70  LIB += libxenctrl.so libxenctrl.so.$(MAJOR) libxenctrl.so.$(MAJOR).$(MINOR)
   80.71 +endif
   80.72  
   80.73  LIB += libxenguest.a
   80.74 +ifneq ($(stubdom),y)
   80.75  LIB += libxenguest.so libxenguest.so.$(MAJOR) libxenguest.so.$(MAJOR).$(MINOR)
   80.76 +endif
   80.77  
   80.78  .PHONY: all
   80.79  all: build
   80.80 @@ -133,7 +152,7 @@ libxenctrl.so.$(MAJOR): libxenctrl.so.$(
   80.81  	ln -sf $< $@
   80.82  
   80.83  libxenctrl.so.$(MAJOR).$(MINOR): $(CTRL_PIC_OBJS)
   80.84 -	$(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ -lpthread
   80.85 +	$(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ $(LDLIBS)
   80.86  
   80.87  # libxenguest
   80.88  
   80.89 @@ -146,7 +165,7 @@ libxenguest.so.$(MAJOR): libxenguest.so.
   80.90  	ln -sf $< $@
   80.91  
   80.92  libxenguest.so.$(MAJOR).$(MINOR): $(GUEST_PIC_OBJS) libxenctrl.so
   80.93 -	$(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $(GUEST_PIC_OBJS) -lz -lxenctrl -lpthread
   80.94 +	$(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $(GUEST_PIC_OBJS) -lz -lxenctrl $(LDLIBS)
   80.95  
   80.96  -include $(DEPS)
   80.97  
    81.1 --- a/tools/libxc/ia64/Makefile	Tue Feb 12 11:37:45 2008 +0000
    81.2 +++ b/tools/libxc/ia64/Makefile	Tue Feb 12 14:35:39 2008 +0000
    81.3 @@ -1,3 +1,4 @@
    81.4 +ifneq ($(stubdom),y)
    81.5  CTRL_SRCS-y += ia64/xc_ia64_stubs.c
    81.6  
    81.7  GUEST_SRCS-y += ia64/xc_ia64_hvm_build.c
    81.8 @@ -8,6 +9,7 @@ GUEST_SRCS-y += ia64/xc_dom_ia64_util.c
    81.9  GUEST_SRCS-y += ia64/dom_fw_acpi.c
   81.10  
   81.11  DOMFW_SRCS_BASE := dom_fw_common.c dom_fw_domu.c dom_fw_asm.S
   81.12 +endif
   81.13  DOMFW_SRCS := $(addprefix ia64/, $(DOMFW_SRCS_BASE))
   81.14  $(DOMFW_SRCS):
   81.15  	ln -sf ../$(XEN_ROOT)/xen/arch/ia64/xen/$(@F) $@
    82.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.2 +++ b/tools/libxc/xc_minios.c	Tue Feb 12 14:35:39 2008 +0000
    82.3 @@ -0,0 +1,313 @@
    82.4 +/******************************************************************************
    82.5 + *
    82.6 + * Copyright 2007-2008 Samuel Thibault <samuel.thibault@eu.citrix.com>.
    82.7 + * All rights reserved.
    82.8 + * Use is subject to license terms.
    82.9 + *
   82.10 + * This program is free software; you can redistribute it and/or
   82.11 + * modify it under the terms of the GNU General Public License as
   82.12 + * published by the Free Software Foundation, version 2 of the
   82.13 + * License.
   82.14 + */
   82.15 +
   82.16 +#undef NDEBUG
   82.17 +#include <types.h>
   82.18 +#include <os.h>
   82.19 +#include <mm.h>
   82.20 +#include <lib.h>
   82.21 +#include <events.h>
   82.22 +#include <wait.h>
   82.23 +#include <sys/mman.h>
   82.24 +#include <errno.h>
   82.25 +
   82.26 +#include <xen/memory.h>
   82.27 +#include <xen/sys/evtchn.h>
   82.28 +#include <unistd.h>
   82.29 +#include <fcntl.h>
   82.30 +#include <stdio.h>
   82.31 +#include <assert.h>
   82.32 +#include <stdint.h>
   82.33 +#include <inttypes.h>
   82.34 +
   82.35 +#include "xc_private.h"
   82.36 +
   82.37 +extern struct wait_queue_head event_queue;
   82.38 +
   82.39 +int xc_interface_open(void)
   82.40 +{
   82.41 +    return 0;
   82.42 +}
   82.43 +
   82.44 +int xc_interface_close(int xc_handle)
   82.45 +{
   82.46 +    return 0;
   82.47 +}
   82.48 +
   82.49 +void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot,
   82.50 +                           xen_pfn_t *arr, int num)
   82.51 +{
   82.52 +    unsigned long pt_prot = 0;
   82.53 +#ifdef __ia64__
   82.54 +    /* TODO */
   82.55 +#else
   82.56 +    if (prot & PROT_READ)
   82.57 +	pt_prot = L1_PROT_RO;
   82.58 +    if (prot & PROT_WRITE)
   82.59 +	pt_prot = L1_PROT;
   82.60 +#endif
   82.61 +    return map_frames_ex(arr, num, 1, 0, 1, dom, 1, pt_prot);
   82.62 +}
   82.63 +
   82.64 +void *xc_map_foreign_range(int xc_handle, uint32_t dom,
   82.65 +                           int size, int prot,
   82.66 +                           unsigned long mfn)
   82.67 +{
   82.68 +    unsigned long pt_prot = 0;
   82.69 +    printf("xc_map_foreign_range(%lx, %d)\n", mfn, size);
   82.70 +#ifdef __ia64__
   82.71 +    /* TODO */
   82.72 +#else
   82.73 +    if (prot & PROT_READ)
   82.74 +	pt_prot = L1_PROT_RO;
   82.75 +    if (prot & PROT_WRITE)
   82.76 +	pt_prot = L1_PROT;
   82.77 +#endif
   82.78 +    assert(!(size % getpagesize()));
   82.79 +    return map_frames_ex(&mfn, size / getpagesize(), 0, 1, 1, dom, 0, pt_prot);
   82.80 +}
   82.81 +
   82.82 +int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
   82.83 +                          privcmd_mmap_entry_t *entries, int nr)
   82.84 +{
   82.85 +    printf("xc_map_foreign_ranges, TODO\n");
   82.86 +    do_exit();
   82.87 +}
   82.88 +
   82.89 +int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
   82.90 +{
   82.91 +    multicall_entry_t call;
   82.92 +    int i, ret;
   82.93 +
   82.94 +    call.op = hypercall->op;
   82.95 +    for (i = 0; i < sizeof(hypercall->arg) / sizeof(*hypercall->arg); i++)
   82.96 +	call.args[i] = hypercall->arg[i];
   82.97 +
   82.98 +    ret = HYPERVISOR_multicall(&call, 1);
   82.99 +
  82.100 +    if (ret < 0) {
  82.101 +	errno = -ret;
  82.102 +	return -1;
  82.103 +    }
  82.104 +    if (call.result < 0) {
  82.105 +        errno = -call.result;
  82.106 +        return -1;
  82.107 +    }
  82.108 +    return call.result;
  82.109 +}
  82.110 +
  82.111 +int xc_find_device_number(const char *name)
  82.112 +{
  82.113 +    printf("xc_find_device_number(%s)\n", name);
  82.114 +    do_exit();
  82.115 +}
  82.116 +
  82.117 +int xc_evtchn_open(void)
  82.118 +{
  82.119 +    int fd = alloc_fd(FTYPE_EVTCHN), i;
  82.120 +    for (i = 0; i < MAX_EVTCHN_PORTS; i++) {
  82.121 +	files[fd].evtchn.ports[i].port = -1;
  82.122 +        files[fd].evtchn.ports[i].bound = 0;
  82.123 +    }
  82.124 +    printf("evtchn_open() -> %d\n", fd);
  82.125 +    return fd;
  82.126 +}
  82.127 +
  82.128 +int xc_evtchn_close(int xce_handle)
  82.129 +{
  82.130 +    int i;
  82.131 +    for (i = 0; i < MAX_EVTCHN_PORTS; i++)
  82.132 +        if (files[xce_handle].evtchn.ports[i].bound)
  82.133 +            unbind_evtchn(files[xce_handle].evtchn.ports[i].port);
  82.134 +    files[xce_handle].type = FTYPE_NONE;
  82.135 +    return 0;
  82.136 +}
  82.137 +
  82.138 +int xc_evtchn_fd(int xce_handle)
  82.139 +{
  82.140 +    return xce_handle;
  82.141 +}
  82.142 +
  82.143 +int xc_evtchn_notify(int xce_handle, evtchn_port_t port)
  82.144 +{
  82.145 +    int ret;
  82.146 +
  82.147 +    ret = notify_remote_via_evtchn(port);
  82.148 +
  82.149 +    if (ret < 0) {
  82.150 +	errno = -ret;
  82.151 +	ret = -1;
  82.152 +    }
  82.153 +    return ret;
  82.154 +}
  82.155 +
  82.156 +/* XXX Note: This is not threadsafe */
  82.157 +static int port_alloc(int xce_handle) {
  82.158 +    int i;
  82.159 +    for (i= 0; i < MAX_EVTCHN_PORTS; i++)
  82.160 +	if (files[xce_handle].evtchn.ports[i].port == -1)
  82.161 +	    break;
  82.162 +    if (i == MAX_EVTCHN_PORTS) {
  82.163 +	printf("Too many ports in xc handle\n");
  82.164 +	errno = EMFILE;
  82.165 +	return -1;
  82.166 +    }
  82.167 +    files[xce_handle].evtchn.ports[i].pending = 0;
  82.168 +    return i;
  82.169 +}
  82.170 +
  82.171 +static void poke_port(int xce_handle, evtchn_port_t port)
  82.172 +{
  82.173 +    shared_info_t *s = HYPERVISOR_shared_info;
  82.174 +    printk("poking port %d\n", port);
  82.175 +    synch_set_bit(port, &s->evtchn_pending[0]);
  82.176 +    xc_evtchn_unmask(xce_handle, port);
  82.177 +}
  82.178 +
  82.179 +static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
  82.180 +{
  82.181 +    int xce_handle = (intptr_t) data;
  82.182 +    int i;
  82.183 +    assert(files[xce_handle].type == FTYPE_EVTCHN);
  82.184 +    mask_evtchn(port);
  82.185 +    for (i= 0; i < MAX_EVTCHN_PORTS; i++)
  82.186 +	if (files[xce_handle].evtchn.ports[i].port == port)
  82.187 +	    break;
  82.188 +    if (i == MAX_EVTCHN_PORTS) {
  82.189 +	printk("Unknown port for handle %d\n", xce_handle);
  82.190 +	return;
  82.191 +    }
  82.192 +    files[xce_handle].evtchn.ports[i].pending++;
  82.193 +    files[xce_handle].read = 1;
  82.194 +    wake_up(&event_queue);
  82.195 +}
  82.196 +
  82.197 +evtchn_port_or_error_t xc_evtchn_bind_unbound_port(int xce_handle, int domid)
  82.198 +{
  82.199 +    int ret, i;
  82.200 +    evtchn_port_t port;
  82.201 +
  82.202 +    assert(get_current() == main_thread);
  82.203 +    i = port_alloc(xce_handle);
  82.204 +    if (i == -1)
  82.205 +	return -1;
  82.206 +
  82.207 +    printf("xc_evtchn_bind_unbound_port(%d)", domid);
  82.208 +    ret = evtchn_alloc_unbound(domid, evtchn_handler, (void*)(intptr_t)xce_handle, &port);
  82.209 +    printf(" = %d\n", ret);
  82.210 +
  82.211 +    if (ret < 0) {
  82.212 +	errno = -ret;
  82.213 +	return -1;
  82.214 +    }
  82.215 +    files[xce_handle].evtchn.ports[i].bound = 1;
  82.216 +    files[xce_handle].evtchn.ports[i].port = port;
  82.217 +    return port;
  82.218 +}
  82.219 +
  82.220 +evtchn_port_or_error_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
  82.221 +    evtchn_port_t remote_port)
  82.222 +{
  82.223 +    evtchn_port_t local_port;
  82.224 +    int ret, i;
  82.225 +
  82.226 +    assert(get_current() == main_thread);
  82.227 +    i = port_alloc(xce_handle);
  82.228 +    if (i == -1)
  82.229 +	return -1;
  82.230 +
  82.231 +    printf("xc_evtchn_bind_interdomain(%d, %"PRId32")", domid, remote_port);
  82.232 +    ret = evtchn_bind_interdomain(domid, remote_port, evtchn_handler, (void*)(intptr_t)xce_handle, &local_port);
  82.233 +    printf(" = %d\n", ret);
  82.234 +
  82.235 +    if (ret < 0) {
  82.236 +	errno = -ret;
  82.237 +	return -1;
  82.238 +    }
  82.239 +    files[xce_handle].evtchn.ports[i].bound = 1;
  82.240 +    files[xce_handle].evtchn.ports[i].port = local_port;
  82.241 +/* Poke port on start: HVM won't send an event for the very first request since
  82.242 + * we were not ready yet */
  82.243 +    poke_port(xce_handle, local_port);
  82.244 +    return local_port;
  82.245 +}
  82.246 +
  82.247 +int xc_evtchn_unbind(int xce_handle, evtchn_port_t port)
  82.248 +{
  82.249 +    int i;
  82.250 +    for (i = 0; i < MAX_EVTCHN_PORTS; i++)
  82.251 +	if (files[xce_handle].evtchn.ports[i].port == port) {
  82.252 +	    files[xce_handle].evtchn.ports[i].port = -1;
  82.253 +	    break;
  82.254 +	}
  82.255 +    if (i == MAX_EVTCHN_PORTS)
  82.256 +	printf("Warning: couldn't find port %"PRId32" for xc handle %x\n", port, xce_handle);
  82.257 +    files[xce_handle].evtchn.ports[i].bound = 0;
  82.258 +    unbind_evtchn(port);
  82.259 +    return 0;
  82.260 +}
  82.261 +
  82.262 +evtchn_port_or_error_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq)
  82.263 +{
  82.264 +    evtchn_port_t port;
  82.265 +    int i;
  82.266 +
  82.267 +    assert(get_current() == main_thread);
  82.268 +    i = port_alloc(xce_handle);
  82.269 +    if (i == -1)
  82.270 +	return -1;
  82.271 +
  82.272 +    printf("xc_evtchn_bind_virq(%d)", virq);
  82.273 +    port = bind_virq(virq, evtchn_handler, (void*)(intptr_t)xce_handle);
  82.274 +
  82.275 +    if (port < 0) {
  82.276 +	errno = -port;
  82.277 +	return -1;
  82.278 +    }
  82.279 +    files[xce_handle].evtchn.ports[i].bound = 1;
  82.280 +    files[xce_handle].evtchn.ports[i].port = port;
  82.281 +    return port;
  82.282 +}
  82.283 +
  82.284 +evtchn_port_or_error_t xc_evtchn_pending(int xce_handle)
  82.285 +{
  82.286 +    int i;
  82.287 +    unsigned long flags;
  82.288 +    local_irq_save(flags);
  82.289 +    for (i = 0; i < MAX_EVTCHN_PORTS; i++) {
  82.290 +	evtchn_port_t port = files[xce_handle].evtchn.ports[i].port;
  82.291 +	if (port != -1 && files[xce_handle].evtchn.ports[i].pending) {
  82.292 +	    files[xce_handle].evtchn.ports[i].pending--;
  82.293 +	    local_irq_restore(flags);
  82.294 +	    return port;
  82.295 +	}
  82.296 +    }
  82.297 +    files[xce_handle].read = 0;
  82.298 +    local_irq_restore(flags);
  82.299 +    return -1;
  82.300 +}
  82.301 +
  82.302 +int xc_evtchn_unmask(int xce_handle, evtchn_port_t port)
  82.303 +{
  82.304 +    unmask_evtchn(port);
  82.305 +    return 0;
  82.306 +}
  82.307 +
  82.308 +/*
  82.309 + * Local variables:
  82.310 + * mode: C
  82.311 + * c-set-style: "BSD"
  82.312 + * c-basic-offset: 4
  82.313 + * tab-width: 4
  82.314 + * indent-tabs-mode: nil
  82.315 + * End:
  82.316 + */