debuggers.hg
changeset 17066: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>
- 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>
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 + */