ia64/xen-unstable

changeset 17885:0034766b45c2

merge with xen-unstable.hg
author Isaku Yamahata <yamahata@valinux.co.jp>
date Thu Jun 19 12:46:26 2008 +0900 (2008-06-19)
parents 1201c7657832 b55f6d42668d
children cfbc535ebf6f
files xen/drivers/acpi/utglobal.c
line diff
     1.1 --- a/.hgignore	Tue Jun 10 16:00:33 2008 +0900
     1.2 +++ b/.hgignore	Thu Jun 19 12:46:26 2008 +0900
     1.3 @@ -1,6 +1,7 @@
     1.4  .*\.a$
     1.5  .*\.cmi$
     1.6  .*\.cmo$
     1.7 +.*\.cmx$
     1.8  .*\.d$
     1.9  .*\.o$
    1.10  .*\.opic$
    1.11 @@ -62,6 +63,7 @@
    1.12  ^extras/mini-os/h/hypervisor-ifs$
    1.13  ^extras/mini-os/h/xen-public$
    1.14  ^extras/mini-os/mini-os.*$
    1.15 +^extras/mini-os/*-stubdom.*$
    1.16  ^install/.*$
    1.17  ^linux-[^/]*-paravirt/.*$
    1.18  ^linux-2.6[^/]*/.*$
    1.19 @@ -88,10 +90,13 @@
    1.20  ^stubdom/ioemu$
    1.21  ^stubdom/libxc$
    1.22  ^stubdom/lwip-.*$
    1.23 -^stubdom/mini-os$
    1.24 +^stubdom/mini-os-.*$
    1.25  ^stubdom/newlib-.*$
    1.26  ^stubdom/pciutils-.*$
    1.27  ^stubdom/zlib-.*$
    1.28 +^stubdom/grub-cvs$
    1.29 +^stubdom/grub/stage2$
    1.30 +^stubdom/grub/netboot$
    1.31  ^tools/.*/TAGS$
    1.32  ^tools/.*/build/lib.*/.*\.py$
    1.33  ^tools/blktap/Makefile\.smh$
     2.1 --- a/buildconfigs/select-repository	Tue Jun 10 16:00:33 2008 +0900
     2.2 +++ b/buildconfigs/select-repository	Thu Jun 19 12:46:26 2008 +0900
     2.3 @@ -32,31 +32,38 @@ if [ X"${LINUX_SRC_PATH}" != X ] ; then
     2.4      IFS="$IFS_saved"
     2.5  fi
     2.6  
     2.7 -XEN=$(hg -R ${XEN_ROOT} path default)
     2.8 -if [ $? -ne 0 ] || [ X"$XEN" = "X" ] ; then
     2.9 -    echo "$ME: Unable to determine Xen repository parent." 1>&2
    2.10 -    exit 1;
    2.11 +if [ -d ${XEN_ROOT}/.hgxxx ] ; then
    2.12 +    XEN=$(hg -R ${XEN_ROOT} path default)
    2.13 +    if [ $? -ne 0 ] || [ X"$XEN" = "X" ] ; then
    2.14 +	echo "$ME: Unable to determine Xen repository parent." 1>&2
    2.15 +	exit 1;
    2.16 +    fi
    2.17 +
    2.18 +    BASE=$(dirname ${XEN})
    2.19 +    if [ $? -ne 0 ] || [ X"$BASE" = "X" ] ; then
    2.20 +	echo "$ME: Unable to determine Xen repository base." 1>&2
    2.21 +	exit 1;
    2.22 +    fi
    2.23 +    if [ -d "$XEN" ] && [ ! -d "$BASE/$REPO" ] ; then
    2.24 +	echo "$ME: No such dir: $BASE/$REPO" 1>&2
    2.25 +	exit 1
    2.26 +    fi
    2.27 +
    2.28 +    echo "$ME: Found ${BASE}/${REPO}" 1>&2
    2.29 +
    2.30 +    # If ${BASE}/${REPO} is a local directory then prepend file:// so that
    2.31 +    # the test in src.hg-clone will fail and we will clone instead of
    2.32 +    # linking this repository. We only want to link repositories which
    2.33 +    # were found via LINUX_SRC_PATH.
    2.34 +    if [ -d "${BASE}/${REPO}" ] ; then
    2.35 +	echo "file://${BASE}/${REPO}"
    2.36 +    else
    2.37 +	echo ${BASE}/${REPO}
    2.38 +    fi
    2.39 +else
    2.40 +    echo "Unable to determine path to Linux source tree." 1>&2
    2.41 +    echo "Falling back to linux-2.6.18-xen Mercurial repository." 1>&2
    2.42 +    echo http://xenbits.xensource.com/linux-2.6.18-xen.hg
    2.43  fi
    2.44  
    2.45 -BASE=$(dirname ${XEN})
    2.46 -if [ $? -ne 0 ] || [ X"$BASE" = "X" ] ; then
    2.47 -    echo "$ME: Unable to determine Xen repository base." 1>&2
    2.48 -    exit 1;
    2.49 -fi
    2.50 -if [ -d "$XEN" ] && [ ! -d "$BASE/$REPO" ] ; then
    2.51 -    echo "$ME: No such dir: $BASE/$REPO" 1>&2
    2.52 -    exit 1
    2.53 -fi
    2.54 -
    2.55 -echo "$ME: Found ${BASE}/${REPO}" 1>&2
    2.56 -
    2.57 -# If ${BASE}/${REPO} is a local directory then prepend file:// so that
    2.58 -# the test in src.hg-clone will fail and we will clone instead of
    2.59 -# linking this repository. We only want to link repositories which
    2.60 -# were found via LINUX_SRC_PATH.
    2.61 -if [ -d "${BASE}/${REPO}" ] ; then
    2.62 -    echo "file://${BASE}/${REPO}"
    2.63 -else
    2.64 -    echo ${BASE}/${REPO}
    2.65 -fi
    2.66  exit 0
     3.1 --- a/extras/mini-os/Makefile	Tue Jun 10 16:00:33 2008 +0900
     3.2 +++ b/extras/mini-os/Makefile	Thu Jun 19 12:46:26 2008 +0900
     3.3 @@ -6,6 +6,7 @@
     3.4  
     3.5  export XEN_ROOT = ../..
     3.6  include $(XEN_ROOT)/Config.mk
     3.7 +OBJ_DIR ?= $(CURDIR)
     3.8  
     3.9  ifneq ($(stubdom),y)
    3.10  include Config.mk
    3.11 @@ -20,7 +21,7 @@ include minios.mk
    3.12  # Define some default flags for linking.
    3.13  LDLIBS := 
    3.14  APP_LDLIBS := 
    3.15 -LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
    3.16 +LDARCHLIB := -L$(OBJ_DIR)/$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
    3.17  LDFLAGS_FINAL := -T $(TARGET_ARCH_DIR)/minios-$(XEN_TARGET_ARCH).lds
    3.18  
    3.19  # Prefix for global API names. All other symbols are localised before
    3.20 @@ -35,14 +36,14 @@ SUBDIRS := lib xenbus console
    3.21  
    3.22  # The common mini-os objects to build.
    3.23  APP_OBJS :=
    3.24 -OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
    3.25 -OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c))
    3.26 -OBJS += $(patsubst %.c,%.o,$(wildcard xenbus/*.c))
    3.27 -OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c))
    3.28 +OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard *.c))
    3.29 +OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard lib/*.c))
    3.30 +OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard xenbus/*.c))
    3.31 +OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard console/*.c))
    3.32  
    3.33  
    3.34  .PHONY: default
    3.35 -default: $(TARGET)
    3.36 +default: $(OBJ_DIR)/$(TARGET)
    3.37  
    3.38  # Create special architecture specific links. The function arch_links
    3.39  # has to be defined in arch.mk (see include above).
    3.40 @@ -57,7 +58,7 @@ links:	$(ARCH_LINKS)
    3.41  
    3.42  .PHONY: arch_lib
    3.43  arch_lib:
    3.44 -	$(MAKE) --directory=$(TARGET_ARCH_DIR) || exit 1;
    3.45 +	$(MAKE) --directory=$(TARGET_ARCH_DIR) OBJ_DIR=$(OBJ_DIR)/$(TARGET_ARCH_DIR) || exit 1;
    3.46  
    3.47  ifeq ($(lwip),y)
    3.48  # lwIP library
    3.49 @@ -66,14 +67,14 @@ LWC	:= $(filter-out %6.c %ip6_addr.c %et
    3.50  LWC	+= lwip-arch.c lwip-net.c
    3.51  LWO	:= $(patsubst %.c,%.o,$(LWC))
    3.52  
    3.53 -lwip.a: $(LWO)
    3.54 +$(OBJ_DIR)/lwip.a: $(LWO)
    3.55  	$(RM) $@
    3.56  	$(AR) cqs $@ $^
    3.57  
    3.58 -OBJS += lwip.a
    3.59 +OBJS += $(OBJ_DIR)/lwip.a
    3.60  endif
    3.61  
    3.62 -OBJS := $(filter-out main.o lwip%.o $(LWO), $(OBJS))
    3.63 +OBJS := $(filter-out $(OBJ_DIR)/lwip%.o $(LWO), $(OBJS))
    3.64  
    3.65  ifeq ($(libc),y)
    3.66  APP_LDLIBS += -L$(XEN_ROOT)/stubdom/libxc -whole-archive -lxenguest -lxenctrl -no-whole-archive
    3.67 @@ -84,14 +85,14 @@ LDLIBS += -lc
    3.68  endif
    3.69  
    3.70  ifneq ($(APP_OBJS)-$(lwip),-y)
    3.71 -OBJS := $(filter-out daytime.o, $(OBJS))
    3.72 +OBJS := $(filter-out $(OBJ_DIR)/daytime.o, $(OBJS))
    3.73  endif
    3.74  
    3.75 -$(TARGET)_app.o: $(APP_OBJS) app.lds
    3.76 -	$(LD) -r -d $(LDFLAGS) $^ $(APP_LDLIBS) --undefined app_main -o $@
    3.77 +$(OBJ_DIR)/$(TARGET)_app.o: $(APP_OBJS) app.lds
    3.78 +	$(LD) -r -d $(LDFLAGS) $^ $(APP_LDLIBS) --undefined main -o $@
    3.79  
    3.80 -$(TARGET): links $(OBJS) $(TARGET)_app.o arch_lib
    3.81 -	$(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(TARGET)_app.o $(OBJS) $(LDARCHLIB) $(LDLIBS) -o $@.o
    3.82 +$(OBJ_DIR)/$(TARGET): links $(OBJS) $(OBJ_DIR)/$(TARGET)_app.o arch_lib
    3.83 +	$(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJ_DIR)/$(TARGET)_app.o $(OBJS) $(LDARCHLIB) $(LDLIBS) -o $@.o
    3.84  	$(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o
    3.85  	$(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@
    3.86  	gzip -f -9 -c $@ >$@.gz
    3.87 @@ -99,15 +100,15 @@ endif
    3.88  .PHONY: clean arch_clean
    3.89  
    3.90  arch_clean:
    3.91 -	$(MAKE) --directory=$(TARGET_ARCH_DIR) clean || exit 1;
    3.92 +	$(MAKE) --directory=$(TARGET_ARCH_DIR) OBJ_DIR=$(OBJ_DIR)/$(TARGET_ARCH_DIR) clean || exit 1;
    3.93  
    3.94  clean:	arch_clean
    3.95 -	for dir in $(SUBDIRS); do \
    3.96 +	for dir in $(addprefix $(OBJ_DIR)/,$(SUBDIRS)); do \
    3.97  		rm -f $$dir/*.o; \
    3.98  	done
    3.99 -	rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz
   3.100 -	find . -type l | xargs rm -f
   3.101 -	$(RM) lwip.a $(LWO)
   3.102 +	rm -f $(OBJ_DIR)/*.o *~ $(OBJ_DIR)/core $(OBJ_DIR)/$(TARGET).elf $(OBJ_DIR)/$(TARGET).raw $(OBJ_DIR)/$(TARGET) $(OBJ_DIR)/$(TARGET).gz
   3.103 +	find . $(OBJ_DIR) -type l | xargs rm -f
   3.104 +	$(RM) $(OBJ_DIR)/lwip.a $(LWO)
   3.105  	rm -f tags TAGS
   3.106  
   3.107  
     4.1 --- a/extras/mini-os/arch/ia64/Makefile	Tue Jun 10 16:00:33 2008 +0900
     4.2 +++ b/extras/mini-os/arch/ia64/Makefile	Thu Jun 19 12:46:26 2008 +0900
     4.3 @@ -40,12 +40,13 @@ ARCH_OBJS += __umoddi3.o
     4.4  ARCH_OBJS += __udivdi3.o
     4.5  ARCH_OBJS += __udivsi3.o
     4.6  ARCH_OBJS += __divdi3.o
     4.7 +ARCH_OBJS := $(addprefix $(OBJ_DIR)/,$(ARCH_OBJS))
     4.8  
     4.9  GEN_OFF_SRC := gen_off.c
    4.10  GEN_OFF_ASM := gen_off.s
    4.11  GEN_OFF_H   := $(MINI-OS_ROOT)/include/$(ARCH_INC)/offsets.h
    4.12  
    4.13 -all: $(ARCH_LIB)
    4.14 +all: $(OBJ_DIR)/$(ARCH_LIB)
    4.15  
    4.16  $(GEN_OFF_ASM): $(GEN_OFF_SRC)
    4.17  	$(CC) -S -o $@ $(CPPFLAGS) $<
    4.18 @@ -53,10 +54,10 @@ all: $(ARCH_LIB)
    4.19  $(GEN_OFF_H): $(GEN_OFF_ASM)
    4.20  	sed -ne "/^->/ {s/->/#define /; p}" < $< > $@
    4.21  
    4.22 -$(ARCH_LIB): $(GEN_OFF_H) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
    4.23 +$(OBJ_DIR)/$(ARCH_LIB): $(GEN_OFF_H) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
    4.24  	$(AR) rv $(ARCH_LIB) $(ARCH_OBJS)
    4.25  
    4.26  clean:
    4.27 -	rm -f $(ARCH_LIB) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
    4.28 +	rm -f $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
    4.29  	rm -f $(GEN_OFF_ASM)
    4.30  	rm -f $(GEN_OFF_H)
     5.1 --- a/extras/mini-os/arch/ia64/common.c	Tue Jun 10 16:00:33 2008 +0900
     5.2 +++ b/extras/mini-os/arch/ia64/common.c	Thu Jun 19 12:46:26 2008 +0900
     5.3 @@ -236,6 +236,12 @@ arch_init(start_info_t *si)
     5.4  }
     5.5  
     5.6  void
     5.7 +arch_fini(void)
     5.8 +{
     5.9 +	/* TODO */
    5.10 +}
    5.11 +
    5.12 +void
    5.13  arch_print_info(void)
    5.14  {
    5.15  	int major, minor;
     6.1 --- a/extras/mini-os/arch/ia64/time.c	Tue Jun 10 16:00:33 2008 +0900
     6.2 +++ b/extras/mini-os/arch/ia64/time.c	Thu Jun 19 12:46:26 2008 +0900
     6.3 @@ -280,3 +280,9 @@ init_time(void)
     6.4  	ia64_set_itm(new);
     6.5  	ia64_srlz_d();
     6.6  }
     6.7 +
     6.8 +void
     6.9 +fini_time(void)
    6.10 +{
    6.11 +	/* TODO */
    6.12 +}
     7.1 --- a/extras/mini-os/arch/x86/Makefile	Tue Jun 10 16:00:33 2008 +0900
     7.2 +++ b/extras/mini-os/arch/x86/Makefile	Thu Jun 19 12:46:26 2008 +0900
     7.3 @@ -17,15 +17,15 @@ include ../../minios.mk
     7.4  ARCH_SRCS := $(wildcard *.c)
     7.5  
     7.6  # The objects built from the sources.
     7.7 -ARCH_OBJS := $(patsubst %.c,%.o,$(ARCH_SRCS))
     7.8 +ARCH_OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(ARCH_SRCS))
     7.9  
    7.10 -all: $(ARCH_LIB)
    7.11 +all: $(OBJ_DIR)/$(ARCH_LIB)
    7.12  
    7.13  # $(HEAD_ARCH_OBJ) is only build here, needed on linking
    7.14  # in ../../Makefile.
    7.15 -$(ARCH_LIB): $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
    7.16 -	$(AR) rv $(ARCH_LIB) $(ARCH_OBJS)
    7.17 +$(OBJ_DIR)/$(ARCH_LIB): $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
    7.18 +	$(AR) rv $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS)
    7.19  
    7.20  clean:
    7.21 -	rm -f $(ARCH_LIB) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
    7.22 +	rm -f $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
    7.23  
     8.1 --- a/extras/mini-os/arch/x86/mm.c	Tue Jun 10 16:00:33 2008 +0900
     8.2 +++ b/extras/mini-os/arch/x86/mm.c	Thu Jun 19 12:46:26 2008 +0900
     8.3 @@ -59,7 +59,7 @@ void new_pt_frame(unsigned long *pt_pfn,
     8.4  {   
     8.5      pgentry_t *tab = (pgentry_t *)start_info.pt_base;
     8.6      unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn); 
     8.7 -    unsigned long prot_e, prot_t;
     8.8 +    pgentry_t prot_e, prot_t;
     8.9      mmu_update_t mmu_updates[1];
    8.10      
    8.11      prot_e = prot_t = 0;
    8.12 @@ -69,7 +69,7 @@ void new_pt_frame(unsigned long *pt_pfn,
    8.13  
    8.14      /* We need to clear the page, otherwise we might fail to map it
    8.15         as a page table page */
    8.16 -    memset((unsigned long*)pfn_to_virt(*pt_pfn), 0, PAGE_SIZE);  
    8.17 +    memset((void*) pt_page, 0, PAGE_SIZE);  
    8.18   
    8.19      switch ( level )
    8.20      {
    8.21 @@ -99,7 +99,7 @@ void new_pt_frame(unsigned long *pt_pfn,
    8.22  #endif
    8.23      tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
    8.24  
    8.25 -    mmu_updates[0].ptr = ((pgentry_t)tab[l2_table_offset(pt_page)] & PAGE_MASK) + 
    8.26 +    mmu_updates[0].ptr = (tab[l2_table_offset(pt_page)] & PAGE_MASK) + 
    8.27                           sizeof(pgentry_t) * l1_table_offset(pt_page);
    8.28      mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | 
    8.29                           (prot_e & ~_PAGE_RW);
    8.30 @@ -372,7 +372,7 @@ static pgentry_t *get_pgt(unsigned long 
    8.31      return &tab[offset];
    8.32  }
    8.33  
    8.34 -static pgentry_t *need_pgt(unsigned long addr)
    8.35 +pgentry_t *need_pgt(unsigned long addr)
    8.36  {
    8.37      unsigned long mfn;
    8.38      pgentry_t *tab;
    8.39 @@ -474,7 +474,7 @@ void do_map_frames(unsigned long addr,
    8.40                  if (!pgt || !(addr & L1_MASK))
    8.41                      pgt = need_pgt(addr);
    8.42  		mmu_updates[i].ptr = virt_to_mach(pgt);
    8.43 -		mmu_updates[i].val = ((f[(done + i) * stride] + (done + i) * increment) << PAGE_SHIFT) | prot;
    8.44 +		mmu_updates[i].val = ((pgentry_t)(f[(done + i) * stride] + (done + i) * increment) << PAGE_SHIFT) | prot;
    8.45  	    }
    8.46  
    8.47  	    rc = HYPERVISOR_mmu_update(mmu_updates, todo, NULL, id);
     9.1 --- a/extras/mini-os/arch/x86/setup.c	Tue Jun 10 16:00:33 2008 +0900
     9.2 +++ b/extras/mini-os/arch/x86/setup.c	Thu Jun 19 12:46:26 2008 +0900
     9.3 @@ -100,6 +100,16 @@ arch_init(start_info_t *si)
     9.4  }
     9.5  
     9.6  void
     9.7 +arch_fini(void)
     9.8 +{
     9.9 +#ifdef __i386__
    9.10 +	HYPERVISOR_set_callbacks(0, 0, 0, 0);
    9.11 +#else
    9.12 +	HYPERVISOR_set_callbacks(0, 0, 0);
    9.13 +#endif
    9.14 +}
    9.15 +
    9.16 +void
    9.17  arch_print_info(void)
    9.18  {
    9.19  	printk("  stack:      %p-%p\n", stack, stack + sizeof(stack));
    10.1 --- a/extras/mini-os/arch/x86/time.c	Tue Jun 10 16:00:33 2008 +0900
    10.2 +++ b/extras/mini-os/arch/x86/time.c	Thu Jun 19 12:46:26 2008 +0900
    10.3 @@ -222,10 +222,17 @@ static void timer_handler(evtchn_port_t 
    10.4  
    10.5  
    10.6  
    10.7 +static evtchn_port_t port;
    10.8  void init_time(void)
    10.9  {
   10.10 -    evtchn_port_t port;
   10.11      printk("Initialising timer interface\n");
   10.12      port = bind_virq(VIRQ_TIMER, &timer_handler, NULL);
   10.13      unmask_evtchn(port);
   10.14  }
   10.15 +
   10.16 +void fini_time(void)
   10.17 +{
   10.18 +    /* Clear any pending timer */
   10.19 +    HYPERVISOR_set_timer_op(0);
   10.20 +    unbind_evtchn(port);
   10.21 +}
    11.1 --- a/extras/mini-os/arch/x86/traps.c	Tue Jun 10 16:00:33 2008 +0900
    11.2 +++ b/extras/mini-os/arch/x86/traps.c	Thu Jun 19 12:46:26 2008 +0900
    11.3 @@ -268,3 +268,7 @@ void trap_init(void)
    11.4      HYPERVISOR_set_trap_table(trap_table);    
    11.5  }
    11.6  
    11.7 +void trap_fini(void)
    11.8 +{
    11.9 +    HYPERVISOR_set_trap_table(NULL);
   11.10 +}
    12.1 --- a/extras/mini-os/arch/x86/x86_32.S	Tue Jun 10 16:00:33 2008 +0900
    12.2 +++ b/extras/mini-os/arch/x86/x86_32.S	Thu Jun 19 12:46:26 2008 +0900
    12.3 @@ -8,7 +8,7 @@
    12.4  	.ascii	",VIRT_BASE=0x0" /* &_text from minios_x86_32.lds */
    12.5  	.ascii	",ELF_PADDR_OFFSET=0x0"
    12.6  	.ascii	",HYPERCALL_PAGE=0x2"
    12.7 -	.ascii	",PAE=yes"
    12.8 +	.ascii	",PAE=yes[extended-cr3]"
    12.9  	.ascii	",LOADER=generic"
   12.10  	.byte	0
   12.11  .text
    13.1 --- a/extras/mini-os/blkfront.c	Tue Jun 10 16:00:33 2008 +0900
    13.2 +++ b/extras/mini-os/blkfront.c	Thu Jun 19 12:46:26 2008 +0900
    13.3 @@ -63,7 +63,8 @@ void blkfront_handler(evtchn_port_t port
    13.4      struct blkfront_dev *dev = data;
    13.5      int fd = dev->fd;
    13.6  
    13.7 -    files[fd].read = 1;
    13.8 +    if (fd != -1)
    13.9 +        files[fd].read = 1;
   13.10  #endif
   13.11      wake_up(&blkfront_queue);
   13.12  }
   13.13 @@ -105,6 +106,9 @@ struct blkfront_dev *init_blkfront(char 
   13.14      dev = malloc(sizeof(*dev));
   13.15      memset(dev, 0, sizeof(*dev));
   13.16      dev->nodename = strdup(nodename);
   13.17 +#ifdef HAVE_LIBC
   13.18 +    dev->fd = -1;
   13.19 +#endif
   13.20  
   13.21      snprintf(path, sizeof(path), "%s/backend-id", nodename);
   13.22      dev->dom = xenbus_read_integer(path); 
   13.23 @@ -238,8 +242,16 @@ void shutdown_blkfront(struct blkfront_d
   13.24      err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
   13.25      xenbus_wait_for_value(path, "6", &dev->events);
   13.26  
   13.27 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
   13.28 +    xenbus_wait_for_value(path, "2", &dev->events);
   13.29 +
   13.30      xenbus_unwatch_path(XBT_NIL, path);
   13.31  
   13.32 +    snprintf(path, sizeof(path), "%s/ring-ref", nodename);
   13.33 +    xenbus_rm(XBT_NIL, path);
   13.34 +    snprintf(path, sizeof(path), "%s/event-channel", nodename);
   13.35 +    xenbus_rm(XBT_NIL, path);
   13.36 +
   13.37      free_blkfront(dev);
   13.38  }
   13.39  
   13.40 @@ -323,14 +335,33 @@ void blkfront_aio(struct blkfront_aiocb 
   13.41      if(notify) notify_remote_via_evtchn(dev->evtchn);
   13.42  }
   13.43  
   13.44 -void blkfront_aio_write(struct blkfront_aiocb *aiocbp)
   13.45 +static void blkfront_aio_cb(struct blkfront_aiocb *aiocbp, int ret)
   13.46  {
   13.47 -    blkfront_aio(aiocbp, 1);
   13.48 +    aiocbp->data = (void*) 1;
   13.49  }
   13.50  
   13.51 -void blkfront_aio_read(struct blkfront_aiocb *aiocbp)
   13.52 +void blkfront_io(struct blkfront_aiocb *aiocbp, int write)
   13.53  {
   13.54 -    blkfront_aio(aiocbp, 0);
   13.55 +    unsigned long flags;
   13.56 +    ASSERT(!aiocbp->aio_cb);
   13.57 +    aiocbp->aio_cb = blkfront_aio_cb;
   13.58 +    blkfront_aio(aiocbp, write);
   13.59 +    aiocbp->data = NULL;
   13.60 +
   13.61 +    local_irq_save(flags);
   13.62 +    DEFINE_WAIT(w);
   13.63 +    while (1) {
   13.64 +	blkfront_aio_poll(aiocbp->aio_dev);
   13.65 +	if (aiocbp->data)
   13.66 +	    break;
   13.67 +
   13.68 +	add_waiter(w, blkfront_queue);
   13.69 +	local_irq_restore(flags);
   13.70 +	schedule();
   13.71 +	local_irq_save(flags);
   13.72 +    }
   13.73 +    remove_waiter(w);
   13.74 +    local_irq_restore(flags);
   13.75  }
   13.76  
   13.77  static void blkfront_push_operation(struct blkfront_dev *dev, uint8_t op, uint64_t id)
   13.78 @@ -397,8 +428,10 @@ int blkfront_aio_poll(struct blkfront_de
   13.79  
   13.80  moretodo:
   13.81  #ifdef HAVE_LIBC
   13.82 -    files[dev->fd].read = 0;
   13.83 -    mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
   13.84 +    if (dev->fd != -1) {
   13.85 +        files[dev->fd].read = 0;
   13.86 +        mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
   13.87 +    }
   13.88  #endif
   13.89  
   13.90      rp = dev->ring.sring->rsp_prod;
    14.1 --- a/extras/mini-os/console/console.c	Tue Jun 10 16:00:33 2008 +0900
    14.2 +++ b/extras/mini-os/console/console.c	Thu Jun 19 12:46:26 2008 +0900
    14.3 @@ -49,17 +49,13 @@
    14.4     of standard dom0 handled console */
    14.5  #define USE_XEN_CONSOLE
    14.6  
    14.7 -/* Low level functions defined in xencons_ring.c */
    14.8 -extern int xencons_ring_init(void);
    14.9 -extern int xencons_ring_send(const char *data, unsigned len);
   14.10 -extern int xencons_ring_send_no_notify(const char *data, unsigned len);
   14.11 -
   14.12  
   14.13  /* If console not initialised the printk will be sent to xen serial line 
   14.14     NOTE: you need to enable verbose in xen/Rules.mk for it to work. */
   14.15  static int console_initialised = 0;
   14.16  
   14.17  
   14.18 +#ifndef HAVE_LIBC
   14.19  void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
   14.20  {
   14.21      if(len > 0)
   14.22 @@ -77,6 +73,7 @@ void xencons_tx(void)
   14.23  {
   14.24      /* Do nothing, handled by _rx */
   14.25  }
   14.26 +#endif
   14.27  
   14.28  
   14.29  void console_print(char *data, int length)
   14.30 @@ -153,3 +150,8 @@ void init_console(void)
   14.31      /* This is also required to notify the daemon */
   14.32      printk("done.\n");
   14.33  }
   14.34 +
   14.35 +void fini_console(void)
   14.36 +{
   14.37 +    /* Destruct the console and get the parameters of the restarted one */
   14.38 +}
    15.1 --- a/extras/mini-os/console/xencons_ring.c	Tue Jun 10 16:00:33 2008 +0900
    15.2 +++ b/extras/mini-os/console/xencons_ring.c	Thu Jun 19 12:46:26 2008 +0900
    15.3 @@ -8,6 +8,7 @@
    15.4  #include <xenbus.h>
    15.5  #include <xen/io/console.h>
    15.6  
    15.7 +DECLARE_WAIT_QUEUE_HEAD(console_queue);
    15.8  
    15.9  static inline struct xencons_interface *xencons_interface(void)
   15.10  {
   15.11 @@ -52,6 +53,9 @@ int xencons_ring_send(const char *data, 
   15.12  
   15.13  static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *ign)
   15.14  {
   15.15 +#ifdef HAVE_LIBC
   15.16 +        wake_up(&console_queue);
   15.17 +#else
   15.18  	struct xencons_interface *intf = xencons_interface();
   15.19  	XENCONS_RING_IDX cons, prod;
   15.20  
   15.21 @@ -71,8 +75,48 @@ static void handle_input(evtchn_port_t p
   15.22  	notify_daemon();
   15.23  
   15.24  	xencons_tx();
   15.25 +#endif
   15.26  }
   15.27  
   15.28 +#ifdef HAVE_LIBC
   15.29 +int xencons_ring_avail(void)
   15.30 +{
   15.31 +	struct xencons_interface *intf = xencons_interface();
   15.32 +	XENCONS_RING_IDX cons, prod;
   15.33 +
   15.34 +	cons = intf->in_cons;
   15.35 +	prod = intf->in_prod;
   15.36 +	mb();
   15.37 +	BUG_ON((prod - cons) > sizeof(intf->in));
   15.38 +
   15.39 +        return prod - cons;
   15.40 +}
   15.41 +
   15.42 +int xencons_ring_recv(char *data, unsigned len)
   15.43 +{
   15.44 +	struct xencons_interface *intf = xencons_interface();
   15.45 +	XENCONS_RING_IDX cons, prod;
   15.46 +        unsigned filled = 0;
   15.47 +
   15.48 +	cons = intf->in_cons;
   15.49 +	prod = intf->in_prod;
   15.50 +	mb();
   15.51 +	BUG_ON((prod - cons) > sizeof(intf->in));
   15.52 +
   15.53 +        while (filled < len && cons + filled != prod) {
   15.54 +                data[filled] = *(intf->in + MASK_XENCONS_IDX(cons + filled, intf->in));
   15.55 +                filled++;
   15.56 +	}
   15.57 +
   15.58 +	mb();
   15.59 +        intf->in_cons = cons + filled;
   15.60 +
   15.61 +	notify_daemon();
   15.62 +
   15.63 +        return filled;
   15.64 +}
   15.65 +#endif
   15.66 +
   15.67  int xencons_ring_init(void)
   15.68  {
   15.69  	int err;
    16.1 --- a/extras/mini-os/events.c	Tue Jun 10 16:00:33 2008 +0900
    16.2 +++ b/extras/mini-os/events.c	Thu Jun 19 12:46:26 2008 +0900
    16.3 @@ -39,19 +39,29 @@ static unsigned long bound_ports[NR_EVS/
    16.4  void unbind_all_ports(void)
    16.5  {
    16.6      int i;
    16.7 +    int cpu = 0;
    16.8 +    shared_info_t *s = HYPERVISOR_shared_info;
    16.9 +    vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
   16.10  
   16.11      for (i = 0; i < NR_EVS; i++)
   16.12      {
   16.13 +        if (i == start_info.console.domU.evtchn ||
   16.14 +            i == start_info.store_evtchn)
   16.15 +            continue;
   16.16          if (test_and_clear_bit(i, bound_ports))
   16.17          {
   16.18              struct evtchn_close close;
   16.19 +            printk("port %d still bound!\n", i);
   16.20              mask_evtchn(i);
   16.21              close.port = i;
   16.22              HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
   16.23 +            clear_evtchn(i);
   16.24          }
   16.25      }
   16.26 +    vcpu_info->evtchn_upcall_pending = 0;
   16.27 +    vcpu_info->evtchn_pending_sel = 0;
   16.28  }
   16.29 -  
   16.30 +
   16.31  /*
   16.32   * Demux events to different handlers.
   16.33   */
   16.34 @@ -86,17 +96,27 @@ evtchn_port_t bind_evtchn(evtchn_port_t 
   16.35  	ev_actions[port].data = data;
   16.36  	wmb();
   16.37  	ev_actions[port].handler = handler;
   16.38 +	set_bit(port, bound_ports);
   16.39  
   16.40  	return port;
   16.41  }
   16.42  
   16.43  void unbind_evtchn(evtchn_port_t port )
   16.44  {
   16.45 +	struct evtchn_close close;
   16.46 +
   16.47  	if (ev_actions[port].handler == default_handler)
   16.48  		printk("WARN: No handler for port %d when unbinding\n", port);
   16.49 +	mask_evtchn(port);
   16.50 +	clear_evtchn(port);
   16.51 +
   16.52  	ev_actions[port].handler = default_handler;
   16.53  	wmb();
   16.54  	ev_actions[port].data = NULL;
   16.55 +	clear_bit(port, bound_ports);
   16.56 +
   16.57 +	close.port = port;
   16.58 +	HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
   16.59  }
   16.60  
   16.61  evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
   16.62 @@ -112,7 +132,6 @@ evtchn_port_t bind_virq(uint32_t virq, e
   16.63  		printk("Failed to bind virtual IRQ %d\n", virq);
   16.64  		return -1;
   16.65      }
   16.66 -    set_bit(op.port,bound_ports);
   16.67      bind_evtchn(op.port, handler, data);
   16.68  	return op.port;
   16.69  }
   16.70 @@ -147,6 +166,15 @@ void init_events(void)
   16.71      }
   16.72  }
   16.73  
   16.74 +void fini_events(void)
   16.75 +{
   16.76 +    /* Dealloc all events */
   16.77 +    unbind_all_ports();
   16.78 +#if defined(__x86_64__)
   16.79 +    wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */
   16.80 +#endif
   16.81 +}
   16.82 +
   16.83  void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
   16.84  {
   16.85      printk("[Port %d] - event received\n", port);
   16.86 @@ -185,7 +213,6 @@ int evtchn_bind_interdomain(domid_t pal,
   16.87      int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op);
   16.88      if (err)
   16.89  		return err;
   16.90 -    set_bit(op.local_port,bound_ports);
   16.91      evtchn_port_t port = op.local_port;
   16.92      *local_port = bind_evtchn(port, handler, data);
   16.93      return err;
    17.1 --- a/extras/mini-os/fbfront.c	Tue Jun 10 16:00:33 2008 +0900
    17.2 +++ b/extras/mini-os/fbfront.c	Thu Jun 19 12:46:26 2008 +0900
    17.3 @@ -44,7 +44,8 @@ void kbdfront_handler(evtchn_port_t port
    17.4      struct kbdfront_dev *dev = data;
    17.5      int fd = dev->fd;
    17.6  
    17.7 -    files[fd].read = 1;
    17.8 +    if (fd != -1)
    17.9 +        files[fd].read = 1;
   17.10  #endif
   17.11      wake_up(&kbdfront_queue);
   17.12  }
   17.13 @@ -83,6 +84,9 @@ struct kbdfront_dev *init_kbdfront(char 
   17.14  
   17.15      dev = malloc(sizeof(*dev));
   17.16      dev->nodename = strdup(nodename);
   17.17 +#ifdef HAVE_LIBC
   17.18 +    dev->fd = -1;
   17.19 +#endif
   17.20  
   17.21      snprintf(path, sizeof(path), "%s/backend-id", nodename);
   17.22      dev->dom = xenbus_read_integer(path); 
   17.23 @@ -179,8 +183,10 @@ int kbdfront_receive(struct kbdfront_dev
   17.24      int i;
   17.25  
   17.26  #ifdef HAVE_LIBC
   17.27 -    files[dev->fd].read = 0;
   17.28 -    mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
   17.29 +    if (dev->fd != -1) {
   17.30 +        files[dev->fd].read = 0;
   17.31 +        mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
   17.32 +    }
   17.33  #endif
   17.34  
   17.35      prod = page->in_prod;
   17.36 @@ -198,7 +204,7 @@ int kbdfront_receive(struct kbdfront_dev
   17.37      notify_remote_via_evtchn(dev->evtchn);
   17.38  
   17.39  #ifdef HAVE_LIBC
   17.40 -    if (cons != prod)
   17.41 +    if (cons != prod && dev->fd != -1)
   17.42          /* still some events to read */
   17.43          files[dev->fd].read = 1;
   17.44  #endif
   17.45 @@ -223,8 +229,19 @@ void shutdown_kbdfront(struct kbdfront_d
   17.46      err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
   17.47      xenbus_wait_for_value(path, "6", &dev->events);
   17.48  
   17.49 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
   17.50 +    // does not work yet.
   17.51 +    //xenbus_wait_for_value(path, "2", &dev->events);
   17.52 +
   17.53      xenbus_unwatch_path(XBT_NIL, path);
   17.54  
   17.55 +    snprintf(path, sizeof(path), "%s/page-ref", nodename);
   17.56 +    xenbus_rm(XBT_NIL, path);
   17.57 +    snprintf(path, sizeof(path), "%s/event-channel", nodename);
   17.58 +    xenbus_rm(XBT_NIL, path);
   17.59 +    snprintf(path, sizeof(path), "%s/request-abs-pointer", nodename);
   17.60 +    xenbus_rm(XBT_NIL, path);
   17.61 +
   17.62      free_kbdfront(dev);
   17.63  }
   17.64  
   17.65 @@ -279,7 +296,8 @@ void fbfront_handler(evtchn_port_t port,
   17.66      struct fbfront_dev *dev = data;
   17.67      int fd = dev->fd;
   17.68  
   17.69 -    files[fd].read = 1;
   17.70 +    if (fd != -1)
   17.71 +        files[fd].read = 1;
   17.72  #endif
   17.73      wake_up(&fbfront_queue);
   17.74  }
   17.75 @@ -305,8 +323,10 @@ int fbfront_receive(struct fbfront_dev *
   17.76      int i;
   17.77  
   17.78  #ifdef HAVE_LIBC
   17.79 -    files[dev->fd].read = 0;
   17.80 -    mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
   17.81 +    if (dev->fd != -1) {
   17.82 +        files[dev->fd].read = 0;
   17.83 +        mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */
   17.84 +    }
   17.85  #endif
   17.86  
   17.87      prod = page->in_prod;
   17.88 @@ -324,7 +344,7 @@ int fbfront_receive(struct fbfront_dev *
   17.89      notify_remote_via_evtchn(dev->evtchn);
   17.90  
   17.91  #ifdef HAVE_LIBC
   17.92 -    if (cons != prod)
   17.93 +    if (cons != prod && dev->fd != -1)
   17.94          /* still some events to read */
   17.95          files[dev->fd].read = 1;
   17.96  #endif
   17.97 @@ -352,6 +372,9 @@ struct fbfront_dev *init_fbfront(char *n
   17.98  
   17.99      dev = malloc(sizeof(*dev));
  17.100      dev->nodename = strdup(nodename);
  17.101 +#ifdef HAVE_LIBC
  17.102 +    dev->fd = -1;
  17.103 +#endif
  17.104  
  17.105      snprintf(path, sizeof(path), "%s/backend-id", nodename);
  17.106      dev->dom = xenbus_read_integer(path); 
  17.107 @@ -547,8 +570,21 @@ void shutdown_fbfront(struct fbfront_dev
  17.108      err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
  17.109      xenbus_wait_for_value(path, "6", &dev->events);
  17.110  
  17.111 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
  17.112 +    // does not work yet
  17.113 +    //xenbus_wait_for_value(path, "2", &dev->events);
  17.114 +
  17.115      xenbus_unwatch_path(XBT_NIL, path);
  17.116  
  17.117 +    snprintf(path, sizeof(path), "%s/page-ref", nodename);
  17.118 +    xenbus_rm(XBT_NIL, path);
  17.119 +    snprintf(path, sizeof(path), "%s/event-channel", nodename);
  17.120 +    xenbus_rm(XBT_NIL, path);
  17.121 +    snprintf(path, sizeof(path), "%s/protocol", nodename);
  17.122 +    xenbus_rm(XBT_NIL, path);
  17.123 +    snprintf(path, sizeof(path), "%s/feature-update", nodename);
  17.124 +    xenbus_rm(XBT_NIL, path);
  17.125 +
  17.126      unbind_evtchn(dev->evtchn);
  17.127  
  17.128      free_fbfront(dev);
    18.1 --- a/extras/mini-os/fs-front.c	Tue Jun 10 16:00:33 2008 +0900
    18.2 +++ b/extras/mini-os/fs-front.c	Thu Jun 19 12:46:26 2008 +0900
    18.3 @@ -1127,3 +1127,5 @@ void init_fs_frontend(void)
    18.4      if (!fs_import)
    18.5  	printk("No FS import\n");
    18.6  }
    18.7 +
    18.8 +/* TODO: shutdown */
    19.1 --- a/extras/mini-os/gnttab.c	Tue Jun 10 16:00:33 2008 +0900
    19.2 +++ b/extras/mini-os/gnttab.c	Thu Jun 19 12:46:26 2008 +0900
    19.3 @@ -35,7 +35,7 @@ static grant_ref_t gnttab_list[NR_GRANT_
    19.4  #ifdef GNT_DEBUG
    19.5  static char inuse[NR_GRANT_ENTRIES];
    19.6  #endif
    19.7 -static __DECLARE_SEMAPHORE_GENERIC(gnttab_sem, NR_GRANT_ENTRIES);
    19.8 +static __DECLARE_SEMAPHORE_GENERIC(gnttab_sem, 0);
    19.9  
   19.10  static void
   19.11  put_free_entry(grant_ref_t ref)
   19.12 @@ -60,6 +60,7 @@ get_free_entry(void)
   19.13      down(&gnttab_sem);
   19.14      local_irq_save(flags);
   19.15      ref = gnttab_list[0];
   19.16 +    BUG_ON(ref < NR_RESERVED_ENTRIES || ref >= NR_GRANT_ENTRIES);
   19.17      gnttab_list[0] = gnttab_list[ref];
   19.18  #ifdef GNT_DEBUG
   19.19      BUG_ON(inuse[ref]);
   19.20 @@ -193,3 +194,14 @@ init_gnttab(void)
   19.21      gnttab_table = map_frames(frames, NR_GRANT_FRAMES);
   19.22      printk("gnttab_table mapped at %p.\n", gnttab_table);
   19.23  }
   19.24 +
   19.25 +void
   19.26 +fini_gnttab(void)
   19.27 +{
   19.28 +    struct gnttab_setup_table setup;
   19.29 +
   19.30 +    setup.dom = DOMID_SELF;
   19.31 +    setup.nr_frames = 0;
   19.32 +
   19.33 +    HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
   19.34 +}
    20.1 --- a/extras/mini-os/include/blkfront.h	Tue Jun 10 16:00:33 2008 +0900
    20.2 +++ b/extras/mini-os/include/blkfront.h	Thu Jun 19 12:46:26 2008 +0900
    20.3 @@ -29,8 +29,11 @@ struct blkfront_dev *init_blkfront(char 
    20.4  int blkfront_open(struct blkfront_dev *dev);
    20.5  #endif
    20.6  void blkfront_aio(struct blkfront_aiocb *aiocbp, int write);
    20.7 -void blkfront_aio_read(struct blkfront_aiocb *aiocbp);
    20.8 -void blkfront_aio_write(struct blkfront_aiocb *aiocbp);
    20.9 +#define blkfront_aio_read(aiocbp) blkfront_aio(aiocbp, 0)
   20.10 +#define blkfront_aio_write(aiocbp) blkfront_aio(aiocbp, 1)
   20.11 +void blkfront_io(struct blkfront_aiocb *aiocbp, int write);
   20.12 +#define blkfront_read(aiocbp) blkfront_io(aiocbp, 0)
   20.13 +#define blkfront_write(aiocbp) blkfront_io(aiocbp, 1)
   20.14  void blkfront_aio_push_operation(struct blkfront_aiocb *aiocbp, uint8_t op);
   20.15  int blkfront_aio_poll(struct blkfront_dev *dev);
   20.16  void blkfront_sync(struct blkfront_dev *dev);
    21.1 --- a/extras/mini-os/include/byteswap.h	Tue Jun 10 16:00:33 2008 +0900
    21.2 +++ b/extras/mini-os/include/byteswap.h	Thu Jun 19 12:46:26 2008 +0900
    21.3 @@ -2,21 +2,32 @@
    21.4  #define _BYTESWAP_H_
    21.5  
    21.6  /* Unfortunately not provided by newlib.  */
    21.7 -#define bswap_16(x) \
    21.8 -    ((((x) & 0xff00) >> 8) | (((x) & 0xff) << 8))
    21.9  
   21.10 -#define bswap_32(x) \
   21.11 -    ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) | \
   21.12 -     (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
   21.13 +#include <types.h>
   21.14 +static inline uint16_t bswap_16(uint16_t x)
   21.15 +{
   21.16 +    return
   21.17 +    ((((x) & 0xff00) >> 8) | (((x) & 0xff) << 8));
   21.18 +}
   21.19  
   21.20 -#define bswap_64(x) \
   21.21 -    ((((x) & 0xff00000000000000ULL) >> 56) | \
   21.22 -     (((x) & 0x00ff000000000000ULL) >> 40) | \
   21.23 -     (((x) & 0x0000ff0000000000ULL) >> 24) | \
   21.24 -     (((x) & 0x000000ff00000000ULL) >>  8) | \
   21.25 -     (((x) & 0x00000000ff000000ULL) <<  8) | \
   21.26 -     (((x) & 0x0000000000ff0000ULL) << 24) | \
   21.27 -     (((x) & 0x000000000000ff00ULL) << 40) | \
   21.28 -     (((x) & 0x00000000000000ffULL) << 56))
   21.29 +static inline uint32_t bswap_32(uint32_t x)
   21.30 +{
   21.31 +    return
   21.32 +    ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |
   21.33 +     (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24));
   21.34 +}
   21.35 +
   21.36 +static inline uint64_t bswap_64(uint64_t x)
   21.37 +{
   21.38 +    return
   21.39 +    ((((x) & 0xff00000000000000ULL) >> 56) |
   21.40 +     (((x) & 0x00ff000000000000ULL) >> 40) |
   21.41 +     (((x) & 0x0000ff0000000000ULL) >> 24) |
   21.42 +     (((x) & 0x000000ff00000000ULL) >>  8) |
   21.43 +     (((x) & 0x00000000ff000000ULL) <<  8) |
   21.44 +     (((x) & 0x0000000000ff0000ULL) << 24) |
   21.45 +     (((x) & 0x000000000000ff00ULL) << 40) |
   21.46 +     (((x) & 0x00000000000000ffULL) << 56));
   21.47 +}
   21.48  
   21.49  #endif /* _BYTESWAP_H */
    22.1 --- a/extras/mini-os/include/console.h	Tue Jun 10 16:00:33 2008 +0900
    22.2 +++ b/extras/mini-os/include/console.h	Thu Jun 19 12:46:26 2008 +0900
    22.3 @@ -51,5 +51,15 @@ void xencons_tx(void);
    22.4  
    22.5  void init_console(void);
    22.6  void console_print(char *data, int length);
    22.7 +void fini_console(void);
    22.8 +
    22.9 +/* Low level functions defined in xencons_ring.c */
   22.10 +extern struct wait_queue_head console_queue;
   22.11 +int xencons_ring_init(void);
   22.12 +int xencons_ring_send(const char *data, unsigned len);
   22.13 +int xencons_ring_send_no_notify(const char *data, unsigned len);
   22.14 +int xencons_ring_avail(void);
   22.15 +int xencons_ring_recv(char *data, unsigned len);
   22.16 +
   22.17  
   22.18  #endif /* _LIB_CONSOLE_H_ */
    23.1 --- a/extras/mini-os/include/events.h	Tue Jun 10 16:00:33 2008 +0900
    23.2 +++ b/extras/mini-os/include/events.h	Thu Jun 19 12:46:26 2008 +0900
    23.3 @@ -45,5 +45,6 @@ static inline int notify_remote_via_evtc
    23.4      return HYPERVISOR_event_channel_op(EVTCHNOP_send, &op);
    23.5  }
    23.6  
    23.7 +void fini_events(void);
    23.8  
    23.9  #endif /* _EVENTS_H_ */
    24.1 --- a/extras/mini-os/include/gnttab.h	Tue Jun 10 16:00:33 2008 +0900
    24.2 +++ b/extras/mini-os/include/gnttab.h	Thu Jun 19 12:46:26 2008 +0900
    24.3 @@ -11,5 +11,6 @@ grant_ref_t gnttab_grant_transfer(domid_
    24.4  unsigned long gnttab_end_transfer(grant_ref_t gref);
    24.5  int gnttab_end_access(grant_ref_t ref);
    24.6  const char *gnttabop_error(int16_t status);
    24.7 +void fini_gnttab(void);
    24.8  
    24.9  #endif /* !__GNTTAB_H__ */
    25.1 --- a/extras/mini-os/include/ia64/os.h	Tue Jun 10 16:00:33 2008 +0900
    25.2 +++ b/extras/mini-os/include/ia64/os.h	Thu Jun 19 12:46:26 2008 +0900
    25.3 @@ -35,6 +35,7 @@
    25.4  #include "sal.h"
    25.5  #include "pal.h"
    25.6  #include "hypervisor.h"
    25.7 +#include <kernel.h>
    25.8  
    25.9  
   25.10  typedef uint64_t paddr_t;		/* Physical address. */
   25.11 @@ -46,9 +47,9 @@ typedef uint64_t caddr_t;		/* rr7/kernel
   25.12  #include "mm.h"
   25.13  
   25.14  
   25.15 -void do_exit(void) __attribute__((noreturn));
   25.16  void arch_init(start_info_t *si);	/* in common.c */
   25.17  void arch_print_info(void);		/* in common.c */
   25.18 +void arch_fini(void);
   25.19  
   25.20  
   25.21  /* Size of xen_ia64_boot_param.command_line */
    26.1 --- a/extras/mini-os/include/ia64/traps.h	Tue Jun 10 16:00:33 2008 +0900
    26.2 +++ b/extras/mini-os/include/ia64/traps.h	Thu Jun 19 12:46:26 2008 +0900
    26.3 @@ -38,6 +38,10 @@ inline static void trap_init(void)
    26.4  {
    26.5  	//printk("trap_init() until now not needed!\n");
    26.6  }
    26.7 +inline static void trap_fini(void)
    26.8 +{
    26.9 +	//printk("trap_fini() until now not needed!\n");
   26.10 +}
   26.11  
   26.12  
   26.13  #endif /* !defined(__ASSEMBLY__) */
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/extras/mini-os/include/kernel.h	Thu Jun 19 12:46:26 2008 +0900
    27.3 @@ -0,0 +1,7 @@
    27.4 +#ifndef _KERNEL_H_
    27.5 +#define _KERNEL_H_
    27.6 +
    27.7 +extern void do_exit(void) __attribute__((noreturn));
    27.8 +extern void stop_kernel(void);
    27.9 +
   27.10 +#endif /* _KERNEL_H_ */
    28.1 --- a/extras/mini-os/include/mm.h	Tue Jun 10 16:00:33 2008 +0900
    28.2 +++ b/extras/mini-os/include/mm.h	Thu Jun 19 12:46:26 2008 +0900
    28.3 @@ -75,5 +75,6 @@ extern unsigned long heap, brk, heap_map
    28.4  #endif
    28.5  
    28.6  int free_physical_pages(xen_pfn_t *mfns, int n);
    28.7 +void fini_mm(void);
    28.8  
    28.9  #endif /* _MM_H_ */
    29.1 --- a/extras/mini-os/include/netfront.h	Tue Jun 10 16:00:33 2008 +0900
    29.2 +++ b/extras/mini-os/include/netfront.h	Thu Jun 19 12:46:26 2008 +0900
    29.3 @@ -18,6 +18,7 @@ extern struct wait_queue_head netfront_q
    29.4   * N.B. _must_ be called from a thread; it's not safe to call this from 
    29.5   * app_main(). */
    29.6  void start_networking(void);
    29.7 +void stop_networking(void);
    29.8  
    29.9  void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw);
   29.10  #endif
    30.1 --- a/extras/mini-os/include/time.h	Tue Jun 10 16:00:33 2008 +0900
    30.2 +++ b/extras/mini-os/include/time.h	Thu Jun 19 12:46:26 2008 +0900
    30.3 @@ -54,6 +54,7 @@ typedef long suseconds_t;
    30.4  
    30.5  /* prototypes */
    30.6  void     init_time(void);
    30.7 +void     fini_time(void);
    30.8  s_time_t get_s_time(void);
    30.9  s_time_t get_v_time(void);
   30.10  u64      monotonic_clock(void);
    31.1 --- a/extras/mini-os/include/wait.h	Tue Jun 10 16:00:33 2008 +0900
    31.2 +++ b/extras/mini-os/include/wait.h	Thu Jun 19 12:46:26 2008 +0900
    31.3 @@ -87,9 +87,9 @@ static inline void wake_up(struct wait_q
    31.4  
    31.5  #define wait_event_deadline(wq, condition, deadline) do {       \
    31.6      unsigned long flags;                                        \
    31.7 +    DEFINE_WAIT(__wait);                                        \
    31.8      if(condition)                                               \
    31.9          break;                                                  \
   31.10 -    DEFINE_WAIT(__wait);                                        \
   31.11      for(;;)                                                     \
   31.12      {                                                           \
   31.13          /* protect the list */                                  \
    32.1 --- a/extras/mini-os/include/x86/arch_mm.h	Tue Jun 10 16:00:33 2008 +0900
    32.2 +++ b/extras/mini-os/include/x86/arch_mm.h	Thu Jun 19 12:46:26 2008 +0900
    32.3 @@ -109,16 +109,16 @@ typedef unsigned long pgentry_t;
    32.4    (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
    32.5  #endif
    32.6  
    32.7 -#define _PAGE_PRESENT  0x001UL
    32.8 -#define _PAGE_RW       0x002UL
    32.9 -#define _PAGE_USER     0x004UL
   32.10 -#define _PAGE_PWT      0x008UL
   32.11 -#define _PAGE_PCD      0x010UL
   32.12 -#define _PAGE_ACCESSED 0x020UL
   32.13 -#define _PAGE_DIRTY    0x040UL
   32.14 -#define _PAGE_PAT      0x080UL
   32.15 -#define _PAGE_PSE      0x080UL
   32.16 -#define _PAGE_GLOBAL   0x100UL
   32.17 +#define _PAGE_PRESENT  0x001ULL
   32.18 +#define _PAGE_RW       0x002ULL
   32.19 +#define _PAGE_USER     0x004ULL
   32.20 +#define _PAGE_PWT      0x008ULL
   32.21 +#define _PAGE_PCD      0x010ULL
   32.22 +#define _PAGE_ACCESSED 0x020ULL
   32.23 +#define _PAGE_DIRTY    0x040ULL
   32.24 +#define _PAGE_PAT      0x080ULL
   32.25 +#define _PAGE_PSE      0x080ULL
   32.26 +#define _PAGE_GLOBAL   0x100ULL
   32.27  
   32.28  #if defined(__i386__)
   32.29  #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
   32.30 @@ -140,7 +140,7 @@ typedef unsigned long pgentry_t;
   32.31  
   32.32  #define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
   32.33  #define PFN_DOWN(x)	((x) >> L1_PAGETABLE_SHIFT)
   32.34 -#define PFN_PHYS(x)	((x) << L1_PAGETABLE_SHIFT)
   32.35 +#define PFN_PHYS(x)	((uint64_t)(x) << L1_PAGETABLE_SHIFT)
   32.36  #define PHYS_PFN(x)	((x) >> L1_PAGETABLE_SHIFT)
   32.37  
   32.38  /* to align the pointer to the (next) page boundary */
   32.39 @@ -221,4 +221,6 @@ static __inline__ paddr_t machine_to_phy
   32.40  #define map_zero(n, a) map_frames_ex(&mfn_zero, n, 0, 0, a, DOMID_SELF, 0, L1_PROT_RO)
   32.41  #define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0, DOMID_SELF, 0, L1_PROT_RO)
   32.42  
   32.43 +pgentry_t *need_pgt(unsigned long addr);
   32.44 +
   32.45  #endif /* _ARCH_MM_H_ */
    33.1 --- a/extras/mini-os/include/x86/os.h	Tue Jun 10 16:00:33 2008 +0900
    33.2 +++ b/extras/mini-os/include/x86/os.h	Thu Jun 19 12:46:26 2008 +0900
    33.3 @@ -18,10 +18,10 @@
    33.4  #ifndef __ASSEMBLY__
    33.5  #include <types.h>
    33.6  #include <hypervisor.h>
    33.7 +#include <kernel.h>
    33.8  
    33.9  #define USED    __attribute__ ((used))
   33.10  
   33.11 -extern void do_exit(void) __attribute__((noreturn));
   33.12  #define BUG do_exit
   33.13  
   33.14  #endif
   33.15 @@ -61,9 +61,11 @@ extern void do_exit(void) __attribute__(
   33.16  extern shared_info_t *HYPERVISOR_shared_info;
   33.17  
   33.18  void trap_init(void);
   33.19 +void trap_fini(void);
   33.20  
   33.21  void arch_init(start_info_t *si);
   33.22  void arch_print_info(void);
   33.23 +void arch_fini(void);
   33.24  
   33.25  
   33.26  
    34.1 --- a/extras/mini-os/include/xenbus.h	Tue Jun 10 16:00:33 2008 +0900
    34.2 +++ b/extras/mini-os/include/xenbus.h	Thu Jun 19 12:46:26 2008 +0900
    34.3 @@ -90,4 +90,7 @@ char* xenbus_printf(xenbus_transaction_t
    34.4                                    char* node, char* path,
    34.5                                    char* fmt, ...);
    34.6  
    34.7 +/* Reset the XenBus system. */
    34.8 +void fini_xenbus(void);
    34.9 +
   34.10  #endif /* XENBUS_H__ */
    35.1 --- a/extras/mini-os/kernel.c	Tue Jun 10 16:00:33 2008 +0900
    35.2 +++ b/extras/mini-os/kernel.c	Thu Jun 19 12:46:26 2008 +0900
    35.3 @@ -46,6 +46,7 @@
    35.4  #include <xen/features.h>
    35.5  #include <xen/version.h>
    35.6  
    35.7 +static struct netfront_dev *net_dev;
    35.8  
    35.9  u8 xen_features[XENFEAT_NR_SUBMAPS * 32];
   35.10  
   35.11 @@ -87,7 +88,7 @@ static void periodic_thread(void *p)
   35.12  
   35.13  static void netfront_thread(void *p)
   35.14  {
   35.15 -    init_netfront(NULL, NULL, NULL, NULL);
   35.16 +    net_dev = init_netfront(NULL, NULL, NULL, NULL);
   35.17  }
   35.18  
   35.19  static struct blkfront_dev *blk_dev;
   35.20 @@ -347,9 +348,9 @@ static void refresh_cursor(int new_x, in
   35.21      fbfront_update(fb_dev, new_x, new_y, 9, 9);
   35.22  }
   35.23  
   35.24 +static struct kbdfront_dev *kbd_dev;
   35.25  static void kbdfront_thread(void *p)
   35.26  {
   35.27 -    struct kbdfront_dev *kbd_dev;
   35.28      DEFINE_WAIT(w);
   35.29      int x = WIDTH / 2, y = HEIGHT / 2, z = 0;
   35.30  
   35.31 @@ -509,6 +510,49 @@ void start_kernel(start_info_t *si)
   35.32      run_idle_thread();
   35.33  }
   35.34  
   35.35 +void stop_kernel(void)
   35.36 +{
   35.37 +    if (net_dev)
   35.38 +        shutdown_netfront(net_dev);
   35.39 +
   35.40 +    if (blk_dev)
   35.41 +        shutdown_blkfront(blk_dev);
   35.42 +
   35.43 +    if (fb_dev)
   35.44 +        shutdown_fbfront(fb_dev);
   35.45 +
   35.46 +    if (kbd_dev)
   35.47 +        shutdown_kbdfront(kbd_dev);
   35.48 +
   35.49 +    /* TODO: fs import */
   35.50 +
   35.51 +    local_irq_disable();
   35.52 +
   35.53 +    /* Reset grant tables */
   35.54 +    fini_gnttab();
   35.55 +
   35.56 +    /* Reset the console driver. */
   35.57 +    fini_console();
   35.58 +    /* TODO: record new ring mfn & event in start_info */
   35.59 +
   35.60 +    /* Reset XenBus */
   35.61 +    fini_xenbus();
   35.62 +
   35.63 +    /* Reset timers */
   35.64 +    fini_time();
   35.65 +
   35.66 +    /* Reset memory management. */
   35.67 +    fini_mm();
   35.68 +
   35.69 +    /* Reset events. */
   35.70 +    fini_events();
   35.71 +
   35.72 +    /* Reset traps */
   35.73 +    trap_fini();
   35.74 +
   35.75 +    /* Reset arch details */
   35.76 +    arch_fini();
   35.77 +}
   35.78  
   35.79  /*
   35.80   * do_exit: This is called whenever an IRET fails in entry.S.
    36.1 --- a/extras/mini-os/lib/sys.c	Tue Jun 10 16:00:33 2008 +0900
    36.2 +++ b/extras/mini-os/lib/sys.c	Thu Jun 19 12:46:26 2008 +0900
    36.3 @@ -43,7 +43,9 @@
    36.4  #include <stdlib.h>
    36.5  #include <math.h>
    36.6  
    36.7 +#ifdef HAVE_LWIP
    36.8  #include <lwip/sockets.h>
    36.9 +#endif
   36.10  #include <fs.h>
   36.11  
   36.12  #define debug(fmt, ...) \
   36.13 @@ -213,8 +215,19 @@ int isatty(int fd)
   36.14  int read(int fd, void *buf, size_t nbytes)
   36.15  {
   36.16      switch (files[fd].type) {
   36.17 -	case FTYPE_CONSOLE:
   36.18 -	    return 0;
   36.19 +	case FTYPE_CONSOLE: {
   36.20 +	    int ret;
   36.21 +            DEFINE_WAIT(w);
   36.22 +            while(1) {
   36.23 +                add_waiter(w, console_queue);
   36.24 +                ret = xencons_ring_recv(buf, nbytes);
   36.25 +                if (ret)
   36.26 +                    break;
   36.27 +                schedule();
   36.28 +            }
   36.29 +            remove_waiter(w);
   36.30 +            return ret;
   36.31 +        }
   36.32  	case FTYPE_FILE: {
   36.33  	    ssize_t ret;
   36.34  	    if (nbytes > PAGE_SIZE)
   36.35 @@ -229,8 +242,10 @@ int read(int fd, void *buf, size_t nbyte
   36.36  	    }
   36.37  	    return 0;
   36.38  	}
   36.39 +#ifdef HAVE_LWIP
   36.40  	case FTYPE_SOCKET:
   36.41  	    return lwip_read(files[fd].socket.fd, buf, nbytes);
   36.42 +#endif
   36.43  	case FTYPE_TAP: {
   36.44  	    ssize_t ret;
   36.45  	    ret = netfront_receive(files[fd].tap.dev, buf, nbytes);
   36.46 @@ -288,8 +303,10 @@ int write(int fd, const void *buf, size_
   36.47  	    }
   36.48  	    return 0;
   36.49  	}
   36.50 +#ifdef HAVE_LWIP
   36.51  	case FTYPE_SOCKET:
   36.52  	    return lwip_write(files[fd].socket.fd, (void*) buf, nbytes);
   36.53 +#endif
   36.54  	case FTYPE_TAP:
   36.55  	    netfront_xmit(files[fd].tap.dev, (void*) buf, nbytes);
   36.56  	    return nbytes;
   36.57 @@ -356,7 +373,7 @@ int close(int fd)
   36.58  {
   36.59      printk("close(%d)\n", fd);
   36.60      switch (files[fd].type) {
   36.61 -	case FTYPE_CONSOLE:
   36.62 +        default:
   36.63  	    files[fd].type = FTYPE_NONE;
   36.64  	    return 0;
   36.65  	case FTYPE_FILE: {
   36.66 @@ -371,11 +388,13 @@ int close(int fd)
   36.67  	case FTYPE_XENBUS:
   36.68              xs_daemon_close((void*)(intptr_t) fd);
   36.69              return 0;
   36.70 +#ifdef HAVE_LWIP
   36.71  	case FTYPE_SOCKET: {
   36.72  	    int res = lwip_close(files[fd].socket.fd);
   36.73  	    files[fd].type = FTYPE_NONE;
   36.74  	    return res;
   36.75  	}
   36.76 +#endif
   36.77  	case FTYPE_XC:
   36.78  	    xc_interface_close(fd);
   36.79  	    return 0;
   36.80 @@ -544,6 +563,7 @@ int fcntl(int fd, int cmd, ...)
   36.81      va_end(ap);
   36.82  
   36.83      switch (cmd) {
   36.84 +#ifdef HAVE_LWIP
   36.85  	case F_SETFL:
   36.86  	    if (files[fd].type == FTYPE_SOCKET && !(arg & ~O_NONBLOCK)) {
   36.87  		/* Only flag supported: non-blocking mode */
   36.88 @@ -551,6 +571,7 @@ int fcntl(int fd, int cmd, ...)
   36.89  		return lwip_ioctl(files[fd].socket.fd, FIONBIO, &nblock);
   36.90  	    }
   36.91  	    /* Fallthrough */
   36.92 +#endif
   36.93  	default:
   36.94  	    printk("fcntl(%d, %d, %lx/%lo)\n", fd, cmd, arg, arg);
   36.95  	    errno = ENOSYS;
   36.96 @@ -655,9 +676,12 @@ static void dump_set(int nfds, fd_set *r
   36.97  /* Just poll without blocking */
   36.98  static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
   36.99  {
  36.100 -    int i, n = 0, sock_n, sock_nfds = 0;
  36.101 +    int i, n = 0;
  36.102 +#ifdef HAVE_LWIP
  36.103 +    int sock_n, sock_nfds = 0;
  36.104      fd_set sock_readfds, sock_writefds, sock_exceptfds;
  36.105      struct timeval timeout = { .tv_sec = 0, .tv_usec = 0};
  36.106 +#endif
  36.107  
  36.108  #ifdef LIBC_VERBOSE
  36.109      static int nb;
  36.110 @@ -667,6 +691,7 @@ static int select_poll(int nfds, fd_set 
  36.111      nb++;
  36.112  #endif
  36.113  
  36.114 +#ifdef HAVE_LWIP
  36.115      /* first poll network */
  36.116      FD_ZERO(&sock_readfds);
  36.117      FD_ZERO(&sock_writefds);
  36.118 @@ -693,6 +718,7 @@ static int select_poll(int nfds, fd_set 
  36.119      sock_n = lwip_select(sock_nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
  36.120      dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
  36.121      DEBUG("\n");
  36.122 +#endif
  36.123  
  36.124      /* Then see others as well. */
  36.125      for (i = 0; i < nfds; i++) {
  36.126 @@ -707,7 +733,12 @@ static int select_poll(int nfds, fd_set 
  36.127  	    FD_CLR(i, exceptfds);
  36.128  	    break;
  36.129  	case FTYPE_CONSOLE:
  36.130 -	    FD_CLR(i, readfds);
  36.131 +	    if (FD_ISSET(i, writefds)) {
  36.132 +                if (xencons_ring_avail())
  36.133 +		    n++;
  36.134 +		else
  36.135 +		    FD_CLR(i, readfds);
  36.136 +            }
  36.137  	    if (FD_ISSET(i, writefds))
  36.138                  n++;
  36.139  	    FD_CLR(i, exceptfds);
  36.140 @@ -736,6 +767,7 @@ static int select_poll(int nfds, fd_set 
  36.141  	    FD_CLR(i, writefds);
  36.142  	    FD_CLR(i, exceptfds);
  36.143  	    break;
  36.144 +#ifdef HAVE_LWIP
  36.145  	case FTYPE_SOCKET:
  36.146  	    if (FD_ISSET(i, readfds)) {
  36.147  	        /* Optimize no-network-packet case.  */
  36.148 @@ -757,6 +789,7 @@ static int select_poll(int nfds, fd_set 
  36.149  		    FD_CLR(i, exceptfds);
  36.150              }
  36.151  	    break;
  36.152 +#endif
  36.153  	}
  36.154  #ifdef LIBC_VERBOSE
  36.155  	if (FD_ISSET(i, readfds))
  36.156 @@ -809,6 +842,7 @@ int select(int nfds, fd_set *readfds, fd
  36.157      DEFINE_WAIT(w3);
  36.158      DEFINE_WAIT(w4);
  36.159      DEFINE_WAIT(w5);
  36.160 +    DEFINE_WAIT(w6);
  36.161  
  36.162      assert(thread == main_thread);
  36.163  
  36.164 @@ -830,6 +864,7 @@ int select(int nfds, fd_set *readfds, fd
  36.165      add_waiter(w3, blkfront_queue);
  36.166      add_waiter(w4, xenbus_watch_queue);
  36.167      add_waiter(w5, kbdfront_queue);
  36.168 +    add_waiter(w6, console_queue);
  36.169  
  36.170      if (readfds)
  36.171          myread = *readfds;
  36.172 @@ -916,9 +951,11 @@ out:
  36.173      remove_waiter(w3);
  36.174      remove_waiter(w4);
  36.175      remove_waiter(w5);
  36.176 +    remove_waiter(w6);
  36.177      return ret;
  36.178  }
  36.179  
  36.180 +#ifdef HAVE_LWIP
  36.181  int socket(int domain, int type, int protocol)
  36.182  {
  36.183      int fd, res;
  36.184 @@ -970,6 +1007,7 @@ LWIP_STUB(ssize_t, recvfrom, (int s, voi
  36.185  LWIP_STUB(ssize_t, send, (int s, void *buf, size_t len, int flags), (s, buf, len, flags))
  36.186  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))
  36.187  LWIP_STUB(int, getsockname, (int s, struct sockaddr *name, socklen_t *namelen), (s, name, namelen))
  36.188 +#endif
  36.189  
  36.190  int nanosleep(const struct timespec *req, struct timespec *rem)
  36.191  {
    37.1 --- a/extras/mini-os/lwip-net.c	Tue Jun 10 16:00:33 2008 +0900
    37.2 +++ b/extras/mini-os/lwip-net.c	Thu Jun 19 12:46:26 2008 +0900
    37.3 @@ -376,3 +376,9 @@ void start_networking(void)
    37.4  
    37.5    tprintk("Network is ready.\n");
    37.6  }
    37.7 +
    37.8 +/* Shut down the network */
    37.9 +void stop_networking(void)
   37.10 +{
   37.11 +  shutdown_netfront(dev);
   37.12 +}
    38.1 --- a/extras/mini-os/main.c	Tue Jun 10 16:00:33 2008 +0900
    38.2 +++ b/extras/mini-os/main.c	Thu Jun 19 12:46:26 2008 +0900
    38.3 @@ -4,6 +4,7 @@
    38.4   * Samuel Thibault <Samuel.Thibault@eu.citrix.net>, October 2007
    38.5   */
    38.6  
    38.7 +#ifdef HAVE_LIBC
    38.8  #include <os.h>
    38.9  #include <sched.h>
   38.10  #include <console.h>
   38.11 @@ -41,24 +42,30 @@ void _fini(void)
   38.12  extern char __app_bss_start, __app_bss_end;
   38.13  static void call_main(void *p)
   38.14  {
   38.15 -    char *args, /**path,*/ *msg, *c;
   38.16 +    char *c;
   38.17  #ifdef CONFIG_QEMU
   38.18 -    char *domargs;
   38.19 +    char *domargs, *msg;
   38.20  #endif
   38.21      int argc;
   38.22      char **argv;
   38.23      char *envp[] = { NULL };
   38.24 +#ifdef CONFIG_QEMU
   38.25      char *vm;
   38.26 +    char path[128];
   38.27 +#endif
   38.28      int i;
   38.29 -    char path[128];
   38.30  
   38.31      /* Let other parts initialize (including console output) before maybe
   38.32       * crashing. */
   38.33      //sleep(1);
   38.34  
   38.35 +#ifndef CONFIG_GRUB
   38.36      sparse((unsigned long) &__app_bss_start, &__app_bss_end - &__app_bss_start);
   38.37 +#ifdef HAVE_LWIP
   38.38      start_networking();
   38.39 +#endif
   38.40      init_fs_frontend();
   38.41 +#endif
   38.42  
   38.43  #ifdef CONFIG_QEMU
   38.44      if (!fs_import) {
   38.45 @@ -92,22 +99,6 @@ static void call_main(void *p)
   38.46      }
   38.47  #endif
   38.48  
   38.49 -    msg = xenbus_read(XBT_NIL, "vm", &vm);
   38.50 -    if (msg) {
   38.51 -        printk("Couldn't read vm path\n");
   38.52 -        do_exit();
   38.53 -    }
   38.54 -
   38.55 -    printk("my vm is at %s\n", vm);
   38.56 -    snprintf(path, sizeof(path), "%s/image/cmdline", vm);
   38.57 -    free(vm);
   38.58 -    msg = xenbus_read(XBT_NIL, path, &args);
   38.59 -
   38.60 -    if (msg) {
   38.61 -        printk("Couldn't get my args: %s\n", msg);
   38.62 -        args = strdup("");
   38.63 -    }
   38.64 -
   38.65      argc = 1;
   38.66  
   38.67  #define PARSE_ARGS(ARGS,START,END) \
   38.68 @@ -124,7 +115,7 @@ static void call_main(void *p)
   38.69  	} \
   38.70      }
   38.71  
   38.72 -    PARSE_ARGS(args, argc++, );
   38.73 +    PARSE_ARGS((char*)start_info.cmd_line, argc++, );
   38.74  #ifdef CONFIG_QEMU
   38.75      PARSE_ARGS(domargs, argc++, );
   38.76  #endif
   38.77 @@ -133,7 +124,7 @@ static void call_main(void *p)
   38.78      argv[0] = "main";
   38.79      argc = 1;
   38.80  
   38.81 -    PARSE_ARGS(args, argv[argc++] = c, *c++ = 0)
   38.82 +    PARSE_ARGS((char*)start_info.cmd_line, argv[argc++] = c, *c++ = 0)
   38.83  #ifdef CONFIG_QEMU
   38.84      PARSE_ARGS(domargs, argv[argc++] = c, *c++ = 0)
   38.85  #endif
   38.86 @@ -162,7 +153,10 @@ void _exit(int ret)
   38.87      close_all_files();
   38.88      __libc_fini_array();
   38.89      printk("main returned %d\n", ret);
   38.90 -    unbind_all_ports();
   38.91 +#ifdef HAVE_LWIP
   38.92 +    stop_networking();
   38.93 +#endif
   38.94 +    stop_kernel();
   38.95      if (!ret) {
   38.96  	/* No problem, just shutdown.  */
   38.97          struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff };
   38.98 @@ -177,3 +171,4 @@ int app_main(start_info_t *si)
   38.99      main_thread = create_thread("main", call_main, si);
  38.100      return 0;
  38.101  }
  38.102 +#endif
    39.1 --- a/extras/mini-os/minios.mk	Tue Jun 10 16:00:33 2008 +0900
    39.2 +++ b/extras/mini-os/minios.mk	Thu Jun 19 12:46:26 2008 +0900
    39.3 @@ -57,13 +57,13 @@ ARCH_LIB := lib$(ARCH_LIB_NAME).a
    39.4  # This object contains the entrypoint for startup from Xen.
    39.5  # $(HEAD_ARCH_OBJ) has to be built in the architecture specific directory.
    39.6  HEAD_ARCH_OBJ := $(XEN_TARGET_ARCH).o
    39.7 -HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ)
    39.8 +HEAD_OBJ := $(OBJ_DIR)/$(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ)
    39.9  
   39.10  
   39.11 -%.o: %.c $(HDRS) Makefile $(EXTRA_DEPS)
   39.12 +$(OBJ_DIR)/%.o: %.c $(HDRS) Makefile $(EXTRA_DEPS)
   39.13  	$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
   39.14  
   39.15 -%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS)
   39.16 +$(OBJ_DIR)/%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS)
   39.17  	$(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@
   39.18  
   39.19  
    40.1 --- a/extras/mini-os/mm.c	Tue Jun 10 16:00:33 2008 +0900
    40.2 +++ b/extras/mini-os/mm.c	Thu Jun 19 12:46:26 2008 +0900
    40.3 @@ -419,6 +419,10 @@ void init_mm(void)
    40.4      arch_init_demand_mapping_area(max_pfn);
    40.5  }
    40.6  
    40.7 +void fini_mm(void)
    40.8 +{
    40.9 +}
   40.10 +
   40.11  void sanity_check(void)
   40.12  {
   40.13      int x;
    41.1 --- a/extras/mini-os/netfront.c	Tue Jun 10 16:00:33 2008 +0900
    41.2 +++ b/extras/mini-os/netfront.c	Thu Jun 19 12:46:26 2008 +0900
    41.3 @@ -259,7 +259,8 @@ void netfront_select_handler(evtchn_port
    41.4      network_tx_buf_gc(dev);
    41.5      local_irq_restore(flags);
    41.6  
    41.7 -    files[fd].read = 1;
    41.8 +    if (fd != -1)
    41.9 +        files[fd].read = 1;
   41.10      wake_up(&netfront_queue);
   41.11  }
   41.12  #endif
   41.13 @@ -323,6 +324,9 @@ struct netfront_dev *init_netfront(char 
   41.14      dev = malloc(sizeof(*dev));
   41.15      memset(dev, 0, sizeof(*dev));
   41.16      dev->nodename = strdup(nodename);
   41.17 +#ifdef HAVE_LIBC
   41.18 +    dev->fd = -1;
   41.19 +#endif
   41.20  
   41.21      printk("net TX ring size %d\n", NET_TX_RING_SIZE);
   41.22      printk("net RX ring size %d\n", NET_RX_RING_SIZE);
   41.23 @@ -493,14 +497,27 @@ void shutdown_netfront(struct netfront_d
   41.24      printk("close network: backend at %s\n",dev->backend);
   41.25  
   41.26      snprintf(path, sizeof(path), "%s/state", dev->backend);
   41.27 +
   41.28      err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
   41.29      xenbus_wait_for_value(path, "5", &dev->events);
   41.30  
   41.31      err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
   41.32      xenbus_wait_for_value(path, "6", &dev->events);
   41.33  
   41.34 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
   41.35 +    xenbus_wait_for_value(path, "2", &dev->events);
   41.36 +
   41.37      xenbus_unwatch_path(XBT_NIL, path);
   41.38  
   41.39 +    snprintf(path, sizeof(path), "%s/tx-ring-ref", nodename);
   41.40 +    xenbus_rm(XBT_NIL, path);
   41.41 +    snprintf(path, sizeof(path), "%s/rx-ring-ref", nodename);
   41.42 +    xenbus_rm(XBT_NIL, path);
   41.43 +    snprintf(path, sizeof(path), "%s/event-channel", nodename);
   41.44 +    xenbus_rm(XBT_NIL, path);
   41.45 +    snprintf(path, sizeof(path), "%s/request-rx-copy", nodename);
   41.46 +    xenbus_rm(XBT_NIL, path);
   41.47 +
   41.48      free_netfront(dev);
   41.49  }
   41.50  
   41.51 @@ -597,7 +614,7 @@ ssize_t netfront_receive(struct netfront
   41.52  
   41.53      local_irq_save(flags);
   41.54      network_rx(dev);
   41.55 -    if (!dev->rlen)
   41.56 +    if (!dev->rlen && fd != -1)
   41.57  	/* No data for us, make select stop returning */
   41.58  	files[fd].read = 0;
   41.59      /* Before re-enabling the interrupts, in case a packet just arrived in the
    42.1 --- a/extras/mini-os/xenbus/xenbus.c	Tue Jun 10 16:00:33 2008 +0900
    42.2 +++ b/extras/mini-os/xenbus/xenbus.c	Thu Jun 19 12:46:26 2008 +0900
    42.3 @@ -124,7 +124,7 @@ char* xenbus_wait_for_value(const char* 
    42.4  static void xenbus_thread_func(void *ign)
    42.5  {
    42.6      struct xsd_sockmsg msg;
    42.7 -    unsigned prod = 0;
    42.8 +    unsigned prod = xenstore_buf->rsp_prod;
    42.9  
   42.10      for (;;) 
   42.11      {
   42.12 @@ -174,9 +174,14 @@ static void xenbus_thread_func(void *ign
   42.13                          break;
   42.14                      }
   42.15  
   42.16 -		event->next = *events;
   42.17 -		*events = event;
   42.18 -                wake_up(&xenbus_watch_queue);
   42.19 +                if (events) {
   42.20 +                    event->next = *events;
   42.21 +                    *events = event;
   42.22 +                    wake_up(&xenbus_watch_queue);
   42.23 +                } else {
   42.24 +                    printk("unexpected watch token %s\n", event->token);
   42.25 +                    free(event);
   42.26 +                }
   42.27              }
   42.28  
   42.29              else
   42.30 @@ -265,6 +270,10 @@ void init_xenbus(void)
   42.31      DEBUG("xenbus on irq %d\n", err);
   42.32  }
   42.33  
   42.34 +void fini_xenbus(void)
   42.35 +{
   42.36 +}
   42.37 +
   42.38  /* Send data to xenbus.  This can block.  All of the requests are seen
   42.39     by xenbus as if sent atomically.  The header is added
   42.40     automatically, using type %type, req_id %req_id, and trans_id
    43.1 --- a/stubdom/Makefile	Tue Jun 10 16:00:33 2008 +0900
    43.2 +++ b/stubdom/Makefile	Thu Jun 19 12:46:26 2008 +0900
    43.3 @@ -1,4 +1,5 @@
    43.4  XEN_ROOT = ..
    43.5 +MINI_OS = $(XEN_ROOT)/extras/mini-os
    43.6  
    43.7  export XEN_OS=MiniOS
    43.8  
    43.9 @@ -12,7 +13,8 @@ GCC_VERSION=4.2.2
   43.10  ZLIB_VERSION=1.2.3
   43.11  LIBPCI_VERSION=2.2.9
   43.12  NEWLIB_DATE=2008-01-01
   43.13 -LWIP_DATE=2008-02-08
   43.14 +LWIP_DATE=2008-06-01
   43.15 +GRUB_DATE=2008-06-01
   43.16  
   43.17  WGET=wget -c
   43.18  
   43.19 @@ -23,9 +25,11 @@ endif
   43.20  
   43.21  ifeq ($(GNU_TARGET_ARCH), i686)
   43.22  TARGET_CFLAGS=
   43.23 +NEWLIB_CFLAGS+=-D_I386MACH_ALLOW_HW_INTERRUPTS
   43.24  endif
   43.25  ifeq ($(GNU_TARGET_ARCH), x86_64)
   43.26  TARGET_CFLAGS=-mno-red-zone
   43.27 +NEWLIB_CFLAGS+=-D_I386MACH_ALLOW_HW_INTERRUPTS
   43.28  endif
   43.29  ifeq ($(GNU_TARGET_ARCH), ia64)
   43.30  TARGET_CFLAGS=-mconstant-gp
   43.31 @@ -36,8 +40,10 @@ CROSS_PREFIX=$(CURDIR)/$(CROSS_ROOT)
   43.32  export CROSS_COMPILE=$(GNU_TARGET_ARCH)-xen-elf-
   43.33  export PATH:=$(CROSS_PREFIX)/bin:$(PATH)
   43.34  
   43.35 +TARGETS=ioemu c caml grub
   43.36 +
   43.37  .PHONY: all
   43.38 -all: ioemu-stubdom c-stubdom
   43.39 +all: ioemu-stubdom c-stubdom pv-grub
   43.40  
   43.41  ################
   43.42  # Cross-binutils
   43.43 @@ -46,8 +52,8 @@ all: ioemu-stubdom c-stubdom
   43.44  binutils-$(BINUTILS_VERSION).tar.bz2:
   43.45  	$(WGET) http://ftp.gnu.org/gnu/binutils/$@
   43.46  binutils-$(BINUTILS_VERSION): binutils-$(BINUTILS_VERSION).tar.bz2
   43.47 -	tar xjf $@.tar.bz2
   43.48 -	( cd binutils-$(BINUTILS_VERSION) && patch -p1 < ../binutils.patch )
   43.49 +	tar xjf $<
   43.50 +	patch -d $@ -p1 < binutils.patch
   43.51  	touch $@
   43.52  
   43.53  BINUTILS_STAMPFILE=$(CROSS_ROOT)/bin/$(GNU_TARGET_ARCH)-xen-elf-ar
   43.54 @@ -68,10 +74,10 @@ cross-binutils: $(BINUTILS_STAMPFILE)
   43.55  gcc-$(GCC_VERSION).tar.bz2:
   43.56  	$(WGET) http://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)/gcc-$(GCC_VERSION).tar.bz2
   43.57  gcc-$(GCC_VERSION): gcc-$(GCC_VERSION).tar.bz2
   43.58 -	tar xjf gcc-$(GCC_VERSION).tar.bz2
   43.59 -	( cd gcc-$(GCC_VERSION) && patch -p1 < ../gcc.patch )
   43.60 +	tar xjf $<
   43.61 +	patch -d $@ -p1 < gcc.patch
   43.62  	touch $@
   43.63 -	
   43.64 +
   43.65  GCC_STAMPFILE=$(CROSS_ROOT)/bin/$(GNU_TARGET_ARCH)-xen-elf-gcc-$(GCC_VERSION)
   43.66  .PHONY: cross-gcc
   43.67  cross-gcc: $(GCC_STAMPFILE)
   43.68 @@ -89,7 +95,7 @@ cross-gcc: $(GCC_STAMPFILE)
   43.69  newlib-cvs:
   43.70  	cvs -z 9 -d :pserver:anoncvs@sources.redhat.com:/cvs/src co -D $(NEWLIB_DATE) newlib
   43.71  	mv src newlib-cvs
   43.72 -	( cd newlib-cvs && patch -p0 < ../newlib.patch)
   43.73 +	patch -d $@ -p0 < newlib.patch
   43.74  
   43.75  NEWLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libc.a
   43.76  .PHONY: cross-newlib
   43.77 @@ -97,7 +103,7 @@ cross-newlib: $(NEWLIB_STAMPFILE)
   43.78  $(NEWLIB_STAMPFILE): newlib-cvs $(GCC_STAMPFILE)
   43.79  	mkdir -p newlib-build
   43.80  	( cd newlib-build && \
   43.81 -	  CC_FOR_TARGET="$(GNU_TARGET_ARCH)-xen-elf-gcc $(TARGET_CFLAGS)" ../newlib-cvs/configure --prefix=$(CROSS_PREFIX) --verbose --target=$(GNU_TARGET_ARCH)-xen-elf --enable-newlib-io-long-long && \
   43.82 +	  CC_FOR_TARGET="$(GNU_TARGET_ARCH)-xen-elf-gcc $(TARGET_CFLAGS) $(NEWLIB_CFLAGS)" ../newlib-cvs/configure --prefix=$(CROSS_PREFIX) --verbose --target=$(GNU_TARGET_ARCH)-xen-elf --enable-newlib-io-long-long && \
   43.83  	  $(MAKE) && \
   43.84  	  $(MAKE) install )
   43.85  
   43.86 @@ -145,8 +151,7 @@ cross-libpci: $(LIBPCI_STAMPFILE)
   43.87  ######
   43.88  
   43.89  lwip-cvs:
   43.90 -	cvs -z 9 -d :pserver:anonymous@cvs.savannah.nongnu.org:/sources/lwip co -D $(LWIP_DATE) lwip
   43.91 -	mv lwip lwip-cvs
   43.92 +	cvs -z 9 -d :pserver:anonymous@cvs.savannah.nongnu.org:/sources/lwip co -D $(LWIP_DATE) -d $@ lwip
   43.93  
   43.94  #######
   43.95  # Links
   43.96 @@ -160,29 +165,36 @@ mk-symlinks:
   43.97  	[ -h include ] || ln -sf ../tools/include .
   43.98  	mkdir -p libxc
   43.99  	[ -h libxc/Makefile ] || ( cd libxc && \
  43.100 -	  ln -sf ../../tools/libxc/*.h . && \
  43.101 -	  ln -sf ../../tools/libxc/*.c . && \
  43.102 -	  ln -sf ../../tools/libxc/Makefile . )
  43.103 +	  ln -sf ../$(XEN_ROOT)/tools/libxc/*.h . && \
  43.104 +	  ln -sf ../$(XEN_ROOT)/tools/libxc/*.c . && \
  43.105 +	  ln -sf ../$(XEN_ROOT)/tools/libxc/Makefile . )
  43.106  	mkdir -p libxc/$(XEN_TARGET_ARCH)
  43.107  	[ -h libxc/$(XEN_TARGET_ARCH) ] || ( cd libxc/$(XEN_TARGET_ARCH) && \
  43.108 -	  ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/*.c . && \
  43.109 -	  ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/*.h . && \
  43.110 -	  ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/Makefile . )
  43.111 +	  ln -sf ../$(XEN_ROOT)/tools/libxc/$(XEN_TARGET_ARCH)/*.c . && \
  43.112 +	  ln -sf ../$(XEN_ROOT)/tools/libxc/$(XEN_TARGET_ARCH)/*.h . && \
  43.113 +	  ln -sf ../$(XEN_ROOT)/tools/libxc/$(XEN_TARGET_ARCH)/Makefile . )
  43.114  	mkdir -p ioemu
  43.115  	[ -h ioemu/Makefile ] || ( cd ioemu && \
  43.116 -	  ln -sf ../../tools/ioemu/* . && \
  43.117 +	  ln -sf ../$(XEN_ROOT)/tools/ioemu/* . && \
  43.118  	  ([ ! -h config-host.h ] || rm -f config-host.h) && \
  43.119  	  ([ ! -h config-host.mak ] || rm -f config-host.mak) )
  43.120 -	[ -h mini-os ] || ln -sf ../extras/mini-os .
  43.121 -	[ -h mini-os/include/xen ] || ln -sf ../../../xen/include/public mini-os/include/xen
  43.122 +	$(MAKE) -C $(MINI_OS) links
  43.123 +
  43.124 +TARGETS_MINIOS=$(addprefix mini-os-,$(TARGETS))
  43.125 +$(TARGETS_MINIOS): mini-os-%:
  43.126 +	[ -d $@ ] || \
  43.127 +	for i in $$(cd $(MINI_OS) ; find . -type d) ; do \
  43.128 +                mkdir -p $@/$$i ; \
  43.129 +	done
  43.130  
  43.131  #######
  43.132  # libxc
  43.133  #######
  43.134  
  43.135  .PHONY: libxc
  43.136 -libxc: cross-zlib mk-symlinks
  43.137 -	$(MAKE) -C $@
  43.138 +libxc: libxc/libxenctrl.a libxc/libxenguest.a
  43.139 +libxc/libxenctrl.a libxc/libxenguest.a: cross-zlib mk-symlinks
  43.140 +	$(MAKE) -C libxc
  43.141  
  43.142  #######
  43.143  # ioemu
  43.144 @@ -199,7 +211,7 @@ ioemu: cross-zlib cross-libpci mk-symlin
  43.145  ######
  43.146  
  43.147  .PHONY: caml
  43.148 -caml: mk-symlinks
  43.149 +caml: cross-newlib mk-symlinks
  43.150  	$(MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip-cvs 
  43.151  
  43.152  ###
  43.153 @@ -207,33 +219,56 @@ caml: mk-symlinks
  43.154  ###
  43.155  
  43.156  .PHONY: c
  43.157 -c: mk-symlinks
  43.158 +c: cross-newlib mk-symlinks
  43.159  	$(MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip-cvs 
  43.160  
  43.161 +######
  43.162 +# Grub
  43.163 +######
  43.164 +
  43.165 +grub-cvs:
  43.166 +	cvs -z 9 -d :pserver:anonymous@cvs.sv.gnu.org:/sources/grub co -D $(GRUB_DATE) -d $@ grub
  43.167 +	for i in grub.patches/* ; do \
  43.168 +		patch -d $@ -p1 < $$i ; \
  43.169 +	done
  43.170 +
  43.171 +.PHONY: grub
  43.172 +grub: grub-cvs cross-newlib mk-symlinks
  43.173 +	$(MAKE) -C $@
  43.174 +
  43.175  ########
  43.176  # minios
  43.177  ########
  43.178  
  43.179  .PHONY: ioemu-stubdom
  43.180 -ioemu-stubdom: lwip-cvs libxc ioemu
  43.181 -	$(MAKE) -C mini-os TARGET=$@ LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS="$(CURDIR)/ioemu/i386-dm-stubdom/qemu.a $(CURDIR)/ioemu/i386-dm-stubdom/libqemu.a"
  43.182 +ioemu-stubdom: mini-os-ioemu lwip-cvs libxc ioemu
  43.183 +	DEF_CFLAGS=-DCONFIG_QEMU $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS="$(CURDIR)/ioemu/i386-dm-stubdom/qemu.a $(CURDIR)/ioemu/i386-dm-stubdom/libqemu.a"
  43.184  
  43.185  CAMLLIB = $(shell ocamlc -where)
  43.186  .PHONY: caml-stubdom
  43.187 -caml-stubdom: lwip-cvs libxc caml
  43.188 -	$(MAKE) -C mini-os TARGET=$@ LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS="$(CURDIR)/caml/main-c.o $(CURDIR)/caml/main-caml.o $(CURDIR)/caml/caml.o $(CAMLLIB)/libasmrun.a"
  43.189 +caml-stubdom: mini-os-caml lwip-cvs libxc caml
  43.190 +	DEF_CFLAGS=-DCONFIG_CAML $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS="$(CURDIR)/caml/main-caml.o $(CURDIR)/caml/caml.o $(CAMLLIB)/libasmrun.a"
  43.191  
  43.192  .PHONY: c-stubdom
  43.193 -c-stubdom: lwip-cvs libxc c
  43.194 -	$(MAKE) -C mini-os TARGET=$@ LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS=$(CURDIR)/c/main.a
  43.195 +c-stubdom: mini-os-c lwip-cvs libxc c
  43.196 +	DEF_CFLAGS=-DCONFIG_C $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS=$(CURDIR)/c/main.a
  43.197 +
  43.198 +.PHONY: pv-grub
  43.199 +pv-grub: mini-os-grub libxc grub
  43.200 +	DEF_CFLAGS=-DCONFIG_GRUB $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< APP_OBJS=$(CURDIR)/grub/main.a
  43.201  
  43.202  #########
  43.203  # install
  43.204  #########
  43.205  
  43.206 -install: mini-os/ioemu-stubdom.gz
  43.207 +install: install-ioemu install-grub
  43.208 +
  43.209 +install-ioemu: mini-os-ioemu/mini-os.gz
  43.210  	$(INSTALL_PROG) stubdom-dm "$(DESTDIR)/usr/lib/xen/bin"
  43.211 -	$(INSTALL_PROG) $< "$(DESTDIR)/usr/lib/xen/boot/stubdom.gz"
  43.212 +	$(INSTALL_PROG) $< "$(DESTDIR)/usr/lib/xen/boot/ioemu-stubdom.gz"
  43.213 +
  43.214 +install-grub: mini-os-grub/mini-os.gz
  43.215 +	$(INSTALL_PROG) $< "$(DESTDIR)/usr/lib/xen/boot/pv-grub.gz"
  43.216  
  43.217  #######
  43.218  # clean
  43.219 @@ -242,9 +277,13 @@ install: mini-os/ioemu-stubdom.gz
  43.220  # Only clean the libxc/ioemu/mini-os part
  43.221  .PHONY: clean
  43.222  clean:
  43.223 -	-$(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip-cvs clean
  43.224 +	rm -fr mini-os-ioemu
  43.225 +	rm -fr mini-os-c
  43.226 +	rm -fr mini-os-caml
  43.227 +	rm -fr mini-os-grub
  43.228  	$(MAKE) -C caml clean
  43.229  	$(MAKE) -C c clean
  43.230 +	$(MAKE) -C grub clean
  43.231  	rm -fr libxc ioemu mini-os include
  43.232  
  43.233  # clean the cross-compilation result
  43.234 @@ -261,6 +300,7 @@ patchclean: crossclean
  43.235  	rm -fr gcc-$(GCC_VERSION)
  43.236  	rm -fr newlib-cvs
  43.237  	rm -fr lwip-cvs
  43.238 +	rm -fr grub-cvs
  43.239  
  43.240  # clean downloads
  43.241  .PHONY: downloadclean
    44.1 --- a/stubdom/README	Tue Jun 10 16:00:33 2008 +0900
    44.2 +++ b/stubdom/README	Thu Jun 19 12:46:26 2008 +0900
    44.3 @@ -6,12 +6,19 @@ Then make install to install the result.
    44.4  
    44.5  Also, run make and make install in $XEN_ROOT/tools/fs-back
    44.6  
    44.7 +
    44.8 +
    44.9 +                                IOEMU stubdom
   44.10 +                                =============
   44.11 +
   44.12 +  This boosts HVM performance by putting ioemu in its own lightweight domain.
   44.13 +
   44.14  General Configuration
   44.15  =====================
   44.16  
   44.17  In your HVM config "hvmconfig",
   44.18  
   44.19 -- use /usr/lib/xen/bin/stubdom-dm as dm script
   44.20 +- use /usr/lib/xen/bin/stubdom-dm as dm script:
   44.21  
   44.22  device_model = '/usr/lib/xen/bin/stubdom-dm'
   44.23  
   44.24 @@ -19,11 +26,13 @@ device_model = '/usr/lib/xen/bin/stubdom
   44.25  
   44.26  #disk = [  'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ]
   44.27  
   44.28 +- disable anything related to dom0, like pty serial assignments
   44.29 +
   44.30  
   44.31  Create /etc/xen/stubdom-hvmconfig (where "hvmconfig" is the name of your HVM
   44.32  guest) with
   44.33  
   44.34 -kernel = "/usr/lib/xen/boot/stubdom.gz"
   44.35 +kernel = "/usr/lib/xen/boot/ioemu-stubdom.gz"
   44.36  vif = [ '', 'ip=10.0.1.1,mac=aa:00:00:12:23:34']
   44.37  disk = [  'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ]
   44.38  
   44.39 @@ -40,34 +49,36 @@ There are three posibilities
   44.40  
   44.41  * Using SDL
   44.42  
   44.43 -In hvmconfig, disable vnc:
   44.44 +  - In hvmconfig, disable vnc and sdl:
   44.45  
   44.46  vnc = 0
   44.47 +sdl = 0
   44.48  
   44.49 -In stubdom-hvmconfig, set a vfb:
   44.50 +  - In stubdom-hvmconfig, set an sdl vfb:
   44.51  
   44.52  vfb = [ 'type=sdl' ]
   44.53  
   44.54  * Using a VNC server in the stub domain
   44.55  
   44.56 -In hvmconfig, set vnclisten to "172.30.206.1" for instance.  Do not use a host
   44.57 -name as Mini-OS does not have a name resolver.  Do not use 127.0.0.1 since then
   44.58 -you will not be able to connect to it.
   44.59 +  - In hvmconfig, set vnclisten to "172.30.206.1" for instance.  Do not use a
   44.60 +host name as Mini-OS does not have a name resolver.  Do not use 127.0.0.1 since
   44.61 +then you will not be able to connect to it.
   44.62  
   44.63  vnc = 1
   44.64  vnclisten = "172.30.206.1"
   44.65  
   44.66 -In stubdom-hvmconfig, fill the reserved vif with the same IP, for instance:
   44.67 +  - In stubdom-hvmconfig, fill the reserved vif with the same IP, for instance:
   44.68  
   44.69  vif = [ 'ip=172.30.206.1', 'ip=10.0.1.1,mac=aa:00:00:12:23:34']
   44.70  
   44.71  * Using a VNC server in dom0
   44.72  
   44.73 -In hvmconfig, disable vnc:
   44.74 +  - In hvmconfig, disable vnc and sdl:
   44.75  
   44.76  vnc = 0
   44.77 +sdl = 0
   44.78  
   44.79 -In stubdom-hvmconfig, set a vfb:
   44.80 +  - In stubdom-hvmconfig, set a vnc vfb:
   44.81  
   44.82  vfb = [ 'type=vnc' ]
   44.83  
   44.84 @@ -83,3 +94,43 @@ ln -s /var/lib/xen /exports/var/lib
   44.85  /usr/sbin/fs-backend &
   44.86  
   44.87  xm create hvmconfig
   44.88 +
   44.89 +
   44.90 +
   44.91 +                                   PV-GRUB
   44.92 +                                   =======
   44.93 +
   44.94 +  This replaces pygrub to boot domU images safely: it runs the regular grub
   44.95 +inside the created domain itself and uses regular domU facilities to read the
   44.96 +disk / fetch files from network etc. ; it eventually loads the PV kernel and
   44.97 +chain-boots it.
   44.98 +  
   44.99 +Configuration
  44.100 +=============
  44.101 +
  44.102 +In your PV config,
  44.103 +
  44.104 +- use /usr/lib/xen/boot/pv-grub.gz as kernel:
  44.105 +
  44.106 +kernel = "/usr/lib/xen/boot/pv-grub.gz"
  44.107 +
  44.108 +- set the path to menu.lst, as seen from the domU, in extra:
  44.109 +
  44.110 +extra = "(hd0,0)/boot/grub/menu.lst"
  44.111 +
  44.112 +you can also use a tftp path (dhcp will be automatically performed):
  44.113 +
  44.114 +extra = "(nd)/somepath/menu.lst"
  44.115 +
  44.116 +or you can set it in option 150 of your dhcp server and leave extra empty
  44.117 +
  44.118 +Limitations
  44.119 +===========
  44.120 +
  44.121 +- You can not boot a 64bit kernel with a 32bit-compiled PV-GRUB and vice-versa.
  44.122 +To cross-compile a 32bit PV-GRUB,
  44.123 +
  44.124 +export XEN_TARGET_ARCH=x86_32
  44.125 +
  44.126 +- bootsplash is supported, but the ioemu backend does not yet support restart
  44.127 +for use by the booted kernel.
    45.1 --- a/stubdom/c/Makefile	Tue Jun 10 16:00:33 2008 +0900
    45.2 +++ b/stubdom/c/Makefile	Thu Jun 19 12:46:26 2008 +0900
    45.3 @@ -4,10 +4,7 @@ include $(XEN_ROOT)/Config.mk
    45.4  
    45.5  all: main.a
    45.6  
    45.7 -main-c.c:
    45.8 -	ln -sf $(XEN_ROOT)/extras/mini-os/main.c $@
    45.9 -
   45.10 -main.a: main-c.o main.o 
   45.11 +main.a: main.o 
   45.12  	$(AR) cr $@ $^
   45.13  
   45.14  clean:
    46.1 --- a/stubdom/caml/Makefile	Tue Jun 10 16:00:33 2008 +0900
    46.2 +++ b/stubdom/caml/Makefile	Thu Jun 19 12:46:26 2008 +0900
    46.3 @@ -11,10 +11,7 @@ OCAMLOPT=ocamlopt
    46.4  OBJS := hello.cmx
    46.5  LIBS := 
    46.6  
    46.7 -all: main-c.o main-caml.o caml.o
    46.8 -
    46.9 -main-c.c:
   46.10 -	ln -sf $(XEN_ROOT)/extras/mini-os/main.c $@
   46.11 +all: main-caml.o caml.o
   46.12  
   46.13  %.cmx: %.ml
   46.14  	$(OCAMLFIND) $(OCAMLOPT) -c $< -o $@
    47.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.2 +++ b/stubdom/grub.patches/10graphics.diff	Thu Jun 19 12:46:26 2008 +0900
    47.3 @@ -0,0 +1,2299 @@
    47.4 +diff -Naur grub-0.97.orig/configure.ac grub-0.97/configure.ac
    47.5 +--- grub-0.97.orig/configure.ac	2005-05-07 23:36:03.000000000 -0300
    47.6 ++++ grub-0.97/configure.ac	2005-06-12 20:56:49.000000000 -0300
    47.7 +@@ -595,6 +595,11 @@
    47.8 +   [  --enable-diskless       enable diskless support])
    47.9 + AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes)
   47.10 + 
   47.11 ++dnl Graphical splashscreen support
   47.12 ++AC_ARG_ENABLE(graphics,
   47.13 ++  [  --disable-graphics      disable graphics terminal support])
   47.14 ++AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno)
   47.15 ++
   47.16 + dnl Hercules terminal
   47.17 + AC_ARG_ENABLE(hercules,
   47.18 +   [  --disable-hercules      disable hercules terminal support])
   47.19 +diff -Naur grub-0.97.orig/stage2/asm.S grub-0.97/stage2/asm.S
   47.20 +--- grub-0.97.orig/stage2/asm.S	2004-06-19 13:55:22.000000000 -0300
   47.21 ++++ grub-0.97/stage2/asm.S	2005-06-13 14:05:31.000000000 -0300
   47.22 +@@ -2216,7 +2216,304 @@
   47.23 + 	pop	%ebx
   47.24 + 	pop	%ebp
   47.25 + 	ret
   47.26 +-		
   47.27 ++
   47.28 ++
   47.29 ++/* graphics mode functions */
   47.30 ++#ifdef SUPPORT_GRAPHICS
   47.31 ++VARIABLE(cursorX)
   47.32 ++.word	0
   47.33 ++VARIABLE(cursorY)
   47.34 ++.word	0
   47.35 ++VARIABLE(cursorCount)
   47.36 ++.word 0
   47.37 ++VARIABLE(cursorBuf)
   47.38 ++.byte	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
   47.39 ++
   47.40 ++
   47.41 ++/*
   47.42 ++ * set_int1c_handler(void)
   47.43 ++ */
   47.44 ++ENTRY(set_int1c_handler)
   47.45 ++	pushl   %edi
   47.46 ++
   47.47 ++	/* save the original int1c handler */
   47.48 ++	movl    $0x70, %edi
   47.49 ++	movw    (%edi), %ax
   47.50 ++	movw    %ax, ABS(int1c_offset)
   47.51 ++	movw    2(%edi), %ax
   47.52 ++	movw    %ax, ABS(int1c_segment)
   47.53 ++
   47.54 ++	/* save the new int1c handler */
   47.55 ++	movw    $ABS(int1c_handler), %ax
   47.56 ++	movw    %ax, (%edi)
   47.57 ++	xorw    %ax, %ax
   47.58 ++	movw    %ax, 2(%edi)
   47.59 ++
   47.60 ++	popl    %edi
   47.61 ++	ret
   47.62 ++
   47.63 ++
   47.64 ++/*
   47.65 ++ * unset_int1c_handler(void)
   47.66 ++ */
   47.67 ++ENTRY(unset_int1c_handler)
   47.68 ++	pushl   %edi
   47.69 ++
   47.70 ++	/* check if int1c_handler is set */
   47.71 ++	movl    $0x70, %edi
   47.72 ++	movw    $ABS(int1c_handler), %ax
   47.73 ++	cmpw    %ax, (%edi)
   47.74 ++	jne     int1c_1
   47.75 ++	xorw    %ax, %ax
   47.76 ++	cmpw    %ax, 2(%edi)
   47.77 ++	jne     int1c_1
   47.78 ++
   47.79 ++	/* restore the original */
   47.80 ++	movw    ABS(int1c_offset), %ax
   47.81 ++	movw    %ax, (%edi)
   47.82 ++	movw    ABS(int1c_segment), %ax
   47.83 ++	movw    %ax, 2(%edi)
   47.84 ++
   47.85 ++int1c_1:
   47.86 ++	popl    %edi
   47.87 ++	ret
   47.88 ++
   47.89 ++
   47.90 ++/*
   47.91 ++ * blinks graphics cursor
   47.92 ++ */
   47.93 ++	.code16
   47.94 ++write_data:
   47.95 ++	movw    $0, %ax
   47.96 ++	movw    %ax, %ds
   47.97 ++
   47.98 ++	mov     $0xA000, %ax            /* video in es:di */
   47.99 ++	mov     %ax, %es
  47.100 ++	mov     $80, %ax
  47.101 ++	movw    $ABS(cursorY), %si
  47.102 ++	mov     %ds:(%si), %bx
  47.103 ++	mul     %bx
  47.104 ++	movw    $ABS(cursorX), %si
  47.105 ++	mov     %ds:(%si), %bx
  47.106 ++	shr     $3, %bx                 /* %bx /= 8 */
  47.107 ++	add     %bx, %ax
  47.108 ++	mov     %ax, %di
  47.109 ++
  47.110 ++	movw    $ABS(cursorBuf), %si    /* fontBuf in ds:si */
  47.111 ++
  47.112 ++	/* prepare for data moving */
  47.113 ++	mov     $16, %dx                /* altura da fonte */
  47.114 ++	mov     $80, %bx                /* bytes por linha */
  47.115 ++
  47.116 ++write_loop:
  47.117 ++	movb    %ds:(%si), %al
  47.118 ++	xorb    $0xff, %al
  47.119 ++	movb    %al, %ds:(%si)          /* invert cursorBuf */
  47.120 ++	movb    %al, %es:(%di)          /* write to video */
  47.121 ++	add     %bx, %di
  47.122 ++	inc     %si
  47.123 ++	dec     %dx
  47.124 ++	jg      write_loop
  47.125 ++	ret
  47.126 ++
  47.127 ++int1c_handler:
  47.128 ++	pusha
  47.129 ++	mov     $0, %ax
  47.130 ++	mov     %ax, %ds
  47.131 ++	mov     $ABS(cursorCount), %si
  47.132 ++	mov     %ds:(%si), %ax
  47.133 ++	inc     %ax
  47.134 ++	mov     %ax, %ds:(%si)
  47.135 ++	cmp     $9, %ax
  47.136 ++	jne     int1c_done
  47.137 ++
  47.138 ++	mov     $0, %ax
  47.139 ++	mov     %ax, %ds:(%si)
  47.140 ++	call    write_data
  47.141 ++
  47.142 ++int1c_done:
  47.143 ++	popa
  47.144 ++	iret
  47.145 ++	/* call previous int1c handler */
  47.146 ++	/* ljmp */
  47.147 ++	.byte   0xea
  47.148 ++int1c_offset:  .word   0
  47.149 ++int1c_segment: .word   0
  47.150 ++	.code32
  47.151 ++
  47.152 ++
  47.153 ++/*
  47.154 ++ * unsigned char set_videomode(unsigned char mode)
  47.155 ++ * BIOS call "INT 10H Function 0h" to set video mode
  47.156 ++ *	Call with	%ah = 0x0
  47.157 ++ *			%al = video mode
  47.158 ++ *  Returns old videomode.
  47.159 ++ */
  47.160 ++ENTRY(set_videomode)
  47.161 ++	pushl	%ebp
  47.162 ++	movl	%esp,%ebp
  47.163 ++	pushl	%ebx
  47.164 ++	pushl	%ecx
  47.165 ++
  47.166 ++	movb	8(%ebp), %cl
  47.167 ++
  47.168 ++	call	EXT_C(prot_to_real)
  47.169 ++	.code16
  47.170 ++
  47.171 ++	xorb	%al, %al
  47.172 ++	movb	$0xf, %ah
  47.173 ++	int	$0x10			/* Get Current Video mode */
  47.174 ++	movb	%al, %ch
  47.175 ++	xorb	%ah, %ah
  47.176 ++	movb	%cl, %al
  47.177 ++	int	$0x10			/* Set Video mode */
  47.178 ++
  47.179 ++	DATA32	call	EXT_C(real_to_prot)
  47.180 ++	.code32
  47.181 ++
  47.182 ++	xorl	%eax, %eax
  47.183 ++	movb	%ch, %al
  47.184 ++
  47.185 ++	popl	%ecx
  47.186 ++	popl	%ebx
  47.187 ++	popl	%ebp
  47.188 ++	ret
  47.189 ++
  47.190 ++
  47.191 ++/*
  47.192 ++ * int get_videomode()
  47.193 ++ * BIOS call "INT 10H Function 0Fh" to get current video mode
  47.194 ++ *	Call with	%al = 0x0
  47.195 ++ *			%ah = 0xF
  47.196 ++ *	Returns current videomode.
  47.197 ++ */
  47.198 ++ENTRY(get_videomode)
  47.199 ++	pushl	%ebp
  47.200 ++	movl	%esp,%ebp
  47.201 ++	pushl	%ebx
  47.202 ++	pushl	%ecx
  47.203 ++
  47.204 ++	call	EXT_C(prot_to_real)
  47.205 ++	.code16
  47.206 ++
  47.207 ++	xorb	%al, %al
  47.208 ++	movb	$0xF, %ah
  47.209 ++	int	$0x10			/* Get Current Video mode */
  47.210 ++	movb	%al, %cl	/* For now we only want display mode */
  47.211 ++
  47.212 ++	DATA32	call	EXT_C(real_to_prot)
  47.213 ++	.code32
  47.214 ++
  47.215 ++	xorl	%eax, %eax
  47.216 ++	movb	%cl, %al
  47.217 ++
  47.218 ++	popl	%ecx
  47.219 ++	popl	%ebx
  47.220 ++	popl	%ebp
  47.221 ++	ret
  47.222 ++
  47.223 ++
  47.224 ++/*
  47.225 ++ * unsigned char * graphics_get_font()
  47.226 ++ * BIOS call "INT 10H Function 11h" to set font
  47.227 ++ *      Call with       %ah = 0x11
  47.228 ++ */
  47.229 ++ENTRY(graphics_get_font)
  47.230 ++	push	%ebp
  47.231 ++	push	%ebx
  47.232 ++	push	%ecx
  47.233 ++	push	%edx
  47.234 ++
  47.235 ++	call	EXT_C(prot_to_real)
  47.236 ++	.code16
  47.237 ++
  47.238 ++	movw	$0x1130, %ax
  47.239 ++	movb	$6, %bh		/* font 8x16 */
  47.240 ++	int	$0x10
  47.241 ++	movw	%bp, %dx
  47.242 ++	movw	%es, %cx
  47.243 ++
  47.244 ++	DATA32	call	EXT_C(real_to_prot)
  47.245 ++	.code32
  47.246 ++
  47.247 ++	xorl	%eax, %eax
  47.248 ++	movw	%cx, %ax
  47.249 ++	shll	$4, %eax
  47.250 ++	movw	%dx, %ax
  47.251 ++
  47.252 ++	pop	%edx
  47.253 ++	pop	%ecx
  47.254 ++	pop	%ebx
  47.255 ++	pop	%ebp
  47.256 ++	ret
  47.257 ++
  47.258 ++
  47.259 ++/*
  47.260 ++ * graphics_set_palette(index, red, green, blue)
  47.261 ++ * BIOS call "INT 10H Function 10h" to set individual dac register
  47.262 ++ *	Call with	%ah = 0x10
  47.263 ++ *			%bx = register number
  47.264 ++ *			%ch = new value for green (0-63)
  47.265 ++ *			%cl = new value for blue (0-63)
  47.266 ++ *			%dh = new value for red (0-63)
  47.267 ++ */
  47.268 ++
  47.269 ++ENTRY(graphics_set_palette)
  47.270 ++	push	%ebp
  47.271 ++	push	%eax
  47.272 ++	push	%ebx
  47.273 ++	push	%ecx
  47.274 ++	push	%edx
  47.275 ++
  47.276 ++	movw	$0x3c8, %bx		/* address write mode register */
  47.277 ++
  47.278 ++	/* wait vertical retrace */
  47.279 ++	movw	$0x3da, %dx
  47.280 ++l1b:
  47.281 ++	inb	%dx, %al	/* wait vertical active display */
  47.282 ++	test	$8, %al
  47.283 ++	jnz	l1b
  47.284 ++
  47.285 ++l2b:
  47.286 ++	inb	%dx, %al	/* wait vertical retrace */
  47.287 ++	test	$8, %al
  47.288 ++	jnz	l2b
  47.289 ++
  47.290 ++	mov	%bx, %dx
  47.291 ++	movb	0x18(%esp), %al		/* index */
  47.292 ++	outb	%al, %dx
  47.293 ++	inc	%dx
  47.294 ++
  47.295 ++	movb	0x1c(%esp), %al		/* red */
  47.296 ++	outb	%al, %dx
  47.297 ++
  47.298 ++	movb	0x20(%esp), %al		/* green */
  47.299 ++	outb	%al, %dx
  47.300 ++
  47.301 ++	movb	0x24(%esp), %al		/* blue */
  47.302 ++	outb	%al, %dx
  47.303 ++
  47.304 ++	movw	0x18(%esp), %bx
  47.305 ++
  47.306 ++	call	EXT_C(prot_to_real)
  47.307 ++	.code16
  47.308 ++
  47.309 ++	movb	%bl, %bh
  47.310 ++	movw	$0x1000, %ax
  47.311 ++	int	$0x10
  47.312 ++
  47.313 ++	DATA32	call	EXT_C(real_to_prot)
  47.314 ++	.code32
  47.315 ++
  47.316 ++	pop	%edx
  47.317 ++	pop	%ecx
  47.318 ++	pop	%ebx
  47.319 ++	pop	%eax
  47.320 ++	pop	%ebp
  47.321 ++	ret
  47.322 ++#endif /* SUPPORT_GRAPHICS */
  47.323 ++
  47.324 ++
  47.325 + /*
  47.326 +  * getrtsecs()
  47.327 +  *	if a seconds value can be read, read it and return it (BCD),
  47.328 +diff -Naur grub-0.97.orig/stage2/builtins.c grub-0.97/stage2/builtins.c
  47.329 +--- grub-0.97.orig/stage2/builtins.c	2005-02-15 19:58:23.000000000 -0200
  47.330 ++++ grub-0.97/stage2/builtins.c	2005-06-13 18:44:03.000000000 -0300
  47.331 +@@ -28,6 +28,10 @@
  47.332 + #include <filesys.h>
  47.333 + #include <term.h>
  47.334 + 
  47.335 ++#ifdef SUPPORT_GRAPHICS
  47.336 ++# include <graphics.h>
  47.337 ++#endif
  47.338 ++
  47.339 + #ifdef SUPPORT_NETBOOT
  47.340 + # define GRUB	1
  47.341 + # include <etherboot.h>
  47.342 +@@ -237,12 +241,22 @@
  47.343 + static int
  47.344 + boot_func (char *arg, int flags)
  47.345 + {
  47.346 ++  struct term_entry *prev_term = current_term;
  47.347 +   /* Clear the int15 handler if we can boot the kernel successfully.
  47.348 +      This assumes that the boot code never fails only if KERNEL_TYPE is
  47.349 +      not KERNEL_TYPE_NONE. Is this assumption is bad?  */
  47.350 +   if (kernel_type != KERNEL_TYPE_NONE)
  47.351 +     unset_int15_handler ();
  47.352 + 
  47.353 ++  /* if our terminal needed initialization, we should shut it down
  47.354 ++   * before booting the kernel, but we want to save what it was so
  47.355 ++   * we can come back if needed */
  47.356 ++  if (current_term->shutdown) 
  47.357 ++    {
  47.358 ++      current_term->shutdown();
  47.359 ++      current_term = term_table; /* assumption: console is first */
  47.360 ++    }
  47.361 ++
  47.362 + #ifdef SUPPORT_NETBOOT
  47.363 +   /* Shut down the networking.  */
  47.364 +   cleanup_net ();
  47.365 +@@ -306,6 +320,13 @@
  47.366 +       return 1;
  47.367 +     }
  47.368 + 
  47.369 ++  /* if we get back here, we should go back to what our term was before */
  47.370 ++  current_term = prev_term;
  47.371 ++  if (current_term->startup)
  47.372 ++      /* if our terminal fails to initialize, fall back to console since
  47.373 ++       * it should always work */
  47.374 ++      if (current_term->startup() == 0)
  47.375 ++          current_term = term_table; /* we know that console is first */
  47.376 +   return 0;
  47.377 + }
  47.378 + 
  47.379 +@@ -852,6 +873,251 @@
  47.380 + };
  47.381 + #endif /* SUPPORT_NETBOOT */
  47.382 + 
  47.383 ++#ifdef SUPPORT_GRAPHICS
  47.384 ++
  47.385 ++static int splashimage_func(char *arg, int flags) {
  47.386 ++  int i;
  47.387 ++    
  47.388 ++  /* filename can only be 256 characters due to our buffer size */
  47.389 ++  if (grub_strlen(arg) > 256) {
  47.390 ++    grub_printf("Splash image filename too large\n");
  47.391 ++    grub_printf("Press any key to continue...");
  47.392 ++    getkey();
  47.393 ++    return 1;
  47.394 ++  }
  47.395 ++
  47.396 ++  /* get rid of TERM_NEED_INIT from the graphics terminal. */
  47.397 ++  for (i = 0; term_table[i].name; i++) {
  47.398 ++    if (grub_strcmp (term_table[i].name, "graphics") == 0) {
  47.399 ++      term_table[i].flags &= ~TERM_NEED_INIT;
  47.400 ++      break;
  47.401 ++    }
  47.402 ++  }
  47.403 ++
  47.404 ++  graphics_set_splash(arg);
  47.405 ++
  47.406 ++  if (flags == BUILTIN_CMDLINE && graphics_inited) {
  47.407 ++    graphics_end();
  47.408 ++    if (graphics_init() == 0) {
  47.409 ++      /* Fallback to default term */
  47.410 ++      current_term = term_table;
  47.411 ++      max_lines = current_term->max_lines;
  47.412 ++      if (current_term->cls)
  47.413 ++        current_term->cls();
  47.414 ++      grub_printf("Failed to set splash image and/or graphics mode\n");
  47.415 ++      return 1;
  47.416 ++    }
  47.417 ++    graphics_cls();
  47.418 ++  }
  47.419 ++
  47.420 ++  if (flags == BUILTIN_MENU)
  47.421 ++    current_term = term_table + i;
  47.422 ++
  47.423 ++  return 0;
  47.424 ++}
  47.425 ++
  47.426 ++static struct builtin builtin_splashimage =
  47.427 ++{
  47.428 ++  "splashimage",
  47.429 ++  splashimage_func,
  47.430 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
  47.431 ++  "splashimage FILE",
  47.432 ++  "Load FILE as the background image when in graphics mode."
  47.433 ++};
  47.434 ++
  47.435 ++
  47.436 ++/* shade */
  47.437 ++static int
  47.438 ++shade_func(char *arg, int flags)
  47.439 ++{
  47.440 ++    int new_shade;
  47.441 ++
  47.442 ++    if (!arg || safe_parse_maxint(&arg, &new_shade) == 0)
  47.443 ++       return (1);
  47.444 ++
  47.445 ++    if (shade != new_shade) {
  47.446 ++       shade = new_shade;
  47.447 ++       if (flags == BUILTIN_CMDLINE && graphics_inited) {
  47.448 ++           graphics_end();
  47.449 ++           graphics_init();
  47.450 ++           graphics_cls();
  47.451 ++       }
  47.452 ++    }
  47.453 ++
  47.454 ++    return 0;
  47.455 ++}
  47.456 ++
  47.457 ++static struct builtin builtin_shade =
  47.458 ++{
  47.459 ++  "shade",
  47.460 ++  shade_func,
  47.461 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
  47.462 ++  "shade INTEGER",
  47.463 ++  "If set to 0, disables the use of shaded text, else enables it."
  47.464 ++};
  47.465 ++
  47.466 ++
  47.467 ++/* foreground */
  47.468 ++static int
  47.469 ++foreground_func(char *arg, int flags)
  47.470 ++{
  47.471 ++    if (grub_strlen(arg) == 6) {
  47.472 ++	int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
  47.473 ++	int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
  47.474 ++	int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
  47.475 ++
  47.476 ++	foreground = (r << 16) | (g << 8) | b;
  47.477 ++	if (graphics_inited)
  47.478 ++	    graphics_set_palette(15, r, g, b);
  47.479 ++
  47.480 ++	return 0;
  47.481 ++    }
  47.482 ++
  47.483 ++    return 1;
  47.484 ++}
  47.485 ++
  47.486 ++static struct builtin builtin_foreground =
  47.487 ++{
  47.488 ++  "foreground",
  47.489 ++  foreground_func,
  47.490 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
  47.491 ++  "foreground RRGGBB",
  47.492 ++  "Sets the foreground color when in graphics mode."
  47.493 ++  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
  47.494 ++};
  47.495 ++
  47.496 ++
  47.497 ++/* background */
  47.498 ++static int
  47.499 ++background_func(char *arg, int flags)
  47.500 ++{
  47.501 ++    if (grub_strlen(arg) == 6) {
  47.502 ++	int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
  47.503 ++	int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
  47.504 ++	int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
  47.505 ++
  47.506 ++	background = (r << 16) | (g << 8) | b;
  47.507 ++	if (graphics_inited)
  47.508 ++	    graphics_set_palette(0, r, g, b);
  47.509 ++	return 0;
  47.510 ++    }
  47.511 ++
  47.512 ++    return 1;
  47.513 ++}
  47.514 ++
  47.515 ++static struct builtin builtin_background =
  47.516 ++{
  47.517 ++  "background",
  47.518 ++  background_func,
  47.519 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
  47.520 ++  "background RRGGBB",
  47.521 ++  "Sets the background color when in graphics mode."
  47.522 ++  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
  47.523 ++};
  47.524 ++
  47.525 ++
  47.526 ++/* border */
  47.527 ++static int
  47.528 ++border_func(char *arg, int flags)
  47.529 ++{
  47.530 ++    if (grub_strlen(arg) == 6) {
  47.531 ++       int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
  47.532 ++       int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
  47.533 ++       int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
  47.534 ++
  47.535 ++       window_border = (r << 16) | (g << 8) | b;
  47.536 ++       if (graphics_inited)
  47.537 ++           graphics_set_palette(0x11, r, g, b);
  47.538 ++
  47.539 ++       return 0;
  47.540 ++    }
  47.541 ++
  47.542 ++    return 1;
  47.543 ++}
  47.544 ++
  47.545 ++static struct builtin builtin_border =
  47.546 ++{
  47.547 ++  "border",
  47.548 ++  border_func,
  47.549 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
  47.550 ++  "border RRGGBB",
  47.551 ++  "Sets the border video color when in graphics mode."
  47.552 ++  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
  47.553 ++};
  47.554 ++
  47.555 ++
  47.556 ++/* viewport */
  47.557 ++static int
  47.558 ++viewport_func (char *arg, int flags)
  47.559 ++{
  47.560 ++    int i;
  47.561 ++    int x0 = 0, y0 = 0, x1 = 80, y1 = 30;
  47.562 ++    int *pos[4] = { &x0, &y0, &x1, &y1 };
  47.563 ++
  47.564 ++    if (!arg)
  47.565 ++       return (1);
  47.566 ++    for (i = 0; i < 4; i++) {
  47.567 ++       if (!*arg)
  47.568 ++           return (1);
  47.569 ++    while (*arg && (*arg == ' ' || *arg == '\t'))
  47.570 ++           ++arg;
  47.571 ++       if (!safe_parse_maxint(&arg, pos[i]))
  47.572 ++           return (1);
  47.573 ++       while (*arg && (*arg != ' ' && *arg != '\t'))
  47.574 ++           ++arg;
  47.575 ++    }
  47.576 ++
  47.577 ++    /* minimum size is 65 colums and 16 rows */
  47.578 ++    if (x0 > x1 - 66 || y0 > y1 - 16 || x0 < 0 || y0 < 0 || x1 > 80 || y1 > 30)
  47.579 ++       return 1;
  47.580 ++
  47.581 ++    view_x0 = x0;
  47.582 ++    view_y0 = y0;
  47.583 ++    view_x1 = x1;
  47.584 ++    view_y1 = y1;
  47.585 ++
  47.586 ++    if (flags == BUILTIN_CMDLINE && graphics_inited) {
  47.587 ++       graphics_end();
  47.588 ++       graphics_init();
  47.589 ++       graphics_cls();
  47.590 ++    }
  47.591 ++
  47.592 ++    return 0;
  47.593 ++}
  47.594 ++
  47.595 ++static struct builtin builtin_viewport =
  47.596 ++{
  47.597 ++  "viewport",
  47.598 ++  viewport_func,
  47.599 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
  47.600 ++  "viewport x0 y0 x1 y1",
  47.601 ++  "Changes grub internals to output text in the window defined by"
  47.602 ++  " four parameters. The x and y parameters are 0 based. This option"
  47.603 ++  " only works with the graphics interface."
  47.604 ++};
  47.605 ++
  47.606 ++#endif /* SUPPORT_GRAPHICS */
  47.607 ++
  47.608 ++
  47.609 ++/* clear */
  47.610 ++static int 
  47.611 ++clear_func() 
  47.612 ++{
  47.613 ++  if (current_term->cls)
  47.614 ++    current_term->cls();
  47.615 ++
  47.616 ++  return 0;
  47.617 ++}
  47.618 ++
  47.619 ++static struct builtin builtin_clear =
  47.620 ++{
  47.621 ++  "clear",
  47.622 ++  clear_func,
  47.623 ++  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
  47.624 ++  "clear",
  47.625 ++  "Clear the screen"
  47.626 ++};
  47.627 ++
  47.628 + 
  47.629 + /* displayapm */
  47.630 + static int
  47.631 +@@ -1454,14 +1720,20 @@
  47.632 + 
  47.633 + 
  47.634 + /* help */
  47.635 +-#define MAX_SHORT_DOC_LEN	39
  47.636 +-#define MAX_LONG_DOC_LEN	66
  47.637 +-
  47.638 + static int
  47.639 + help_func (char *arg, int flags)
  47.640 + {
  47.641 +-  int all = 0;
  47.642 +-  
  47.643 ++  int all = 0, max_short_doc_len, max_long_doc_len;
  47.644 ++  max_short_doc_len = 39;
  47.645 ++  max_long_doc_len = 66;
  47.646 ++#ifdef SUPPORT_GRAPHICS
  47.647 ++  if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
  47.648 ++    {
  47.649 ++      max_short_doc_len = (view_x1 - view_x0 + 1) / 2 - 1;
  47.650 ++      max_long_doc_len = (view_x1 - view_x0) - 14;
  47.651 ++    }
  47.652 ++#endif
  47.653 ++
  47.654 +   if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0)
  47.655 +     {
  47.656 +       all = 1;
  47.657 +@@ -1491,13 +1763,13 @@
  47.658 + 
  47.659 + 	  len = grub_strlen ((*builtin)->short_doc);
  47.660 + 	  /* If the length of SHORT_DOC is too long, truncate it.  */
  47.661 +-	  if (len > MAX_SHORT_DOC_LEN - 1)
  47.662 +-	    len = MAX_SHORT_DOC_LEN - 1;
  47.663 ++	  if (len > max_short_doc_len - 1)
  47.664 ++	    len = max_short_doc_len - 1;
  47.665 + 
  47.666 + 	  for (i = 0; i < len; i++)
  47.667 + 	    grub_putchar ((*builtin)->short_doc[i]);
  47.668 + 
  47.669 +-	  for (; i < MAX_SHORT_DOC_LEN; i++)
  47.670 ++	  for (; i < max_short_doc_len; i++)
  47.671 + 	    grub_putchar (' ');
  47.672 + 
  47.673 + 	  if (! left)
  47.674 +@@ -1546,10 +1818,10 @@
  47.675 + 		      int i;
  47.676 + 
  47.677 + 		      /* If LEN is too long, fold DOC.  */
  47.678 +-		      if (len > MAX_LONG_DOC_LEN)
  47.679 ++		      if (len > max_long_doc_len)
  47.680 + 			{
  47.681 + 			  /* Fold this line at the position of a space.  */
  47.682 +-			  for (len = MAX_LONG_DOC_LEN; len > 0; len--)
  47.683 ++			  for (len = max_long_doc_len; len > 0; len--)
  47.684 + 			    if (doc[len - 1] == ' ')
  47.685 + 			      break;
  47.686 + 			}
  47.687 +@@ -4085,7 +4357,7 @@
  47.688 + };
  47.689 + 
  47.690 + 
  47.691 +-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
  47.692 ++#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
  47.693 + /* terminal */
  47.694 + static int
  47.695 + terminal_func (char *arg, int flags)
  47.696 +@@ -4244,17 +4516,29 @@
  47.697 +  end:
  47.698 +   current_term = term_table + default_term;
  47.699 +   current_term->flags = term_flags;
  47.700 +-  
  47.701 ++
  47.702 +   if (lines)
  47.703 +     max_lines = lines;
  47.704 +   else
  47.705 +-    /* 24 would be a good default value.  */
  47.706 +-    max_lines = 24;
  47.707 +-  
  47.708 ++    max_lines = current_term->max_lines;
  47.709 ++
  47.710 +   /* If the interface is currently the command-line,
  47.711 +      restart it to repaint the screen.  */
  47.712 +-  if (current_term != prev_term && (flags & BUILTIN_CMDLINE))
  47.713 ++  if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){
  47.714 ++    if (prev_term->shutdown)
  47.715 ++      prev_term->shutdown();
  47.716 ++    if (current_term->startup) {
  47.717 ++      /* If startup fails, return to previous term */
  47.718 ++      if (current_term->startup() == 0) {
  47.719 ++        current_term = prev_term;
  47.720 ++        max_lines = current_term->max_lines;
  47.721 ++        if (current_term->cls) {
  47.722 ++          current_term->cls();
  47.723 ++        }
  47.724 ++      }
  47.725 ++    }
  47.726 +     grub_longjmp (restart_cmdline_env, 0);
  47.727 ++  }
  47.728 +   
  47.729 +   return 0;
  47.730 + }
  47.731 +@@ -4264,7 +4548,7 @@
  47.732 +   "terminal",
  47.733 +   terminal_func,
  47.734 +   BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
  47.735 +-  "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]",
  47.736 ++  "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]",
  47.737 +   "Select a terminal. When multiple terminals are specified, wait until"
  47.738 +   " you push any key to continue. If both console and serial are specified,"
  47.739 +   " the terminal to which you input a key first will be selected. If no"
  47.740 +@@ -4276,7 +4560,7 @@
  47.741 +   " seconds. The option --lines specifies the maximum number of lines."
  47.742 +   " The option --silent is used to suppress messages."
  47.743 + };
  47.744 +-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
  47.745 ++#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
  47.746 + 
  47.747 + 
  47.748 + #ifdef SUPPORT_SERIAL
  47.749 +@@ -4795,13 +5079,20 @@
  47.750 + /* The table of builtin commands. Sorted in dictionary order.  */
  47.751 + struct builtin *builtin_table[] =
  47.752 + {
  47.753 ++#ifdef SUPPORT_GRAPHICS
  47.754 ++  &builtin_background,
  47.755 ++#endif
  47.756 +   &builtin_blocklist,
  47.757 +   &builtin_boot,
  47.758 + #ifdef SUPPORT_NETBOOT
  47.759 +   &builtin_bootp,
  47.760 + #endif /* SUPPORT_NETBOOT */
  47.761 ++#ifdef SUPPORT_GRAPHICS
  47.762 ++  &builtin_border,
  47.763 ++#endif
  47.764 +   &builtin_cat,
  47.765 +   &builtin_chainloader,
  47.766 ++  &builtin_clear,
  47.767 +   &builtin_cmp,
  47.768 +   &builtin_color,
  47.769 +   &builtin_configfile,
  47.770 +@@ -4821,6 +5112,9 @@
  47.771 +   &builtin_embed,
  47.772 +   &builtin_fallback,
  47.773 +   &builtin_find,
  47.774 ++#ifdef SUPPORT_GRAPHICS
  47.775 ++  &builtin_foreground,
  47.776 ++#endif
  47.777 +   &builtin_fstest,
  47.778 +   &builtin_geometry,
  47.779 +   &builtin_halt,
  47.780 +@@ -4864,9 +5158,13 @@
  47.781 + #endif /* SUPPORT_SERIAL */
  47.782 +   &builtin_setkey,
  47.783 +   &builtin_setup,
  47.784 +-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
  47.785 ++#ifdef SUPPORT_GRAPHICS
  47.786 ++  &builtin_shade,
  47.787 ++  &builtin_splashimage,
  47.788 ++#endif /* SUPPORT_GRAPHICS */
  47.789 ++#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
  47.790 +   &builtin_terminal,
  47.791 +-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
  47.792 ++#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
  47.793 + #ifdef SUPPORT_SERIAL
  47.794 +   &builtin_terminfo,
  47.795 + #endif /* SUPPORT_SERIAL */
  47.796 +@@ -4880,5 +5178,8 @@
  47.797 +   &builtin_unhide,
  47.798 +   &builtin_uppermem,
  47.799 +   &builtin_vbeprobe,
  47.800 ++#ifdef SUPPORT_GRAPHICS
  47.801 ++  &builtin_viewport,
  47.802 ++#endif
  47.803 +   0
  47.804 + };
  47.805 +diff -Naur grub-0.97.orig/stage2/char_io.c grub-0.97/stage2/char_io.c
  47.806 +--- grub-0.97.orig/stage2/char_io.c	2005-02-01 18:51:23.000000000 -0200
  47.807 ++++ grub-0.97/stage2/char_io.c	2005-06-12 20:56:49.000000000 -0300
  47.808 +@@ -29,12 +29,17 @@
  47.809 + # include <serial.h>
  47.810 + #endif
  47.811 + 
  47.812 ++#ifdef SUPPORT_GRAPHICS
  47.813 ++# include <graphics.h>
  47.814 ++#endif
  47.815 ++
  47.816 + #ifndef STAGE1_5
  47.817 + struct term_entry term_table[] =
  47.818 +   {
  47.819 +     {
  47.820 +       "console",
  47.821 +       0,
  47.822 ++      24,
  47.823 +       console_putchar,
  47.824 +       console_checkkey,
  47.825 +       console_getkey,
  47.826 +@@ -43,13 +48,16 @@
  47.827 +       console_cls,
  47.828 +       console_setcolorstate,
  47.829 +       console_setcolor,
  47.830 +-      console_setcursor
  47.831 ++      console_setcursor,
  47.832 ++      0, 
  47.833 ++      0
  47.834 +     },
  47.835 + #ifdef SUPPORT_SERIAL
  47.836 +     {
  47.837 +       "serial",
  47.838 +       /* A serial device must be initialized.  */
  47.839 +       TERM_NEED_INIT,
  47.840 ++      24,
  47.841 +       serial_putchar,
  47.842 +       serial_checkkey,
  47.843 +       serial_getkey,
  47.844 +@@ -58,6 +66,8 @@
  47.845 +       serial_cls,
  47.846 +       serial_setcolorstate,
  47.847 +       0,
  47.848 ++      0,
  47.849 ++      0, 
  47.850 +       0
  47.851 +     },
  47.852 + #endif /* SUPPORT_SERIAL */
  47.853 +@@ -65,6 +75,7 @@
  47.854 +     {
  47.855 +       "hercules",
  47.856 +       0,
  47.857 ++      24,
  47.858 +       hercules_putchar,
  47.859 +       console_checkkey,
  47.860 +       console_getkey,
  47.861 +@@ -73,11 +84,30 @@
  47.862 +       hercules_cls,
  47.863 +       hercules_setcolorstate,
  47.864 +       hercules_setcolor,
  47.865 +-      hercules_setcursor
  47.866 ++      hercules_setcursor,
  47.867 ++      0,
  47.868 ++      0
  47.869 +     },      
  47.870 + #endif /* SUPPORT_HERCULES */
  47.871 ++#ifdef SUPPORT_GRAPHICS
  47.872 ++    { "graphics",
  47.873 ++      TERM_NEED_INIT, /* flags */
  47.874 ++      30, /* number of lines */
  47.875 ++      graphics_putchar, /* putchar */
  47.876 ++      console_checkkey, /* checkkey */
  47.877 ++      console_getkey, /* getkey */
  47.878 ++      graphics_getxy, /* getxy */
  47.879 ++      graphics_gotoxy, /* gotoxy */
  47.880 ++      graphics_cls, /* cls */
  47.881 ++      graphics_setcolorstate, /* setcolorstate */
  47.882 ++      graphics_setcolor, /* setcolor */
  47.883 ++      graphics_setcursor, /* nocursor */
  47.884 ++      graphics_init, /* initialize */
  47.885 ++      graphics_end /* shutdown */
  47.886 ++    },
  47.887 ++#endif /* SUPPORT_GRAPHICS */
  47.888 +     /* This must be the last entry.  */
  47.889 +-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
  47.890 ++    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
  47.891 +   };
  47.892 + 
  47.893 + /* This must be console.  */
  47.894 +@@ -305,9 +335,10 @@
  47.895 + 
  47.896 +   /* XXX: These should be defined in shared.h, but I leave these here,
  47.897 +      until this code is freezed.  */
  47.898 +-#define CMDLINE_WIDTH	78
  47.899 + #define CMDLINE_MARGIN	10
  47.900 +-  
  47.901 ++
  47.902 ++  /* command-line limits */
  47.903 ++  int cmdline_width = 78, col_start = 0;
  47.904 +   int xpos, lpos, c, section;
  47.905 +   /* The length of PROMPT.  */
  47.906 +   int plen;
  47.907 +@@ -338,7 +369,7 @@
  47.908 +       
  47.909 +       /* If the cursor is in the first section, display the first section
  47.910 + 	 instead of the second.  */
  47.911 +-      if (section == 1 && plen + lpos < CMDLINE_WIDTH)
  47.912 ++      if (section == 1 && plen + lpos < cmdline_width)
  47.913 + 	cl_refresh (1, 0);
  47.914 +       else if (xpos - count < 1)
  47.915 + 	cl_refresh (1, 0);
  47.916 +@@ -354,7 +385,7 @@
  47.917 + 		grub_putchar ('\b');
  47.918 + 	    }
  47.919 + 	  else
  47.920 +-	    gotoxy (xpos, getxy () & 0xFF);
  47.921 ++	    gotoxy (xpos + col_start, getxy () & 0xFF);
  47.922 + 	}
  47.923 +     }
  47.924 + 
  47.925 +@@ -364,7 +395,7 @@
  47.926 +       lpos += count;
  47.927 + 
  47.928 +       /* If the cursor goes outside, scroll the screen to the right.  */
  47.929 +-      if (xpos + count >= CMDLINE_WIDTH)
  47.930 ++      if (xpos + count >= cmdline_width)
  47.931 + 	cl_refresh (1, 0);
  47.932 +       else
  47.933 + 	{
  47.934 +@@ -383,7 +414,7 @@
  47.935 + 		}
  47.936 + 	    }
  47.937 + 	  else
  47.938 +-	    gotoxy (xpos, getxy () & 0xFF);
  47.939 ++	    gotoxy (xpos + col_start, getxy () & 0xFF);
  47.940 + 	}
  47.941 +     }
  47.942 + 
  47.943 +@@ -398,14 +429,14 @@
  47.944 +       if (full)
  47.945 + 	{
  47.946 + 	  /* Recompute the section number.  */
  47.947 +-	  if (lpos + plen < CMDLINE_WIDTH)
  47.948 ++	  if (lpos + plen < cmdline_width)
  47.949 + 	    section = 0;
  47.950 + 	  else
  47.951 +-	    section = ((lpos + plen - CMDLINE_WIDTH)
  47.952 +-		       / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1);
  47.953 ++	    section = ((lpos + plen - cmdline_width)
  47.954 ++		       / (cmdline_width - 1 - CMDLINE_MARGIN) + 1);
  47.955 + 
  47.956 + 	  /* From the start to the end.  */
  47.957 +-	  len = CMDLINE_WIDTH;
  47.958 ++	  len = cmdline_width;
  47.959 + 	  pos = 0;
  47.960 + 	  grub_putchar ('\r');
  47.961 + 
  47.962 +@@ -445,8 +476,8 @@
  47.963 + 	  if (! full)
  47.964 + 	    offset = xpos - 1;
  47.965 + 	  
  47.966 +-	  start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN)
  47.967 +-		   + CMDLINE_WIDTH - plen - CMDLINE_MARGIN);
  47.968 ++	  start = ((section - 1) * (cmdline_width - 1 - CMDLINE_MARGIN)
  47.969 ++		   + cmdline_width - plen - CMDLINE_MARGIN);
  47.970 + 	  xpos = lpos + 1 - start;
  47.971 + 	  start += offset;
  47.972 + 	}
  47.973 +@@ -471,7 +502,7 @@
  47.974 +       
  47.975 +       /* If the cursor is at the last position, put `>' or a space,
  47.976 + 	 depending on if there are more characters in BUF.  */
  47.977 +-      if (pos == CMDLINE_WIDTH)
  47.978 ++      if (pos == cmdline_width)
  47.979 + 	{
  47.980 + 	  if (start + len < llen)
  47.981 + 	    grub_putchar ('>');
  47.982 +@@ -488,7 +519,7 @@
  47.983 + 	    grub_putchar ('\b');
  47.984 + 	}
  47.985 +       else
  47.986 +-	gotoxy (xpos, getxy () & 0xFF);
  47.987 ++	gotoxy (xpos + col_start, getxy () & 0xFF);
  47.988 +     }
  47.989 + 
  47.990 +   /* Initialize the command-line.  */
  47.991 +@@ -518,10 +549,10 @@
  47.992 + 	  
  47.993 + 	  llen += l;
  47.994 + 	  lpos += l;
  47.995 +-	  if (xpos + l >= CMDLINE_WIDTH)
  47.996 ++	  if (xpos + l >= cmdline_width)
  47.997 + 	    cl_refresh (1, 0);
  47.998 +-	  else if (xpos + l + llen - lpos > CMDLINE_WIDTH)
  47.999 +-	    cl_refresh (0, CMDLINE_WIDTH - xpos);
 47.1000 ++	  else if (xpos + l + llen - lpos > cmdline_width)
 47.1001 ++	    cl_refresh (0, cmdline_width - xpos);
 47.1002 + 	  else
 47.1003 + 	    cl_refresh (0, l + llen - lpos);
 47.1004 + 	}
 47.1005 +@@ -533,12 +564,22 @@
 47.1006 +       grub_memmove (buf + lpos, buf + lpos + count, llen - count + 1);
 47.1007 +       llen -= count;
 47.1008 +       
 47.1009 +-      if (xpos + llen + count - lpos > CMDLINE_WIDTH)
 47.1010 +-	cl_refresh (0, CMDLINE_WIDTH - xpos);
 47.1011 ++      if (xpos + llen + count - lpos > cmdline_width)
 47.1012 ++	cl_refresh (0, cmdline_width - xpos);
 47.1013 +       else
 47.1014 + 	cl_refresh (0, llen + count - lpos);
 47.1015 +     }
 47.1016 + 
 47.1017 ++  max_lines = current_term->max_lines;
 47.1018 ++#ifdef SUPPORT_GRAPHICS
 47.1019 ++  if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
 47.1020 ++    {
 47.1021 ++      cmdline_width = (view_x1 - view_x0) - 2;
 47.1022 ++      col_start = view_x0;
 47.1023 ++      max_lines = view_y1 - view_y0;
 47.1024 ++    }
 47.1025 ++#endif
 47.1026 ++
 47.1027 +   plen = grub_strlen (prompt);
 47.1028 +   llen = grub_strlen (cmdline);
 47.1029 + 
 47.1030 +@@ -1006,6 +1047,48 @@
 47.1031 + }
 47.1032 + #endif /* ! STAGE1_5 */
 47.1033 + 
 47.1034 ++#ifndef STAGE1_5
 47.1035 ++/* Internal pager.  */
 47.1036 ++int
 47.1037 ++do_more (void)
 47.1038 ++{
 47.1039 ++  if (count_lines >= 0)
 47.1040 ++    {
 47.1041 ++      count_lines++;
 47.1042 ++      if (count_lines >= max_lines - 2)
 47.1043 ++        {
 47.1044 ++          int tmp;
 47.1045 ++
 47.1046 ++          /* It's important to disable the feature temporarily, because
 47.1047 ++             the following grub_printf call will print newlines.  */
 47.1048 ++          count_lines = -1;
 47.1049 ++
 47.1050 ++          grub_printf("\n");
 47.1051 ++          if (current_term->setcolorstate)
 47.1052 ++            current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
 47.1053 ++
 47.1054 ++          grub_printf ("[Hit return to continue]");
 47.1055 ++
 47.1056 ++          if (current_term->setcolorstate)
 47.1057 ++            current_term->setcolorstate (COLOR_STATE_NORMAL);
 47.1058 ++
 47.1059 ++
 47.1060 ++          do
 47.1061 ++            {
 47.1062 ++              tmp = ASCII_CHAR (getkey ());
 47.1063 ++            }
 47.1064 ++          while (tmp != '\n' && tmp != '\r');
 47.1065 ++          grub_printf ("\r                        \r");
 47.1066 ++
 47.1067 ++          /* Restart to count lines.  */
 47.1068 ++          count_lines = 0;
 47.1069 ++          return 1;
 47.1070 ++        }
 47.1071 ++    }
 47.1072 ++  return 0;
 47.1073 ++}
 47.1074 ++#endif
 47.1075 ++
 47.1076 + /* Display an ASCII character.  */
 47.1077 + void
 47.1078 + grub_putchar (int c)
 47.1079 +@@ -1034,38 +1117,11 @@
 47.1080 + 
 47.1081 +   if (c == '\n')
 47.1082 +     {
 47.1083 ++      int flag;
 47.1084 +       /* Internal `more'-like feature.  */
 47.1085 +-      if (count_lines >= 0)
 47.1086 +-	{
 47.1087 +-	  count_lines++;
 47.1088 +-	  if (count_lines >= max_lines - 2)
 47.1089 +-	    {
 47.1090 +-	      int tmp;
 47.1091 +-	      
 47.1092 +-	      /* It's important to disable the feature temporarily, because
 47.1093 +-		 the following grub_printf call will print newlines.  */
 47.1094 +-	      count_lines = -1;
 47.1095 +-
 47.1096 +-	      if (current_term->setcolorstate)
 47.1097 +-		current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
 47.1098 +-	      
 47.1099 +-	      grub_printf ("\n[Hit return to continue]");
 47.1100 +-
 47.1101 +-	      if (current_term->setcolorstate)
 47.1102 +-		current_term->setcolorstate (COLOR_STATE_NORMAL);
 47.1103 +-	      
 47.1104 +-	      do
 47.1105 +-		{
 47.1106 +-		  tmp = ASCII_CHAR (getkey ());
 47.1107 +-		}
 47.1108 +-	      while (tmp != '\n' && tmp != '\r');
 47.1109 +-	      grub_printf ("\r                        \r");
 47.1110 +-	      
 47.1111 +-	      /* Restart to count lines.  */
 47.1112 +-	      count_lines = 0;
 47.1113 +-	      return;
 47.1114 +-	    }
 47.1115 +-	}
 47.1116 ++      flag = do_more ();
 47.1117 ++      if (flag)
 47.1118 ++        return;
 47.1119 +     }
 47.1120 + 
 47.1121 +   current_term->putchar (c);
 47.1122 +@@ -1090,7 +1146,7 @@
 47.1123 + cls (void)
 47.1124 + {
 47.1125 +   /* If the terminal is dumb, there is no way to clean the terminal.  */
 47.1126 +-  if (current_term->flags & TERM_DUMB)
 47.1127 ++  if (current_term->flags & TERM_DUMB) 
 47.1128 +     grub_putchar ('\n');
 47.1129 +   else
 47.1130 +     current_term->cls ();
 47.1131 +@@ -1217,6 +1273,16 @@
 47.1132 +   return ! errnum;
 47.1133 + }
 47.1134 + 
 47.1135 ++void
 47.1136 ++grub_memcpy(void *dest, const void *src, int len)
 47.1137 ++{
 47.1138 ++  int i;
 47.1139 ++  register char *d = (char*)dest, *s = (char*)src;
 47.1140 ++
 47.1141 ++  for (i = 0; i < len; i++)
 47.1142 ++    d[i] = s[i];
 47.1143 ++}
 47.1144 ++
 47.1145 + void *
 47.1146 + grub_memmove (void *to, const void *from, int len)
 47.1147 + {
 47.1148 +diff -Naur grub-0.97.orig/stage2/cmdline.c grub-0.97/stage2/cmdline.c
 47.1149 +--- grub-0.97.orig/stage2/cmdline.c	2004-08-16 20:23:01.000000000 -0300
 47.1150 ++++ grub-0.97/stage2/cmdline.c	2005-06-12 20:56:49.000000000 -0300
 47.1151 +@@ -50,10 +50,11 @@
 47.1152 + void
 47.1153 + print_cmdline_message (int forever)
 47.1154 + {
 47.1155 +-  printf (" [ Minimal BASH-like line editing is supported.  For the first word, TAB\n"
 47.1156 +-	  "   lists possible command completions.  Anywhere else TAB lists the possible\n"
 47.1157 +-	  "   completions of a device/filename.%s ]\n",
 47.1158 +-	  (forever ? "" : "  ESC at any time exits."));
 47.1159 ++  grub_printf("       [ Minimal BASH-like line editing is supported.   For\n"
 47.1160 ++              "         the   first   word,  TAB  lists  possible  command\n"
 47.1161 ++              "         completions.  Anywhere else TAB lists the possible\n"
 47.1162 ++              "         completions of a device/filename.%s ]\n",
 47.1163 ++              (forever ? "" : "  ESC at any time\n         exits."));
 47.1164 + }
 47.1165 + 
 47.1166 + /* Find the builtin whose command name is COMMAND and return the
 47.1167 +diff -Naur grub-0.97.orig/stage2/graphics.c grub-0.97/stage2/graphics.c
 47.1168 +--- grub-0.97.orig/stage2/graphics.c	1969-12-31 21:00:00.000000000 -0300
 47.1169 ++++ grub-0.97/stage2/graphics.c	2005-06-13 19:13:31.000000000 -0300
 47.1170 +@@ -0,0 +1,585 @@
 47.1171 ++/*
 47.1172 ++ * graphics.c - graphics mode support for GRUB
 47.1173 ++ * Implemented as a terminal type by Jeremy Katz <katzj@redhat.com> based
 47.1174 ++ * on a patch by Paulo CÚsar Pereira de Andrade <pcpa@conectiva.com.br>
 47.1175 ++ * Options and enhancements made by Herton Ronaldo Krzesinski
 47.1176 ++ * <herton@mandriva.com>
 47.1177 ++ *
 47.1178 ++ *  GRUB  --  GRand Unified Bootloader
 47.1179 ++ *  Copyright (C) 2001,2002  Red Hat, Inc.
 47.1180 ++ *  Portions copyright (C) 2000  Conectiva, Inc.
 47.1181 ++ *
 47.1182 ++ *  This program is free software; you can redistribute it and/or modify
 47.1183 ++ *  it under the terms of the GNU General Public License as published by
 47.1184 ++ *  the Free Software Foundation; either version 2 of the License, or
 47.1185 ++ *  (at your option) any later version.
 47.1186 ++ *
 47.1187 ++ *  This program is distributed in the hope that it will be useful,
 47.1188 ++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 47.1189 ++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 47.1190 ++ *  GNU General Public License for more details.
 47.1191 ++ *
 47.1192 ++ *  You should have received a copy of the GNU General Public License
 47.1193 ++ *  along with this program; if not, write to the Free Software
 47.1194 ++ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 47.1195 ++ */
 47.1196 ++
 47.1197 ++#ifdef SUPPORT_GRAPHICS
 47.1198 ++
 47.1199 ++#include <term.h>
 47.1200 ++#include <shared.h>
 47.1201 ++#include <graphics.h>
 47.1202 ++
 47.1203 ++int saved_videomode;
 47.1204 ++unsigned char *font8x16;
 47.1205 ++
 47.1206 ++int graphics_inited = 0;
 47.1207 ++static char splashimage[256];
 47.1208 ++
 47.1209 ++int shade = 1, no_cursor = 0;
 47.1210 ++
 47.1211 ++#define VSHADOW VSHADOW1
 47.1212 ++unsigned char VSHADOW1[38400];
 47.1213 ++unsigned char VSHADOW2[38400];
 47.1214 ++unsigned char VSHADOW4[38400];
 47.1215 ++unsigned char VSHADOW8[38400];
 47.1216 ++
 47.1217 ++/* define the default viewable area */
 47.1218 ++int view_x0 = 0;
 47.1219 ++int view_y0 = 0;
 47.1220 ++int view_x1 = 80;
 47.1221 ++int view_y1 = 30;
 47.1222 ++
 47.1223 ++/* text buffer has to be kept around so that we can write things as we
 47.1224 ++ * scroll and the like */
 47.1225 ++unsigned short text[80 * 30];
 47.1226 ++
 47.1227 ++/* graphics options */
 47.1228 ++int foreground = (63 << 16) | (63 << 8) | (63), background = 0, window_border = 0;
 47.1229 ++
 47.1230 ++/* current position */
 47.1231 ++static int fontx = 0;
 47.1232 ++static int fonty = 0;
 47.1233 ++
 47.1234 ++/* global state so that we don't try to recursively scroll or cursor */
 47.1235 ++static int no_scroll = 0;
 47.1236 ++
 47.1237 ++/* color state */
 47.1238 ++static int graphics_standard_color = A_NORMAL;
 47.1239 ++static int graphics_normal_color = A_NORMAL;
 47.1240 ++static int graphics_highlight_color = A_REVERSE;
 47.1241 ++static int graphics_current_color = A_NORMAL;
 47.1242 ++static color_state graphics_color_state = COLOR_STATE_STANDARD;
 47.1243 ++
 47.1244 ++static inline void outb(unsigned short port, unsigned char val)
 47.1245 ++{
 47.1246 ++    __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
 47.1247 ++}
 47.1248 ++
 47.1249 ++static void MapMask(int value) {
 47.1250 ++    outb(0x3c4, 2);
 47.1251 ++    outb(0x3c5, value);
 47.1252 ++}
 47.1253 ++
 47.1254 ++/* bit mask register */
 47.1255 ++static void BitMask(int value) {
 47.1256 ++    outb(0x3ce, 8);
 47.1257 ++    outb(0x3cf, value);
 47.1258 ++}
 47.1259 ++
 47.1260 ++/* move the graphics cursor location to col, row */
 47.1261 ++static void graphics_setxy(int col, int row) {
 47.1262 ++    if (col >= view_x0 && col < view_x1) {
 47.1263 ++        fontx = col;
 47.1264 ++        cursorX = col << 3;
 47.1265 ++    }
 47.1266 ++    if (row >= view_y0 && row < view_y1) {
 47.1267 ++        fonty = row;
 47.1268 ++        cursorY = row << 4;
 47.1269 ++    }
 47.1270 ++}
 47.1271 ++
 47.1272 ++/* scroll the screen */
 47.1273 ++static void graphics_scroll() {
 47.1274 ++    int i, j, k;
 47.1275 ++
 47.1276 ++    /* we don't want to scroll recursively... that would be bad */
 47.1277 ++    if (no_scroll)
 47.1278 ++        return;
 47.1279 ++    no_scroll = 1;
 47.1280 ++
 47.1281 ++    /* disable pager temporarily */
 47.1282 ++    k = count_lines;
 47.1283 ++    count_lines = -1;
 47.1284 ++    
 47.1285 ++    /* move everything up a line */
 47.1286 ++    for (j = view_y0 + 1; j < view_y1; j++) {
 47.1287 ++        graphics_gotoxy(view_x0, j - 1);
 47.1288 ++        for (i = view_x0; i < view_x1; i++) {
 47.1289 ++            graphics_putchar(text[j * 80 + i]);
 47.1290 ++        }
 47.1291 ++    }
 47.1292 ++
 47.1293 ++    /* last line should be blank */
 47.1294 ++    graphics_gotoxy(view_x0, view_y1 - 1);
 47.1295 ++    for (i = view_x0; i < view_x1; i++)
 47.1296 ++        graphics_putchar(' ');
 47.1297 ++    graphics_setxy(view_x0, view_y1 - 1);
 47.1298 ++
 47.1299 ++    count_lines = k;
 47.1300 ++
 47.1301 ++    no_scroll = 0;
 47.1302 ++}
 47.1303 ++
 47.1304 ++/* Set the splash image */
 47.1305 ++void graphics_set_splash(char *splashfile) {
 47.1306 ++    grub_strcpy(splashimage, splashfile);
 47.1307 ++}
 47.1308 ++
 47.1309 ++/* Get the current splash image */
 47.1310 ++char *graphics_get_splash(void) {
 47.1311 ++    return splashimage;
 47.1312 ++}
 47.1313 ++
 47.1314 ++/* 
 47.1315 ++ * Initialize a vga16 graphics display with the palette based off of
 47.1316 ++ * the image in splashimage.  If the image doesn't exist, leave graphics
 47.1317 ++ * mode. The mode initiated is 12h. From "Ralf Brown's Interrupt List":
 47.1318 ++ *      text/ text pixel   pixel   colors disply scrn  system
 47.1319 ++ *      grph resol  box  resolution       pages  addr
 47.1320 ++ * 12h   G   80x30  8x16  640x480  16/256K  .    A000  VGA,ATI VIP
 47.1321 ++ *       G   80x30  8x16  640x480  16/64    .    A000  ATI EGA Wonder
 47.1322 ++ *       G     .     .    640x480  16       .      .   UltraVision+256K EGA
 47.1323 ++ */
 47.1324 ++int graphics_init()
 47.1325 ++{
 47.1326 ++    if (!graphics_inited) {
 47.1327 ++        saved_videomode = set_videomode(0x12);
 47.1328 ++        if (get_videomode() != 0x12) {
 47.1329 ++            set_videomode(saved_videomode);
 47.1330 ++            return 0;
 47.1331 ++        }
 47.1332 ++        graphics_inited = 1;
 47.1333 ++    }
 47.1334 ++    else
 47.1335 ++        return 1;
 47.1336 ++
 47.1337 ++    font8x16 = (unsigned char*)graphics_get_font();
 47.1338 ++
 47.1339 ++    /* make sure that the highlight color is set correctly */
 47.1340 ++    graphics_highlight_color = ((graphics_normal_color >> 4) | 
 47.1341 ++                                ((graphics_normal_color & 0xf) << 4));
 47.1342 ++
 47.1343 ++    graphics_cls();
 47.1344 ++
 47.1345 ++    if (!read_image(splashimage)) {
 47.1346 ++        grub_printf("Failed to read splash image (%s)\n", splashimage);
 47.1347 ++        grub_printf("Press any key to continue...");
 47.1348 ++        getkey();
 47.1349 ++        set_videomode(saved_videomode);
 47.1350 ++        graphics_inited = 0;
 47.1351 ++        return 0;
 47.1352 ++    }
 47.1353 ++
 47.1354 ++    set_int1c_handler();
 47.1355 ++
 47.1356 ++    return 1;
 47.1357 ++}
 47.1358 ++
 47.1359 ++/* Leave graphics mode */
 47.1360 ++void graphics_end(void)
 47.1361 ++{
 47.1362 ++    if (graphics_inited) {
 47.1363 ++        unset_int1c_handler();
 47.1364 ++        set_videomode(saved_videomode);
 47.1365 ++        graphics_inited = 0;
 47.1366 ++        no_cursor = 0;
 47.1367 ++    }
 47.1368 ++}
 47.1369 ++
 47.1370 ++/* Print ch on the screen.  Handle any needed scrolling or the like */
 47.1371 ++void graphics_putchar(int ch) {
 47.1372 ++    ch &= 0xff;
 47.1373 ++
 47.1374 ++    graphics_cursor(0);
 47.1375 ++
 47.1376 ++    if (ch == '\n') {
 47.1377 ++        if (fonty + 1 < view_y1)
 47.1378 ++            graphics_setxy(fontx, fonty + 1);
 47.1379 ++        else
 47.1380 ++            graphics_scroll();
 47.1381 ++        graphics_cursor(1);
 47.1382 ++        return;
 47.1383 ++    } else if (ch == '\r') {
 47.1384 ++        graphics_setxy(view_x0, fonty);
 47.1385 ++        graphics_cursor(1);
 47.1386 ++        return;
 47.1387 ++    }
 47.1388 ++
 47.1389 ++    graphics_cursor(0);
 47.1390 ++
 47.1391 ++    text[fonty * 80 + fontx] = ch;
 47.1392 ++    text[fonty * 80 + fontx] &= 0x00ff;
 47.1393 ++    if (graphics_current_color & 0xf0)
 47.1394 ++        text[fonty * 80 + fontx] |= 0x100;
 47.1395 ++
 47.1396 ++    graphics_cursor(0);
 47.1397 ++
 47.1398 ++    if ((fontx + 1) >= view_x1) {
 47.1399 ++        graphics_setxy(view_x0, fonty);
 47.1400 ++        if (fonty + 1 < view_y1)
 47.1401 ++            graphics_setxy(view_x0, fonty + 1);
 47.1402 ++        else
 47.1403 ++            graphics_scroll();
 47.1404 ++        graphics_cursor(1);
 47.1405 ++        do_more ();
 47.1406 ++        graphics_cursor(0);
 47.1407 ++    } else {
 47.1408 ++        graphics_setxy(fontx + 1, fonty);
 47.1409 ++    }
 47.1410 ++
 47.1411 ++    graphics_cursor(1);
 47.1412 ++}
 47.1413 ++
 47.1414 ++/* get the current location of the cursor */
 47.1415 ++int graphics_getxy(void) {
 47.1416 ++    return (fontx << 8) | fonty;
 47.1417 ++}
 47.1418 ++
 47.1419 ++void graphics_gotoxy(int x, int y) {
 47.1420 ++    graphics_cursor(0);
 47.1421 ++
 47.1422 ++    graphics_setxy(x, y);
 47.1423 ++
 47.1424 ++    graphics_cursor(1);
 47.1425 ++}
 47.1426 ++
 47.1427 ++void graphics_cls(void) {
 47.1428 ++    int i;
 47.1429 ++    unsigned char *mem, *s1, *s2, *s4, *s8;
 47.1430 ++
 47.1431 ++    graphics_cursor(0);
 47.1432 ++    graphics_gotoxy(view_x0, view_y0);
 47.1433 ++
 47.1434 ++    mem = (unsigned char*)VIDEOMEM;
 47.1435 ++    s1 = (unsigned char*)VSHADOW1;
 47.1436 ++    s2 = (unsigned char*)VSHADOW2;
 47.1437 ++    s4 = (unsigned char*)VSHADOW4;
 47.1438 ++    s8 = (unsigned char*)VSHADOW8;
 47.1439 ++
 47.1440 ++    for (i = 0; i < 80 * 30; i++)
 47.1441 ++        text[i] = ' ';
 47.1442 ++    graphics_cursor(1);
 47.1443 ++
 47.1444 ++    BitMask(0xff);
 47.1445 ++
 47.1446 ++    /* plane 1 */
 47.1447 ++    MapMask(1);
 47.1448 ++    grub_memcpy(mem, s1, 38400);
 47.1449 ++
 47.1450 ++    /* plane 2 */
 47.1451 ++    MapMask(2);
 47.1452 ++    grub_memcpy(mem, s2, 38400);
 47.1453 ++
 47.1454 ++    /* plane 3 */
 47.1455 ++    MapMask(4);
 47.1456 ++    grub_memcpy(mem, s4, 38400);
 47.1457 ++
 47.1458 ++    /* plane 4 */
 47.1459 ++    MapMask(8);
 47.1460 ++    grub_memcpy(mem, s8, 38400);
 47.1461 ++
 47.1462 ++    MapMask(15);
 47.1463 ++
 47.1464 ++    if (no_cursor) {
 47.1465 ++        no_cursor = 0;
 47.1466 ++        set_int1c_handler();
 47.1467 ++    }
 47.1468 ++}
 47.1469 ++
 47.1470 ++void graphics_setcolorstate (color_state state) {
 47.1471 ++    switch (state) {
 47.1472 ++    case COLOR_STATE_STANDARD:
 47.1473 ++        graphics_current_color = graphics_standard_color;
 47.1474 ++        break;
 47.1475 ++    case COLOR_STATE_NORMAL:
 47.1476 ++        graphics_current_color = graphics_normal_color;
 47.1477 ++        break;
 47.1478 ++    case COLOR_STATE_HIGHLIGHT:
 47.1479 ++        graphics_current_color = graphics_highlight_color;
 47.1480 ++        break;
 47.1481 ++    default:
 47.1482 ++        graphics_current_color = graphics_standard_color;
 47.1483 ++        break;
 47.1484 ++    }
 47.1485 ++
 47.1486 ++    graphics_color_state = state;
 47.1487 ++}
 47.1488 ++
 47.1489 ++void graphics_setcolor (int normal_color, int highlight_color) {
 47.1490 ++    graphics_normal_color = normal_color;
 47.1491 ++    graphics_highlight_color = highlight_color;
 47.1492 ++
 47.1493 ++    graphics_setcolorstate (graphics_color_state);
 47.1494 ++}
 47.1495 ++
 47.1496 ++int graphics_setcursor (int on) {
 47.1497 ++    if (!no_cursor && !on) {
 47.1498 ++        no_cursor = 1;
 47.1499 ++        unset_int1c_handler();
 47.1500 ++        graphics_cursor(0);
 47.1501 ++    }
 47.1502 ++    else if(no_cursor && on) {
 47.1503 ++        no_cursor = 0;
 47.1504 ++        set_int1c_handler();
 47.1505 ++        graphics_cursor(1);
 47.1506 ++    }
 47.1507 ++    return 0;
 47.1508 ++}
 47.1509 ++
 47.1510 ++/* Read in the splashscreen image and set the palette up appropriately.
 47.1511 ++ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
 47.1512 ++ * 640x480. */
 47.1513 ++int read_image(char *s)
 47.1514 ++{
 47.1515 ++    char buf[32], pal[16], c;
 47.1516 ++    unsigned char base, mask, *s1, *s2, *s4, *s8;
 47.1517 ++    unsigned i, len, idx, colors, x, y, width, height;
 47.1518 ++
 47.1519 ++    if (!grub_open(s))
 47.1520 ++        return 0;
 47.1521 ++
 47.1522 ++    /* read header */
 47.1523 ++    if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {
 47.1524 ++        grub_close();
 47.1525 ++        return 0;
 47.1526 ++    }
 47.1527 ++    
 47.1528 ++    /* parse info */
 47.1529 ++    while (grub_read(&c, 1)) {
 47.1530 ++        if (c == '"')
 47.1531 ++            break;
 47.1532 ++    }
 47.1533 ++
 47.1534 ++    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
 47.1535 ++        ;
 47.1536 ++
 47.1537 ++    i = 0;
 47.1538 ++    width = c - '0';
 47.1539 ++    while (grub_read(&c, 1)) {
 47.1540 ++        if (c >= '0' && c <= '9')
 47.1541 ++            width = width * 10 + c - '0';
 47.1542 ++        else
 47.1543 ++            break;
 47.1544 ++    }
 47.1545 ++    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
 47.1546 ++        ;
 47.1547 ++
 47.1548 ++    height = c - '0';
 47.1549 ++    while (grub_read(&c, 1)) {
 47.1550 ++        if (c >= '0' && c <= '9')
 47.1551 ++            height = height * 10 + c - '0';
 47.1552 ++        else
 47.1553 ++            break;
 47.1554 ++    }
 47.1555 ++    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
 47.1556 ++        ;
 47.1557 ++
 47.1558 ++    colors = c - '0';
 47.1559 ++    while (grub_read(&c, 1)) {
 47.1560 ++        if (c >= '0' && c <= '9')
 47.1561 ++            colors = colors * 10 + c - '0';
 47.1562 ++        else
 47.1563 ++            break;
 47.1564 ++    }
 47.1565 ++
 47.1566 ++    base = 0;
 47.1567 ++    while (grub_read(&c, 1) && c != '"')
 47.1568 ++        ;
 47.1569 ++
 47.1570 ++    /* palette */
 47.1571 ++    for (i = 0, idx = 1; i < colors; i++) {
 47.1572 ++        len = 0;
 47.1573 ++
 47.1574 ++        while (grub_read(&c, 1) && c != '"')
 47.1575 ++            ;
 47.1576 ++        grub_read(&c, 1);       /* char */
 47.1577 ++        base = c;
 47.1578 ++        grub_read(buf, 4);      /* \t c # */
 47.1579 ++
 47.1580 ++        while (grub_read(&c, 1) && c != '"') {
 47.1581 ++            if (len < sizeof(buf))
 47.1582 ++                buf[len++] = c;
 47.1583 ++        }
 47.1584 ++
 47.1585 ++        if (len == 6 && idx < 15) {
 47.1586 ++            int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
 47.1587 ++            int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
 47.1588 ++            int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
 47.1589 ++
 47.1590 ++            pal[idx] = base;
 47.1591 ++            graphics_set_palette(idx, r, g, b);
 47.1592 ++            ++idx;
 47.1593 ++        }
 47.1594 ++    }
 47.1595 ++
 47.1596 ++    x = y = len = 0;
 47.1597 ++
 47.1598 ++    s1 = (unsigned char*)VSHADOW1;
 47.1599 ++    s2 = (unsigned char*)VSHADOW2;
 47.1600 ++    s4 = (unsigned char*)VSHADOW4;
 47.1601 ++    s8 = (unsigned char*)VSHADOW8;
 47.1602 ++
 47.1603 ++    for (i = 0; i < 38400; i++)
 47.1604 ++        s1[i] = s2[i] = s4[i] = s8[i] = 0;
 47.1605 ++
 47.1606 ++    /* parse xpm data */
 47.1607 ++    while (y < height) {
 47.1608 ++        while (1) {
 47.1609 ++            if (!grub_read(&c, 1)) {
 47.1610 ++                grub_close();
 47.1611 ++                return 0;
 47.1612 ++            }
 47.1613 ++            if (c == '"')
 47.1614 ++                break;
 47.1615 ++        }
 47.1616 ++
 47.1617 ++        while (grub_read(&c, 1) && c != '"') {
 47.1618 ++            for (i = 1; i < 15; i++)
 47.1619 ++                if (pal[i] == c) {
 47.1620 ++                    c = i;
 47.1621 ++                    break;
 47.1622 ++                }
 47.1623 ++
 47.1624 ++            mask = 0x80 >> (x & 7);
 47.1625 ++            if (c & 1)
 47.1626 ++                s1[len + (x >> 3)] |= mask;
 47.1627 ++            if (c & 2)
 47.1628 ++                s2[len + (x >> 3)] |= mask;
 47.1629 ++            if (c & 4)
 47.1630 ++                s4[len + (x >> 3)] |= mask;
 47.1631 ++            if (c & 8)
 47.1632 ++                s8[len + (x >> 3)] |= mask;
 47.1633 ++
 47.1634 ++            if (++x >= 640) {
 47.1635 ++                x = 0;
 47.1636 ++
 47.1637 ++                if (y < 480)
 47.1638 ++                    len += 80;
 47.1639 ++                ++y;
 47.1640 ++            }
 47.1641 ++        }
 47.1642 ++    }
 47.1643 ++
 47.1644 ++    grub_close();
 47.1645 ++
 47.1646 ++    graphics_set_palette(0, (background >> 16), (background >> 8) & 63, 
 47.1647 ++                background & 63);
 47.1648 ++    graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63, 
 47.1649 ++                foreground & 63);
 47.1650 ++    graphics_set_palette(0x11, (window_border >> 16), (window_border >> 8) & 63, 
 47.1651 ++                         window_border & 63);
 47.1652 ++
 47.1653 ++    return 1;
 47.1654 ++}
 47.1655 ++
 47.1656 ++/* Convert a character which is a hex digit to the appropriate integer */
 47.1657 ++int hex(int v)
 47.1658 ++{
 47.1659 ++    if (v >= 'A' && v <= 'F')
 47.1660 ++        return (v - 'A' + 10);
 47.1661 ++    if (v >= 'a' && v <= 'f')
 47.1662 ++        return (v - 'a' + 10);
 47.1663 ++    return (v - '0');
 47.1664 ++}
 47.1665 ++
 47.1666 ++void graphics_cursor(int set) {
 47.1667 ++    unsigned char *pat, *mem, *ptr, chr[16 << 2];
 47.1668 ++    int i, ch, invert, offset;
 47.1669 ++
 47.1670 ++    if (set && (no_cursor || no_scroll))
 47.1671 ++        return;
 47.1672 ++
 47.1673 ++    offset = cursorY * 80 + fontx;
 47.1674 ++    ch = text[fonty * 80 + fontx] & 0xff;
 47.1675 ++    invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
 47.1676 ++    pat = font8x16 + (ch << 4);
 47.1677 ++
 47.1678 ++    mem = (unsigned char*)VIDEOMEM + offset;
 47.1679 ++
 47.1680 ++    if (!set) {
 47.1681 ++        for (i = 0; i < 16; i++) {
 47.1682 ++            unsigned char mask = pat[i];
 47.1683 ++
 47.1684 ++            if (!invert) {
 47.1685 ++                chr[i     ] = ((unsigned char*)VSHADOW1)[offset];
 47.1686 ++                chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
 47.1687 ++                chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
 47.1688 ++                chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
 47.1689 ++
 47.1690 ++                if (shade) {
 47.1691 ++                    if (ch == DISP_VERT || ch == DISP_LL ||
 47.1692 ++                        ch == DISP_UR || ch == DISP_LR) {
 47.1693 ++                        unsigned char pmask = ~(pat[i] >> 1);
 47.1694 ++
 47.1695 ++                        chr[i     ] &= pmask;
 47.1696 ++                        chr[16 + i] &= pmask;
 47.1697 ++                        chr[32 + i] &= pmask;
 47.1698 ++                        chr[48 + i] &= pmask;
 47.1699 ++                    }
 47.1700 ++                    if (i > 0 && ch != DISP_VERT) {
 47.1701 ++                        unsigned char pmask = ~(pat[i - 1] >> 1);
 47.1702 ++
 47.1703 ++                        chr[i     ] &= pmask;
 47.1704 ++                        chr[16 + i] &= pmask;
 47.1705 ++                        chr[32 + i] &= pmask;
 47.1706 ++                        chr[48 + i] &= pmask;
 47.1707 ++                        if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) {
 47.1708 ++                            pmask = ~pat[i - 1];
 47.1709 ++
 47.1710 ++                            chr[i     ] &= pmask;
 47.1711 ++                            chr[16 + i] &= pmask;
 47.1712 ++                            chr[32 + i] &= pmask;
 47.1713 ++                            chr[48 + i] &= pmask;
 47.1714 ++                        }
 47.1715 ++                    }
 47.1716 ++                }
 47.1717 ++                chr[i     ] |= mask;
 47.1718 ++                chr[16 + i] |= mask;
 47.1719 ++                chr[32 + i] |= mask;
 47.1720 ++                chr[48 + i] |= mask;
 47.1721 ++
 47.1722 ++                offset += 80;
 47.1723 ++            }
 47.1724 ++            else {
 47.1725 ++                chr[i     ] = mask;
 47.1726 ++                chr[16 + i] = mask;
 47.1727 ++                chr[32 + i] = mask;
 47.1728 ++                chr[48 + i] = mask;
 47.1729 ++            }
 47.1730 ++        }
 47.1731 ++    }
 47.1732 ++    else {
 47.1733 ++        MapMask(15);
 47.1734 ++        ptr = mem;
 47.1735 ++        for (i = 0; i < 16; i++, ptr += 80) {
 47.1736 ++            cursorBuf[i] = pat[i];
 47.1737 ++            *ptr = ~pat[i];
 47.1738 ++        }
 47.1739 ++        return;
 47.1740 ++    }
 47.1741 ++
 47.1742 ++    offset = 0;
 47.1743 ++    for (i = 1; i < 16; i <<= 1, offset += 16) {
 47.1744 ++        int j;
 47.1745 ++
 47.1746 ++        MapMask(i);
 47.1747 ++        ptr = mem;
 47.1748 ++        for (j = 0; j < 16; j++, ptr += 80)
 47.1749 ++            *ptr = chr[j + offset];
 47.1750 ++    }
 47.1751 ++
 47.1752 ++    MapMask(15);
 47.1753 ++}
 47.1754 ++
 47.1755 ++#endif /* SUPPORT_GRAPHICS */
 47.1756 +diff -Naur grub-0.97.orig/stage2/graphics.h grub-0.97/stage2/graphics.h
 47.1757 +--- grub-0.97.orig/stage2/graphics.h	1969-12-31 21:00:00.000000000 -0300
 47.1758 ++++ grub-0.97/stage2/graphics.h	2005-06-12 20:56:49.000000000 -0300
 47.1759 +@@ -0,0 +1,44 @@
 47.1760 ++/* graphics.h - graphics console interface */
 47.1761 ++/*
 47.1762 ++ *  GRUB  --  GRand Unified Bootloader
 47.1763 ++ *  Copyright (C) 2002  Free Software Foundation, Inc.
 47.1764 ++ *
 47.1765 ++ *  This program is free software; you can redistribute it and/or modify
 47.1766 ++ *  it under the terms of the GNU General Public License as published by
 47.1767 ++ *  the Free Software Foundation; either version 2 of the License, or
 47.1768 ++ *  (at your option) any later version.
 47.1769 ++ *
 47.1770 ++ *  This program is distributed in the hope that it will be useful,
 47.1771 ++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 47.1772 ++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 47.1773 ++ *  GNU General Public License for more details.
 47.1774 ++ *
 47.1775 ++ *  You should have received a copy of the GNU General Public License
 47.1776 ++ *  along with this program; if not, write to the Free Software
 47.1777 ++ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 47.1778 ++ */
 47.1779 ++
 47.1780 ++#ifndef GRAPHICS_H
 47.1781 ++#define GRAPHICS_H
 47.1782 ++
 47.1783 ++/* magic constant */
 47.1784 ++#define VIDEOMEM 0xA0000
 47.1785 ++
 47.1786 ++/* function prototypes */
 47.1787 ++char *graphics_get_splash(void);
 47.1788 ++
 47.1789 ++int read_image(char *s);
 47.1790 ++void graphics_cursor(int set);
 47.1791 ++
 47.1792 ++/* function prototypes for asm functions */
 47.1793 ++void * graphics_get_font();
 47.1794 ++void graphics_set_palette(int idx, int red, int green, int blue);
 47.1795 ++void set_int1c_handler();
 47.1796 ++void unset_int1c_handler();
 47.1797 ++
 47.1798 ++extern short cursorX, cursorY;
 47.1799 ++extern char cursorBuf[16];
 47.1800 ++extern int shade;
 47.1801 ++extern int view_x0, view_y0, view_x1, view_y1;
 47.1802 ++
 47.1803 ++#endif /* GRAPHICS_H */
 47.1804 +diff -Naur grub-0.97.orig/stage2/Makefile.am grub-0.97/stage2/Makefile.am
 47.1805 +--- grub-0.97.orig/stage2/Makefile.am	2005-02-02 18:37:35.000000000 -0200
 47.1806 ++++ grub-0.97/stage2/Makefile.am	2005-06-12 20:56:49.000000000 -0300
 47.1807 +@@ -7,7 +7,7 @@
 47.1808 +         fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \
 47.1809 + 	imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \
 47.1810 + 	nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \
 47.1811 +-	terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h
 47.1812 ++	terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h
 47.1813 + EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
 47.1814 + 
 47.1815 + # For <stage1.h>.
 47.1816 +@@ -19,7 +19,7 @@
 47.1817 + 	disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
 47.1818 + 	fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
 47.1819 + 	fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
 47.1820 +-	terminfo.c tparm.c
 47.1821 ++	terminfo.c tparm.c graphics.c
 47.1822 + libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
 47.1823 + 	-DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
 47.1824 + 	-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
 47.1825 +@@ -79,8 +79,14 @@
 47.1826 + HERCULES_FLAGS =
 47.1827 + endif
 47.1828 + 
 47.1829 ++if GRAPHICS_SUPPORT
 47.1830 ++GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1
 47.1831 ++else
 47.1832 ++GRAPHICS_FLAGS =
 47.1833 ++endif
 47.1834 ++
 47.1835 + STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
 47.1836 +-	$(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
 47.1837 ++	$(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS)
 47.1838 + 
 47.1839 + STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
 47.1840 + STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
 47.1841 +@@ -90,7 +96,8 @@
 47.1842 + 	cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
 47.1843 + 	fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
 47.1844 + 	fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
 47.1845 +-	hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
 47.1846 ++	hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \
 47.1847 ++	graphics.c
 47.1848 + pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
 47.1849 + pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
 47.1850 + pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
 47.1851 +diff -Naur grub-0.97.orig/stage2/shared.h grub-0.97/stage2/shared.h
 47.1852 +--- grub-0.97.orig/stage2/shared.h	2004-06-19 13:40:09.000000000 -0300
 47.1853 ++++ grub-0.97/stage2/shared.h	2005-06-12 20:56:49.000000000 -0300
 47.1854 +@@ -792,6 +792,11 @@
 47.1855 + /* Set the cursor position. */
 47.1856 + void gotoxy (int x, int y);
 47.1857 + 
 47.1858 ++/* Internal pager
 47.1859 ++   Returns 1 = if pager was used
 47.1860 ++           0 = if pager wasn't used  */
 47.1861 ++int do_more (void);
 47.1862 ++
 47.1863 + /* Displays an ASCII character.  IBM displays will translate some
 47.1864 +    characters to special graphical ones (see the DISP_* constants). */
 47.1865 + void grub_putchar (int c);
 47.1866 +@@ -871,6 +876,7 @@
 47.1867 + int grub_tolower (int c);
 47.1868 + int grub_isspace (int c);
 47.1869 + int grub_strncat (char *s1, const char *s2, int n);
 47.1870 ++void grub_memcpy(void *dest, const void *src, int len);
 47.1871 + void *grub_memmove (void *to, const void *from, int len);
 47.1872 + void *grub_memset (void *start, int c, int len);
 47.1873 + int grub_strncat (char *s1, const char *s2, int n);
 47.1874 +diff -Naur grub-0.97.orig/stage2/stage2.c grub-0.97/stage2/stage2.c
 47.1875 +--- grub-0.97.orig/stage2/stage2.c	2005-03-19 14:51:57.000000000 -0300
 47.1876 ++++ grub-0.97/stage2/stage2.c	2005-06-13 22:38:08.000000000 -0300
 47.1877 +@@ -20,6 +20,12 @@
 47.1878 + #include <shared.h>
 47.1879 + #include <term.h>
 47.1880 + 
 47.1881 ++#ifdef SUPPORT_GRAPHICS
 47.1882 ++# include <graphics.h>
 47.1883 ++#endif
 47.1884 ++
 47.1885 ++int col_start, col_end, row_start, box_size;
 47.1886 ++
 47.1887 + grub_jmp_buf restart_env;
 47.1888 + 
 47.1889 + #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
 47.1890 +@@ -105,13 +111,13 @@
 47.1891 +   if (highlight && current_term->setcolorstate)
 47.1892 +     current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
 47.1893 + 
 47.1894 +-  gotoxy (2, y);
 47.1895 ++  gotoxy (2 + col_start, y);
 47.1896 +   grub_putchar (' ');
 47.1897 +-  for (x = 3; x < 75; x++)
 47.1898 ++  for (x = 3 + col_start; x < (col_end - 5); x++)
 47.1899 +     {
 47.1900 +-      if (*entry && x <= 72)
 47.1901 ++      if (*entry && x <= (col_end - 8))
 47.1902 + 	{
 47.1903 +-	  if (x == 72)
 47.1904 ++	  if (x == (col_end - 8))
 47.1905 + 	    grub_putchar (DISP_RIGHT);
 47.1906 + 	  else
 47.1907 + 	    grub_putchar (*entry++);
 47.1908 +@@ -119,7 +125,7 @@
 47.1909 +       else
 47.1910 + 	grub_putchar (' ');
 47.1911 +     }
 47.1912 +-  gotoxy (74, y);
 47.1913 ++  gotoxy ((col_end - 6), y);
 47.1914 + 
 47.1915 +   if (current_term->setcolorstate)
 47.1916 +     current_term->setcolorstate (COLOR_STATE_STANDARD);
 47.1917 +@@ -131,7 +137,7 @@
 47.1918 + {
 47.1919 +   int i;
 47.1920 +   
 47.1921 +-  gotoxy (77, y + 1);
 47.1922 ++  gotoxy ((col_end - 3), y + 1);
 47.1923 + 
 47.1924 +   if (first)
 47.1925 +     grub_putchar (DISP_UP);
 47.1926 +@@ -151,14 +157,14 @@
 47.1927 + 	menu_entries++;
 47.1928 +     }
 47.1929 + 
 47.1930 +-  gotoxy (77, y + size);
 47.1931 ++  gotoxy ((col_end - 3), y + size);
 47.1932 + 
 47.1933 +   if (*menu_entries)
 47.1934 +     grub_putchar (DISP_DOWN);
 47.1935 +   else
 47.1936 +     grub_putchar (' ');
 47.1937 + 
 47.1938 +-  gotoxy (74, y + entryno + 1);
 47.1939 ++  gotoxy ((col_end - 6), y + entryno + 1);
 47.1940 + }
 47.1941 + 
 47.1942 + static void
 47.1943 +@@ -196,30 +202,30 @@
 47.1944 +   if (current_term->setcolorstate)
 47.1945 +     current_term->setcolorstate (COLOR_STATE_NORMAL);
 47.1946 +   
 47.1947 +-  gotoxy (1, y);
 47.1948 ++  gotoxy (1 + col_start, y);
 47.1949 + 
 47.1950 +   grub_putchar (DISP_UL);
 47.1951 +-  for (i = 0; i < 73; i++)
 47.1952 ++  for (i = col_start; i < (col_end - 7); i++)
 47.1953 +     grub_putchar (DISP_HORIZ);
 47.1954 +   grub_putchar (DISP_UR);
 47.1955 + 
 47.1956 +   i = 1;
 47.1957 +   while (1)
 47.1958 +     {
 47.1959 +-      gotoxy (1, y + i);
 47.1960 ++      gotoxy (1 + col_start, y + i);
 47.1961 + 
 47.1962 +       if (i > size)
 47.1963 + 	break;
 47.1964 +       
 47.1965 +       grub_putchar (DISP_VERT);
 47.1966 +-      gotoxy (75, y + i);
 47.1967 ++      gotoxy ((col_end - 5), y + i);
 47.1968 +       grub_putchar (DISP_VERT);
 47.1969 + 
 47.1970 +       i++;
 47.1971 +     }
 47.1972 + 
 47.1973 +   grub_putchar (DISP_LL);
 47.1974 +-  for (i = 0; i < 73; i++)
 47.1975 ++  for (i = col_start; i < (col_end - 7); i++)
 47.1976 +     grub_putchar (DISP_HORIZ);
 47.1977 +   grub_putchar (DISP_LR);
 47.1978 + 
 47.1979 +@@ -233,6 +239,7 @@
 47.1980 + {
 47.1981 +   int c, time1, time2 = -1, first_entry = 0;
 47.1982 +   char *cur_entry = 0;
 47.1983 ++  struct term_entry *prev_term = NULL;
 47.1984 + 
 47.1985 +   /*
 47.1986 +    *  Main loop for menu UI.
 47.1987 +@@ -250,6 +257,22 @@
 47.1988 + 	}
 47.1989 +     }
 47.1990 + 
 47.1991 ++  col_start = 0;
 47.1992 ++  col_end = 80;
 47.1993 ++  row_start = 0;
 47.1994 ++  box_size = 12;
 47.1995 ++  /* if we're using viewport we need to make sure to setup
 47.1996 ++     coordinates correctly.  */
 47.1997 ++#ifdef SUPPORT_GRAPHICS
 47.1998 ++  if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
 47.1999 ++    {
 47.2000 ++      col_start = view_x0;
 47.2001 ++      col_end = view_x1;
 47.2002 ++      row_start = view_y0;
 47.2003 ++      box_size = (view_y1 - view_y0) - 13;
 47.2004 ++    }
 47.2005 ++#endif
 47.2006 ++
 47.2007 +   /* If the timeout was expired or wasn't set, force to show the menu
 47.2008 +      interface. */
 47.2009 +   if (grub_timeout < 0)
 47.2010 +@@ -302,36 +325,36 @@
 47.2011 +       if (current_term->flags & TERM_DUMB)
 47.2012 + 	print_entries_raw (num_entries, first_entry, menu_entries);
 47.2013 +       else
 47.2014 +-	print_border (3, 12);
 47.2015 ++	print_border (3 + row_start, box_size);
 47.2016 + 
 47.2017 +       grub_printf ("\n\
 47.2018 +-      Use the %c and %c keys to select which entry is highlighted.\n",
 47.2019 ++    Use the %c and %c keys to select which entry is highlighted.\n",
 47.2020 + 		   DISP_UP, DISP_DOWN);
 47.2021 +       
 47.2022 +       if (! auth && password)
 47.2023 + 	{
 47.2024 + 	  printf ("\
 47.2025 +-      Press enter to boot the selected OS or \'p\' to enter a\n\
 47.2026 +-      password to unlock the next set of features.");
 47.2027 ++    Press enter to boot the selected OS or \'p\' to enter a\n\
 47.2028 ++    password to unlock the next set of features.");
 47.2029 + 	}
 47.2030 +       else
 47.2031 + 	{
 47.2032 + 	  if (config_entries)
 47.2033 + 	    printf ("\
 47.2034 +-      Press enter to boot the selected OS, \'e\' to edit the\n\
 47.2035 +-      commands before booting, or \'c\' for a command-line.");
 47.2036 ++    Press enter to boot the selected OS, \'e\' to edit the\n\
 47.2037 ++    commands before booting, or \'c\' for a command-line.");
 47.2038 + 	  else
 47.2039 + 	    printf ("\
 47.2040 +-      Press \'b\' to boot, \'e\' to edit the selected command in the\n\
 47.2041 +-      boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
 47.2042 +-      after (\'O\' for before) the selected line, \'d\' to remove the\n\
 47.2043 +-      selected line, or escape to go back to the main menu.");
 47.2044 ++    Press \'b\' to boot, \'e\' to edit the selected command in the\n\
 47.2045 ++    boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
 47.2046 ++    after (\'O\' for before) the selected line, \'d\' to remove the\n\
 47.2047 ++    selected line, or escape to go back to the main menu.");
 47.2048 + 	}
 47.2049 + 
 47.2050 +       if (current_term->flags & TERM_DUMB)
 47.2051 + 	grub_printf ("\n\nThe selected entry is %d ", entryno);
 47.2052 +       else
 47.2053 +-	print_entries (3, 12, first_entry, entryno, menu_entries);
 47.2054 ++	print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
 47.2055 +     }
 47.2056 + 
 47.2057 +   /* XX using RT clock now, need to initialize value */
 47.2058 +@@ -358,10 +381,10 @@
 47.2059 + 			   entryno, grub_timeout);
 47.2060 + 	  else
 47.2061 + 	    {
 47.2062 +-	      gotoxy (3, 22);
 47.2063 +-	      grub_printf ("The highlighted entry will be booted automatically in %d seconds.    ",
 47.2064 ++	      gotoxy (3 + col_start, 10 + box_size + row_start);
 47.2065 ++	      grub_printf (" The highlighted entry will be booted automatically in %d seconds.   ",
 47.2066 + 			   grub_timeout);
 47.2067 +-	      gotoxy (74, 4 + entryno);
 47.2068 ++	      gotoxy ((col_end - 6), 4 + entryno + row_start);
 47.2069 + 	  }
 47.2070 + 	  
 47.2071 + 	  grub_timeout--;
 47.2072 +@@ -387,12 +410,12 @@
 47.2073 + 	      if (current_term->flags & TERM_DUMB)
 47.2074 + 		grub_putchar ('\r');
 47.2075 + 	      else
 47.2076 +-		gotoxy (3, 22);
 47.2077 ++		gotoxy (3 + col_start, 10 + box_size + row_start);
 47.2078 + 	      printf ("                                                                    ");
 47.2079 + 	      grub_timeout = -1;
 47.2080 + 	      fallback_entryno = -1;
 47.2081 + 	      if (! (current_term->flags & TERM_DUMB))
 47.2082 +-		gotoxy (74, 4 + entryno);
 47.2083 ++		gotoxy ((col_end - 6), 4 + entryno + row_start);
 47.2084 + 	    }
 47.2085 + 
 47.2086 + 	  /* We told them above (at least in SUPPORT_SERIAL) to use
 47.2087 +@@ -408,12 +431,12 @@
 47.2088 + 		{
 47.2089 + 		  if (entryno > 0)
 47.2090 + 		    {
 47.2091 +-		      print_entry (4 + entryno, 0,
 47.2092 ++		      print_entry (4 + entryno + row_start, 0,
 47.2093 + 				   get_entry (menu_entries,
 47.2094 + 					      first_entry + entryno,
 47.2095 + 					      0));
 47.2096 + 		      entryno--;
 47.2097 +-		      print_entry (4 + entryno, 1,
 47.2098 ++		      print_entry (4 + entryno + row_start, 1,
 47.2099 + 				   get_entry (menu_entries,
 47.2100 + 					      first_entry + entryno,
 47.2101 + 					      0));
 47.2102 +@@ -421,7 +444,7 @@
 47.2103 + 		  else if (first_entry > 0)
 47.2104 + 		    {
 47.2105 + 		      first_entry--;
 47.2106 +-		      print_entries (3, 12, first_entry, entryno,
 47.2107 ++		      print_entries (3 + row_start, box_size, first_entry, entryno,
 47.2108 + 				     menu_entries);
 47.2109 + 		    }
 47.2110 + 		}
 47.2111 +@@ -433,29 +456,29 @@
 47.2112 + 		entryno++;
 47.2113 + 	      else
 47.2114 + 		{
 47.2115 +-		  if (entryno < 11)
 47.2116 ++		  if (entryno < (box_size - 1))
 47.2117 + 		    {
 47.2118 +-		      print_entry (4 + entryno, 0,
 47.2119 ++		      print_entry (4 + entryno + row_start, 0,
 47.2120 + 				   get_entry (menu_entries,
 47.2121 + 					      first_entry + entryno,
 47.2122 + 					      0));
 47.2123 + 		      entryno++;
 47.2124 +-		      print_entry (4 + entryno, 1,
 47.2125 ++		      print_entry (4 + entryno + row_start, 1,
 47.2126 + 				   get_entry (menu_entries,
 47.2127 + 					      first_entry + entryno,
 47.2128 + 					      0));
 47.2129 + 		  }
 47.2130 +-		else if (num_entries > 12 + first_entry)
 47.2131 ++		else if (num_entries > box_size + first_entry)
 47.2132 + 		  {
 47.2133 + 		    first_entry++;
 47.2134 +-		    print_entries (3, 12, first_entry, entryno, menu_entries);
 47.2135 ++		    print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
 47.2136 + 		  }
 47.2137 + 		}
 47.2138 + 	    }
 47.2139 + 	  else if (c == 7)
 47.2140 + 	    {
 47.2141 + 	      /* Page Up */
 47.2142 +-	      first_entry -= 12;
 47.2143 ++	      first_entry -= box_size;
 47.2144 + 	      if (first_entry < 0)
 47.2145 + 		{
 47.2146 + 		  entryno += first_entry;
 47.2147 +@@ -463,20 +486,20 @@
 47.2148 + 		  if (entryno < 0)
 47.2149 + 		    entryno = 0;
 47.2150 + 		}
 47.2151 +-	      print_entries (3, 12, first_entry, entryno, menu_entries);
 47.2152 ++	      print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
 47.2153 + 	    }
 47.2154 + 	  else if (c == 3)
 47.2155 + 	    {
 47.2156 + 	      /* Page Down */
 47.2157 +-	      first_entry += 12;
 47.2158 ++	      first_entry += box_size;
 47.2159 + 	      if (first_entry + entryno + 1 >= num_entries)
 47.2160 + 		{
 47.2161 +-		  first_entry = num_entries - 12;
 47.2162 ++		  first_entry = num_entries - box_size;
 47.2163 + 		  if (first_entry < 0)
 47.2164 + 		    first_entry = 0;
 47.2165 + 		  entryno = num_entries - first_entry - 1;
 47.2166 + 		}
 47.2167 +-	      print_entries (3, 12, first_entry, entryno, menu_entries);
 47.2168 ++	      print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
 47.2169 + 	    }
 47.2170 + 
 47.2171 + 	  if (config_entries)
 47.2172 +@@ -489,7 +512,7 @@
 47.2173 + 	      if ((c == 'd') || (c == 'o') || (c == 'O'))
 47.2174 + 		{
 47.2175 + 		  if (! (current_term->flags & TERM_DUMB))
 47.2176 +-		    print_entry (4 + entryno, 0,
 47.2177 ++		    print_entry (4 + entryno + row_start, 0,
 47.2178 + 				 get_entry (menu_entries,
 47.2179 + 					    first_entry + entryno,
 47.2180 + 					    0));
 47.2181 +@@ -537,7 +560,7 @@
 47.2182 + 
 47.2183 + 		      if (entryno >= num_entries)
 47.2184 + 			entryno--;
 47.2185 +-		      if (first_entry && num_entries < 12 + first_entry)
 47.2186 ++		      if (first_entry && num_entries < box_size + first_entry)
 47.2187 + 			first_entry--;
 47.2188 + 		    }
 47.2189 + 
 47.2190 +@@ -549,7 +572,7 @@
 47.2191 + 		      grub_printf ("\n");
 47.2192 + 		    }
 47.2193 + 		  else
 47.2194 +-		    print_entries (3, 12, first_entry, entryno, menu_entries);
 47.2195 ++		    print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
 47.2196 + 		}
 47.2197 + 
 47.2198 + 	      cur_entry = menu_entries;
 47.2199 +@@ -570,7 +593,7 @@
 47.2200 + 		  if (current_term->flags & TERM_DUMB)
 47.2201 + 		    grub_printf ("\r                                    ");
 47.2202 + 		  else
 47.2203 +-		    gotoxy (1, 21);
 47.2204 ++		    gotoxy (1 + col_start, 9 + box_size + row_start);
 47.2205 + 
 47.2206 + 		  /* Wipe out the previously entered password */
 47.2207 + 		  grub_memset (entered, 0, sizeof (entered));
 47.2208 +@@ -714,6 +737,15 @@
 47.2209 +   
 47.2210 +   cls ();
 47.2211 +   setcursor (1);
 47.2212 ++  /* if our terminal needed initialization, we should shut it down
 47.2213 ++   * before booting the kernel, but we want to save what it was so
 47.2214 ++   * we can come back if needed */
 47.2215 ++  prev_term = current_term;
 47.2216 ++  if (current_term->shutdown) 
 47.2217 ++    {
 47.2218 ++      current_term->shutdown();
 47.2219 ++      current_term = term_table; /* assumption: console is first */
 47.2220 ++    }
 47.2221 +   
 47.2222 +   while (1)
 47.2223 +     {
 47.2224 +@@ -748,6 +780,13 @@
 47.2225 + 	break;
 47.2226 +     }
 47.2227 + 
 47.2228 ++  /* if we get back here, we should go back to what our term was before */
 47.2229 ++  current_term = prev_term;
 47.2230 ++  if (current_term->startup)
 47.2231 ++      /* if our terminal fails to initialize, fall back to console since
 47.2232 ++       * it should always work */
 47.2233 ++      if (current_term->startup() == 0)
 47.2234 ++          current_term = term_table; /* we know that console is first */
 47.2235 +   show_menu = 1;
 47.2236 +   goto restart;
 47.2237 + }
 47.2238 +@@ -1050,6 +1089,16 @@
 47.2239 + 	  while (is_preset);
 47.2240 + 	}
 47.2241 + 
 47.2242 ++      /* go ahead and make sure the terminal is setup */
 47.2243 ++      if (current_term->startup)
 47.2244 ++	{
 47.2245 ++	  /* If initialization fails, go back to default terminal */
 47.2246 ++	  if (current_term->startup() == 0)
 47.2247 ++		  {
 47.2248 ++		      current_term = term_table;
 47.2249 ++		  }
 47.2250 ++	}
 47.2251 ++
 47.2252 +       if (! num_entries)
 47.2253 + 	{
 47.2254 + 	  /* If no acceptable config file, goto command-line, starting
 47.2255 +diff -Naur grub-0.97.orig/stage2/term.h grub-0.97/stage2/term.h
 47.2256 +--- grub-0.97.orig/stage2/term.h	2003-07-09 08:45:53.000000000 -0300
 47.2257 ++++ grub-0.97/stage2/term.h	2005-06-13 14:07:40.000000000 -0300
 47.2258 +@@ -60,6 +60,8 @@
 47.2259 +   const char *name;
 47.2260 +   /* The feature flags defined above.  */
 47.2261 +   unsigned long flags;
 47.2262 ++  /* Default for maximum number of lines if not specified */
 47.2263 ++  unsigned short max_lines;
 47.2264 +   /* Put a character.  */
 47.2265 +   void (*putchar) (int c);
 47.2266 +   /* Check if any input character is available.  */
 47.2267 +@@ -79,6 +81,10 @@
 47.2268 +   void (*setcolor) (int normal_color, int highlight_color);
 47.2269 +   /* Turn on/off the cursor.  */
 47.2270 +   int (*setcursor) (int on);
 47.2271 ++  /* function to start a terminal */
 47.2272 ++  int (*startup) (void);
 47.2273 ++  /* function to use to shutdown a terminal */
 47.2274 ++  void (*shutdown) (void);
 47.2275 + };
 47.2276 + 
 47.2277 + /* This lists up available terminals.  */
 47.2278 +@@ -124,4 +130,24 @@
 47.2279 + int hercules_setcursor (int on);
 47.2280 + #endif
 47.2281 + 
 47.2282 ++#ifdef SUPPORT_GRAPHICS
 47.2283 ++extern int foreground, background, window_border, graphics_inited, saved_videomode;
 47.2284 ++
 47.2285 ++void graphics_set_splash(char *splashfile);
 47.2286 ++int set_videomode(int mode);
 47.2287 ++int get_videomode(void);
 47.2288 ++void graphics_putchar (int c);
 47.2289 ++int graphics_getxy(void);
 47.2290 ++void graphics_gotoxy(int x, int y);
 47.2291 ++void graphics_cls(void);
 47.2292 ++void graphics_setcolorstate (color_state state);
 47.2293 ++void graphics_setcolor (int normal_color, int highlight_color);
 47.2294 ++int graphics_setcursor (int on);
 47.2295 ++int graphics_init(void);
 47.2296 ++void graphics_end(void);
 47.2297 ++
 47.2298 ++int hex(int v);
 47.2299 ++void graphics_set_palette(int idx, int red, int green, int blue);
 47.2300 ++#endif /* SUPPORT_GRAPHICS */
 47.2301 ++
 47.2302 + #endif /* ! GRUB_TERM_HEADER */
    48.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.2 +++ b/stubdom/grub.patches/20print_func.diff	Thu Jun 19 12:46:26 2008 +0900
    48.3 @@ -0,0 +1,80 @@
    48.4 +2006-01-05  Otavio Salvador  <otavio@debian.org>
    48.5 +
    48.6 +       * Rediff.
    48.7 +
    48.8 +2005-16-10  Samuel Thibault  <samuel.thibault@ens-lyon.org>
    48.9 +
   48.10 +       * docs/grub.texi: Added print command description.
   48.11 +       * stage2/builtins.c(print_func): New function.
   48.12 +       (builtin_print): New variable.
   48.13 +       (builtin_table): Added builtin_print in table.
   48.14 +
   48.15 +Debian Status Following:
   48.16 +   Added by: Otavio Salvador
   48.17 +       Date: 2006-01-05
   48.18 +
   48.19 +diff -Nur grub-0.97-bkp/docs/grub.texi grub-0.97/docs/grub.texi
   48.20 +--- grub-0.97-bkp/docs/grub.texi	2006-01-05 10:59:05.564347912 -0200
   48.21 ++++ grub-0.97/docs/grub.texi	2006-01-05 11:18:59.033912960 -0200
   48.22 +@@ -2685,6 +2685,7 @@
   48.23 + * module::                      Load a module
   48.24 + * modulenounzip::               Load a module without decompression
   48.25 + * pause::                       Wait for a key press
   48.26 ++* print::                       Print a message
   48.27 + * quit::                        Exit from the grub shell
   48.28 + * reboot::                      Reboot your computer
   48.29 + * read::                        Read data from memory
   48.30 +@@ -3091,6 +3092,16 @@
   48.31 + @end deffn
   48.32 + 
   48.33 + 
   48.34 ++@node print
   48.35 ++@subsection print
   48.36 ++
   48.37 ++@deffn Command print message @dots{}
   48.38 ++Print the @var{message}. Note that placing @key{^G} (ASCII code 7) in the
   48.39 ++message will cause the speaker to emit the standard beep sound, which is
   48.40 ++useful for visually impaired people.
   48.41 ++@end deffn
   48.42 ++
   48.43 ++
   48.44 + @node quit
   48.45 + @subsection quit
   48.46 + 
   48.47 +diff -Nur grub-0.97-bkp/stage2/builtins.c grub-0.97/stage2/builtins.c
   48.48 +--- grub-0.97-bkp/stage2/builtins.c	2006-01-05 10:59:05.550350040 -0200
   48.49 ++++ grub-0.97/stage2/builtins.c	2006-01-05 11:19:28.422445224 -0200
   48.50 +@@ -2323,6 +2323,25 @@
   48.51 +   "Probe I/O ports used for the drive DRIVE."
   48.52 + };
   48.53 + 
   48.54 ++/* print */
   48.55 ++static int
   48.56 ++print_func (char *arg, int flags)
   48.57 ++{
   48.58 ++  printf("%s\n", arg);
   48.59 ++
   48.60 ++  return 0;
   48.61 ++}
   48.62 ++
   48.63 ++static struct builtin builtin_print =
   48.64 ++{
   48.65 ++  "print",
   48.66 ++  print_func,
   48.67 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_NO_ECHO,
   48.68 ++  "print [MESSAGE ...]",
   48.69 ++  "Print MESSAGE."
   48.70 ++};
   48.71 ++
   48.72 ++
   48.73 + 
   48.74 + /* kernel */
   48.75 + static int
   48.76 +@@ -4848,6 +4867,7 @@
   48.77 +   &builtin_parttype,
   48.78 +   &builtin_password,
   48.79 +   &builtin_pause,
   48.80 ++  &builtin_print,
   48.81 + #ifdef GRUB_UTIL
   48.82 +   &builtin_quit,
   48.83 + #endif /* GRUB_UTIL */
    49.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.2 +++ b/stubdom/grub.patches/30savedefault.diff	Thu Jun 19 12:46:26 2008 +0900
    49.3 @@ -0,0 +1,186 @@
    49.4 +Index: grub/stage2/builtins.c
    49.5 +===================================================================
    49.6 +--- grub.orig/stage2/builtins.c	2008-06-02 18:06:08.942580000 +0100
    49.7 ++++ grub/stage2/builtins.c	2008-06-06 18:35:07.548390000 +0100
    49.8 +@@ -86,6 +86,10 @@
    49.9 +    inside other functions.  */
   49.10 + static int configfile_func (char *arg, int flags);
   49.11 + 
   49.12 ++static int savedefault_helper (char *arg, int flags);
   49.13 ++
   49.14 ++static int savedefault_shell (char *arg, int flags);
   49.15 ++
   49.16 + /* Initialize the data for builtins.  */
   49.17 + void
   49.18 + init_builtins (void)
   49.19 +@@ -3512,7 +3516,109 @@
   49.20 + static int
   49.21 + savedefault_func (char *arg, int flags)
   49.22 + {
   49.23 +-#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
   49.24 ++#if !defined(SUPPORT_DISKLESS)
   49.25 ++  #if !defined(GRUB_UTIL)
   49.26 ++	return savedefault_helper(arg, flags);
   49.27 ++  #else
   49.28 ++	return savedefault_shell(arg, flags);
   49.29 ++  #endif
   49.30 ++#else /* !SUPPORT_DISKLESS */ 
   49.31 ++  errnum = ERR_UNRECOGNIZED;
   49.32 ++  return 1;
   49.33 ++#endif /* !SUPPORT_DISKLESS */
   49.34 ++}
   49.35 ++
   49.36 ++#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
   49.37 ++/* savedefault_shell */
   49.38 ++static int
   49.39 ++savedefault_shell(char *arg, int flags)
   49.40 ++ {
   49.41 ++  int once_only = 0;
   49.42 ++  int new_default;
   49.43 ++  int curr_default = -1;
   49.44 ++  int curr_prev_default = -1;
   49.45 ++  int new_prev_default = -1;
   49.46 ++  FILE *fp;
   49.47 ++  size_t bytes = 10;
   49.48 ++  char line[bytes];
   49.49 ++  char *default_file = (char *) DEFAULT_FILE_BUF;
   49.50 ++  char buf[bytes];
   49.51 ++  int i;
   49.52 ++  
   49.53 ++  while (1)
   49.54 ++    {
   49.55 ++      if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0)
   49.56 ++        {
   49.57 ++          char *p = arg + sizeof ("--default=") - 1;
   49.58 ++          if (! safe_parse_maxint (&p, &new_default))
   49.59 ++            return 1;
   49.60 ++          arg = skip_to (0, arg);
   49.61 ++        }
   49.62 ++      else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0)
   49.63 ++        {
   49.64 ++         once_only = 1;
   49.65 ++         arg = skip_to (0, arg);
   49.66 ++	}
   49.67 ++      else
   49.68 ++        break;
   49.69 ++    }
   49.70 ++
   49.71 ++  *default_file = 0;
   49.72 ++  grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN);
   49.73 ++  for (i = grub_strlen(default_file); i >= 0; i--)
   49.74 ++    if (default_file[i] == '/')
   49.75 ++    {
   49.76 ++      i++;
   49.77 ++      break;
   49.78 ++    }
   49.79 ++  default_file[i] = 0;
   49.80 ++  grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i);
   49.81 ++
   49.82 ++  if(!(fp = fopen(default_file,"r")))
   49.83 ++    {
   49.84 ++      errnum = ERR_READ;
   49.85 ++      goto fail;
   49.86 ++    }
   49.87 ++  
   49.88 ++  fgets(line, bytes, fp);
   49.89 ++  fclose(fp);
   49.90 ++ 
   49.91 ++  sscanf(line, "%d:%d", &curr_prev_default, &curr_default);
   49.92 ++     
   49.93 ++  if(curr_default != -1)
   49.94 ++    new_prev_default = curr_default;
   49.95 ++  else
   49.96 ++    {
   49.97 ++      if(curr_prev_default != -1)
   49.98 ++        new_prev_default = curr_prev_default;
   49.99 ++      else
  49.100 ++        new_prev_default = 0;
  49.101 ++    }
  49.102 ++     
  49.103 ++  if(once_only)
  49.104 ++    sprintf(buf, "%d:%d", new_prev_default, new_default);
  49.105 ++  else
  49.106 ++    sprintf(buf, "%d", new_default);
  49.107 ++
  49.108 ++  if(!(fp = fopen(default_file,"w")))
  49.109 ++    {
  49.110 ++      errnum = ERR_READ;
  49.111 ++      goto fail;
  49.112 ++    }
  49.113 ++     
  49.114 ++  fprintf(fp, buf);   
  49.115 ++     
  49.116 ++fail:
  49.117 ++  fclose(fp);
  49.118 ++  return errnum;
  49.119 ++}
  49.120 ++#endif
  49.121 ++
  49.122 ++/* savedefault_helper */
  49.123 ++static int
  49.124 ++savedefault_helper (char *arg, int flags)
  49.125 ++{
  49.126 ++#if !defined(SUPPORT_DISKLESS)
  49.127 +   unsigned long tmp_drive = saved_drive;
  49.128 +   unsigned long tmp_partition = saved_partition;
  49.129 +   char *default_file = (char *) DEFAULT_FILE_BUF;
  49.130 +@@ -3588,22 +3694,26 @@
  49.131 +       
  49.132 +       disk_read_hook = disk_read_savesect_func;
  49.133 +       len = grub_read (buf, sizeof (buf));
  49.134 ++      buf[9]='\0';/* Make sure grub_strstr() below terminates */
  49.135 +       disk_read_hook = 0;
  49.136 +       grub_close ();
  49.137 +       
  49.138 +-      if (len != sizeof (buf))
  49.139 +-	{
  49.140 +-	  /* This is too small. Do not modify the file manually, please!  */
  49.141 +-	  errnum = ERR_READ;
  49.142 +-	  goto fail;
  49.143 +-	}
  49.144 +-
  49.145 +       if (sector_count > 2)
  49.146 + 	{
  49.147 + 	  /* Is this possible?! Too fragmented!  */
  49.148 + 	  errnum = ERR_FSYS_CORRUPT;
  49.149 + 	  goto fail;
  49.150 + 	}
  49.151 ++
  49.152 ++      char *tmp;
  49.153 ++      if((tmp = grub_strstr(buf, ":")) != NULL)
  49.154 ++      {
  49.155 ++       int f_len = grub_strlen(buf) - grub_strlen(tmp);
  49.156 ++       char *def;
  49.157 ++       buf[f_len] = '\0';
  49.158 ++       def = buf;
  49.159 ++       safe_parse_maxint (&def, &entryno);
  49.160 ++      }
  49.161 +       
  49.162 +       /* Set up a string to be written.  */
  49.163 +       grub_memset (buf, '\n', sizeof (buf));
  49.164 +Index: grub/stage2/stage2.c
  49.165 +===================================================================
  49.166 +--- grub.orig/stage2/stage2.c	2008-06-02 18:06:08.858579000 +0100
  49.167 ++++ grub/stage2/stage2.c	2008-06-06 18:04:03.585354000 +0100
  49.168 +@@ -49,7 +49,8 @@
  49.169 +     return 0;
  49.170 + #endif /* GRUB_UTIL */
  49.171 +   
  49.172 +-  preset_menu_offset = 0;
  49.173 ++  if (preset_menu_offset)
  49.174 ++    return 0;
  49.175 +   return preset_menu != 0;
  49.176 + }
  49.177 + 
  49.178 +@@ -934,7 +935,11 @@
  49.179 + 	      len = grub_read (buf, sizeof (buf));
  49.180 + 	      if (len > 0)
  49.181 + 		{
  49.182 ++		  char *tmp;
  49.183 + 		  buf[sizeof (buf) - 1] = 0;
  49.184 ++		  if((tmp = grub_strstr(p, ":")) != NULL)
  49.185 ++		    p = tmp + 1;
  49.186 ++		  
  49.187 + 		  safe_parse_maxint (&p, &saved_entryno);
  49.188 + 		}
  49.189 + 
    50.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.2 +++ b/stubdom/grub.patches/40ext3_256byte_inode.diff	Thu Jun 19 12:46:26 2008 +0900
    50.3 @@ -0,0 +1,114 @@
    50.4 +
    50.5 +Patch from Red Hat. See #463236, #463123.
    50.6 +
    50.7 +Index: grub/stage2/fsys_ext2fs.c
    50.8 +===================================================================
    50.9 +--- grub.orig/stage2/fsys_ext2fs.c	2008-05-27 18:47:19.045183000 +0100
   50.10 ++++ grub/stage2/fsys_ext2fs.c	2008-05-27 19:09:21.293187000 +0100
   50.11 +@@ -79,7 +79,52 @@
   50.12 +     __u32 s_rev_level;		/* Revision level */
   50.13 +     __u16 s_def_resuid;		/* Default uid for reserved blocks */
   50.14 +     __u16 s_def_resgid;		/* Default gid for reserved blocks */
   50.15 +-    __u32 s_reserved[235];	/* Padding to the end of the block */
   50.16 ++    /*
   50.17 ++     * These fields are for EXT2_DYNAMIC_REV superblocks only.
   50.18 ++     *
   50.19 ++     * Note: the difference between the compatible feature set and
   50.20 ++     * the incompatible feature set is that if there is a bit set
   50.21 ++     * in the incompatible feature set that the kernel doesn't
   50.22 ++     * know about, it should refuse to mount the filesystem.
   50.23 ++     *
   50.24 ++     * e2fsck's requirements are more strict; if it doesn't know
   50.25 ++     * about a feature in either the compatible or incompatible
   50.26 ++     * feature set, it must abort and not try to meddle with
   50.27 ++     * things it doesn't understand...
   50.28 ++     */
   50.29 ++    __u32 s_first_ino;		/* First non-reserved inode */
   50.30 ++    __u16 s_inode_size;		/* size of inode structure */
   50.31 ++    __u16 s_block_group_nr;	/* block group # of this superblock */
   50.32 ++    __u32 s_feature_compat;	/* compatible feature set */
   50.33 ++    __u32 s_feature_incompat;	/* incompatible feature set */
   50.34 ++    __u32 s_feature_ro_compat;	/* readonly-compatible feature set */
   50.35 ++    __u8  s_uuid[16];		/* 128-bit uuid for volume */
   50.36 ++    char  s_volume_name[16];	/* volume name */
   50.37 ++    char  s_last_mounted[64];	/* directory where last mounted */
   50.38 ++    __u32 s_algorithm_usage_bitmap; /* For compression */
   50.39 ++    /*
   50.40 ++     * Performance hints.  Directory preallocation should only
   50.41 ++     * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
   50.42 ++     */
   50.43 ++    __u8  s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
   50.44 ++    __u8  s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
   50.45 ++    __u16 s_reserved_gdt_blocks;/* Per group table for online growth */
   50.46 ++    /*
   50.47 ++     * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
   50.48 ++     */
   50.49 ++    __u8 s_journal_uuid[16];	/* uuid of journal superblock */
   50.50 ++    __u32 s_journal_inum;	/* inode number of journal file */
   50.51 ++    __u32 s_journal_dev;	/* device number of journal file */
   50.52 ++    __u32 s_last_orphan;	/* start of list of inodes to delete */
   50.53 ++    __u32 s_hash_seed[4];	/* HTREE hash seed */
   50.54 ++    __u8  s_def_hash_version;	/* Default hash version to use */
   50.55 ++    __u8  s_jnl_backup_type; 	/* Default type of journal backup */
   50.56 ++    __u16 s_reserved_word_pad;
   50.57 ++    __u32 s_default_mount_opts;
   50.58 ++    __u32 s_first_meta_bg;	/* First metablock group */
   50.59 ++    __u32 s_mkfs_time;		/* When the filesystem was created */
   50.60 ++    __u32 s_jnl_blocks[17]; 	/* Backup of the journal inode */
   50.61 ++    __u32 s_reserved[172];	/* Padding to the end of the block */
   50.62 +   };
   50.63 + 
   50.64 + struct ext2_group_desc
   50.65 +@@ -218,6 +263,9 @@
   50.66 + #define EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
   50.67 + #define EXT2_ADDR_PER_BLOCK_BITS(s)		(log2(EXT2_ADDR_PER_BLOCK(s)))
   50.68 + 
   50.69 ++#define EXT2_INODE_SIZE(s)		(SUPERBLOCK->s_inode_size)
   50.70 ++#define EXT2_INODES_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
   50.71 ++
   50.72 + /* linux/ext2_fs.h */
   50.73 + #define EXT2_BLOCK_SIZE_BITS(s)        ((s)->s_log_block_size + 10)
   50.74 + /* kind of from ext2/super.c */
   50.75 +@@ -242,7 +290,14 @@
   50.76 + static __inline__ unsigned long
   50.77 + ffz (unsigned long word)
   50.78 + {
   50.79 +-  __asm__ ("bsfl %1,%0"
   50.80 ++  __asm__ ("bsf"
   50.81 ++#ifdef __i386__
   50.82 ++		  "l"
   50.83 ++#endif
   50.84 ++#ifdef __x86_64__
   50.85 ++		  "q"
   50.86 ++#endif
   50.87 ++		  " %1,%0"
   50.88 + :	   "=r" (word)
   50.89 + :	   "r" (~word));
   50.90 +   return word;
   50.91 +@@ -553,7 +608,7 @@
   50.92 +       gdp = GROUP_DESC;
   50.93 +       ino_blk = gdp[desc].bg_inode_table +
   50.94 + 	(((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group))
   50.95 +-	 >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)));
   50.96 ++	 >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
   50.97 + #ifdef E2DEBUG
   50.98 +       printf ("inode table fsblock=%d\n", ino_blk);
   50.99 + #endif /* E2DEBUG */
  50.100 +@@ -565,13 +620,12 @@
  50.101 +       /* reset indirect blocks! */
  50.102 +       mapblock2 = mapblock1 = -1;
  50.103 + 
  50.104 +-      raw_inode = INODE +
  50.105 +-	((current_ino - 1)
  50.106 +-	 & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1));
  50.107 ++      raw_inode = (struct ext2_inode *)((char *)INODE +
  50.108 ++	((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1)) *
  50.109 ++	EXT2_INODE_SIZE (SUPERBLOCK));
  50.110 + #ifdef E2DEBUG
  50.111 +       printf ("ipb=%d, sizeof(inode)=%d\n",
  50.112 +-	      (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)),
  50.113 +-	      sizeof (struct ext2_inode));
  50.114 ++	      EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK));
  50.115 +       printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode);
  50.116 +       printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE);
  50.117 +       for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode;
    51.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.2 +++ b/stubdom/grub.patches/99minios	Thu Jun 19 12:46:26 2008 +0900
    51.3 @@ -0,0 +1,1456 @@
    51.4 +Index: grub/stage2/builtins.c
    51.5 +===================================================================
    51.6 +--- grub.orig/stage2/builtins.c	2008-06-16 15:18:14.649009000 +0100
    51.7 ++++ grub/stage2/builtins.c	2008-06-16 15:18:14.719009000 +0100
    51.8 +@@ -45,8 +45,10 @@
    51.9 + #ifdef GRUB_UTIL
   51.10 + # include <device.h>
   51.11 + #else /* ! GRUB_UTIL */
   51.12 ++#ifndef __MINIOS
   51.13 + # include <apic.h>
   51.14 + # include <smp-imps.h>
   51.15 ++#endif
   51.16 + #endif /* ! GRUB_UTIL */
   51.17 + 
   51.18 + #ifdef USE_MD5_PASSWORDS
   51.19 +@@ -246,11 +248,13 @@
   51.20 + boot_func (char *arg, int flags)
   51.21 + {
   51.22 +   struct term_entry *prev_term = current_term;
   51.23 ++#ifndef __MINIOS__
   51.24 +   /* Clear the int15 handler if we can boot the kernel successfully.
   51.25 +      This assumes that the boot code never fails only if KERNEL_TYPE is
   51.26 +      not KERNEL_TYPE_NONE. Is this assumption is bad?  */
   51.27 +   if (kernel_type != KERNEL_TYPE_NONE)
   51.28 +     unset_int15_handler ();
   51.29 ++#endif
   51.30 + 
   51.31 +   /* if our terminal needed initialization, we should shut it down
   51.32 +    * before booting the kernel, but we want to save what it was so
   51.33 +@@ -261,13 +265,21 @@
   51.34 +       current_term = term_table; /* assumption: console is first */
   51.35 +     }
   51.36 + 
   51.37 ++#ifndef __MINIOS__
   51.38 + #ifdef SUPPORT_NETBOOT
   51.39 +   /* Shut down the networking.  */
   51.40 +   cleanup_net ();
   51.41 + #endif
   51.42 ++#endif
   51.43 +   
   51.44 +   switch (kernel_type)
   51.45 +     {
   51.46 ++#ifdef __MINIOS__
   51.47 ++    case KERNEL_TYPE_PV:
   51.48 ++      /* Paravirtualized */
   51.49 ++      pv_boot();
   51.50 ++      break;
   51.51 ++#else
   51.52 +     case KERNEL_TYPE_FREEBSD:
   51.53 +     case KERNEL_TYPE_NETBSD:
   51.54 +       /* *BSD */
   51.55 +@@ -319,6 +331,7 @@
   51.56 +       multi_boot ((int) entry_addr, (int) &mbi);
   51.57 +       break;
   51.58 + 
   51.59 ++#endif
   51.60 +     default:
   51.61 +       errnum = ERR_BOOT_COMMAND;
   51.62 +       return 1;
   51.63 +@@ -1123,6 +1136,7 @@
   51.64 + };
   51.65 + 
   51.66 + 
   51.67 ++#ifndef __MINIOS__
   51.68 + /* displayapm */
   51.69 + static int
   51.70 + displayapm_func (char *arg, int flags)
   51.71 +@@ -1163,8 +1177,10 @@
   51.72 +   "displayapm",
   51.73 +   "Display APM BIOS information."
   51.74 + };
   51.75 ++#endif
   51.76 + 
   51.77 + 
   51.78 ++#ifndef __MINIOS__
   51.79 + /* displaymem */
   51.80 + static int
   51.81 + displaymem_func (char *arg, int flags)
   51.82 +@@ -1218,6 +1234,7 @@
   51.83 +   "Display what GRUB thinks the system address space map of the"
   51.84 +   " machine is, including all regions of physical RAM installed."
   51.85 + };
   51.86 ++#endif
   51.87 + 
   51.88 + 
   51.89 + /* dump FROM TO */
   51.90 +@@ -1280,6 +1297,7 @@
   51.91 + #endif /* GRUB_UTIL */
   51.92 + 
   51.93 + 
   51.94 ++#ifndef __MINIOS__
   51.95 + static char embed_info[32];
   51.96 + /* embed */
   51.97 + /* Embed a Stage 1.5 in the first cylinder after MBR or in the
   51.98 +@@ -1413,6 +1431,7 @@
   51.99 +   " is a drive, or in the \"bootloader\" area if DEVICE is a FFS partition."
  51.100 +   " Print the number of sectors which STAGE1_5 occupies if successful."
  51.101 + };
  51.102 ++#endif
  51.103 + 
  51.104 + 
  51.105 + /* fallback */
  51.106 +@@ -1956,6 +1975,7 @@
  51.107 + #endif /* SUPPORT_NETBOOT */
  51.108 + 
  51.109 + 
  51.110 ++#ifndef __MINIOS__
  51.111 + /* impsprobe */
  51.112 + static int
  51.113 + impsprobe_func (char *arg, int flags)
  51.114 +@@ -1982,6 +2002,7 @@
  51.115 +   " configuration table and boot the various CPUs which are found into"
  51.116 +   " a tight loop."
  51.117 + };
  51.118 ++#endif
  51.119 + 
  51.120 + 
  51.121 + /* initrd */
  51.122 +@@ -1992,6 +2013,7 @@
  51.123 +     {
  51.124 +     case KERNEL_TYPE_LINUX:
  51.125 +     case KERNEL_TYPE_BIG_LINUX:
  51.126 ++    case KERNEL_TYPE_PV:
  51.127 +       if (! load_initrd (arg))
  51.128 + 	return 1;
  51.129 +       break;
  51.130 +@@ -2015,6 +2037,7 @@
  51.131 + };
  51.132 + 
  51.133 + 
  51.134 ++#ifndef __MINIOS__
  51.135 + /* install */
  51.136 + static int
  51.137 + install_func (char *arg, int flags)
  51.138 +@@ -2555,8 +2578,10 @@
  51.139 +   " for LBA mode. If the option `--stage2' is specified, rewrite the Stage"
  51.140 +   " 2 via your OS's filesystem instead of the raw device."
  51.141 + };
  51.142 ++#endif
  51.143 + 
  51.144 + 
  51.145 ++#ifndef __MINIOS__
  51.146 + /* ioprobe */
  51.147 + static int
  51.148 + ioprobe_func (char *arg, int flags)
  51.149 +@@ -2598,6 +2623,7 @@
  51.150 +   "ioprobe DRIVE",
  51.151 +   "Probe I/O ports used for the drive DRIVE."
  51.152 + };
  51.153 ++#endif
  51.154 + 
  51.155 + /* print */
  51.156 + static int
  51.157 +@@ -3776,6 +3802,7 @@
  51.158 + };
  51.159 + 
  51.160 + 
  51.161 ++#ifndef __MINIOS__
  51.162 + #ifdef SUPPORT_SERIAL
  51.163 + /* serial */
  51.164 + static int
  51.165 +@@ -3927,8 +3954,10 @@
  51.166 +   " default values are COM1, 9600, 8N1."
  51.167 + };
  51.168 + #endif /* SUPPORT_SERIAL */
  51.169 ++#endif
  51.170 + 
  51.171 + 
  51.172 ++#ifndef __MINIOS__
  51.173 + /* setkey */
  51.174 + struct keysym
  51.175 + {
  51.176 +@@ -4174,8 +4203,10 @@
  51.177 +   " is a digit), and delete. If no argument is specified, reset key"
  51.178 +   " mappings."
  51.179 + };
  51.180 ++#endif
  51.181 + 
  51.182 + 
  51.183 ++#ifndef __MINIOS__
  51.184 + /* setup */
  51.185 + static int
  51.186 + setup_func (char *arg, int flags)
  51.187 +@@ -4484,6 +4515,7 @@
  51.188 +   " partition where GRUB images reside, specify the option `--stage2'"
  51.189 +   " to tell GRUB the file name under your OS."
  51.190 + };
  51.191 ++#endif
  51.192 + 
  51.193 + 
  51.194 + #if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
  51.195 +@@ -4788,6 +4820,7 @@
  51.196 + #endif /* SUPPORT_SERIAL */
  51.197 + 	  
  51.198 + 
  51.199 ++#ifndef __MINIOS__
  51.200 + /* testload */
  51.201 + static int
  51.202 + testload_func (char *arg, int flags)
  51.203 +@@ -4874,8 +4907,10 @@
  51.204 +   " consistent offset error. If this test succeeds, then a good next"
  51.205 +   " step is to try loading a kernel."
  51.206 + };
  51.207 ++#endif
  51.208 + 
  51.209 + 
  51.210 ++#ifndef __MINIOS__
  51.211 + /* testvbe MODE */
  51.212 + static int
  51.213 + testvbe_func (char *arg, int flags)
  51.214 +@@ -4979,6 +5014,7 @@
  51.215 +   "testvbe MODE",
  51.216 +   "Test the VBE mode MODE. Hit any key to return."
  51.217 + };
  51.218 ++#endif
  51.219 + 
  51.220 + 
  51.221 + #ifdef SUPPORT_NETBOOT
  51.222 +@@ -5075,6 +5111,7 @@
  51.223 + };
  51.224 + 
  51.225 + 
  51.226 ++#ifndef __MINIOS__
  51.227 + /* uppermem */
  51.228 + static int
  51.229 + uppermem_func (char *arg, int flags)
  51.230 +@@ -5095,8 +5132,10 @@
  51.231 +   "Force GRUB to assume that only KBYTES kilobytes of upper memory are"
  51.232 +   " installed.  Any system address range maps are discarded."
  51.233 + };
  51.234 ++#endif
  51.235 + 
  51.236 + 
  51.237 ++#ifndef __MINIOS__
  51.238 + /* vbeprobe */
  51.239 + static int
  51.240 + vbeprobe_func (char *arg, int flags)
  51.241 +@@ -5203,6 +5242,7 @@
  51.242 +   "Probe VBE information. If the mode number MODE is specified, show only"
  51.243 +   " the information about only the mode."
  51.244 + };
  51.245 ++#endif
  51.246 +   
  51.247 + 
  51.248 + /* The table of builtin commands. Sorted in dictionary order.  */
  51.249 +@@ -5233,12 +5273,16 @@
  51.250 + #ifdef SUPPORT_NETBOOT
  51.251 +   &builtin_dhcp,
  51.252 + #endif /* SUPPORT_NETBOOT */
  51.253 ++#ifndef __MINIOS__
  51.254 +   &builtin_displayapm,
  51.255 +   &builtin_displaymem,
  51.256 ++#endif
  51.257 + #ifdef GRUB_UTIL
  51.258 +   &builtin_dump,
  51.259 + #endif /* GRUB_UTIL */
  51.260 ++#ifndef __MINIOS__
  51.261 +   &builtin_embed,
  51.262 ++#endif
  51.263 +   &builtin_fallback,
  51.264 +   &builtin_find,
  51.265 + #ifdef SUPPORT_GRAPHICS
  51.266 +@@ -5253,10 +5297,14 @@
  51.267 + #ifdef SUPPORT_NETBOOT
  51.268 +   &builtin_ifconfig,
  51.269 + #endif /* SUPPORT_NETBOOT */
  51.270 ++#ifndef __MINIOS__
  51.271 +   &builtin_impsprobe,
  51.272 ++#endif
  51.273 +   &builtin_initrd,
  51.274 ++#ifndef __MINIOS__
  51.275 +   &builtin_install,
  51.276 +   &builtin_ioprobe,
  51.277 ++#endif
  51.278 +   &builtin_kernel,
  51.279 +   &builtin_lock,
  51.280 +   &builtin_makeactive,
  51.281 +@@ -5283,11 +5331,13 @@
  51.282 +   &builtin_root,
  51.283 +   &builtin_rootnoverify,
  51.284 +   &builtin_savedefault,
  51.285 ++#ifndef __MINIOS__
  51.286 + #ifdef SUPPORT_SERIAL
  51.287 +   &builtin_serial,
  51.288 + #endif /* SUPPORT_SERIAL */
  51.289 +   &builtin_setkey,
  51.290 +   &builtin_setup,
  51.291 ++#endif
  51.292 + #ifdef SUPPORT_GRAPHICS
  51.293 +   &builtin_shade,
  51.294 +   &builtin_splashimage,
  51.295 +@@ -5298,16 +5348,20 @@
  51.296 + #ifdef SUPPORT_SERIAL
  51.297 +   &builtin_terminfo,
  51.298 + #endif /* SUPPORT_SERIAL */
  51.299 ++#ifndef __MINIOS__
  51.300 +   &builtin_testload,
  51.301 +   &builtin_testvbe,
  51.302 ++#endif
  51.303 + #ifdef SUPPORT_NETBOOT
  51.304 +   &builtin_tftpserver,
  51.305 + #endif /* SUPPORT_NETBOOT */
  51.306 +   &builtin_timeout,
  51.307 +   &builtin_title,
  51.308 +   &builtin_unhide,
  51.309 ++#ifndef __MINIOS__
  51.310 +   &builtin_uppermem,
  51.311 +   &builtin_vbeprobe,
  51.312 ++#endif
  51.313 + #ifdef SUPPORT_GRAPHICS
  51.314 +   &builtin_viewport,
  51.315 + #endif
  51.316 +Index: grub/stage2/char_io.c
  51.317 +===================================================================
  51.318 +--- grub.orig/stage2/char_io.c	2008-06-16 15:18:14.516009000 +0100
  51.319 ++++ grub/stage2/char_io.c	2008-06-16 15:18:14.726009000 +0100
  51.320 +@@ -20,6 +20,7 @@
  51.321 + 
  51.322 + #include <shared.h>
  51.323 + #include <term.h>
  51.324 ++#include <stdarg.h>
  51.325 + 
  51.326 + #ifdef SUPPORT_HERCULES
  51.327 + # include <hercules.h>
  51.328 +@@ -36,6 +37,7 @@
  51.329 + #ifndef STAGE1_5
  51.330 + struct term_entry term_table[] =
  51.331 +   {
  51.332 ++#ifdef SUPPORT_CONSOLE
  51.333 +     {
  51.334 +       "console",
  51.335 +       0,
  51.336 +@@ -52,6 +54,7 @@
  51.337 +       0, 
  51.338 +       0
  51.339 +     },
  51.340 ++#endif
  51.341 + #ifdef SUPPORT_SERIAL
  51.342 +     {
  51.343 +       "serial",
  51.344 +@@ -131,9 +134,9 @@
  51.345 + }
  51.346 + 
  51.347 + char *
  51.348 +-convert_to_ascii (char *buf, int c,...)
  51.349 ++convert_to_ascii (char *buf, int c, int _num)
  51.350 + {
  51.351 +-  unsigned long num = *((&c) + 1), mult = 10;
  51.352 ++  unsigned long num = _num, mult = 10;
  51.353 +   char *ptr = buf;
  51.354 + 
  51.355 + #ifndef STAGE1_5
  51.356 +@@ -182,11 +185,11 @@
  51.357 + void
  51.358 + grub_printf (const char *format,...)
  51.359 + {
  51.360 +-  int *dataptr = (int *) &format;
  51.361 ++  va_list ap;
  51.362 +   char c, str[16];
  51.363 +-  
  51.364 +-  dataptr++;
  51.365 + 
  51.366 ++  va_start(ap, format);
  51.367 ++  
  51.368 +   while ((c = *(format++)) != 0)
  51.369 +     {
  51.370 +       if (c != '%')
  51.371 +@@ -200,21 +203,32 @@
  51.372 + 	  case 'X':
  51.373 + #endif
  51.374 + 	  case 'u':
  51.375 +-	    *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0;
  51.376 ++	  {
  51.377 ++	    unsigned i = va_arg(ap, unsigned);
  51.378 ++	    *convert_to_ascii (str, c, i) = 0;
  51.379 + 	    grub_putstr (str);
  51.380 + 	    break;
  51.381 ++          }
  51.382 + 
  51.383 + #ifndef STAGE1_5
  51.384 + 	  case 'c':
  51.385 +-	    grub_putchar ((*(dataptr++)) & 0xff);
  51.386 ++	  {
  51.387 ++	    int c = va_arg(ap, int);
  51.388 ++	    grub_putchar (c & 0xff);
  51.389 + 	    break;
  51.390 ++	  }
  51.391 + 
  51.392 + 	  case 's':
  51.393 +-	    grub_putstr ((char *) *(dataptr++));
  51.394 ++	  {
  51.395 ++	    char *s = va_arg(ap, char*);
  51.396 ++	    grub_putstr (s);
  51.397 + 	    break;
  51.398 ++	  }
  51.399 + #endif
  51.400 + 	  }
  51.401 +     }
  51.402 ++
  51.403 ++  va_end(ap);
  51.404 + }
  51.405 + 
  51.406 + #ifndef STAGE1_5
  51.407 +@@ -223,11 +237,11 @@
  51.408 + {
  51.409 +   /* XXX hohmuth
  51.410 +      ugly hack -- should unify with printf() */
  51.411 +-  int *dataptr = (int *) &format;
  51.412 ++  va_list ap;
  51.413 +   char c, *ptr, str[16];
  51.414 +   char *bp = buffer;
  51.415 + 
  51.416 +-  dataptr++;
  51.417 ++  va_start(ap, format);
  51.418 + 
  51.419 +   while ((c = *format++) != 0)
  51.420 +     {
  51.421 +@@ -237,20 +251,27 @@
  51.422 + 	switch (c = *(format++))
  51.423 + 	  {
  51.424 + 	  case 'd': case 'u': case 'x':
  51.425 +-	    *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0;
  51.426 ++	  {
  51.427 ++	    unsigned i = va_arg(ap, unsigned);
  51.428 ++	    *convert_to_ascii (str, c, i) = 0;
  51.429 + 
  51.430 + 	    ptr = str;
  51.431 + 
  51.432 + 	    while (*ptr)
  51.433 + 	      *bp++ = *(ptr++); /* putchar(*(ptr++)); */
  51.434 + 	    break;
  51.435 ++	  }
  51.436 + 
  51.437 +-	  case 'c': *bp++ = (*(dataptr++))&0xff;
  51.438 ++	  case 'c':
  51.439 ++	  {
  51.440 ++	    int c = va_arg(ap, int);
  51.441 ++	    *bp++ = c&0xff;
  51.442 + 	    /* putchar((*(dataptr++))&0xff); */
  51.443 + 	    break;
  51.444 ++	  }
  51.445 + 
  51.446 + 	  case 's':
  51.447 +-	    ptr = (char *) (*(dataptr++));
  51.448 ++	    ptr = va_arg(ap, char *);
  51.449 + 
  51.450 + 	    while ((c = *ptr++) != 0)
  51.451 + 	      *bp++ = c; /* putchar(c); */
  51.452 +@@ -258,6 +279,8 @@
  51.453 + 	  }
  51.454 +     }
  51.455 + 
  51.456 ++  va_end(ap);
  51.457 ++
  51.458 +   *bp = 0;
  51.459 +   return bp - buffer;
  51.460 + }
  51.461 +@@ -1263,12 +1286,14 @@
  51.462 +     return ! errnum;
  51.463 + #endif /* GRUB_UTIL */
  51.464 + 
  51.465 ++#ifndef __MINIOS__
  51.466 +   if ((addr < RAW_ADDR (0x1000))
  51.467 +       || (addr < RAW_ADDR (0x100000)
  51.468 + 	  && RAW_ADDR (mbi.mem_lower * 1024) < (addr + len))
  51.469 +       || (addr >= RAW_ADDR (0x100000)
  51.470 + 	  && RAW_ADDR (mbi.mem_upper * 1024) < ((addr - 0x100000) + len)))
  51.471 +     errnum = ERR_WONT_FIT;
  51.472 ++#endif
  51.473 + 
  51.474 +   return ! errnum;
  51.475 + }
  51.476 +@@ -1342,7 +1367,7 @@
  51.477 + }
  51.478 + #endif /* ! STAGE1_5 */
  51.479 + 
  51.480 +-#ifndef GRUB_UTIL
  51.481 ++#if !defined(GRUB_UTIL) && !defined(__MINIOS__)
  51.482 + # undef memcpy
  51.483 + /* GCC emits references to memcpy() for struct copies etc.  */
  51.484 + void *memcpy (void *dest, const void *src, int n)  __attribute__ ((alias ("grub_memmove")));
  51.485 +Index: grub/stage2/disk_io.c
  51.486 +===================================================================
  51.487 +--- grub.orig/stage2/disk_io.c	2008-06-16 15:18:03.327932000 +0100
  51.488 ++++ grub/stage2/disk_io.c	2008-06-16 15:18:14.733009000 +0100
  51.489 +@@ -130,7 +130,14 @@
  51.490 + static inline unsigned long
  51.491 + log2 (unsigned long word)
  51.492 + {
  51.493 +-  asm volatile ("bsfl %1,%0"
  51.494 ++  asm volatile ("bsf"
  51.495 ++#ifdef __i386__
  51.496 ++		  "l"
  51.497 ++#endif
  51.498 ++#ifdef __x86_64__
  51.499 ++		  "q"
  51.500 ++#endif  
  51.501 ++		  " %1,%0"
  51.502 + 		: "=r" (word)
  51.503 + 		: "r" (word));
  51.504 +   return word;
  51.505 +Index: grub/stage2/fsys_fat.c
  51.506 +===================================================================
  51.507 +--- grub.orig/stage2/fsys_fat.c	2008-06-16 15:18:03.337934000 +0100
  51.508 ++++ grub/stage2/fsys_fat.c	2008-06-16 15:18:14.737009000 +0100
  51.509 +@@ -57,7 +57,14 @@
  51.510 + static __inline__ unsigned long
  51.511 + log2 (unsigned long word)
  51.512 + {
  51.513 +-  __asm__ ("bsfl %1,%0"
  51.514 ++  __asm__ ("bsf"
  51.515 ++#ifdef __i386__
  51.516 ++		  "l"
  51.517 ++#endif
  51.518 ++#ifdef __x86_64__
  51.519 ++		  "q"
  51.520 ++#endif
  51.521 ++		  " %1,%0"
  51.522 + 	   : "=r" (word)
  51.523 + 	   : "r" (word));
  51.524 +   return word;
  51.525 +Index: grub/stage2/pc_slice.h
  51.526 +===================================================================
  51.527 +--- grub.orig/stage2/pc_slice.h	2008-06-16 15:18:03.347932000 +0100
  51.528 ++++ grub/stage2/pc_slice.h	2008-06-16 15:18:14.746009000 +0100
  51.529 +@@ -38,50 +38,50 @@
  51.530 +  */
  51.531 + 
  51.532 + #define PC_MBR_CHECK_SIG(mbr_ptr) \
  51.533 +-  ( *( (unsigned short *) (((int) mbr_ptr) + PC_MBR_SIG_OFFSET) ) \
  51.534 ++  ( *( (unsigned short *) (((long) mbr_ptr) + PC_MBR_SIG_OFFSET) ) \
  51.535 +    == PC_MBR_SIGNATURE )
  51.536 + 
  51.537 + #define PC_MBR_SIG(mbr_ptr) \
  51.538 +-  ( *( (unsigned short *) (((int) mbr_ptr) + PC_MBR_SIG_OFFSET) ) )
  51.539 ++  ( *( (unsigned short *) (((long) mbr_ptr) + PC_MBR_SIG_OFFSET) ) )
  51.540 + 
  51.541 + #define PC_SLICE_FLAG(mbr_ptr, part) \
  51.542 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET \
  51.543 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET \
  51.544 + 			  + (part << 4)) ) )
  51.545 + 
  51.546 + #define PC_SLICE_HEAD(mbr_ptr, part) \
  51.547 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 1 \
  51.548 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 1 \
  51.549 + 			  + (part << 4)) ) )
  51.550 + 
  51.551 + #define PC_SLICE_SEC(mbr_ptr, part) \
  51.552 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 2 \
  51.553 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 2 \
  51.554 + 			  + (part << 4)) ) )
  51.555 + 
  51.556 + #define PC_SLICE_CYL(mbr_ptr, part) \
  51.557 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 3 \
  51.558 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 3 \
  51.559 + 			  + (part << 4)) ) )
  51.560 + 
  51.561 + #define PC_SLICE_TYPE(mbr_ptr, part) \
  51.562 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 4 \
  51.563 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 4 \
  51.564 + 			  + (part << 4)) ) )
  51.565 + 
  51.566 + #define PC_SLICE_EHEAD(mbr_ptr, part) \
  51.567 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 5 \
  51.568 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 5 \
  51.569 + 			  + (part << 4)) ) )
  51.570 + 
  51.571 + #define PC_SLICE_ESEC(mbr_ptr, part) \
  51.572 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 6 \
  51.573 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 6 \
  51.574 + 			  + (part << 4)) ) )
  51.575 + 
  51.576 + #define PC_SLICE_ECYL(mbr_ptr, part) \
  51.577 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 7 \
  51.578 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 7 \
  51.579 + 			  + (part << 4)) ) )
  51.580 + 
  51.581 + #define PC_SLICE_START(mbr_ptr, part) \
  51.582 +-  ( *( (unsigned long *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 8 \
  51.583 ++  ( *( (unsigned long *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 8 \
  51.584 + 			  + (part << 4)) ) )
  51.585 + 
  51.586 + #define PC_SLICE_LENGTH(mbr_ptr, part) \
  51.587 +-  ( *( (unsigned long *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 12 \
  51.588 ++  ( *( (unsigned long *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 12 \
  51.589 + 			  + (part << 4)) ) )
  51.590 + 
  51.591 + 
  51.592 +Index: grub/stage2/shared.h
  51.593 +===================================================================
  51.594 +--- grub.orig/stage2/shared.h	2008-06-16 15:18:14.537009000 +0100
  51.595 ++++ grub/stage2/shared.h	2008-06-17 14:25:08.443906000 +0100
  51.596 +@@ -39,6 +39,10 @@
  51.597 + extern char *grub_scratch_mem;
  51.598 + # define RAW_ADDR(x) ((x) + (int) grub_scratch_mem)
  51.599 + # define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4)
  51.600 ++#elif defined(__MINIOS__)
  51.601 ++extern char grub_scratch_mem[];
  51.602 ++# define RAW_ADDR(x) ((x) + (int) grub_scratch_mem)
  51.603 ++# define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4)
  51.604 + #else
  51.605 + # define RAW_ADDR(x) (x)
  51.606 + # define RAW_SEG(x) (x)
  51.607 +@@ -707,7 +711,9 @@
  51.608 + 
  51.609 + /* Halt the system, using APM if possible. If NO_APM is true, don't use
  51.610 +    APM even if it is available.  */
  51.611 ++#ifndef __MINIOS__
  51.612 + void grub_halt (int no_apm) __attribute__ ((noreturn));
  51.613 ++#endif
  51.614 + 
  51.615 + /* Copy MAP to the drive map and set up int13_handler.  */
  51.616 + void set_int13_handler (unsigned short *map);
  51.617 +@@ -857,7 +863,8 @@
  51.618 +   KERNEL_TYPE_BIG_LINUX,	/* Big Linux.  */
  51.619 +   KERNEL_TYPE_FREEBSD,		/* FreeBSD.  */
  51.620 +   KERNEL_TYPE_NETBSD,		/* NetBSD.  */
  51.621 +-  KERNEL_TYPE_CHAINLOADER	/* Chainloader.  */
  51.622 ++  KERNEL_TYPE_CHAINLOADER,	/* Chainloader.  */
  51.623 ++  KERNEL_TYPE_PV		/* Paravirtualized.  */
  51.624 + }
  51.625 + kernel_t;
  51.626 + 
  51.627 +@@ -890,7 +897,7 @@
  51.628 + int grub_strlen (const char *str);
  51.629 + char *grub_strcpy (char *dest, const char *src);
  51.630 + 
  51.631 +-#ifndef GRUB_UTIL
  51.632 ++#if !defined(GRUB_UTIL) && !defined(__MINIOS__)
  51.633 + typedef unsigned long grub_jmp_buf[6];
  51.634 + #else
  51.635 + /* In the grub shell, use the libc jmp_buf instead.  */
  51.636 +@@ -898,7 +905,7 @@
  51.637 + # define grub_jmp_buf jmp_buf
  51.638 + #endif
  51.639 + 
  51.640 +-#ifdef GRUB_UTIL
  51.641 ++#if defined(GRUB_UTIL) || defined(__MINIOS__)
  51.642 + # define grub_setjmp	setjmp
  51.643 + # define grub_longjmp	longjmp
  51.644 + #else /* ! GRUB_UTIL */
  51.645 +@@ -914,7 +921,7 @@
  51.646 + /* misc */
  51.647 + void init_page (void);
  51.648 + void print_error (void);
  51.649 +-char *convert_to_ascii (char *buf, int c, ...);
  51.650 ++char *convert_to_ascii (char *buf, int c, int num);
  51.651 + int get_cmdline (char *prompt, char *cmdline, int maxlen,
  51.652 + 		 int echo_char, int history);
  51.653 + int substring (const char *s1, const char *s2);
  51.654 +Index: grub/netboot/etherboot.h
  51.655 +===================================================================
  51.656 +--- grub.orig/netboot/etherboot.h	2008-06-16 15:18:03.446934000 +0100
  51.657 ++++ grub/netboot/etherboot.h	2008-06-16 15:18:14.760009000 +0100
  51.658 +@@ -246,7 +246,7 @@
  51.659 + 
  51.660 + typedef struct
  51.661 + {
  51.662 +-  unsigned long	s_addr;
  51.663 ++  unsigned int	s_addr;
  51.664 + }
  51.665 + in_addr;
  51.666 + 
  51.667 +@@ -302,7 +302,7 @@
  51.668 +   char bp_htype;
  51.669 +   char bp_hlen;
  51.670 +   char bp_hops;
  51.671 +-  unsigned long bp_xid;
  51.672 ++  unsigned int bp_xid;
  51.673 +   unsigned short bp_secs;
  51.674 +   unsigned short unused;
  51.675 +   in_addr bp_ciaddr;
  51.676 +@@ -411,25 +411,25 @@
  51.677 +     
  51.678 +     struct
  51.679 +     {
  51.680 +-      long id;
  51.681 +-      long type;
  51.682 +-      long rpcvers;
  51.683 +-      long prog;
  51.684 +-      long vers;
  51.685 +-      long proc;
  51.686 +-      long data[1];
  51.687 ++      int id;
  51.688 ++      int type;
  51.689 ++      int rpcvers;
  51.690 ++      int prog;
  51.691 ++      int vers;
  51.692 ++      int proc;
  51.693 ++      int data[1];
  51.694 +     }
  51.695 +     call;
  51.696 +     
  51.697 +     struct
  51.698 +     {
  51.699 +-      long id;
  51.700 +-      long type;
  51.701 +-      long rstatus;
  51.702 +-      long verifier;
  51.703 +-      long v2;
  51.704 +-      long astatus;
  51.705 +-      long data[1];
  51.706 ++      int id;
  51.707 ++      int type;
  51.708 ++      int rstatus;
  51.709 ++      int verifier;
  51.710 ++      int v2;
  51.711 ++      int astatus;
  51.712 ++      int data[1];
  51.713 +     }
  51.714 +     reply;
  51.715 +   }
  51.716 +@@ -517,7 +517,9 @@
  51.717 + 
  51.718 + /* misc.c */
  51.719 + extern void twiddle (void);
  51.720 ++#ifndef __MINIOS__
  51.721 + extern void sleep (int secs);
  51.722 ++#endif
  51.723 + extern int getdec (char **s);
  51.724 + extern void etherboot_printf (const char *, ...);
  51.725 + extern int etherboot_sprintf (char *, const char *, ...);
  51.726 +Index: grub/stage2/common.c
  51.727 +===================================================================
  51.728 +--- grub.orig/stage2/common.c	2008-06-16 15:18:03.366934000 +0100
  51.729 ++++ grub/stage2/common.c	2008-06-16 15:18:14.764009000 +0100
  51.730 +@@ -137,6 +137,7 @@
  51.731 + }
  51.732 + #endif /* ! STAGE1_5 */
  51.733 + 
  51.734 ++#ifndef __MINIOS__
  51.735 + /* This queries for BIOS information.  */
  51.736 + void
  51.737 + init_bios_info (void)
  51.738 +@@ -335,3 +336,4 @@
  51.739 +   /* Start main routine here.  */
  51.740 +   cmain ();
  51.741 + }
  51.742 ++#endif
  51.743 +Index: grub/stage2/serial.c
  51.744 +===================================================================
  51.745 +--- grub.orig/stage2/serial.c	2008-06-16 15:18:03.376934000 +0100
  51.746 ++++ grub/stage2/serial.c	2008-06-16 15:18:14.769009000 +0100
  51.747 +@@ -37,7 +37,7 @@
  51.748 + 
  51.749 + /* Hardware-dependent definitions.  */
  51.750 + 
  51.751 +-#ifndef GRUB_UTIL
  51.752 ++#if !defined(GRUB_UTIL) && !defined(__MINIOS__)
  51.753 + /* The structure for speed vs. divisor.  */
  51.754 + struct divisor
  51.755 + {
  51.756 +@@ -222,6 +222,8 @@
  51.757 +       {('3' | ('~' << 8)), 4},
  51.758 +       {('5' | ('~' << 8)), 7},
  51.759 +       {('6' | ('~' << 8)), 3},
  51.760 ++      {('7' | ('~' << 8)), 1},
  51.761 ++      {('8' | ('~' << 8)), 5},
  51.762 +     };
  51.763 +   
  51.764 +   /* The buffer must start with ``ESC [''.  */
  51.765 +Index: grub/stage2/tparm.c
  51.766 +===================================================================
  51.767 +--- grub.orig/stage2/tparm.c	2008-06-16 15:18:03.390933000 +0100
  51.768 ++++ grub/stage2/tparm.c	2008-06-16 15:18:14.774010000 +0100
  51.769 +@@ -48,6 +48,7 @@
  51.770 + #include "shared.h"
  51.771 + 
  51.772 + #include "tparm.h"
  51.773 ++#include <stdarg.h>
  51.774 + 
  51.775 + /*
  51.776 +  * Common/troublesome character definitions
  51.777 +@@ -320,7 +321,7 @@
  51.778 + #define isLOWER(c) ((c) >= 'a' && (c) <= 'z')
  51.779 + 
  51.780 + static inline char *
  51.781 +-tparam_internal(const char *string, int *dataptr)
  51.782 ++tparam_internal(const char *string, va_list ap)
  51.783 + {
  51.784 + #define NUM_VARS 26
  51.785 +     char *p_is_s[9];
  51.786 +@@ -461,9 +462,9 @@
  51.787 + 	 * a char* and an int may not be the same size on the stack.
  51.788 + 	 */
  51.789 + 	if (p_is_s[i] != 0) {
  51.790 +-	  p_is_s[i] = (char *)(*(dataptr++));
  51.791 ++	  p_is_s[i] = va_arg(ap, char *);
  51.792 + 	} else {
  51.793 +-	  param[i] = (int)(*(dataptr++));
  51.794 ++	  param[i] = va_arg(ap, int);
  51.795 + 	}
  51.796 +     }
  51.797 + 
  51.798 +@@ -716,11 +717,13 @@
  51.799 + grub_tparm(const char *string,...)
  51.800 + {
  51.801 +     char *result;
  51.802 +-    int *dataptr = (int *) &string;
  51.803 ++    va_list ap;
  51.804 + 
  51.805 +-    dataptr++;
  51.806 ++    va_start(ap, string);
  51.807 + 
  51.808 +-    result = tparam_internal(string, dataptr);
  51.809 ++    result = tparam_internal(string, ap);
  51.810 ++
  51.811 ++    va_end(ap);
  51.812 + 
  51.813 +     return result;
  51.814 + }
  51.815 +Index: grub/stage2/fsys_iso9660.c
  51.816 +===================================================================
  51.817 +--- grub.orig/stage2/fsys_iso9660.c	2008-06-16 15:18:03.400933000 +0100
  51.818 ++++ grub/stage2/fsys_iso9660.c	2008-06-16 15:18:14.779009000 +0100
  51.819 +@@ -59,7 +59,14 @@
  51.820 + static inline unsigned long
  51.821 + log2 (unsigned long word)
  51.822 + {
  51.823 +-  asm volatile ("bsfl %1,%0"
  51.824 ++  asm volatile ("bsf"
  51.825 ++#ifdef __i386__
  51.826 ++		  "l"
  51.827 ++#endif
  51.828 ++#ifdef __x86_64__
  51.829 ++		  "q"
  51.830 ++#endif
  51.831 ++		  " %1,%0"
  51.832 + 		:          "=r" (word)
  51.833 + 		:          "r" (word));
  51.834 +   return word;
  51.835 +Index: grub/stage2/fsys_reiserfs.c
  51.836 +===================================================================
  51.837 +--- grub.orig/stage2/fsys_reiserfs.c	2008-06-16 15:18:03.410933000 +0100
  51.838 ++++ grub/stage2/fsys_reiserfs.c	2008-06-16 15:18:14.786009000 +0100
  51.839 +@@ -369,7 +369,14 @@
  51.840 + static __inline__ unsigned long
  51.841 + log2 (unsigned long word)
  51.842 + {
  51.843 +-  __asm__ ("bsfl %1,%0"
  51.844 ++  __asm__ ("bsf"
  51.845 ++#ifdef __i386__
  51.846 ++		  "l"
  51.847 ++#endif
  51.848 ++#ifdef __x86_64__
  51.849 ++		  "q"
  51.850 ++#endif
  51.851 ++		  " %1,%0"
  51.852 + 	   : "=r" (word)
  51.853 + 	   : "r" (word));
  51.854 +   return word;
  51.855 +Index: grub/netboot/misc.c
  51.856 +===================================================================
  51.857 +--- grub.orig/netboot/misc.c	2008-06-16 15:18:03.456934000 +0100
  51.858 ++++ grub/netboot/misc.c	2008-06-16 15:18:14.790009000 +0100
  51.859 +@@ -21,7 +21,9 @@
  51.860 + 
  51.861 + #define GRUB	1
  51.862 + #include <etherboot.h>
  51.863 ++#include <stdarg.h>
  51.864 + 
  51.865 ++#ifndef __MINIOS__
  51.866 + void
  51.867 + sleep (int secs)
  51.868 + {
  51.869 +@@ -30,6 +32,7 @@
  51.870 +   while (currticks () < tmo)
  51.871 +     ;
  51.872 + }
  51.873 ++#endif
  51.874 + 
  51.875 + void
  51.876 + twiddle (void)
  51.877 +@@ -71,7 +74,7 @@
  51.878 + 	Note: width specification not supported
  51.879 + **************************************************************************/
  51.880 + static int
  51.881 +-etherboot_vsprintf (char *buf, const char *fmt, const int *dp)
  51.882 ++etherboot_vsprintf (char *buf, const char *fmt, va_list ap)
  51.883 + {
  51.884 +   char *p, *s;
  51.885 +   
  51.886 +@@ -86,7 +89,7 @@
  51.887 +       
  51.888 +       if (*++fmt == 's')
  51.889 + 	{
  51.890 +-	  for (p = (char *) *dp++; *p != '\0'; p++)
  51.891 ++	  for (p = va_arg(ap, char *); *p != '\0'; p++)
  51.892 + 	    buf ? *s++ = *p : grub_putchar (*p);
  51.893 + 	}
  51.894 +       else
  51.895 +@@ -121,11 +124,9 @@
  51.896 + 	  if ((*fmt | 0x20) == 'x')
  51.897 + 	    {
  51.898 + 	      /* With x86 gcc, sizeof(long) == sizeof(int) */
  51.899 +-	      const long *lp = (const long *) dp;
  51.900 +-	      long h = *lp++;
  51.901 ++	      long h = va_arg(ap, int);
  51.902 + 	      int ncase = (*fmt & 0x20);
  51.903 + 	      
  51.904 +-	      dp = (const int *) lp;
  51.905 + 	      if (alt)
  51.906 + 		{
  51.907 + 		  *q++ = '0';
  51.908 +@@ -136,7 +137,7 @@
  51.909 + 	    }
  51.910 + 	  else if (*fmt == 'd')
  51.911 + 	    {
  51.912 +-	      int i = *dp++;
  51.913 ++	      int i = va_arg(ap, int);
  51.914 + 	      char *r;
  51.915 + 	      
  51.916 + 	      if (i < 0)
  51.917 +@@ -171,10 +172,8 @@
  51.918 + 		unsigned char	c[4];
  51.919 + 	      }
  51.920 + 	      u;
  51.921 +-	      const long *lp = (const long *) dp;
  51.922 + 	      
  51.923 +-	      u.l = *lp++;
  51.924 +-	      dp = (const int *) lp;
  51.925 ++	      u.l = va_arg(ap, int);
  51.926 + 	      
  51.927 + 	      for (r = &u.c[0]; r < &u.c[4]; ++r)
  51.928 + 		q += etherboot_sprintf (q, "%d.", *r);
  51.929 +@@ -184,7 +183,7 @@
  51.930 + 	  else if (*fmt == '!')
  51.931 + 	    {
  51.932 + 	      char *r;
  51.933 +-	      p = (char *) *dp++;
  51.934 ++	      p = va_arg(ap, char *);
  51.935 + 	      
  51.936 + 	      for (r = p + ETH_ALEN; p < r; ++p)
  51.937 + 		q += etherboot_sprintf (q, "%hhX:", *p);
  51.938 +@@ -192,7 +191,7 @@
  51.939 + 	      --q;
  51.940 + 	    }
  51.941 + 	  else if (*fmt == 'c')
  51.942 +-	    *q++ = *dp++;
  51.943 ++	    *q++ = va_arg(ap, int);
  51.944 + 	  else
  51.945 + 	    *q++ = *fmt;
  51.946 + 	  
  51.947 +@@ -211,13 +210,21 @@
  51.948 + int
  51.949 + etherboot_sprintf (char *buf, const char *fmt, ...)
  51.950 + {
  51.951 +-  return etherboot_vsprintf (buf, fmt, ((const int *) &fmt) + 1);
  51.952 ++  va_list ap;
  51.953 ++  int ret;
  51.954 ++  va_start(ap, fmt);
  51.955 ++  ret = etherboot_vsprintf (buf, fmt, ap);
  51.956 ++  va_end(ap);
  51.957 ++  return ret;
  51.958 + }
  51.959 + 
  51.960 + void
  51.961 + etherboot_printf (const char *fmt, ...)
  51.962 + {
  51.963 +-  (void) etherboot_vsprintf (0, fmt, ((const int *) &fmt) + 1);
  51.964 ++  va_list ap;
  51.965 ++  va_start(ap, fmt);
  51.966 ++  etherboot_vsprintf (0, fmt, ap);
  51.967 ++  va_end(ap);
  51.968 + }
  51.969 + 
  51.970 + int
  51.971 +Index: grub/netboot/main.c
  51.972 +===================================================================
  51.973 +--- grub.orig/netboot/main.c	2008-06-16 15:18:03.470932000 +0100
  51.974 ++++ grub/netboot/main.c	2008-06-16 15:18:14.797009000 +0100
  51.975 +@@ -55,7 +55,7 @@
  51.976 + static int vendorext_isvalid;
  51.977 + static unsigned long netmask;
  51.978 + static struct bootpd_t bootp_data;
  51.979 +-static unsigned long xid;
  51.980 ++static unsigned int xid;
  51.981 + 
  51.982 + #define	BOOTP_DATA_ADDR	(&bootp_data)
  51.983 + 
  51.984 +@@ -778,7 +778,7 @@
  51.985 + 
  51.986 + 	      arpreply = (struct arprequest *) &nic.packet[ETH_HLEN];
  51.987 + 	      
  51.988 +-	      if (arpreply->opcode == htons (ARP_REPLY)
  51.989 ++	      if (arpreply->opcode == htons (ARP_REPLY) && ptr
  51.990 + 		  && ! grub_memcmp (arpreply->sipaddr, ptr, sizeof (in_addr))
  51.991 + 		  && type == AWAIT_ARP)
  51.992 + 		{
  51.993 +@@ -827,7 +827,7 @@
  51.994 + 	    {
  51.995 + 	      arpreply = (struct arprequest *) &nic.packet[ETH_HLEN];
  51.996 + 	      
  51.997 +-	      if (arpreply->opcode == htons (RARP_REPLY)
  51.998 ++	      if (arpreply->opcode == htons (RARP_REPLY) && ptr
  51.999 + 		  && ! grub_memcmp (arpreply->thwaddr, ptr, ETH_ALEN))
 51.1000 + 		{
 51.1001 + 		  grub_memmove ((char *) arptable[ARP_SERVER].node,
 51.1002 +@@ -1135,7 +1135,7 @@
 51.1003 + long
 51.1004 + rfc2131_sleep_interval (int base, int exp)
 51.1005 + {
 51.1006 +-  static long seed = 0;
 51.1007 ++  static unsigned seed = 0;
 51.1008 +   long q;
 51.1009 +   unsigned long tmo;
 51.1010 +   
 51.1011 +Index: grub/stage2/graphics.c
 51.1012 +===================================================================
 51.1013 +--- grub.orig/stage2/graphics.c	2008-06-16 15:18:14.524009000 +0100
 51.1014 ++++ grub/stage2/graphics.c	2008-06-17 14:29:05.204328000 +0100
 51.1015 +@@ -30,7 +30,29 @@
 51.1016 + #include <shared.h>
 51.1017 + #include <graphics.h>
 51.1018 + 
 51.1019 ++#ifdef __MINIOS__
 51.1020 ++#include <stdint.h>
 51.1021 ++typedef uint8_t Bit8u;
 51.1022 ++#include <vgafonts.h>
 51.1023 ++#include <fbfront.h>
 51.1024 ++#include <malloc.h>
 51.1025 ++#define set_int1c_handler() (void)0
 51.1026 ++#define unset_int1c_handler() (void)0
 51.1027 ++static uint32_t *VIDEOMEM;
 51.1028 ++static struct fbfront_dev *fb_dev;
 51.1029 ++static uint32_t palette[17];
 51.1030 ++short cursorX, cursorY;
 51.1031 ++/* TODO: blink */
 51.1032 ++uint32_t cursorBuf32[16*8];
 51.1033 ++#define WIDTH 640
 51.1034 ++#define HEIGHT 480
 51.1035 ++#define DEPTH 32
 51.1036 ++#define RAMSIZE (WIDTH * HEIGHT * (DEPTH / 8))
 51.1037 ++#else
 51.1038 ++#define fbfront_update(dev, x, y, w, h) (void)0
 51.1039 + int saved_videomode;
 51.1040 ++#endif
 51.1041 ++
 51.1042 + unsigned char *font8x16;
 51.1043 + 
 51.1044 + int graphics_inited = 0;
 51.1045 +@@ -38,11 +60,15 @@
 51.1046 + 
 51.1047 + int shade = 1, no_cursor = 0;
 51.1048 + 
 51.1049 ++#ifdef __MINIOS__
 51.1050 ++uint32_t VSHADOW[RAMSIZE];
 51.1051 ++#else
 51.1052 + #define VSHADOW VSHADOW1
 51.1053 + unsigned char VSHADOW1[38400];
 51.1054 + unsigned char VSHADOW2[38400];
 51.1055 + unsigned char VSHADOW4[38400];
 51.1056 + unsigned char VSHADOW8[38400];
 51.1057 ++#endif
 51.1058 + 
 51.1059 + /* define the default viewable area */
 51.1060 + int view_x0 = 0;
 51.1061 +@@ -129,6 +155,8 @@
 51.1062 +     count_lines = k;
 51.1063 + 
 51.1064 +     no_scroll = 0;
 51.1065 ++
 51.1066 ++    fbfront_update(fb_dev, view_x0 * 8, view_y0 * 16, (view_x1 - view_x0) * 8, (view_y1 - view_y0) * 16);
 51.1067 + }
 51.1068 + 
 51.1069 + /* Set the splash image */
 51.1070 +@@ -154,17 +182,29 @@
 51.1071 + int graphics_init()
 51.1072 + {
 51.1073 +     if (!graphics_inited) {
 51.1074 ++#ifdef __MINIOS__
 51.1075 ++	VIDEOMEM = memalign(PAGE_SIZE, RAMSIZE);
 51.1076 ++	if (!(fb_dev = fb_open(VIDEOMEM, WIDTH, HEIGHT, DEPTH))) {
 51.1077 ++	    free(VIDEOMEM);
 51.1078 ++	    return 0;
 51.1079 ++	}
 51.1080 ++#else
 51.1081 +         saved_videomode = set_videomode(0x12);
 51.1082 +         if (get_videomode() != 0x12) {
 51.1083 +             set_videomode(saved_videomode);
 51.1084 +             return 0;
 51.1085 +         }
 51.1086 ++#endif
 51.1087 +         graphics_inited = 1;
 51.1088 +     }
 51.1089 +     else
 51.1090 +         return 1;
 51.1091 + 
 51.1092 ++#ifdef __MINIOS__
 51.1093 ++    font8x16 = vgafont16;
 51.1094 ++#else
 51.1095 +     font8x16 = (unsigned char*)graphics_get_font();
 51.1096 ++#endif
 51.1097 + 
 51.1098 +     /* make sure that the highlight color is set correctly */
 51.1099 +     graphics_highlight_color = ((graphics_normal_color >> 4) | 
 51.1100 +@@ -176,7 +216,11 @@
 51.1101 +         grub_printf("Failed to read splash image (%s)\n", splashimage);
 51.1102 +         grub_printf("Press any key to continue...");
 51.1103 +         getkey();
 51.1104 ++#ifdef __MINIOS__
 51.1105 ++	fb_close();
 51.1106 ++#else
 51.1107 +         set_videomode(saved_videomode);
 51.1108 ++#endif
 51.1109 +         graphics_inited = 0;
 51.1110 +         return 0;
 51.1111 +     }
 51.1112 +@@ -190,8 +234,13 @@
 51.1113 + void graphics_end(void)
 51.1114 + {
 51.1115 +     if (graphics_inited) {
 51.1116 ++#ifdef __MINIOS__
 51.1117 ++	fb_close();
 51.1118 ++	free(VIDEOMEM);
 51.1119 ++#else
 51.1120 +         unset_int1c_handler();
 51.1121 +         set_videomode(saved_videomode);
 51.1122 ++#endif
 51.1123 +         graphics_inited = 0;
 51.1124 +         no_cursor = 0;
 51.1125 +     }
 51.1126 +@@ -204,15 +253,19 @@
 51.1127 +     graphics_cursor(0);
 51.1128 + 
 51.1129 +     if (ch == '\n') {
 51.1130 ++	fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 51.1131 +         if (fonty + 1 < view_y1)
 51.1132 +             graphics_setxy(fontx, fonty + 1);
 51.1133 +         else
 51.1134 +             graphics_scroll();
 51.1135 +         graphics_cursor(1);
 51.1136 ++	fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 51.1137 +         return;
 51.1138 +     } else if (ch == '\r') {
 51.1139 ++	fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 51.1140 +         graphics_setxy(view_x0, fonty);
 51.1141 +         graphics_cursor(1);
 51.1142 ++	fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 51.1143 +         return;
 51.1144 +     }
 51.1145 + 
 51.1146 +@@ -224,6 +277,7 @@
 51.1147 +         text[fonty * 80 + fontx] |= 0x100;
 51.1148 + 
 51.1149 +     graphics_cursor(0);
 51.1150 ++    fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 51.1151 + 
 51.1152 +     if ((fontx + 1) >= view_x1) {
 51.1153 +         graphics_setxy(view_x0, fonty);
 51.1154 +@@ -232,13 +286,16 @@
 51.1155 +         else
 51.1156 +             graphics_scroll();
 51.1157 +         graphics_cursor(1);
 51.1158 ++	fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 51.1159 +         do_more ();
 51.1160 +         graphics_cursor(0);
 51.1161 ++	fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 51.1162 +     } else {
 51.1163 +         graphics_setxy(fontx + 1, fonty);
 51.1164 +     }
 51.1165 + 
 51.1166 +     graphics_cursor(1);
 51.1167 ++    fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 51.1168 + }
 51.1169 + 
 51.1170 + /* get the current location of the cursor */
 51.1171 +@@ -248,10 +305,12 @@
 51.1172 + 
 51.1173 + void graphics_gotoxy(int x, int y) {
 51.1174 +     graphics_cursor(0);
 51.1175 ++    fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 51.1176 + 
 51.1177 +     graphics_setxy(x, y);
 51.1178 + 
 51.1179 +     graphics_cursor(1);
 51.1180 ++    fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 51.1181 + }
 51.1182 + 
 51.1183 + void graphics_cls(void) {
 51.1184 +@@ -262,15 +321,21 @@
 51.1185 +     graphics_gotoxy(view_x0, view_y0);
 51.1186 + 
 51.1187 +     mem = (unsigned char*)VIDEOMEM;
 51.1188 ++#ifndef __MINIOS__
 51.1189 +     s1 = (unsigned char*)VSHADOW1;
 51.1190 +     s2 = (unsigned char*)VSHADOW2;
 51.1191 +     s4 = (unsigned char*)VSHADOW4;
 51.1192 +     s8 = (unsigned char*)VSHADOW8;
 51.1193 ++#endif
 51.1194 + 
 51.1195 +     for (i = 0; i < 80 * 30; i++)
 51.1196 +         text[i] = ' ';
 51.1197 +     graphics_cursor(1);
 51.1198 + 
 51.1199 ++#ifdef __MINIOS__
 51.1200 ++    memcpy(mem, VSHADOW, RAMSIZE);
 51.1201 ++    fbfront_update(fb_dev, 0, 0, 640, 480);
 51.1202 ++#else
 51.1203 +     BitMask(0xff);
 51.1204 + 
 51.1205 +     /* plane 1 */
 51.1206 +@@ -290,6 +355,7 @@
 51.1207 +     grub_memcpy(mem, s8, 38400);
 51.1208 + 
 51.1209 +     MapMask(15);
 51.1210 ++#endif
 51.1211 + 
 51.1212 +     if (no_cursor) {
 51.1213 +         no_cursor = 0;
 51.1214 +@@ -337,6 +403,11 @@
 51.1215 +     return 0;
 51.1216 + }
 51.1217 + 
 51.1218 ++void graphics_set_palette(int idx, int red, int green, int blue)
 51.1219 ++{
 51.1220 ++    palette[idx] = (red << (16 + 2)) | (green << (8 + 2)) | (blue << 2);
 51.1221 ++}
 51.1222 ++
 51.1223 + /* Read in the splashscreen image and set the palette up appropriately.
 51.1224 +  * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
 51.1225 +  * 640x480. */
 51.1226 +@@ -413,18 +484,19 @@
 51.1227 +         }
 51.1228 + 
 51.1229 +         if (len == 6 && idx < 15) {
 51.1230 +-            int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
 51.1231 +-            int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
 51.1232 +-            int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
 51.1233 ++            int r = ((hex(buf[0]) << 4) | hex(buf[1]));
 51.1234 ++            int g = ((hex(buf[2]) << 4) | hex(buf[3]));
 51.1235 ++            int b = ((hex(buf[4]) << 4) | hex(buf[5]));
 51.1236 + 
 51.1237 +             pal[idx] = base;
 51.1238 +-            graphics_set_palette(idx, r, g, b);
 51.1239 ++            graphics_set_palette(idx, r / 4, g / 4, b / 4);
 51.1240 +             ++idx;
 51.1241 +         }
 51.1242 +     }
 51.1243 + 
 51.1244 +     x = y = len = 0;
 51.1245 + 
 51.1246 ++#ifndef __MINIOS__
 51.1247 +     s1 = (unsigned char*)VSHADOW1;
 51.1248 +     s2 = (unsigned char*)VSHADOW2;
 51.1249 +     s4 = (unsigned char*)VSHADOW4;
 51.1250 +@@ -432,6 +504,7 @@
 51.1251 + 
 51.1252 +     for (i = 0; i < 38400; i++)
 51.1253 +         s1[i] = s2[i] = s4[i] = s8[i] = 0;
 51.1254 ++#endif
 51.1255 + 
 51.1256 +     /* parse xpm data */
 51.1257 +     while (y < height) {
 51.1258 +@@ -451,6 +524,9 @@
 51.1259 +                     break;
 51.1260 +                 }
 51.1261 + 
 51.1262 ++#ifdef __MINIOS__
 51.1263 ++	    VSHADOW[x + y * 640] = palette[i];
 51.1264 ++#else
 51.1265 +             mask = 0x80 >> (x & 7);
 51.1266 +             if (c & 1)
 51.1267 +                 s1[len + (x >> 3)] |= mask;
 51.1268 +@@ -460,6 +536,7 @@
 51.1269 +                 s4[len + (x >> 3)] |= mask;
 51.1270 +             if (c & 8)
 51.1271 +                 s8[len + (x >> 3)] |= mask;
 51.1272 ++#endif
 51.1273 + 
 51.1274 +             if (++x >= 640) {
 51.1275 +                 x = 0;
 51.1276 +@@ -494,7 +571,13 @@
 51.1277 + }
 51.1278 + 
 51.1279 + void graphics_cursor(int set) {
 51.1280 +-    unsigned char *pat, *mem, *ptr, chr[16 << 2];
 51.1281 ++    unsigned char *pat;
 51.1282 ++#ifdef __MINIOS__
 51.1283 ++    uint32_t *mem, *ptr, chr[16 * 8];
 51.1284 ++    int j;
 51.1285 ++#else
 51.1286 ++    unsigned char *mem, *ptr, chr[16 << 2];
 51.1287 ++#endif
 51.1288 +     int i, ch, invert, offset;
 51.1289 + 
 51.1290 +     if (set && (no_cursor || no_scroll))
 51.1291 +@@ -505,71 +588,127 @@
 51.1292 +     invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
 51.1293 +     pat = font8x16 + (ch << 4);
 51.1294 + 
 51.1295 +-    mem = (unsigned char*)VIDEOMEM + offset;
 51.1296 ++    mem = (unsigned char*)VIDEOMEM + offset
 51.1297 ++#ifdef __MINIOS__
 51.1298 ++	* 8 * 4
 51.1299 ++#endif
 51.1300 ++	;
 51.1301 + 
 51.1302 +     if (!set) {
 51.1303 +         for (i = 0; i < 16; i++) {
 51.1304 +             unsigned char mask = pat[i];
 51.1305 + 
 51.1306 +             if (!invert) {
 51.1307 ++#ifdef __MINIOS__
 51.1308 ++		memcpy(chr + i * 8, VSHADOW + offset * 8, 8 * 4);
 51.1309 ++#else
 51.1310 +                 chr[i     ] = ((unsigned char*)VSHADOW1)[offset];
 51.1311 +                 chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
 51.1312 +                 chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
 51.1313 +                 chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
 51.1314 ++#endif
 51.1315 + 
 51.1316 +                 if (shade) {
 51.1317 +                     if (ch == DISP_VERT || ch == DISP_LL ||
 51.1318 +                         ch == DISP_UR || ch == DISP_LR) {
 51.1319 +                         unsigned char pmask = ~(pat[i] >> 1);
 51.1320 + 
 51.1321 ++#ifdef __MINIOS__
 51.1322 ++			for (j = 0; j < 8; j++)
 51.1323 ++			    if (!(pmask & (1U << j)))
 51.1324 ++				chr[i * 8 + (7 - j)] = palette[0];
 51.1325 ++#else
 51.1326 +                         chr[i     ] &= pmask;
 51.1327 +                         chr[16 + i] &= pmask;
 51.1328 +                         chr[32 + i] &= pmask;
 51.1329 +                         chr[48 + i] &= pmask;
 51.1330 ++#endif
 51.1331 +                     }
 51.1332 +                     if (i > 0 && ch != DISP_VERT) {
 51.1333 +                         unsigned char pmask = ~(pat[i - 1] >> 1);
 51.1334 + 
 51.1335 ++#ifdef __MINIOS__
 51.1336 ++			for (j = 0; j < 8; j++)
 51.1337 ++			    if (!(pmask & (1U << j)))
 51.1338 ++				chr[i * 8 + (7 - j)] = palette[0];
 51.1339 ++#else
 51.1340 +                         chr[i     ] &= pmask;
 51.1341 +                         chr[16 + i] &= pmask;
 51.1342 +                         chr[32 + i] &= pmask;
 51.1343 +                         chr[48 + i] &= pmask;
 51.1344 ++#endif
 51.1345 +                         if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) {
 51.1346 +                             pmask = ~pat[i - 1];
 51.1347 + 
 51.1348 ++#ifdef __MINIOS__
 51.1349 ++			    for (j = 0; j < 8; j++)
 51.1350 ++				if (!(pmask & (1U << j)))
 51.1351 ++				    chr[i * 8 + (7 - j)] = palette[0];
 51.1352 ++#else
 51.1353 +                             chr[i     ] &= pmask;
 51.1354 +                             chr[16 + i] &= pmask;
 51.1355 +                             chr[32 + i] &= pmask;
 51.1356 +                             chr[48 + i] &= pmask;
 51.1357 ++#endif
 51.1358 +                         }
 51.1359 +                     }
 51.1360 +                 }
 51.1361 ++#ifdef __MINIOS__
 51.1362 ++		for (j = 0; j < 8; j++)
 51.1363 ++		    if (mask & (1U << j))
 51.1364 ++			chr[i * 8 + (7 - j)] = palette[15];
 51.1365 ++#else
 51.1366 +                 chr[i     ] |= mask;
 51.1367 +                 chr[16 + i] |= mask;
 51.1368 +                 chr[32 + i] |= mask;
 51.1369 +                 chr[48 + i] |= mask;
 51.1370 ++#endif
 51.1371 + 
 51.1372 +                 offset += 80;
 51.1373 +             }
 51.1374 +             else {
 51.1375 ++#ifdef __MINIOS__
 51.1376 ++		for (j = 0; j < 8; j++)
 51.1377 ++		    if (mask & (1U << j))
 51.1378 ++			chr[i * 8 + (7 - j)] = palette[15];
 51.1379 ++		    else
 51.1380 ++			chr[i * 8 + (7 - j)] = palette[0];
 51.1381 ++#else
 51.1382 +                 chr[i     ] = mask;
 51.1383 +                 chr[16 + i] = mask;
 51.1384 +                 chr[32 + i] = mask;
 51.1385 +                 chr[48 + i] = mask;
 51.1386 ++#endif
 51.1387 +             }
 51.1388 +         }
 51.1389 +     }
 51.1390 +     else {
 51.1391 ++#ifdef __MINIOS__
 51.1392 ++        ptr = mem;
 51.1393 ++        for (i = 0; i < 16; i++, ptr += 80 * 8)
 51.1394 ++	    for (j = 0; j < 8; j++) {
 51.1395 ++		if (pat[i] & (1U << (7 - j)))
 51.1396 ++		    cursorBuf32[i * 8 + j] = ptr[j] = palette[0];
 51.1397 ++		else
 51.1398 ++		    cursorBuf32[i * 8 + j] = ptr[j] = palette[15];
 51.1399 ++	    }
 51.1400 ++#else
 51.1401 +         MapMask(15);
 51.1402 +         ptr = mem;
 51.1403 +         for (i = 0; i < 16; i++, ptr += 80) {
 51.1404 +             cursorBuf[i] = pat[i];
 51.1405 +             *ptr = ~pat[i];
 51.1406 +         }
 51.1407 ++#endif
 51.1408 +         return;
 51.1409 +     }
 51.1410 + 
 51.1411 +     offset = 0;
 51.1412 ++#ifdef __MINIOS__
 51.1413 ++    ptr = mem;
 51.1414 ++    for (j = 0; j < 16; j++, ptr += 80 * 8)
 51.1415 ++	memcpy(ptr, chr + j * 8 + offset * 8, 8 * 4);
 51.1416 ++#else
 51.1417 +     for (i = 1; i < 16; i <<= 1, offset += 16) {
 51.1418 +         int j;
 51.1419 + 
 51.1420 +@@ -580,6 +719,7 @@
 51.1421 +     }
 51.1422 + 
 51.1423 +     MapMask(15);
 51.1424 ++#endif
 51.1425 + }
 51.1426 + 
 51.1427 + #endif /* SUPPORT_GRAPHICS */
 51.1428 +Index: grub/stage2/graphics.h
 51.1429 +===================================================================
 51.1430 +--- grub.orig/stage2/graphics.h	2008-06-16 15:18:14.527010000 +0100
 51.1431 ++++ grub/stage2/graphics.h	2008-06-16 15:18:14.805010000 +0100
 51.1432 +@@ -21,8 +21,10 @@
 51.1433 + #ifndef GRAPHICS_H
 51.1434 + #define GRAPHICS_H
 51.1435 + 
 51.1436 ++#ifndef __MINIOS__
 51.1437 + /* magic constant */
 51.1438 + #define VIDEOMEM 0xA0000
 51.1439 ++#endif
 51.1440 + 
 51.1441 + /* function prototypes */
 51.1442 + char *graphics_get_splash(void);
 51.1443 +Index: grub/stage2/stage2.c
 51.1444 +===================================================================
 51.1445 +--- grub.orig/stage2/stage2.c	2008-06-17 11:06:47.873523000 +0100
 51.1446 ++++ grub/stage2/stage2.c	2008-06-17 11:07:05.225628000 +0100
 51.1447 +@@ -31,10 +31,10 @@
 51.1448 + #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
 51.1449 + 
 51.1450 + # if defined(PRESET_MENU_STRING)
 51.1451 +-static const char *preset_menu = PRESET_MENU_STRING;
 51.1452 ++const char *preset_menu = PRESET_MENU_STRING;
 51.1453 + # elif defined(SUPPORT_DISKLESS)
 51.1454 + /* Execute the command "bootp" automatically.  */
 51.1455 +-static const char *preset_menu = "bootp\n";
 51.1456 ++const char *preset_menu = "bootp\n";
 51.1457 + # endif /* SUPPORT_DISKLESS */
 51.1458 + 
 51.1459 + static int preset_menu_offset;
    52.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.2 +++ b/stubdom/grub/Makefile	Thu Jun 19 12:46:26 2008 +0900
    52.3 @@ -0,0 +1,76 @@
    52.4 +XEN_ROOT = ../..
    52.5 +
    52.6 +include $(XEN_ROOT)/Config.mk
    52.7 +vpath %.c ../grub-cvs
    52.8 +
    52.9 +BOOT=boot-$(XEN_TARGET_ARCH).o
   52.10 +
   52.11 +DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/libxc -I.
   52.12 +DEF_CPPFLAGS += -I../grub-cvs/stage1
   52.13 +DEF_CPPFLAGS += -I../grub-cvs/stage2
   52.14 +DEF_CPPFLAGS += -I../grub-cvs/netboot
   52.15 +DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/firmware/vgabios
   52.16 +DEF_CPPFLAGS += -DWITHOUT_LIBC_STUBS
   52.17 +DEF_CPPFLAGS += -DSUPPORT_NETBOOT
   52.18 +DEF_CPPFLAGS += -DSUPPORT_GRAPHICS
   52.19 +DEF_CPPFLAGS += -DSUPPORT_SERIAL
   52.20 +DEF_CPPFLAGS += -DPRESET_MENU_STRING='""'
   52.21 +DEF_CPPFLAGS += -DPACKAGE='"grubdom"' -DVERSION='"0.97"'
   52.22 +
   52.23 +all: main.a
   52.24 +
   52.25 +STAGE2_SOURCES=builtins.c char_io.c cmdline.c common.c console.c disk_io.c graphics.c gunzip.c md5.c serial.c stage2.c terminfo.c tparm.c
   52.26 +
   52.27 +NETBOOT_SOURCES=fsys_tftp.c main.c misc.c
   52.28 +CPPFLAGS += -DFSYS_TFTP=1
   52.29 +
   52.30 +STAGE2_SOURCES+=fsys_ext2fs.c
   52.31 +CPPFLAGS += -DFSYS_EXT2FS=1
   52.32 +
   52.33 +STAGE2_SOURCES+=fsys_fat.c
   52.34 +CPPFLAGS += -DFSYS_FAT=1
   52.35 +
   52.36 +STAGE2_SOURCES+=fsys_ffs.c
   52.37 +CPPFLAGS += -DFSYS_FFS=1
   52.38 +
   52.39 +STAGE2_SOURCES+=fsys_iso9660.c
   52.40 +CPPFLAGS += -DFSYS_ISO9660=1
   52.41 +
   52.42 +STAGE2_SOURCES+=fsys_jfs.c
   52.43 +CPPFLAGS += -DFSYS_JFS=1
   52.44 +
   52.45 +STAGE2_SOURCES+=fsys_minix.c
   52.46 +CPPFLAGS += -DFSYS_MINIX=1
   52.47 +
   52.48 +STAGE2_SOURCES+=fsys_reiserfs.c
   52.49 +CPPFLAGS += -DFSYS_REISERFS=1
   52.50 +
   52.51 +STAGE2_SOURCES+=fsys_ufs2.c
   52.52 +CPPFLAGS += -DFSYS_UFS2=1
   52.53 +
   52.54 +STAGE2_SOURCES+=fsys_vstafs.c
   52.55 +CPPFLAGS += -DFSYS_VSTAFS=1
   52.56 +
   52.57 +ifeq (0,1)
   52.58 +STAGE2_SOURCES+=fsys_xfs.c
   52.59 +CPPFLAGS += -DFSYS_XFS=1
   52.60 +endif
   52.61 +
   52.62 +STAGE2_SOURCES:=$(addprefix stage2/,$(STAGE2_SOURCES))
   52.63 +NETBOOT_SOURCES:=$(addprefix netboot/,$(NETBOOT_SOURCES))
   52.64 +
   52.65 +$(BOOT): DEF_CPPFLAGS+=-D__ASSEMBLY__
   52.66 +
   52.67 +OBJS = $(NETBOOT_SOURCES:.c=.o) $(STAGE2_SOURCES:.c=.o) kexec.o mini-os.o
   52.68 +
   52.69 +dirs:
   52.70 +	mkdir -p netboot stage2
   52.71 +	touch $@
   52.72 +
   52.73 +$(OBJS): dirs
   52.74 +
   52.75 +main.a: $(BOOT) $(OBJS)
   52.76 +	$(AR) cr $@ $^
   52.77 +
   52.78 +clean:
   52.79 +	rm -fr dirs *.a *.o stage2 netboot
    53.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.2 +++ b/stubdom/grub/boot-x86_32.S	Thu Jun 19 12:46:26 2008 +0900
    53.3 @@ -0,0 +1,112 @@
    53.4 +#include <os.h>
    53.5 +#include <arch_limits.h>
    53.6 +#include <xen/arch-x86_32.h>
    53.7 +
    53.8 +/* For simplicity, we keep all of this into just one data page */
    53.9 +.data
   53.10 +.globl _boot_page
   53.11 +_boot_page:
   53.12 +        .align __PAGE_SIZE
   53.13 +
   53.14 +/*
   53.15 + * The following data is initialized from C code
   53.16 + */
   53.17 +
   53.18 +/* Pte of this page */
   53.19 +.globl _boot_page_entry
   53.20 +_boot_page_entry:
   53.21 +_boot_page_entry_lo:
   53.22 +        .long 0
   53.23 +_boot_page_entry_hi:
   53.24 +        .long 0
   53.25 +
   53.26 +/* mmuext_op structure */
   53.27 +/* Set new page directory */
   53.28 +_boot_mmuext:
   53.29 +        /* Op # */
   53.30 +        .long MMUEXT_NEW_BASEPTR
   53.31 +
   53.32 +        /* MFN of target page table directory */
   53.33 +.globl _boot_pdmfn
   53.34 +_boot_pdmfn:
   53.35 +        .long 0
   53.36 +
   53.37 +        /* Unused */
   53.38 +        .long 0
   53.39 +
   53.40 +/* Unpin old page directory */
   53.41 +        /* Op # */
   53.42 +        .long MMUEXT_UNPIN_TABLE
   53.43 +
   53.44 +        /* MFN of old page table directory */
   53.45 +.globl _boot_oldpdmfn
   53.46 +_boot_oldpdmfn:
   53.47 +        .long 0
   53.48 +
   53.49 +        /* Unused */
   53.50 +        .long 0
   53.51 +
   53.52 +/* Target stack address, also target virtual address of this page */
   53.53 +.globl _boot_stack
   53.54 +_boot_stack:
   53.55 +        .long 0
   53.56 +        .long __KERNEL_SS
   53.57 +.globl _boot_target
   53.58 +_boot_target:
   53.59 +        .long 0
   53.60 +
   53.61 +/* Target start info */
   53.62 +.globl _boot_start_info
   53.63 +_boot_start_info:
   53.64 +        .long 0
   53.65 +
   53.66 +/* Target start address */
   53.67 +.globl _boot_start
   53.68 +_boot_start:
   53.69 +        .long 0
   53.70 +
   53.71 +/*
   53.72 + * Boot target OS, does not return
   53.73 + */
   53.74 +.globl _boot
   53.75 +_boot:
   53.76 +        /* Project ourselves at the target place. */
   53.77 +        movl    _boot_target, %ebx
   53.78 +        movl    %ebx, %ebp     /* also keep it in ebp for relative addressing */
   53.79 +        movl    _boot_page_entry_lo, %ecx
   53.80 +        movl    _boot_page_entry_hi, %edx
   53.81 +        movl    $2, %esi /* UVMF_INVLPG */
   53.82 +        movl    $__HYPERVISOR_update_va_mapping, %eax
   53.83 +        int     $0x82
   53.84 +        testl   %eax, %eax
   53.85 +        jz      0f
   53.86 +        ud2
   53.87 +
   53.88 +0:
   53.89 +        /* Go there. */
   53.90 +        movl    $(0f - _boot_page), %eax
   53.91 +        movl    _boot_target, %ebx
   53.92 +        addl    %ebx, %eax
   53.93 +        jmpl    *%eax
   53.94 +0:
   53.95 +        
   53.96 +        /* Load target page table and unpin old page table.  */
   53.97 +        /* We shouldn't have any problem since in the new page table our page is
   53.98 +           mapped at the same place.  */
   53.99 +        leal    (_boot_mmuext-_boot_page)(%ebp), %ebx
  53.100 +        movl    $2, %ecx
  53.101 +        xorl    %edx, %edx
  53.102 +        movl    $0x7FF0, %esi /* DOMID_SELF */
  53.103 +        movl    $__HYPERVISOR_mmuext_op, %eax
  53.104 +        int     $0x82
  53.105 +        testl   %eax, %eax
  53.106 +        jns     0f
  53.107 +        ud2
  53.108 +
  53.109 +0:
  53.110 +        /* Initialize registers.  */
  53.111 +        lss     (_boot_stack-_boot_page)(%ebp), %esp
  53.112 +        movl    (_boot_start_info-_boot_page)(%ebp), %esi
  53.113 +
  53.114 +        /* Jump!  */
  53.115 +        jmpl    *(_boot_start-_boot_page)(%ebp)
    54.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.2 +++ b/stubdom/grub/boot-x86_64.S	Thu Jun 19 12:46:26 2008 +0900
    54.3 @@ -0,0 +1,108 @@
    54.4 +#include <os.h>
    54.5 +#include <arch_limits.h>
    54.6 +#include <xen/arch-x86_64.h>
    54.7 +
    54.8 +/* For simplicity, we keep all of this into just one data page */
    54.9 +.data
   54.10 +.globl _boot_page
   54.11 +_boot_page:
   54.12 +        .align __PAGE_SIZE
   54.13 +
   54.14 +/*
   54.15 + * The following data is initialized from C code
   54.16 + */
   54.17 +
   54.18 +/* Pte of this page */
   54.19 +.globl _boot_page_entry
   54.20 +_boot_page_entry:
   54.21 +        .quad 0
   54.22 +
   54.23 +/* mmuext_op structure */
   54.24 +/* Set new page directory */
   54.25 +_boot_mmuext:
   54.26 +        /* Op # */
   54.27 +        .long MMUEXT_NEW_BASEPTR
   54.28 +        .long 0 /* pad */
   54.29 +
   54.30 +        /* MFN of target page table directory */
   54.31 +.globl _boot_pdmfn
   54.32 +_boot_pdmfn:
   54.33 +        .quad 0
   54.34 +
   54.35 +        /* Unused */
   54.36 +        .quad 0
   54.37 +
   54.38 +/* Unpin old page directory */
   54.39 +        /* Op # */
   54.40 +        .long MMUEXT_UNPIN_TABLE
   54.41 +        .long 0 /* pad */
   54.42 +
   54.43 +        /* MFN of old page table directory */
   54.44 +.globl _boot_oldpdmfn
   54.45 +_boot_oldpdmfn:
   54.46 +        .quad 0
   54.47 +
   54.48 +        /* Unused */
   54.49 +        .quad 0
   54.50 +
   54.51 +/* Target stack address, also target virtual address of this page */
   54.52 +.globl _boot_stack
   54.53 +_boot_stack:
   54.54 +        .quad 0
   54.55 +.globl _boot_target
   54.56 +_boot_target:
   54.57 +        .quad 0
   54.58 +
   54.59 +/* Target start info */
   54.60 +.globl _boot_start_info
   54.61 +_boot_start_info:
   54.62 +        .quad 0
   54.63 +
   54.64 +/* Target start address */
   54.65 +.globl _boot_start
   54.66 +_boot_start:
   54.67 +        .quad 0
   54.68 +
   54.69 +/*
   54.70 + * Boot target OS, does not return
   54.71 + */
   54.72 +.globl _boot
   54.73 +_boot:
   54.74 +        /* Project ourselves at the target place. */
   54.75 +        movq    _boot_target, %rdi
   54.76 +        movq    _boot_page_entry, %rsi
   54.77 +        movq    $2, %rdx /* UVMF_INVLPG */
   54.78 +        movq    $__HYPERVISOR_update_va_mapping, %rax
   54.79 +        syscall
   54.80 +        testq   %rax, %rax
   54.81 +        jz      0f
   54.82 +        ud2
   54.83 +
   54.84 +0:
   54.85 +        /* Go there. */
   54.86 +        movq    $(0f - _boot_page), %rax
   54.87 +        movq    _boot_target, %rbx
   54.88 +        addq    %rbx, %rax
   54.89 +        jmpq    *%rax
   54.90 +0:
   54.91 +        
   54.92 +        /* Load target page table and unpin old page table.  */
   54.93 +        /* We shouldn't have any problem since in the new page table our page is
   54.94 +           mapped at the same place.  */
   54.95 +        leaq    _boot_mmuext(%rip), %rdi
   54.96 +        movq    $2, %rsi
   54.97 +        xorq    %rdx, %rdx
   54.98 +        movq    $0x7FF0, %r10 /* DOMID_SELF */
   54.99 +        movq    $__HYPERVISOR_mmuext_op, %rax
  54.100 +        syscall
  54.101 +        testq   %rax, %rax
  54.102 +        jns     0f
  54.103 +        ud2
  54.104 +
  54.105 +0:
  54.106 +        /* Initialize registers.  */
  54.107 +        movq    _boot_stack(%rip), %rsp
  54.108 +        movq    _boot_start_info(%rip), %rsi
  54.109 +
  54.110 +        /* Jump!  */
  54.111 +        jmpq    *_boot_start(%rip)
    55.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.2 +++ b/stubdom/grub/config.h	Thu Jun 19 12:46:26 2008 +0900
    55.3 @@ -0,0 +1,11 @@
    55.4 +#include <stdio.h>
    55.5 +#undef putchar
    55.6 +#include <ctype.h>
    55.7 +#include <string.h>
    55.8 +#define debug _debug
    55.9 +#define grub_halt(a) do_exit()
   55.10 +#define printf grub_printf
   55.11 +void kexec(void *kernel, long kernel_size, void *module, long module_size, char *cmdline);
   55.12 +struct fbfront_dev *fb_open(void *fb, int width, int height, int depth);
   55.13 +void fb_close(void);
   55.14 +void pv_boot (void);
    56.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.2 +++ b/stubdom/grub/kexec.c	Thu Jun 19 12:46:26 2008 +0900
    56.3 @@ -0,0 +1,324 @@
    56.4 +/*
    56.5 + * This supports booting another PV kernel from Mini-OS
    56.6 + *
    56.7 + * The idea is to setup it using libxc, answer to day0 memory allocation
    56.8 + * requests, and using a trampoline boot page to switch to the new page table.
    56.9 + *
   56.10 + * The procedure of the boot page is:
   56.11 + * - map itself at the target position (that may overwrite some C stuff, but we
   56.12 + *   do not care any more)
   56.13 + * - jump there
   56.14 + * - switch to the target page table
   56.15 + * - unpin the old page table
   56.16 + * - jump to the new kernel
   56.17 + *
   56.18 + * Samuel Thibault <Samuel.Thibault@eu.citrix.com>, May 2008
   56.19 + */
   56.20 +#include <stdio.h>
   56.21 +#include <unistd.h>
   56.22 +#include <stdlib.h>
   56.23 +#include <sys/mman.h>
   56.24 +
   56.25 +#include <xenctrl.h>
   56.26 +#include <xc_dom.h>
   56.27 +
   56.28 +#include <kernel.h>
   56.29 +#include <console.h>
   56.30 +#include <os.h>
   56.31 +#include <blkfront.h>
   56.32 +#include <netfront.h>
   56.33 +#include <fbfront.h>
   56.34 +#include <shared.h>
   56.35 +
   56.36 +#include "mini-os.h"
   56.37 +
   56.38 +#if 0
   56.39 +#define DEBUG(fmt, ...) printk(fmt, ## __VA_ARGS__)
   56.40 +#else
   56.41 +#define DEBUG(fmt, ...) (void)0
   56.42 +#endif
   56.43 +
   56.44 +/* Assembly boot page from boot.S */
   56.45 +extern void _boot_page;
   56.46 +extern pgentry_t _boot_page_entry;
   56.47 +extern unsigned long _boot_pdmfn;
   56.48 +extern unsigned long _boot_stack, _boot_target, _boot_start_info, _boot_start;
   56.49 +extern xen_pfn_t _boot_oldpdmfn;
   56.50 +extern void _boot(void);
   56.51 +
   56.52 +static unsigned long *pages;
   56.53 +static unsigned long *pages_mfns;
   56.54 +static unsigned long allocated;
   56.55 +
   56.56 +int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
   56.57 +              domid_t dom);
   56.58 +
   56.59 +/* We need mfn to appear as target_pfn, so exchange with the MFN there */
   56.60 +static void do_exchange(struct xc_dom_image *dom, xen_pfn_t target_pfn, xen_pfn_t source_mfn)
   56.61 +{
   56.62 +    xen_pfn_t source_pfn;
   56.63 +    xen_pfn_t target_mfn;
   56.64 +
   56.65 +    for (source_pfn = 0; source_pfn < start_info.nr_pages; source_pfn++)
   56.66 +        if (dom->p2m_host[source_pfn] == source_mfn)
   56.67 +            break;
   56.68 +    ASSERT(source_pfn < start_info.nr_pages);
   56.69 +
   56.70 +    target_mfn = dom->p2m_host[target_pfn];
   56.71 +
   56.72 +    /* Put target MFN at source PFN */
   56.73 +    dom->p2m_host[source_pfn] = target_mfn;
   56.74 +
   56.75 +    /* Put source MFN at target PFN */
   56.76 +    dom->p2m_host[target_pfn] = source_mfn;
   56.77 +}
   56.78 +
   56.79 +int kexec_allocate(struct xc_dom_image *dom, xen_vaddr_t up_to)
   56.80 +{
   56.81 +    unsigned long new_allocated = (up_to - dom->parms.virt_base) / PAGE_SIZE;
   56.82 +    unsigned long i;
   56.83 +
   56.84 +    pages = realloc(pages, new_allocated * sizeof(*pages));
   56.85 +    pages_mfns = realloc(pages_mfns, new_allocated * sizeof(*pages_mfns));
   56.86 +    for (i = allocated; i < new_allocated; i++) {
   56.87 +        /* Exchange old page of PFN i with a newly allocated page.  */
   56.88 +        xen_pfn_t old_mfn = dom->p2m_host[i];
   56.89 +        xen_pfn_t new_pfn;
   56.90 +        xen_pfn_t new_mfn;
   56.91 +
   56.92 +        pages[i] = alloc_page();
   56.93 +        memset((void*) pages[i], 0, PAGE_SIZE);
   56.94 +        new_pfn = PHYS_PFN(to_phys(pages[i]));
   56.95 +        pages_mfns[i] = new_mfn = pfn_to_mfn(new_pfn);
   56.96 +
   56.97 +        /* Put old page at new PFN */
   56.98 +        dom->p2m_host[new_pfn] = old_mfn;
   56.99 +
  56.100 +        /* Put new page at PFN i */
  56.101 +        dom->p2m_host[i] = new_mfn;
  56.102 +    }
  56.103 +
  56.104 +    allocated = new_allocated;
  56.105 +
  56.106 +    return 0;
  56.107 +}
  56.108 +
  56.109 +void kexec(void *kernel, long kernel_size, void *module, long module_size, char *cmdline)
  56.110 +{
  56.111 +    struct xc_dom_image *dom;
  56.112 +    int rc;
  56.113 +    domid_t domid = DOMID_SELF;
  56.114 +    xen_pfn_t pfn;
  56.115 +    int xc_handle;
  56.116 +    unsigned long i;
  56.117 +    void *seg;
  56.118 +    xen_pfn_t boot_page_mfn = virt_to_mfn(&_boot_page);
  56.119 +    char features[] = "";
  56.120 +    struct mmu_update *m2p_updates;
  56.121 +    unsigned long nr_m2p_updates;
  56.122 +
  56.123 +    DEBUG("booting with cmdline %s\n", cmdline);
  56.124 +    xc_handle = xc_interface_open();
  56.125 +
  56.126 +    dom = xc_dom_allocate(cmdline, features);
  56.127 +    dom->allocate = kexec_allocate;
  56.128 +
  56.129 +    dom->kernel_blob = kernel;
  56.130 +    dom->kernel_size = kernel_size;
  56.131 +
  56.132 +    dom->ramdisk_blob = module;
  56.133 +    dom->ramdisk_size = module_size;
  56.134 +
  56.135 +    dom->flags = 0;
  56.136 +    dom->console_evtchn = start_info.console.domU.evtchn;
  56.137 +    dom->xenstore_evtchn = start_info.store_evtchn;
  56.138 +
  56.139 +    if ( (rc = xc_dom_boot_xen_init(dom, xc_handle, domid)) != 0 ) {
  56.140 +        grub_printf("xc_dom_boot_xen_init returned %d\n", rc);
  56.141 +        errnum = ERR_BOOT_FAILURE;
  56.142 +        goto out;
  56.143 +    }
  56.144 +    if ( (rc = xc_dom_parse_image(dom)) != 0 ) {
  56.145 +        grub_printf("xc_dom_parse_image returned %d\n", rc);
  56.146 +        errnum = ERR_BOOT_FAILURE;
  56.147 +        goto out;
  56.148 +    }
  56.149 +
  56.150 +#ifdef __i386__
  56.151 +    if (strcmp(dom->guest_type, "xen-3.0-x86_32p")) {
  56.152 +        grub_printf("can only boot x86 32 PAE kernels, not %s\n", dom->guest_type);
  56.153 +        errnum = ERR_EXEC_FORMAT;
  56.154 +        goto out;
  56.155 +    }
  56.156 +#endif
  56.157 +#ifdef __x86_64__
  56.158 +    if (strcmp(dom->guest_type, "xen-3.0-x86_64")) {
  56.159 +        grub_printf("can only boot x86 64 kernels, not %s\n", dom->guest_type);
  56.160 +        errnum = ERR_EXEC_FORMAT;
  56.161 +        goto out;
  56.162 +    }
  56.163 +#endif
  56.164 +
  56.165 +    /* equivalent of xc_dom_mem_init */
  56.166 +    dom->arch_hooks = xc_dom_find_arch_hooks(dom->guest_type);
  56.167 +    dom->total_pages = start_info.nr_pages;
  56.168 +
  56.169 +    /* equivalent of arch_setup_meminit */
  56.170 +
  56.171 +    /* setup initial p2m */
  56.172 +    dom->p2m_host = malloc(sizeof(*dom->p2m_host) * dom->total_pages);
  56.173 +
  56.174 +    /* Start with our current P2M */
  56.175 +    for (i = 0; i < dom->total_pages; i++)
  56.176 +        dom->p2m_host[i] = pfn_to_mfn(i);
  56.177 +
  56.178 +    if ( (rc = xc_dom_build_image(dom)) != 0 ) {
  56.179 +        grub_printf("xc_dom_build_image returned %d\n", rc);
  56.180 +        errnum = ERR_BOOT_FAILURE;
  56.181 +        goto out;
  56.182 +    }
  56.183 +
  56.184 +    /* copy hypercall page */
  56.185 +    /* TODO: domctl instead, but requires privileges */
  56.186 +    if (dom->parms.virt_hypercall != -1) {
  56.187 +        pfn = PHYS_PFN(dom->parms.virt_hypercall - dom->parms.virt_base);
  56.188 +        memcpy((void *) pages[pfn], hypercall_page, PAGE_SIZE);
  56.189 +    }
  56.190 +
  56.191 +    /* Equivalent of xc_dom_boot_image */
  56.192 +    dom->shared_info_mfn = PHYS_PFN(start_info.shared_info);
  56.193 +
  56.194 +    if (!xc_dom_compat_check(dom)) {
  56.195 +        grub_printf("xc_dom_compat_check failed\n");
  56.196 +        errnum = ERR_EXEC_FORMAT;
  56.197 +        goto out;
  56.198 +    }
  56.199 +
  56.200 +    /* Move current console, xenstore and boot MFNs to the allocated place */
  56.201 +    do_exchange(dom, dom->console_pfn, start_info.console.domU.mfn);
  56.202 +    do_exchange(dom, dom->xenstore_pfn, start_info.store_mfn);
  56.203 +    DEBUG("virt base at %llx\n", dom->parms.virt_base);
  56.204 +    DEBUG("bootstack_pfn %lx\n", dom->bootstack_pfn);
  56.205 +    _boot_target = dom->parms.virt_base + PFN_PHYS(dom->bootstack_pfn);
  56.206 +    DEBUG("_boot_target %lx\n", _boot_target);
  56.207 +    do_exchange(dom, PHYS_PFN(_boot_target - dom->parms.virt_base),
  56.208 +            virt_to_mfn(&_boot_page));
  56.209 +
  56.210 +    /* Make sure the bootstrap page table does not RW-map any of our current
  56.211 +     * page table frames */
  56.212 +    kexec_allocate(dom, dom->virt_pgtab_end);
  56.213 +
  56.214 +    if ( (rc = xc_dom_update_guest_p2m(dom))) {
  56.215 +        grub_printf("xc_dom_update_guest_p2m returned %d\n", rc);
  56.216 +        errnum = ERR_BOOT_FAILURE;
  56.217 +        goto out;
  56.218 +    }
  56.219 +
  56.220 +    if ( dom->arch_hooks->setup_pgtables )
  56.221 +        if ( (rc = dom->arch_hooks->setup_pgtables(dom))) {
  56.222 +            grub_printf("setup_pgtables returned %d\n", rc);
  56.223 +            errnum = ERR_BOOT_FAILURE;
  56.224 +            goto out;
  56.225 +        }
  56.226 +
  56.227 +    /* start info page */
  56.228 +#undef start_info
  56.229 +    if ( dom->arch_hooks->start_info )
  56.230 +        dom->arch_hooks->start_info(dom);
  56.231 +#define start_info (start_info_union.start_info)
  56.232 +
  56.233 +    xc_dom_log_memory_footprint(dom);
  56.234 +
  56.235 +    /* Unmap libxc's projection of the boot page table */
  56.236 +    seg = xc_dom_seg_to_ptr(dom, &dom->pgtables_seg);
  56.237 +    munmap(seg, dom->pgtables_seg.vend - dom->pgtables_seg.vstart);
  56.238 +
  56.239 +    /* Unmap day0 pages to avoid having a r/w mapping of the future page table */
  56.240 +    for (pfn = 0; pfn < allocated; pfn++)
  56.241 +        munmap((void*) pages[pfn], PAGE_SIZE);
  56.242 +
  56.243 +    /* Pin the boot page table base */
  56.244 +    if ( (rc = pin_table(dom->guest_xc, 
  56.245 +#ifdef __i386__
  56.246 +                MMUEXT_PIN_L3_TABLE,
  56.247 +#endif
  56.248 +#ifdef __x86_64__
  56.249 +                MMUEXT_PIN_L4_TABLE,
  56.250 +#endif
  56.251 +                xc_dom_p2m_host(dom, dom->pgtables_seg.pfn),
  56.252 +                dom->guest_domid)) != 0 ) {
  56.253 +        grub_printf("pin_table(%lx) returned %d\n", xc_dom_p2m_host(dom,
  56.254 +                    dom->pgtables_seg.pfn), rc);
  56.255 +        errnum = ERR_BOOT_FAILURE;
  56.256 +        goto out_remap;
  56.257 +    }
  56.258 +
  56.259 +    /* We populate the Mini-OS page table here so that boot.S can just call
  56.260 +     * update_va_mapping to project itself there.  */
  56.261 +    need_pgt(_boot_target);
  56.262 +    DEBUG("day0 pages %lx\n", allocated);
  56.263 +    DEBUG("boot target page %lx\n", _boot_target);
  56.264 +    DEBUG("boot page %p\n", &_boot_page);
  56.265 +    DEBUG("boot page mfn %lx\n", boot_page_mfn);
  56.266 +    _boot_page_entry = PFN_PHYS(boot_page_mfn) | L1_PROT;
  56.267 +    DEBUG("boot page entry %llx\n", _boot_page_entry);
  56.268 +    _boot_oldpdmfn = virt_to_mfn(start_info.pt_base);
  56.269 +    DEBUG("boot old pd mfn %lx\n", _boot_oldpdmfn);
  56.270 +    DEBUG("boot pd virt %lx\n", dom->pgtables_seg.vstart);
  56.271 +    _boot_pdmfn = dom->p2m_host[PHYS_PFN(dom->pgtables_seg.vstart - dom->parms.virt_base)];
  56.272 +    DEBUG("boot pd mfn %lx\n", _boot_pdmfn);
  56.273 +    _boot_stack = _boot_target + PAGE_SIZE;
  56.274 +    DEBUG("boot stack %lx\n", _boot_stack);
  56.275 +    _boot_start_info = dom->parms.virt_base + PFN_PHYS(dom->start_info_pfn);
  56.276 +    DEBUG("boot start info %lx\n", _boot_start_info);
  56.277 +    _boot_start = dom->parms.virt_entry;
  56.278 +    DEBUG("boot start %lx\n", _boot_start);
  56.279 +
  56.280 +    /* Keep only useful entries */
  56.281 +    for (nr_m2p_updates = pfn = 0; pfn < start_info.nr_pages; pfn++)
  56.282 +        if (dom->p2m_host[pfn] != pfn_to_mfn(pfn))
  56.283 +            nr_m2p_updates++;
  56.284 +
  56.285 +    m2p_updates = malloc(sizeof(*m2p_updates) * nr_m2p_updates);
  56.286 +    for (i = pfn = 0; pfn < start_info.nr_pages; pfn++)
  56.287 +        if (dom->p2m_host[pfn] != pfn_to_mfn(pfn)) {
  56.288 +            m2p_updates[i].ptr = PFN_PHYS(dom->p2m_host[pfn]) | MMU_MACHPHYS_UPDATE;
  56.289 +            m2p_updates[i].val = pfn;
  56.290 +            i++;
  56.291 +        }
  56.292 +
  56.293 +    for (i = 0; i < blk_nb; i++)
  56.294 +        shutdown_blkfront(blk_dev[i]);
  56.295 +    if (net_dev)
  56.296 +        shutdown_netfront(net_dev);
  56.297 +    if (kbd_dev)
  56.298 +        shutdown_kbdfront(kbd_dev);
  56.299 +    stop_kernel();
  56.300 +
  56.301 +    /* Update M2P */
  56.302 +    if ((rc = HYPERVISOR_mmu_update(m2p_updates, nr_m2p_updates, NULL, DOMID_SELF)) < 0) {
  56.303 +        xprintk("Could not update M2P\n");
  56.304 +        ASSERT(0);
  56.305 +    }
  56.306 +
  56.307 +    xprintk("go!\n");
  56.308 +
  56.309 +    /* Jump to trampoline boot page */
  56.310 +    _boot();
  56.311 +
  56.312 +    ASSERT(0);
  56.313 +
  56.314 +out_remap:
  56.315 +    for (pfn = 0; pfn < allocated; pfn++)
  56.316 +        do_map_frames(pages[pfn], &pages_mfns[pfn], 1, 0, 0, DOMID_SELF, 0, L1_PROT);
  56.317 +out:
  56.318 +    xc_dom_release(dom);
  56.319 +    for (pfn = 0; pfn < allocated; pfn++)
  56.320 +        free_page((void*)pages[pfn]);
  56.321 +    free(pages);
  56.322 +    free(pages_mfns);
  56.323 +    pages = NULL;
  56.324 +    pages_mfns = NULL;
  56.325 +    allocated = 0;
  56.326 +    xc_interface_close(xc_handle );
  56.327 +}
    57.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.2 +++ b/stubdom/grub/mini-os.c	Thu Jun 19 12:46:26 2008 +0900
    57.3 @@ -0,0 +1,702 @@
    57.4 +/*
    57.5 + * Mini-OS support for GRUB.
    57.6 + *
    57.7 + * Samuel Thibault <Samuel.Thibault@eu.citrix.com>, May 2008
    57.8 + */
    57.9 +#include <sys/types.h>
   57.10 +#include <sys/time.h>
   57.11 +#include <stdarg.h>
   57.12 +#include <stdlib.h>
   57.13 +#include <malloc.h>
   57.14 +#include <unistd.h>
   57.15 +
   57.16 +#include <hypervisor.h>
   57.17 +#include <blkfront.h>
   57.18 +#include <netfront.h>
   57.19 +#include <fbfront.h>
   57.20 +#include <semaphore.h>
   57.21 +
   57.22 +#include <osdep.h>
   57.23 +#include <shared.h>
   57.24 +#include <nic.h>
   57.25 +#include <etherboot.h>
   57.26 +#include <terminfo.h>
   57.27 +#include <term.h>
   57.28 +
   57.29 +#include "mini-os.h"
   57.30 +
   57.31 +extern const char *preset_menu;
   57.32 +char config_file[DEFAULT_FILE_BUFLEN] = "(hd0,0)/boot/grub/menu.lst";
   57.33 +unsigned long boot_drive = NETWORK_DRIVE;
   57.34 +unsigned long install_partition = 0xFFFFFF;
   57.35 +
   57.36 +char version_string[] = VERSION;
   57.37 +
   57.38 +/* Variables from asm.S */
   57.39 +int saved_entryno;
   57.40 +
   57.41 +/*
   57.42 + * Disk
   57.43 + */
   57.44 +
   57.45 +struct blkfront_dev **blk_dev;
   57.46 +int blk_nb;
   57.47 +static struct blkfront_info *blk_info;
   57.48 +
   57.49 +static int vbdcmp(const void *_vbd1, const void *_vbd2) {
   57.50 +    char *vbd1 = *(char **)_vbd1;
   57.51 +    char *vbd2 = *(char **)_vbd2;
   57.52 +    int vbdn1 = atoi(vbd1);
   57.53 +    int vbdn2 = atoi(vbd2);
   57.54 +    return vbdn1 - vbdn2;
   57.55 +}
   57.56 +
   57.57 +void init_disk (void)
   57.58 +{
   57.59 +    char **list;
   57.60 +    char *msg;
   57.61 +    int i;
   57.62 +    char *path;
   57.63 +
   57.64 +    msg = xenbus_ls(XBT_NIL, "device/vbd", &list);
   57.65 +    if (msg) {
   57.66 +        printk("Error %s while reading list of disks\n", msg);
   57.67 +        free(msg);
   57.68 +        return;
   57.69 +    }
   57.70 +    blk_nb = 0;
   57.71 +    while (list[blk_nb])
   57.72 +        blk_nb++;
   57.73 +    blk_dev = malloc(blk_nb * sizeof(*blk_dev));
   57.74 +    blk_info = malloc(blk_nb * sizeof(*blk_info));
   57.75 +
   57.76 +    qsort(list, blk_nb, sizeof(*list), vbdcmp);
   57.77 +
   57.78 +    for (i = 0; i < blk_nb; i++) {
   57.79 +        printk("vbd %s is hd%d\n", list[i], i);
   57.80 +        asprintf(&path, "device/vbd/%s", list[i]);
   57.81 +        blk_dev[i] = init_blkfront(path, &blk_info[i]);
   57.82 +        free(path);
   57.83 +        free(list[i]);
   57.84 +    }
   57.85 +}
   57.86 +
   57.87 +/* Return the geometry of DRIVE in GEOMETRY. If an error occurs, return
   57.88 +   non-zero, otherwise zero.  */
   57.89 +int get_diskinfo (int drive, struct geometry *geometry)
   57.90 +{
   57.91 +    int i;
   57.92 +    if (!(drive & 0x80))
   57.93 +        return -1;
   57.94 +
   57.95 +    i = drive - 0x80;
   57.96 +    if (i >= blk_nb)
   57.97 +        return -1;
   57.98 +
   57.99 +    /* Bogus geometry */
  57.100 +    geometry->cylinders = 65535;
  57.101 +    geometry->heads = 255;
  57.102 +    geometry->sectors = 63;
  57.103 +
  57.104 +    geometry->total_sectors = blk_info[i].sectors;
  57.105 +    geometry->sector_size = blk_info[i].sector_size;
  57.106 +    geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION;
  57.107 +    if (blk_info[i].info & VDISK_CDROM)
  57.108 +        geometry->flags |= BIOSDISK_FLAG_CDROM;
  57.109 +    return 0;
  57.110 +}
  57.111 +
  57.112 +/* Read/write NSEC sectors starting from SECTOR in DRIVE disk with GEOMETRY
  57.113 +   from/into SEGMENT segment. If READ is BIOSDISK_READ, then read it,
  57.114 +   else if READ is BIOSDISK_WRITE, then write it. If an geometry error
  57.115 +   occurs, return BIOSDISK_ERROR_GEOMETRY, and if other error occurs, then
  57.116 +   return the error number. Otherwise, return 0.  */
  57.117 +int
  57.118 +biosdisk (int read, int drive, struct geometry *geometry,
  57.119 +          unsigned int sector, int nsec, int segment)
  57.120 +{
  57.121 +    void *addr = (void *) ((unsigned long)segment << 4);
  57.122 +    struct blkfront_aiocb aiocb;
  57.123 +    int i;
  57.124 +
  57.125 +    if (!(drive & 0x80))
  57.126 +        return -1;
  57.127 +
  57.128 +    i = drive - 0x80;
  57.129 +    if (i >= blk_nb)
  57.130 +        return -1;
  57.131 +
  57.132 +    aiocb.aio_dev = blk_dev[i];
  57.133 +    aiocb.aio_buf = addr;
  57.134 +    aiocb.aio_nbytes = (size_t)nsec * blk_info[i].sector_size;
  57.135 +    aiocb.aio_offset = (off_t)sector * blk_info[i].sector_size;
  57.136 +    aiocb.aio_cb = NULL;
  57.137 +
  57.138 +    blkfront_io(&aiocb, read == BIOSDISK_WRITE);
  57.139 +
  57.140 +    return 0;
  57.141 +}
  57.142 +
  57.143 +static int
  57.144 +load_file(char *name, void **ptr, long *size)
  57.145 +{
  57.146 +    char *buf = NULL;
  57.147 +    int allocated = 1 * 1024 * 1024;
  57.148 +    int len, filled = 0;
  57.149 +
  57.150 +    if (!grub_open (name))
  57.151 +        return -1;
  57.152 +
  57.153 +    buf = malloc(allocated);
  57.154 +
  57.155 +    errnum = 0;
  57.156 +    while (1) {
  57.157 +        len = grub_read (buf + filled, allocated - filled);
  57.158 +        if (! len) {
  57.159 +            if (!errnum)
  57.160 +                break;
  57.161 +            grub_close ();
  57.162 +            return -1;
  57.163 +        }
  57.164 +        filled += len;
  57.165 +        if (filled < allocated)
  57.166 +            break;
  57.167 +        allocated *= 2;
  57.168 +        buf = realloc(buf, allocated);
  57.169 +    }
  57.170 +    grub_close ();
  57.171 +    *ptr = buf;
  57.172 +    *size = filled;
  57.173 +    return 0;
  57.174 +}
  57.175 +
  57.176 +void *kernel_image, *module_image;
  57.177 +long  kernel_size, module_size;
  57.178 +char *kernel_arg, *module_arg;
  57.179 +
  57.180 +kernel_t
  57.181 +load_image (char *kernel, char *arg, kernel_t suggested_type,
  57.182 +            unsigned long load_flags)
  57.183 +{
  57.184 +    arg = skip_to(0, arg);
  57.185 +    if (kernel_image)
  57.186 +        free(kernel_image);
  57.187 +    kernel_image = NULL;
  57.188 +    if (load_file (kernel, &kernel_image, &kernel_size))
  57.189 +        return KERNEL_TYPE_NONE;
  57.190 +    if (kernel_arg)
  57.191 +        free(kernel_arg);
  57.192 +    kernel_arg = strdup(arg);
  57.193 +    return KERNEL_TYPE_PV;
  57.194 +}
  57.195 +
  57.196 +int
  57.197 +load_initrd (char *initrd)
  57.198 +{
  57.199 +    if (module_image)
  57.200 +        free(module_image);
  57.201 +    module_image = NULL;
  57.202 +    load_file (initrd, &module_image, &module_size);
  57.203 +    return ! errnum;
  57.204 +}
  57.205 +
  57.206 +int
  57.207 +load_module (char *module, char *arg)
  57.208 +{
  57.209 +    if (module_image)
  57.210 +        free(module_image);
  57.211 +    module_image = NULL;
  57.212 +    load_file (module, &module_image, &module_size);
  57.213 +    if (module_arg)
  57.214 +        free(module_arg);
  57.215 +    module_arg = strdup(arg);
  57.216 +    return ! errnum;
  57.217 +}
  57.218 +
  57.219 +void
  57.220 +pv_boot (void)
  57.221 +{
  57.222 +    kexec(kernel_image, kernel_size, module_image, module_size, kernel_arg);
  57.223 +}
  57.224 +
  57.225 +/*
  57.226 + * Network
  57.227 + */
  57.228 +
  57.229 +struct netfront_dev *net_dev;
  57.230 +
  57.231 +int
  57.232 +minios_probe (struct nic *nic)
  57.233 +{
  57.234 +    char *ip;
  57.235 +
  57.236 +    if (net_dev)
  57.237 +        return 1;
  57.238 +
  57.239 +    /* Clear the ARP table.  */
  57.240 +    grub_memset ((char *) arptable, 0,
  57.241 +                 MAX_ARP * sizeof (struct arptable_t));
  57.242 +
  57.243 +    net_dev = init_netfront(NULL, (void*) -1, nic->node_addr, &ip);
  57.244 +    if (!net_dev)
  57.245 +        return 0;
  57.246 +
  57.247 +    return 1;
  57.248 +}
  57.249 +
  57.250 +/* reset adapter */
  57.251 +static void minios_reset(struct nic *nic)
  57.252 +{
  57.253 +    /* TODO? */
  57.254 +}
  57.255 +
  57.256 +static void minios_disable(struct nic *nic)
  57.257 +{
  57.258 +}
  57.259 +
  57.260 +/* Wait for a frame */
  57.261 +static int minios_poll(struct nic *nic)
  57.262 +{
  57.263 +    return !! (nic->packetlen = netfront_receive(net_dev, (void*) nic->packet, ETH_FRAME_LEN));
  57.264 +}
  57.265 +
  57.266 +/* Transmit a frame */
  57.267 +struct frame {
  57.268 +        uint8_t dest[ETH_ALEN];
  57.269 +        uint8_t src[ETH_ALEN];
  57.270 +        uint16_t type;
  57.271 +        unsigned char data[];
  57.272 +};
  57.273 +static void minios_transmit (struct nic *nic, const char *d, unsigned int t,
  57.274 +                             unsigned int s, const char *p)
  57.275 +{
  57.276 +    struct frame *frame = alloca(sizeof(frame) + s);
  57.277 +
  57.278 +    memcpy(frame->dest, d, ETH_ALEN);
  57.279 +    memcpy(frame->src, nic->node_addr, ETH_ALEN);
  57.280 +    frame->type = htons(t);
  57.281 +    memcpy(frame->data, p, s);
  57.282 +
  57.283 +    netfront_xmit(net_dev, (void*) frame, sizeof(*frame) + s);
  57.284 +}
  57.285 +
  57.286 +static char packet[ETH_FRAME_LEN];
  57.287 +
  57.288 +struct nic nic = {
  57.289 +    .reset = minios_reset,
  57.290 +    .poll = minios_poll,
  57.291 +    .transmit = minios_transmit,
  57.292 +    .disable = minios_disable,
  57.293 +    .flags = 0,
  57.294 +    .rom_info = NULL,
  57.295 +    .node_addr = arptable[ARP_CLIENT].node,
  57.296 +    .packet = packet,
  57.297 +    .packetlen = 0,
  57.298 +    .priv_data = NULL,
  57.299 +};
  57.300 +
  57.301 +int
  57.302 +eth_probe (void)
  57.303 +{
  57.304 +    return minios_probe(&nic);
  57.305 +}
  57.306 +
  57.307 +int
  57.308 +eth_poll (void)
  57.309 +{
  57.310 +    return minios_poll (&nic);
  57.311 +}
  57.312 +
  57.313 +void
  57.314 +eth_disable (void)
  57.315 +{
  57.316 +    minios_disable (&nic);
  57.317 +}
  57.318 +
  57.319 +void
  57.320 +eth_transmit (const char *d, unsigned int t,
  57.321 +              unsigned int s, const void *p)
  57.322 +{
  57.323 +    minios_transmit (&nic, d, t, s, p);
  57.324 +    if (t == IP)
  57.325 +        twiddle();
  57.326 +}
  57.327 +
  57.328 +/*
  57.329 + * Console
  57.330 + */
  57.331 +void
  57.332 +serial_hw_put (int _c)
  57.333 +{
  57.334 +  char c = _c;
  57.335 +  console_print(&c, 1);
  57.336 +}
  57.337 +
  57.338 +int
  57.339 +serial_hw_fetch (void)
  57.340 +{
  57.341 +    char key;
  57.342 +
  57.343 +    if (!xencons_ring_avail())
  57.344 +        return -1;
  57.345 +
  57.346 +    read(STDIN_FILENO, &key, 1);
  57.347 +    switch (key) {
  57.348 +    case 0x7f: key = '\b'; break;
  57.349 +    }
  57.350 +    return key;
  57.351 +}
  57.352 +
  57.353 +/*
  57.354 + * PVFB
  57.355 + */
  57.356 +struct kbdfront_dev *kbd_dev;
  57.357 +struct fbfront_dev *fb_dev;
  57.358 +static union xenkbd_in_event ev;
  57.359 +static int has_ev;
  57.360 +int console_checkkey (void)
  57.361 +{
  57.362 +    if (has_ev)
  57.363 +        return 1;
  57.364 +    has_ev = kbdfront_receive(kbd_dev, &ev, 1);
  57.365 +    return has_ev;
  57.366 +}
  57.367 +
  57.368 +/* static QWERTY layout, that's what most PC BIOSes do anyway */
  57.369 +static char linux2ascii[] = {
  57.370 +    [ 1 ] = 27,
  57.371 +    [ 2 ] = '1',
  57.372 +    [ 3 ] = '2',
  57.373 +    [ 4 ] = '3',
  57.374 +    [ 5 ] = '4',
  57.375 +    [ 6 ] = '5',
  57.376 +    [ 7 ] = '6',
  57.377 +    [ 8 ] = '7',
  57.378 +    [ 9 ] = '8',
  57.379 +    [ 10 ] = '9',
  57.380 +    [ 11 ] = '0',
  57.381 +    [ 12 ] = '-',
  57.382 +    [ 13 ] = '=',
  57.383 +    [ 14 ] = '\b',
  57.384 +    [ 15 ] = '\t',
  57.385 +    [ 16 ] = 'q',
  57.386 +    [ 17 ] = 'w',
  57.387 +    [ 18 ] = 'e',
  57.388 +    [ 19 ] = 'r',
  57.389 +    [ 20 ] = 't',
  57.390 +    [ 21 ] = 'y',
  57.391 +    [ 22 ] = 'u',
  57.392 +    [ 23 ] = 'i',
  57.393 +    [ 24 ] = 'o',
  57.394 +    [ 25 ] = 'p',
  57.395 +    [ 26 ] = '[',
  57.396 +    [ 27 ] = ']',
  57.397 +    [ 28 ] = '\n',
  57.398 +
  57.399 +    [ 30 ] = 'a',
  57.400 +    [ 31 ] = 's',
  57.401 +    [ 32 ] = 'd',
  57.402 +    [ 33 ] = 'f',
  57.403 +    [ 34 ] = 'g',
  57.404 +    [ 35 ] = 'h',
  57.405 +    [ 36 ] = 'j',
  57.406 +    [ 37 ] = 'k',
  57.407 +    [ 38 ] = 'l',
  57.408 +    [ 39 ] = ';',
  57.409 +    [ 40 ] = '\'',
  57.410 +    [ 41 ] = '`',
  57.411 +
  57.412 +    [ 43 ] = '\\',
  57.413 +    [ 44 ] = 'z',
  57.414 +    [ 45 ] = 'x',
  57.415 +    [ 46 ] = 'c',
  57.416 +    [ 47 ] = 'v',
  57.417 +    [ 48 ] = 'b',
  57.418 +    [ 49 ] = 'n',
  57.419 +    [ 50 ] = 'm',
  57.420 +    [ 51 ] = ',',
  57.421 +    [ 52 ] = '.',
  57.422 +    [ 53 ] = '/',
  57.423 +
  57.424 +    [ 55 ] = '*',
  57.425 +    [ 57 ] = ' ',
  57.426 +
  57.427 +    [ 71 ] = '7',
  57.428 +    [ 72 ] = '8',
  57.429 +    [ 73 ] = '9',
  57.430 +    [ 74 ] = '-',
  57.431 +    [ 75 ] = '4',
  57.432 +    [ 76 ] = '5',
  57.433 +    [ 77 ] = '6',
  57.434 +    [ 78 ] = '+',
  57.435 +    [ 79 ] = '1',
  57.436 +    [ 80 ] = '2',
  57.437 +    [ 81 ] = '3',
  57.438 +    [ 82 ] = '0',
  57.439 +    [ 83 ] = '.',
  57.440 +
  57.441 +    [ 86 ] = '<',
  57.442 +
  57.443 +    [ 96 ] = '\n',
  57.444 +
  57.445 +    [ 98 ] = '/',
  57.446 +
  57.447 +    [ 102 ] = 1,  /* home */
  57.448 +    [ 103 ] = 16, /* up */
  57.449 +    [ 104 ] = 7,  /* page up */
  57.450 +    [ 105 ] = 2,  /* left */
  57.451 +    [ 106 ] = 6,  /* right */
  57.452 +    [ 107 ] = 5,  /* end */
  57.453 +    [ 108 ] = 14, /* down */
  57.454 +    [ 109 ] = 3,  /* page down */
  57.455 +
  57.456 +    [ 111 ] = 4,  /* delete */
  57.457 +};
  57.458 +
  57.459 +static char linux2ascii_shifted[] = {
  57.460 +    [ 1 ] = 27,
  57.461 +    [ 2 ] = '!',
  57.462 +    [ 3 ] = '@',
  57.463 +    [ 4 ] = '#',
  57.464 +    [ 5 ] = '$',
  57.465 +    [ 6 ] = '%',
  57.466 +    [ 7 ] = '^',
  57.467 +    [ 8 ] = '&',
  57.468 +    [ 9 ] = '*',
  57.469 +    [ 10 ] = '(',
  57.470 +    [ 11 ] = ')',
  57.471 +    [ 12 ] = '_',
  57.472 +    [ 13 ] = '+',
  57.473 +    [ 14 ] = '\b',
  57.474 +    [ 15 ] = '\t',
  57.475 +    [ 16 ] = 'Q',
  57.476 +    [ 17 ] = 'W',
  57.477 +    [ 18 ] = 'E',
  57.478 +    [ 19 ] = 'R',
  57.479 +    [ 20 ] = 'T',
  57.480 +    [ 21 ] = 'Y',
  57.481 +    [ 22 ] = 'U',
  57.482 +    [ 23 ] = 'I',
  57.483 +    [ 24 ] = 'O',
  57.484 +    [ 25 ] = 'P',
  57.485 +    [ 26 ] = '{',
  57.486 +    [ 27 ] = '}',
  57.487 +    [ 28 ] = '\n',
  57.488 +
  57.489 +    [ 30 ] = 'A',
  57.490 +    [ 31 ] = 'S',
  57.491 +    [ 32 ] = 'D',
  57.492 +    [ 33 ] = 'F',
  57.493 +    [ 34 ] = 'G',
  57.494 +    [ 35 ] = 'H',
  57.495 +    [ 36 ] = 'J',
  57.496 +    [ 37 ] = 'K',
  57.497 +    [ 38 ] = 'L',
  57.498 +    [ 39 ] = ':',
  57.499 +    [ 40 ] = '"',
  57.500 +    [ 41 ] = '~',
  57.501 +
  57.502 +    [ 43 ] = '|',
  57.503 +    [ 44 ] = 'Z',
  57.504 +    [ 45 ] = 'X',
  57.505 +    [ 46 ] = 'C',
  57.506 +    [ 47 ] = 'V',
  57.507 +    [ 48 ] = 'B',
  57.508 +    [ 49 ] = 'N',
  57.509 +    [ 50 ] = 'M',
  57.510 +    [ 51 ] = '<',
  57.511 +    [ 52 ] = '>',
  57.512 +    [ 53 ] = '?',
  57.513 +
  57.514 +    [ 55 ] = '*',
  57.515 +    [ 57 ] = ' ',
  57.516 +
  57.517 +    [ 71 ] = '7',
  57.518 +    [ 72 ] = '8',
  57.519 +    [ 73 ] = '9',
  57.520 +    [ 74 ] = '-',
  57.521 +    [ 75 ] = '4',
  57.522 +    [ 76 ] = '5',
  57.523 +    [ 77 ] = '6',
  57.524 +    [ 78 ] = '+',
  57.525 +    [ 79 ] = '1',
  57.526 +    [ 80 ] = '2',
  57.527 +    [ 81 ] = '3',
  57.528 +    [ 82 ] = '0',
  57.529 +    [ 83 ] = '.',
  57.530 +
  57.531 +    [ 86 ] = '>',
  57.532 +
  57.533 +    [ 96 ] = '\n',
  57.534 +
  57.535 +    [ 98 ] = '/',
  57.536 +
  57.537 +    [ 102 ] = 1,  /* home */
  57.538 +    [ 103 ] = 16, /* up */
  57.539 +    [ 104 ] = 7,  /* page up */
  57.540 +    [ 105 ] = 2,  /* left */
  57.541 +    [ 106 ] = 6,  /* right */
  57.542 +    [ 107 ] = 5,  /* end */
  57.543 +    [ 108 ] = 14, /* down */
  57.544 +    [ 109 ] = 3,  /* page down */
  57.545 +
  57.546 +    [ 111 ] = 4,  /* delete */
  57.547 +};
  57.548 +
  57.549 +int console_getkey (void)
  57.550 +{
  57.551 +    static int shift, control, alt, caps_lock;
  57.552 +
  57.553 +    if (!has_ev)
  57.554 +        has_ev = kbdfront_receive(kbd_dev, &ev, 1);
  57.555 +    if (!has_ev)
  57.556 +        return 0;
  57.557 +
  57.558 +    has_ev = 0;
  57.559 +    if (ev.type != XENKBD_TYPE_KEY)
  57.560 +        return 0;
  57.561 +
  57.562 +    if (ev.key.keycode == 42 || ev.key.keycode == 54) {
  57.563 +        caps_lock = 0;
  57.564 +        shift = ev.key.pressed;
  57.565 +        return 0;
  57.566 +    }
  57.567 +    if (ev.key.keycode == 58) {
  57.568 +        caps_lock ^= 1;
  57.569 +        return 0;
  57.570 +    }
  57.571 +    if (ev.key.keycode == 29 || ev.key.keycode == 97) {
  57.572 +        control = ev.key.pressed;
  57.573 +        return 0;
  57.574 +    }
  57.575 +    if (ev.key.keycode == 56) {
  57.576 +        alt = ev.key.pressed;
  57.577 +        return 0;
  57.578 +    }
  57.579 +
  57.580 +    if (!ev.key.pressed)
  57.581 +        return 0;
  57.582 +
  57.583 +    if (ev.key.keycode < sizeof(linux2ascii) / sizeof(*linux2ascii)) {
  57.584 +        char val;
  57.585 +        if (shift || caps_lock)
  57.586 +            val = linux2ascii_shifted[ev.key.keycode];
  57.587 +        else
  57.588 +            val = linux2ascii[ev.key.keycode];
  57.589 +        if (control)
  57.590 +            val &= ~0x60;
  57.591 +        return val;
  57.592 +    }
  57.593 +
  57.594 +    return 0;
  57.595 +}
  57.596 +
  57.597 +static void kbd_thread(void *p)
  57.598 +{
  57.599 +    struct semaphore *sem = p;
  57.600 +
  57.601 +    kbd_dev = init_kbdfront(NULL, 1);
  57.602 +    up(sem);
  57.603 +}
  57.604 +
  57.605 +struct fbfront_dev *fb_open(void *fb, int width, int height, int depth)
  57.606 +{
  57.607 +    unsigned long *mfns;
  57.608 +    int linesize = width * (depth / 8);
  57.609 +    int memsize = linesize * height;
  57.610 +    int numpages = (memsize + PAGE_SIZE - 1) / PAGE_SIZE;
  57.611 +    DECLARE_MUTEX_LOCKED(sem);
  57.612 +    int i;
  57.613 +
  57.614 +    create_thread("kbdfront", kbd_thread, &sem);
  57.615 +
  57.616 +    mfns = malloc(numpages * sizeof(*mfns));
  57.617 +    for (i = 0; i < numpages; i++) {
  57.618 +        memset(fb + i * PAGE_SIZE, 0, PAGE_SIZE);
  57.619 +        mfns[i] = virtual_to_mfn(fb + i * PAGE_SIZE);
  57.620 +    }
  57.621 +    fb_dev = init_fbfront(NULL, mfns, width, height, depth, linesize, numpages);
  57.622 +    free(mfns);
  57.623 +
  57.624 +    if (!fb_dev)
  57.625 +        return NULL;
  57.626 +
  57.627 +    down(&sem);
  57.628 +    if (!kbd_dev)
  57.629 +        return NULL;
  57.630 +
  57.631 +    return fb_dev;
  57.632 +}
  57.633 +
  57.634 +void kbd_close(void *foo)
  57.635 +{
  57.636 +    shutdown_kbdfront(kbd_dev);
  57.637 +    kbd_dev = NULL;
  57.638 +}
  57.639 +
  57.640 +void fb_close(void)
  57.641 +{
  57.642 +    create_thread("kbdfront close", kbd_close, NULL);
  57.643 +    shutdown_fbfront(fb_dev);
  57.644 +    fb_dev = NULL;
  57.645 +}
  57.646 +
  57.647 +/*
  57.648 + * Misc
  57.649 + */
  57.650 +
  57.651 +int getrtsecs (void)
  57.652 +{
  57.653 +    struct timeval tv;
  57.654 +    gettimeofday(&tv, NULL);
  57.655 +    return tv.tv_sec;
  57.656 +}
  57.657 +
  57.658 +int currticks (void)
  57.659 +{
  57.660 +    struct timeval tv;
  57.661 +    gettimeofday(&tv, NULL);
  57.662 +    return ((tv.tv_sec * 1000000ULL + tv.tv_usec) * TICKS_PER_SEC) / 1000000;
  57.663 +}
  57.664 +
  57.665 +void __attribute__ ((noreturn)) grub_reboot (void)
  57.666 +{
  57.667 +    for ( ;; )
  57.668 +    {
  57.669 +        struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_reboot };
  57.670 +        HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
  57.671 +    }
  57.672 +}
  57.673 +
  57.674 +#define SCRATCH_MEMSIZE (4 * 1024 * 1024)
  57.675 +
  57.676 +/* Note: not allocating it dynamically permits to make sure it lays below 4G
  57.677 + * for grub's 32bit pointers to work */
  57.678 +char grub_scratch_mem[SCRATCH_MEMSIZE] __attribute__((aligned(PAGE_SIZE)));
  57.679 +
  57.680 +int main(int argc, char *argv[])
  57.681 +{
  57.682 +    if (argc > 1) {
  57.683 +        strncpy(config_file, argv[1], sizeof(config_file) - 1);
  57.684 +        config_file[sizeof(config_file) - 1] = 0;
  57.685 +        if (!strncmp(config_file, "(nd)", 4))
  57.686 +            preset_menu = "dhcp";
  57.687 +    } else
  57.688 +        preset_menu = "dhcp --with-configfile";
  57.689 +
  57.690 +    mbi.drives_addr = BOOTSEC_LOCATION + (60 * 1024);
  57.691 +    mbi.drives_length = 0;
  57.692 +
  57.693 +    mbi.boot_loader_name = (unsigned long) "GNU GRUB " VERSION;
  57.694 +    mbi.mem_lower = (start_info.nr_pages * PAGE_SIZE) / 1024;
  57.695 +    mbi.mem_upper = 0;
  57.696 +    saved_drive = boot_drive;
  57.697 +    saved_partition = install_partition;
  57.698 +
  57.699 +    init_disk();
  57.700 +
  57.701 +    /* Try to make sure the client part got launched */
  57.702 +    sleep(1);
  57.703 +    cmain();
  57.704 +    printk("cmain returned!\n");
  57.705 +}
    58.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.2 +++ b/stubdom/grub/mini-os.h	Thu Jun 19 12:46:26 2008 +0900
    58.3 @@ -0,0 +1,5 @@
    58.4 +extern int blk_nb;
    58.5 +extern struct blkfront_dev **blk_dev;
    58.6 +extern struct netfront_dev *net_dev;
    58.7 +extern struct kbdfront_dev *kbd_dev;
    58.8 +extern struct fbfront_dev *fb_dev;
    59.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.2 +++ b/stubdom/grub/osdep.h	Thu Jun 19 12:46:26 2008 +0900
    59.3 @@ -0,0 +1,30 @@
    59.4 +#ifndef __OSDEP_H__
    59.5 +#define __OSDEP_H__
    59.6 +
    59.7 +#include <byteswap.h>
    59.8 +#define swap32(x) bswap_32(x)
    59.9 +#define swap16(x) bswap_16(x)
   59.10 +
   59.11 +#include <machine/endian.h>
   59.12 +#if BYTE_ORDER == BIG_ENDIAN
   59.13 +#define htons(x) (x)
   59.14 +#define ntohs(x) (x)
   59.15 +#define htonl(x) (x)
   59.16 +#define ntohl(x) (x)
   59.17 +#else
   59.18 +#define htons(x) swap16(x)
   59.19 +#define ntohs(x) swap16(x)
   59.20 +#define htonl(x) swap32(x)
   59.21 +#define ntohl(x) swap32(x)
   59.22 +#endif
   59.23 +
   59.24 +typedef unsigned long Address;
   59.25 +
   59.26 +/* ANSI prototyping macro */
   59.27 +#ifdef  __STDC__
   59.28 +#define P(x)	x
   59.29 +#else
   59.30 +#define P(x)	()
   59.31 +#endif
   59.32 +
   59.33 +#endif
    61.1 --- a/tools/console/daemon/io.c	Tue Jun 10 16:00:33 2008 +0900
    61.2 +++ b/tools/console/daemon/io.c	Thu Jun 19 12:46:26 2008 +0900
    61.3 @@ -525,7 +525,8 @@ static int domain_create_ring(struct dom
    61.4  	} else
    61.5  		dom->use_consolepath = 0;
    61.6  
    61.7 -	sprintf(path, "%s/type", dom->use_consolepath ? dom->conspath: dom->serialpath);
    61.8 +	snprintf(path, sizeof(path), "%s/type",
    61.9 +		dom->use_consolepath ? dom->conspath: dom->serialpath);
   61.10  	type = xs_read(xs, XBT_NULL, path, NULL);
   61.11  	if (type && strcmp(type, "xenconsoled") != 0) {
   61.12  		free(type);
    62.1 --- a/tools/examples/xmexample.hvm	Tue Jun 10 16:00:33 2008 +0900
    62.2 +++ b/tools/examples/xmexample.hvm	Thu Jun 19 12:46:26 2008 +0900
    62.3 @@ -256,16 +256,16 @@ serial='pty'
    62.4  #vcpus=5
    62.5  #
    62.6  #  Downgrade the cpuid to make a better compatibility for migration :
    62.7 -# Look like a PIII :
    62.8 -# cpuid = [ '0:eax=0x3',
    62.9 +# Look like a generic 686 :
   62.10 +# cpuid = [ '0:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0',
   62.11  #           '1:eax=0x06b1,
   62.12  #              ecx=xxxxxxxxxx0000xx00xxx0000000xx0,
   62.13  #              edx=xx00000xxxxxxx0xxxxxxxxx0xxxxxx',
   62.14 -#           '4:eax=0x3,ebx=0x756e6547,ecx=0x6c65746e,edx=0x49656e69',
   62.15 -#  '0x80000000:eax=0x3,ebx=0x756e6547,ecx=0x6c65746e,edx=0x49656e69']
   62.16 +#           '4:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0',
   62.17 +#  '0x80000000:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0']
   62.18  #  with the highest leaf
   62.19  #  - CPUID.0[EAX] : Set the highest leaf
   62.20 -#  - CPUID.1[EAX] : Pentium III
   62.21 +#  - CPUID.1[EAX] : 686 
   62.22  #  - CPUID.1[ECX] : Mask some features
   62.23  #  - CPUID.1[EDX] : Mask some features
   62.24  #  - CPUID.4 : Reply like the highest leaf, in our case CPUID.3
    63.1 --- a/tools/firmware/rombios/rombios.c	Tue Jun 10 16:00:33 2008 +0900
    63.2 +++ b/tools/firmware/rombios/rombios.c	Thu Jun 19 12:46:26 2008 +0900
    63.3 @@ -2311,10 +2311,31 @@ debugger_off()
    63.4  #define ACPI_FACS_OFFSET 0x10
    63.5  /* S3 resume status in CMOS 0Fh shutdown status byte*/
    63.6  
    63.7 +Bit32u facs_get32(offs)
    63.8 +Bit16u offs;
    63.9 +{
   63.10 +ASM_START
   63.11 +  push bp
   63.12 +  mov  bp, sp
   63.13 +
   63.14 +    push ds
   63.15 +    mov ax, #(ACPI_FACS_ADDRESS >> 4)
   63.16 +    mov ds, ax
   63.17 +
   63.18 +    mov bx, 4[bp]
   63.19 +    mov ax, [bx]
   63.20 +    mov dx, 2[bx]
   63.21 +    pop ds
   63.22 +
   63.23 +  pop  bp
   63.24 +ASM_END
   63.25 +}
   63.26 +
   63.27 +
   63.28  void 
   63.29  s3_resume()
   63.30  {
   63.31 -    Bit16u s3_wakeup_vector;
   63.32 +    Bit32u s3_wakeup_vector;
   63.33      extern Bit16u s3_wakeup_ip;
   63.34      extern Bit16u s3_wakeup_cs;
   63.35      extern Bit8u s3_resume_flag;
   63.36 @@ -2330,19 +2351,14 @@ ASM_END
   63.37      }
   63.38      s3_resume_flag = 0;
   63.39  
   63.40 -ASM_START
   63.41 -    mov ax, #0x0
   63.42 -    mov ds, ax
   63.43 -ASM_END
   63.44 -
   63.45      /* get x_firmware_waking_vector */
   63.46 -    s3_wakeup_vector = *((Bit16u*)(ACPI_FACS_ADDRESS+ACPI_FACS_OFFSET+24));
   63.47 -    if (s3_wakeup_vector == 0){
   63.48 +    s3_wakeup_vector = facs_get32(ACPI_FACS_OFFSET+24);
   63.49 +    if (!s3_wakeup_vector) {
   63.50          /* get firmware_waking_vector */
   63.51 -        s3_wakeup_vector = *((Bit16u*)(ACPI_FACS_ADDRESS+ACPI_FACS_OFFSET+12));
   63.52 -        if (s3_wakeup_vector == 0){
   63.53 +	s3_wakeup_vector = facs_get32(ACPI_FACS_OFFSET+12);
   63.54 +    	if (!s3_wakeup_vector) {
   63.55              goto s3_out;
   63.56 -        }
   63.57 +	}
   63.58      }
   63.59  
   63.60      /* setup wakeup vector */
   63.61 @@ -2350,13 +2366,6 @@ ASM_END
   63.62      s3_wakeup_cs = s3_wakeup_vector >> 4;
   63.63  
   63.64  ASM_START
   63.65 -    mov bx, [_s3_wakeup_cs]
   63.66 -    mov dx, [_s3_wakeup_ip]
   63.67 -
   63.68 -    mov ax, #0xF000
   63.69 -    mov ds, ax
   63.70 -    mov [_s3_wakeup_cs], bx
   63.71 -    mov [_s3_wakeup_ip], dx
   63.72      jmpf [_s3_wakeup_ip]
   63.73  
   63.74  ; S3 data
    64.1 --- a/tools/fs-back/fs-ops.c	Tue Jun 10 16:00:33 2008 +0900
    64.2 +++ b/tools/fs-back/fs-ops.c	Thu Jun 19 12:46:26 2008 +0900
    64.3 @@ -55,7 +55,8 @@ void dispatch_file_open(struct mount *mo
    64.4      printf("File open issued for %s\n", file_name); 
    64.5      assert(BUFFER_SIZE > 
    64.6             strlen(file_name) + strlen(mount->export->export_path) + 1); 
    64.7 -    sprintf(full_path, "%s/%s", mount->export->export_path, file_name);
    64.8 +    snprintf(full_path, sizeof(full_path), "%s/%s",
    64.9 +           mount->export->export_path, file_name);
   64.10      assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0);
   64.11      printf("Issuing open for %s\n", full_path);
   64.12      fd = open(full_path, O_RDWR);
   64.13 @@ -311,7 +312,8 @@ void dispatch_remove(struct mount *mount
   64.14      printf("File remove issued for %s\n", file_name); 
   64.15      assert(BUFFER_SIZE > 
   64.16             strlen(file_name) + strlen(mount->export->export_path) + 1); 
   64.17 -    sprintf(full_path, "%s/%s", mount->export->export_path, file_name);
   64.18 +    snprintf(full_path, sizeof(full_path), "%s/%s",
   64.19 +           mount->export->export_path, file_name);
   64.20      assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0);
   64.21      printf("Issuing remove for %s\n", full_path);
   64.22      ret = remove(full_path);
   64.23 @@ -355,8 +357,10 @@ void dispatch_rename(struct mount *mount
   64.24             strlen(old_file_name) + strlen(mount->export->export_path) + 1); 
   64.25      assert(BUFFER_SIZE > 
   64.26             strlen(new_file_name) + strlen(mount->export->export_path) + 1); 
   64.27 -    sprintf(old_full_path, "%s/%s", mount->export->export_path, old_file_name);
   64.28 -    sprintf(new_full_path, "%s/%s", mount->export->export_path, new_file_name);
   64.29 +    snprintf(old_full_path, sizeof(old_full_path), "%s/%s",
   64.30 +           mount->export->export_path, old_file_name);
   64.31 +    snprintf(new_full_path, sizeof(new_full_path), "%s/%s",
   64.32 +           mount->export->export_path, new_file_name);
   64.33      assert(xc_gnttab_munmap(mount->gnth, buf, 1) == 0);
   64.34      printf("Issuing rename for %s -> %s\n", old_full_path, new_full_path);
   64.35      ret = rename(old_full_path, new_full_path);
   64.36 @@ -398,7 +402,8 @@ void dispatch_create(struct mount *mount
   64.37      printf("File create issued for %s\n", file_name); 
   64.38      assert(BUFFER_SIZE > 
   64.39             strlen(file_name) + strlen(mount->export->export_path) + 1); 
   64.40 -    sprintf(full_path, "%s/%s", mount->export->export_path, file_name);
   64.41 +    snprintf(full_path, sizeof(full_path), "%s/%s",
   64.42 +           mount->export->export_path, file_name);
   64.43      assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0);
   64.44      /* We can advance the request consumer index, from here on, the request
   64.45       * should not be used (it may be overrinden by a response) */
   64.46 @@ -447,7 +452,8 @@ void dispatch_list(struct mount *mount, 
   64.47      printf("Dir list issued for %s\n", file_name); 
   64.48      assert(BUFFER_SIZE > 
   64.49             strlen(file_name) + strlen(mount->export->export_path) + 1); 
   64.50 -    sprintf(full_path, "%s/%s", mount->export->export_path, file_name);
   64.51 +    snprintf(full_path, sizeof(full_path), "%s/%s",
   64.52 +           mount->export->export_path, file_name);
   64.53      /* We can advance the request consumer index, from here on, the request
   64.54       * should not be used (it may be overrinden by a response) */
   64.55      mount->ring.req_cons++;
   64.56 @@ -540,7 +546,8 @@ void dispatch_fs_space(struct mount *mou
   64.57      printf("Fs space issued for %s\n", file_name); 
   64.58      assert(BUFFER_SIZE > 
   64.59             strlen(file_name) + strlen(mount->export->export_path) + 1); 
   64.60 -    sprintf(full_path, "%s/%s", mount->export->export_path, file_name);
   64.61 +    snprintf(full_path, sizeof(full_path), "%s/%s",
   64.62 +           mount->export->export_path, file_name);
   64.63      assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0);
   64.64      printf("Issuing fs space for %s\n", full_path);
   64.65      ret = statfs(full_path, &stat);
    65.1 --- a/tools/fs-back/fs-xenbus.c	Tue Jun 10 16:00:33 2008 +0900
    65.2 +++ b/tools/fs-back/fs-xenbus.c	Thu Jun 19 12:46:26 2008 +0900
    65.3 @@ -22,8 +22,8 @@ static bool xenbus_printf(struct xs_hand
    65.4      va_list args;
    65.5      
    65.6      va_start(args, fmt);
    65.7 -    sprintf(fullpath,"%s/%s", node, path);
    65.8 -    vsprintf(val, fmt, args);
    65.9 +    snprintf(fullpath, sizeof(fullpath), "%s/%s", node, path);
   65.10 +    vsnprintf(val, sizeof(val), fmt, args);
   65.11      va_end(args);
   65.12      printf("xenbus_printf (%s) <= %s.\n", fullpath, val);    
   65.13  
   65.14 @@ -72,7 +72,7 @@ int xenbus_register_export(struct fs_exp
   65.15      printf("XS transaction is %d\n", xst); 
   65.16   
   65.17      /* Create node string */
   65.18 -    sprintf(node, "%s/%d", EXPORTS_NODE, export->export_id); 
   65.19 +    snprintf(node, sizeof(node), "%s/%d", EXPORTS_NODE, export->export_id); 
   65.20      /* Remove old export (if exists) */ 
   65.21      xs_rm(xsh, xst, node);
   65.22  
   65.23 @@ -116,20 +116,20 @@ void xenbus_read_mount_request(struct mo
   65.24  
   65.25      assert(xsh != NULL);
   65.26  #if 0
   65.27 -    sprintf(node, WATCH_NODE"/%d/%d/frontend", 
   65.28 +    snprintf(node, sizeof(node), WATCH_NODE"/%d/%d/frontend", 
   65.29                             mount->dom_id, mount->export->export_id);
   65.30      frontend = xs_read(xsh, XBT_NULL, node, NULL);
   65.31  #endif
   65.32      mount->frontend = frontend;
   65.33 -    sprintf(node, "%s/state", frontend);
   65.34 +    snprintf(node, sizeof(node), "%s/state", frontend);
   65.35      s = xs_read(xsh, XBT_NULL, node, NULL);
   65.36      assert(strcmp(s, STATE_READY) == 0);
   65.37      free(s);
   65.38 -    sprintf(node, "%s/ring-ref", frontend);
   65.39 +    snprintf(node, sizeof(node), "%s/ring-ref", frontend);
   65.40      s = xs_read(xsh, XBT_NULL, node, NULL);
   65.41      mount->gref = atoi(s);
   65.42      free(s);
   65.43 -    sprintf(node, "%s/event-channel", frontend);
   65.44 +    snprintf(node, sizeof(node), "%s/event-channel", frontend);
   65.45      s = xs_read(xsh, XBT_NULL, node, NULL);
   65.46      mount->remote_evtchn = atoi(s);
   65.47      free(s);
   65.48 @@ -158,12 +158,12 @@ void xenbus_write_backend_node(struct mo
   65.49      assert(xsh != NULL);
   65.50      self_id = get_self_id();
   65.51      printf("Our own dom_id=%d\n", self_id);
   65.52 -    sprintf(node, "%s/backend", mount->frontend);
   65.53 -    sprintf(backend_node, "/local/domain/%d/"ROOT_NODE"/%d",
   65.54 +    snprintf(node, sizeof(node), "%s/backend", mount->frontend);
   65.55 +    snprintf(backend_node, sizeof(backend_node), "/local/domain/%d/"ROOT_NODE"/%d",
   65.56                                  self_id, mount->mount_id);
   65.57      xs_write(xsh, XBT_NULL, node, backend_node, strlen(backend_node));
   65.58  
   65.59 -    sprintf(node, ROOT_NODE"/%d/state", mount->mount_id);
   65.60 +    snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id);
   65.61      xs_write(xsh, XBT_NULL, node, STATE_INITIALISED, strlen(STATE_INITIALISED));
   65.62  }
   65.63  
   65.64 @@ -174,7 +174,7 @@ void xenbus_write_backend_ready(struct m
   65.65  
   65.66      assert(xsh != NULL);
   65.67      self_id = get_self_id();
   65.68 -    sprintf(node, ROOT_NODE"/%d/state", mount->mount_id);
   65.69 +    snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id);
   65.70      xs_write(xsh, XBT_NULL, node, STATE_READY, strlen(STATE_READY));
   65.71  }
   65.72  
    66.1 --- a/tools/include/xen-sys/NetBSD/privcmd.h	Tue Jun 10 16:00:33 2008 +0900
    66.2 +++ b/tools/include/xen-sys/NetBSD/privcmd.h	Thu Jun 19 12:46:26 2008 +0900
    66.3 @@ -36,6 +36,7 @@ typedef struct privcmd_hypercall
    66.4  {
    66.5      unsigned long op;
    66.6      unsigned long arg[5];
    66.7 +    long retval;
    66.8  } privcmd_hypercall_t;
    66.9  
   66.10  typedef struct privcmd_mmap_entry {
    67.1 --- a/tools/ioemu/Makefile.target	Tue Jun 10 16:00:33 2008 +0900
    67.2 +++ b/tools/ioemu/Makefile.target	Thu Jun 19 12:46:26 2008 +0900
    67.3 @@ -358,13 +358,6 @@ VL_OBJS+=tap-win32.o
    67.4  endif
    67.5  
    67.6  ifdef CONFIG_STUBDOM
    67.7 -VL_OBJS+=main-qemu.o
    67.8 -CFLAGS += -DCONFIG_QEMU
    67.9 -main-qemu.c:
   67.10 -	ln -s $(XEN_ROOT)/extras/mini-os/main.c $@
   67.11 -endif
   67.12 -
   67.13 -ifdef CONFIG_STUBDOM
   67.14  #CONFIG_PASSTHROUGH=1
   67.15  else
   67.16    ifeq (,$(wildcard /usr/include/pci))
   67.17 @@ -444,7 +437,11 @@ VL_OBJS+= xen_platform.o
   67.18  VL_OBJS+= xen_machine_fv.o
   67.19  VL_OBJS+= xen_machine_pv.o
   67.20  VL_OBJS+= xenfb.o
   67.21 +ifdef CONFIG_STUBDOM
   67.22 +VL_OBJS+= xenfbfront.o
   67.23 +endif
   67.24  VL_OBJS+= xen_console.o
   67.25 +VL_OBJS+= pci_emulation.o
   67.26  ifndef CONFIG_STUBDOM
   67.27  VL_OBJS+= tpm_tis.o
   67.28  VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o 
    68.1 --- a/tools/ioemu/cocoa.m	Tue Jun 10 16:00:33 2008 +0900
    68.2 +++ b/tools/ioemu/cocoa.m	Thu Jun 19 12:46:26 2008 +0900
    68.3 @@ -96,7 +96,7 @@ static void cocoa_update(DisplayState *d
    68.4      cocoa_resize
    68.5   ------------------------------------------------------
    68.6  */
    68.7 -static void cocoa_resize(DisplayState *ds, int w, int h, int linesize)
    68.8 +static void cocoa_resize(DisplayState *ds, int w, int h)
    68.9  {
   68.10      const int device_bpp = 32;
   68.11      static void *screen_pixels;
    69.1 --- a/tools/ioemu/hw/pc.c	Tue Jun 10 16:00:33 2008 +0900
    69.2 +++ b/tools/ioemu/hw/pc.c	Thu Jun 19 12:46:26 2008 +0900
    69.3 @@ -1090,6 +1090,13 @@ static void pc_init1(uint64_t ram_size, 
    69.4          }
    69.5      }
    69.6  #endif /* !CONFIG_DM */
    69.7 +
    69.8 +    if (pci_enabled) {
    69.9 +        PCI_EMULATION_INFO *p;
   69.10 +        for (p = PciEmulationInfoHead; p != NULL; p = p->next) {
   69.11 +            pci_emulation_init(pci_bus, p);
   69.12 +        }
   69.13 +    }
   69.14  }
   69.15  
   69.16  static void pc_init_pci(uint64_t ram_size, int vga_ram_size, char *boot_device,
    70.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.2 +++ b/tools/ioemu/hw/pci_emulation.c	Thu Jun 19 12:46:26 2008 +0900
    70.3 @@ -0,0 +1,118 @@
    70.4 +/*
    70.5 + * Changes to PCI emulation made by Marathon Technologies, June 2008
    70.6 + */
    70.7 +
    70.8 +#include "vl.h"
    70.9 +
   70.10 +typedef struct {
   70.11 +    PCIDevice dev;
   70.12 +}   PCI_EMULATION_State;
   70.13 +
   70.14 +void parse_pci_emulation_info(char *config_text, PCI_EMULATION_INFO *pci_emulation_info)
   70.15 +{
   70.16 +    char *p;
   70.17 +    int i;
   70.18 +    int ret;
   70.19 +    for (p = config_text, i = 0; *p != '\0'; p++) {
   70.20 +        if (*p == ':') {
   70.21 +            break;
   70.22 +        }
   70.23 +        if (i < sizeof(pci_emulation_info->name) - 1) {
   70.24 +            pci_emulation_info->name[i] = *p;
   70.25 +            i++;
   70.26 +        }
   70.27 +    }
   70.28 +    pci_emulation_info->name[i] = '\0';
   70.29 +    if (*p == '\0') return;
   70.30 +    p++;
   70.31 +    ret = sscanf(p, "%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x",
   70.32 +                 &(pci_emulation_info->vendorid),
   70.33 +                 &(pci_emulation_info->deviceid),
   70.34 +                 &(pci_emulation_info->command),
   70.35 +                 &(pci_emulation_info->status),
   70.36 +                 &(pci_emulation_info->revision),
   70.37 +                 &(pci_emulation_info->classcode),
   70.38 +                 &(pci_emulation_info->headertype),
   70.39 +                 &(pci_emulation_info->subvendorid),
   70.40 +                 &(pci_emulation_info->subsystemid),
   70.41 +                 &(pci_emulation_info->interruputline),
   70.42 +                 &(pci_emulation_info->interruputpin));
   70.43 +#ifdef DEBUG
   70.44 +    fprintf(logfile, "qemu: pciemulation %s:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x\n",
   70.45 +            pci_emulation_info->name,
   70.46 +            pci_emulation_info->vendorid,
   70.47 +            pci_emulation_info->deviceid,
   70.48 +            pci_emulation_info->command,
   70.49 +            pci_emulation_info->status,
   70.50 +            pci_emulation_info->revision,
   70.51 +            pci_emulation_info->classcode,
   70.52 +            pci_emulation_info->headertype,
   70.53 +            pci_emulation_info->subvendorid,
   70.54 +            pci_emulation_info->subsystemid,
   70.55 +            pci_emulation_info->interruputline,
   70.56 +            pci_emulation_info->interruputpin);
   70.57 +#endif
   70.58 +    return;
   70.59 +}
   70.60 +
   70.61 +static void pci_emulation_save(QEMUFile *f, void *opaque)
   70.62 +{
   70.63 +    PCIDevice *d = opaque;
   70.64 +
   70.65 +    pci_device_save(d, f);
   70.66 +}
   70.67 +
   70.68 +static int pci_emulation_load(QEMUFile *f, void *opaque, int version_id)
   70.69 +{
   70.70 +    PCIDevice *d = opaque;
   70.71 +
   70.72 +    if (version_id != 1)
   70.73 +        return -EINVAL;
   70.74 +
   70.75 +    return pci_device_load(d, f);
   70.76 +}
   70.77 +
   70.78 +
   70.79 +void pci_emulation_init(PCIBus *bus, PCI_EMULATION_INFO *pci_emulation_info)
   70.80 +{
   70.81 +    int instance_id;
   70.82 +    PCI_EMULATION_State *d;
   70.83 +    uint8_t *pci_conf;
   70.84 +
   70.85 +#ifdef DEBUG
   70.86 +    fprintf(logfile, "qemu: pciinit\n");
   70.87 +#endif
   70.88 +    
   70.89 +    d = (PCI_EMULATION_State *)pci_register_device(bus,
   70.90 +                                                   pci_emulation_info->name, 
   70.91 +                                                   sizeof(PCI_EMULATION_State),
   70.92 +                                                   -1, 
   70.93 +                                                    NULL, NULL);
   70.94 +    pci_conf = d->dev.config;
   70.95 +    pci_conf[0x00] = pci_emulation_info->vendorid & 0xff;
   70.96 +    pci_conf[0x01] = (pci_emulation_info->vendorid & 0xff00) >> 8;
   70.97 +    pci_conf[0x02] = pci_emulation_info->deviceid & 0xff;
   70.98 +    pci_conf[0x03] = (pci_emulation_info->deviceid & 0xff00) >> 8;
   70.99 +    pci_conf[0x04] = pci_emulation_info->command & 0xff;
  70.100 +    pci_conf[0x05] = (pci_emulation_info->command & 0xff00) >> 8;
  70.101 +    pci_conf[0x06] = pci_emulation_info->status & 0xff;
  70.102 +    pci_conf[0x07] = (pci_emulation_info->status & 0xff00) >> 8;
  70.103 +    pci_conf[0x08] = pci_emulation_info->revision & 0xff;
  70.104 +    pci_conf[0x09] = pci_emulation_info->classcode & 0xff;
  70.105 +    pci_conf[0x0a] = (pci_emulation_info->classcode & 0xff00) >> 8;
  70.106 +    pci_conf[0x0b] = (pci_emulation_info->classcode & 0xff0000) >> 16;
  70.107 +    pci_conf[0x0e] = pci_emulation_info->headertype & 0xff;
  70.108 +    pci_conf[0x2c] = pci_emulation_info->subvendorid & 0xff;
  70.109 +    pci_conf[0x2d] = (pci_emulation_info->subvendorid & 0xff00) >> 8;
  70.110 +    pci_conf[0x2e] = pci_emulation_info->subsystemid & 0xff;
  70.111 +    pci_conf[0x2f] = (pci_emulation_info->subsystemid & 0xff00) >> 8;
  70.112 +    pci_conf[0x3c] = pci_emulation_info->interruputline & 0xff;
  70.113 +    pci_conf[0x3d] = pci_emulation_info->interruputpin & 0xff;
  70.114 +
  70.115 +    instance_id = pci_bus_num(bus) << 8 | d->dev.devfn;
  70.116 +    register_savevm(pci_emulation_info->name, instance_id,
  70.117 +                    1, pci_emulation_save, pci_emulation_load, d);
  70.118 +
  70.119 +
  70.120 +    return;    
  70.121 +}
    71.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.2 +++ b/tools/ioemu/hw/pci_emulation.h	Thu Jun 19 12:46:26 2008 +0900
    71.3 @@ -0,0 +1,24 @@
    71.4 +/*
    71.5 + * Changes to PCI emulation made by Marathon Technologies, June 2008
    71.6 + */
    71.7 +
    71.8 +typedef struct PCI_EMULATION_INFO_t {
    71.9 +    struct PCI_EMULATION_INFO_t *next;
   71.10 +    char name[32];
   71.11 +    unsigned int vendorid;
   71.12 +    unsigned int deviceid;
   71.13 +    unsigned int command;
   71.14 +    unsigned int status;
   71.15 +    unsigned int revision;
   71.16 +    unsigned int classcode;
   71.17 +    unsigned int headertype;
   71.18 +    unsigned int subvendorid;
   71.19 +    unsigned int subsystemid;
   71.20 +    unsigned int interruputline;
   71.21 +    unsigned int interruputpin;
   71.22 +}   PCI_EMULATION_INFO;
   71.23 +    
   71.24 +void parse_pci_emulation_info(char *config_text, PCI_EMULATION_INFO *pci_emulation_info);
   71.25 +void pci_emulation_init(PCIBus *bus, PCI_EMULATION_INFO *pci_emulation_info);
   71.26 +
   71.27 +extern PCI_EMULATION_INFO *PciEmulationInfoHead;
    72.1 --- a/tools/ioemu/hw/pl110.c	Tue Jun 10 16:00:33 2008 +0900
    72.2 +++ b/tools/ioemu/hw/pl110.c	Thu Jun 19 12:46:26 2008 +0900
    72.3 @@ -262,7 +262,7 @@ static void pl110_resize(pl110_state *s,
    72.4  {
    72.5      if (width != s->cols || height != s->rows) {
    72.6          if (pl110_enabled(s)) {
    72.7 -            dpy_resize(s->ds, width, height, width * 4);
    72.8 +            dpy_resize(s->ds, width, height);
    72.9          }
   72.10      }
   72.11      s->cols = width;
   72.12 @@ -375,7 +375,7 @@ static void pl110_write(void *opaque, ta
   72.13          s->cr = val;
   72.14          s->bpp = (val >> 1) & 7;
   72.15          if (pl110_enabled(s)) {
   72.16 -            dpy_resize(s->ds, s->cols, s->rows, s->cols * 4);
   72.17 +            dpy_resize(s->ds, s->cols, s->rows);
   72.18          }
   72.19          break;
   72.20      case 10: /* LCDICR */
    73.1 --- a/tools/ioemu/hw/tcx.c	Tue Jun 10 16:00:33 2008 +0900
    73.2 +++ b/tools/ioemu/hw/tcx.c	Thu Jun 19 12:46:26 2008 +0900
    73.3 @@ -342,7 +342,7 @@ void tcx_init(DisplayState *ds, uint32_t
    73.4      register_savevm("tcx", addr, 1, tcx_save, tcx_load, s);
    73.5      qemu_register_reset(tcx_reset, s);
    73.6      tcx_reset(s);
    73.7 -    dpy_resize(s->ds, width, height, width * 1);
    73.8 +    dpy_resize(s->ds, width, height);
    73.9  }
   73.10  
   73.11  static void tcx_screen_dump(void *opaque, const char *filename)
    74.1 --- a/tools/ioemu/hw/usb-msd.c	Tue Jun 10 16:00:33 2008 +0900
    74.2 +++ b/tools/ioemu/hw/usb-msd.c	Thu Jun 19 12:46:26 2008 +0900
    74.3 @@ -510,7 +510,7 @@ static void usb_msd_handle_destroy(USBDe
    74.4      qemu_free(s);
    74.5  }
    74.6  
    74.7 -USBDevice *usb_msd_init(const char *filename)
    74.8 +USBDevice *usb_msd_init(const char *filename, BlockDriver *drv)
    74.9  {
   74.10      MSDState *s;
   74.11      BlockDriverState *bdrv;
   74.12 @@ -520,7 +520,7 @@ USBDevice *usb_msd_init(const char *file
   74.13          return NULL;
   74.14  
   74.15      bdrv = bdrv_new("usb");
   74.16 -    if (bdrv_open(bdrv, filename, 0) < 0)
   74.17 +    if (bdrv_open2(bdrv, filename, 0, drv) < 0)
   74.18          goto fail;
   74.19      s->bs = bdrv;
   74.20  
    75.1 --- a/tools/ioemu/hw/usb.h	Tue Jun 10 16:00:33 2008 +0900
    75.2 +++ b/tools/ioemu/hw/usb.h	Thu Jun 19 12:46:26 2008 +0900
    75.3 @@ -217,7 +217,7 @@ USBDevice *usb_mouse_init(void);
    75.4  USBDevice *usb_tablet_init(void);
    75.5  
    75.6  /* usb-msd.c */
    75.7 -USBDevice *usb_msd_init(const char *filename);
    75.8 +USBDevice *usb_msd_init(const char *filename, BlockDriver *drv);
    75.9  
   75.10  /* usb.c */
   75.11  void generic_usb_save(QEMUFile* f, void *opaque);
    76.1 --- a/tools/ioemu/hw/vga.c	Tue Jun 10 16:00:33 2008 +0900
    76.2 +++ b/tools/ioemu/hw/vga.c	Thu Jun 19 12:46:26 2008 +0900
    76.3 @@ -1089,14 +1089,48 @@ static void vga_draw_text(VGAState *s, i
    76.4      /* Disable dirty bit tracking */
    76.5      xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL);
    76.6  
    76.7 -    if (s->ds->dpy_colourdepth != NULL && s->ds->depth != 0)
    76.8 -        s->ds->dpy_colourdepth(s->ds, 0);
    76.9 +    /* total width & height */
   76.10 +    cheight = (s->cr[9] & 0x1f) + 1;
   76.11 +    cw = 8;
   76.12 +    if (!(s->sr[1] & 0x01))
   76.13 +        cw = 9;
   76.14 +    if (s->sr[1] & 0x08)
   76.15 +        cw = 16; /* NOTE: no 18 pixel wide */
   76.16 +    width = (s->cr[0x01] + 1);
   76.17 +    if (s->cr[0x06] == 100) {
   76.18 +        /* ugly hack for CGA 160x100x16 - explain me the logic */
   76.19 +        height = 100;
   76.20 +    } else {
   76.21 +        height = s->cr[0x12] | 
   76.22 +            ((s->cr[0x07] & 0x02) << 7) | 
   76.23 +            ((s->cr[0x07] & 0x40) << 3);
   76.24 +        height = (height + 1) / cheight;
   76.25 +    }
   76.26 +    if ((height * width) > CH_ATTR_SIZE) {
   76.27 +        /* better than nothing: exit if transient size is too big */
   76.28 +        return;
   76.29 +    }
   76.30 +
   76.31 +    s->last_scr_width = width * cw;
   76.32 +    s->last_scr_height = height * cheight;
   76.33 +    if (width != s->last_width || height != s->last_height ||
   76.34 +        cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
   76.35 +        dpy_resize(s->ds, s->last_scr_width, s->last_scr_height);
   76.36 +        s->last_depth = 0;
   76.37 +        full_update = 1;
   76.38 +    }
   76.39 +    s->last_width = width;
   76.40 +    s->last_height = height;
   76.41 +    s->last_ch = cheight;
   76.42 +    s->last_cw = cw;
   76.43 +
   76.44      s->rgb_to_pixel = 
   76.45          rgb_to_pixel_dup_table[get_depth_index(s->ds)];
   76.46  
   76.47      full_update |= update_palette16(s);
   76.48      palette = s->last_palette;
   76.49      
   76.50 +    x_incr = cw * ((s->ds->depth + 7) >> 3);
   76.51      /* compute font data address (in plane 2) */
   76.52      v = s->sr[3];
   76.53      offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
   76.54 @@ -1123,40 +1157,6 @@ static void vga_draw_text(VGAState *s, i
   76.55      line_offset = s->line_offset;
   76.56      s1 = s->vram_ptr + (s->start_addr * 4);
   76.57  
   76.58 -    /* total width & height */
   76.59 -    cheight = (s->cr[9] & 0x1f) + 1;
   76.60 -    cw = 8;
   76.61 -    if (!(s->sr[1] & 0x01))
   76.62 -        cw = 9;
   76.63 -    if (s->sr[1] & 0x08)
   76.64 -        cw = 16; /* NOTE: no 18 pixel wide */
   76.65 -    x_incr = cw * ((s->ds->depth + 7) >> 3);
   76.66 -    width = (s->cr[0x01] + 1);
   76.67 -    if (s->cr[0x06] == 100) {
   76.68 -        /* ugly hack for CGA 160x100x16 - explain me the logic */
   76.69 -        height = 100;
   76.70 -    } else {
   76.71 -        height = s->cr[0x12] | 
   76.72 -            ((s->cr[0x07] & 0x02) << 7) | 
   76.73 -            ((s->cr[0x07] & 0x40) << 3);
   76.74 -        height = (height + 1) / cheight;
   76.75 -    }
   76.76 -    if ((height * width) > CH_ATTR_SIZE) {
   76.77 -        /* better than nothing: exit if transient size is too big */
   76.78 -        return;
   76.79 -    }
   76.80 -
   76.81 -    if (width != s->last_width || height != s->last_height ||
   76.82 -        cw != s->last_cw || cheight != s->last_ch) {
   76.83 -        s->last_scr_width = width * cw;
   76.84 -        s->last_scr_height = height * cheight;
   76.85 -        dpy_resize(s->ds, s->last_scr_width, s->last_scr_height, s->last_scr_width * (s->ds->depth / 8));
   76.86 -        s->last_width = width;
   76.87 -        s->last_height = height;
   76.88 -        s->last_ch = cheight;
   76.89 -        s->last_cw = cw;
   76.90 -        full_update = 1;
   76.91 -    }
   76.92      cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
   76.93      if (cursor_offset != s->cursor_offset ||
   76.94          s->cr[0xa] != s->cursor_start ||
   76.95 @@ -1501,16 +1501,6 @@ static void vga_draw_graphic(VGAState *s
   76.96      s->get_resolution(s, &width, &height);
   76.97      disp_width = width;
   76.98  
   76.99 -    ds_depth = s->ds->depth;
  76.100 -    depth = s->get_bpp(s);
  76.101 -    if (s->ds->dpy_colourdepth != NULL && 
  76.102 -            (ds_depth != depth || !s->ds->shared_buf))
  76.103 -        s->ds->dpy_colourdepth(s->ds, depth);
  76.104 -    if (ds_depth != s->ds->depth) full_update = 1;
  76.105 -
  76.106 -    s->rgb_to_pixel = 
  76.107 -        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
  76.108 -
  76.109      shift_control = (s->gr[0x05] >> 5) & 3;
  76.110      double_scan = (s->cr[0x09] >> 7);
  76.111      if (shift_control != 1) {
  76.112 @@ -1527,12 +1517,44 @@ static void vga_draw_graphic(VGAState *s
  76.113          s->shift_control = shift_control;
  76.114          s->double_scan = double_scan;
  76.115      }
  76.116 -    
  76.117 +    if (shift_control == 1 && (s->sr[0x01] & 8)) {
  76.118 +        disp_width <<= 1;
  76.119 +    }
  76.120 +
  76.121 +    ds_depth = s->ds->depth;
  76.122 +    depth = s->get_bpp(s);
  76.123 +    if (s->ds->dpy_resize_shared) {
  76.124 +        if (s->line_offset != s->last_line_offset || 
  76.125 +            disp_width != s->last_width ||
  76.126 +            height != s->last_height ||
  76.127 +            s->last_depth != depth) {
  76.128 +            dpy_resize_shared(s->ds, disp_width, height, depth, s->line_offset, s->vram_ptr + (s->start_addr * 4));
  76.129 +            s->last_scr_width = disp_width;
  76.130 +            s->last_scr_height = height;
  76.131 +            s->last_width = disp_width;
  76.132 +            s->last_height = height;
  76.133 +            s->last_line_offset = s->line_offset;
  76.134 +            s->last_depth = depth;
  76.135 +            full_update = 1;
  76.136 +        } else if (s->ds->shared_buf && (full_update || s->ds->data != s->vram_ptr + (s->start_addr * 4)))
  76.137 +            s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));
  76.138 +    } else if (disp_width != s->last_width ||
  76.139 +               height != s->last_height) {
  76.140 +        dpy_resize(s->ds, disp_width, height);
  76.141 +        s->last_scr_width = disp_width;
  76.142 +        s->last_scr_height = height;
  76.143 +        s->last_width = disp_width;
  76.144 +        s->last_height = height;
  76.145 +        full_update = 1;
  76.146 +    }
  76.147 +
  76.148 +    s->rgb_to_pixel = 
  76.149 +        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
  76.150 +
  76.151      if (shift_control == 0) {
  76.152          full_update |= update_palette16(s);
  76.153          if (s->sr[0x01] & 8) {
  76.154              v = VGA_DRAW_LINE4D2;
  76.155 -            disp_width <<= 1;
  76.156          } else {
  76.157              v = VGA_DRAW_LINE4;
  76.158          }
  76.159 @@ -1541,7 +1563,6 @@ static void vga_draw_graphic(VGAState *s
  76.160          full_update |= update_palette16(s);
  76.161          if (s->sr[0x01] & 8) {
  76.162              v = VGA_DRAW_LINE2D2;
  76.163 -            disp_width <<= 1;
  76.164          } else {
  76.165              v = VGA_DRAW_LINE2;
  76.166          }
  76.167 @@ -1579,19 +1600,6 @@ static void vga_draw_graphic(VGAState *s
  76.168      }
  76.169  
  76.170      vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];
  76.171 -    if (s->line_offset != s->last_line_offset || 
  76.172 -        disp_width != s->last_width ||
  76.173 -        height != s->last_height) {
  76.174 -        dpy_resize(s->ds, disp_width, height, s->line_offset);
  76.175 -        s->last_scr_width = disp_width;
  76.176 -        s->last_scr_height = height;
  76.177 -        s->last_width = disp_width;
  76.178 -        s->last_height = height;
  76.179 -        s->last_line_offset = s->line_offset; 
  76.180 -        full_update = 1;
  76.181 -    }
  76.182 -    if (s->ds->shared_buf && (full_update || s->ds->data != s->vram_ptr + (s->start_addr * 4)))
  76.183 -        s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));
  76.184      if (!s->ds->shared_buf && s->cursor_invalidate)
  76.185          s->cursor_invalidate(s);
  76.186      
  76.187 @@ -2144,6 +2152,11 @@ void vga_common_init(VGAState *s, Displa
  76.188      /* and page-aligned for PVFB memory sharing */
  76.189      s->vram_ptr = s->vram_alloc = qemu_memalign(TARGET_PAGE_SIZE, vga_ram_size);
  76.190  
  76.191 +#ifdef CONFIG_STUBDOM
  76.192 +    if (!cirrus_vga_enabled)
  76.193 +        xenfb_pv_display_start(s->vram_ptr);
  76.194 +#endif
  76.195 +
  76.196      s->vram_offset = vga_ram_offset;
  76.197      s->vram_size = vga_ram_size;
  76.198      s->ds = ds;
  76.199 @@ -2311,7 +2324,7 @@ static void vga_save_dpy_update(DisplayS
  76.200  {
  76.201  }
  76.202  
  76.203 -static void vga_save_dpy_resize(DisplayState *s, int w, int h, int linesize)
  76.204 +static void vga_save_dpy_resize(DisplayState *s, int w, int h)
  76.205  {
  76.206      s->linesize = w * 4;
  76.207      s->data = qemu_malloc(h * s->linesize);
    77.1 --- a/tools/ioemu/hw/vga_int.h	Tue Jun 10 16:00:33 2008 +0900
    77.2 +++ b/tools/ioemu/hw/vga_int.h	Thu Jun 19 12:46:26 2008 +0900
    77.3 @@ -135,6 +135,7 @@
    77.4      uint8_t last_cw, last_ch;                                           \
    77.5      uint32_t last_width, last_height; /* in chars or pixels */          \
    77.6      uint32_t last_scr_width, last_scr_height; /* in pixels */           \
    77.7 +    uint32_t last_depth; /* in bits */                                  \
    77.8      uint8_t cursor_start, cursor_end;                                   \
    77.9      uint32_t cursor_offset;                                             \
   77.10      unsigned int (*rgb_to_pixel)(unsigned int r,                        \
    78.1 --- a/tools/ioemu/hw/xenfb.c	Tue Jun 10 16:00:33 2008 +0900
    78.2 +++ b/tools/ioemu/hw/xenfb.c	Thu Jun 19 12:46:26 2008 +0900
    78.3 @@ -19,12 +19,6 @@
    78.4  
    78.5  #include "xenfb.h"
    78.6  
    78.7 -#ifdef CONFIG_STUBDOM
    78.8 -#include <semaphore.h>
    78.9 -#include <sched.h>
   78.10 -#include <fbfront.h>
   78.11 -#endif
   78.12 -
   78.13  #ifndef BTN_LEFT
   78.14  #define BTN_LEFT 0x110 /* from <linux/input.h> */
   78.15  #endif
   78.16 @@ -90,7 +84,7 @@ static int xenfb_register_console(struct
   78.17   * Scancodes are hardware-specific.  These maps assumes a 
   78.18   * standard AT or PS/2 keyboard which is what QEMU feeds us.
   78.19   */
   78.20 -static const unsigned char atkbd_set2_keycode[512] = {
   78.21 +const unsigned char atkbd_set2_keycode[512] = {
   78.22  
   78.23  	  0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
   78.24  	  0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
   78.25 @@ -112,7 +106,7 @@ static const unsigned char atkbd_set2_ke
   78.26  
   78.27  };
   78.28  
   78.29 -static const unsigned char atkbd_unxlate_table[128] = {
   78.30 +const unsigned char atkbd_unxlate_table[128] = {
   78.31  
   78.32  	  0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
   78.33  	 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
   78.34 @@ -587,10 +581,10 @@ static void xenfb_on_fb_event(struct xen
   78.35  					       event->resize.offset,
   78.36  					       event->resize.stride) < 0)
   78.37  				break;
   78.38 -			dpy_colourdepth(xenfb->ds, xenfb->depth);
   78.39 -			dpy_resize(xenfb->ds, xenfb->width, xenfb->height, xenfb->row_stride);
   78.40 -			if (xenfb->ds->shared_buf)
   78.41 -				dpy_setdata(xenfb->ds, xenfb->pixels + xenfb->offset);
   78.42 +			if (xenfb->ds->dpy_resize_shared)
   78.43 +			    dpy_resize_shared(xenfb->ds, xenfb->width, xenfb->height, xenfb->depth, xenfb->row_stride, xenfb->pixels + xenfb->offset);
   78.44 +			else
   78.45 +			    dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
   78.46  			xenfb_invalidate(xenfb);
   78.47  			break;
   78.48  		}
   78.49 @@ -1324,10 +1318,10 @@ static int xenfb_register_console(struct
   78.50  			     xenfb_invalidate,
   78.51  			     xenfb_screen_dump,
   78.52  			     xenfb);
   78.53 -	dpy_colourdepth(xenfb->ds, xenfb->depth);
   78.54 -        dpy_resize(xenfb->ds, xenfb->width, xenfb->height, xenfb->row_stride);
   78.55 -	if (xenfb->ds->shared_buf)
   78.56 -	    dpy_setdata(xenfb->ds, xenfb->pixels);
   78.57 +        if (xenfb->ds->dpy_resize_shared)
   78.58 +            dpy_resize_shared(xenfb->ds, xenfb->width, xenfb->height, xenfb->depth, xenfb->row_stride, xenfb->pixels + xenfb->offset);
   78.59 +        else
   78.60 +            dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
   78.61  
   78.62  	if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, xenfb_dispatch_channel, NULL, xenfb) < 0)
   78.63  	        return -1;
   78.64 @@ -1338,323 +1332,6 @@ static int xenfb_register_console(struct
   78.65          return 0;
   78.66  }
   78.67  
   78.68 -#ifdef CONFIG_STUBDOM
   78.69 -typedef struct XenFBState {
   78.70 -    struct semaphore kbd_sem;
   78.71 -    struct kbdfront_dev *kbd_dev;
   78.72 -    struct fbfront_dev *fb_dev;
   78.73 -    void *vga_vram, *nonshared_vram;
   78.74 -    DisplayState *ds;
   78.75 -} XenFBState;
   78.76 -
   78.77 -XenFBState *xs;
   78.78 -
   78.79 -static char *kbd_path, *fb_path;
   78.80 -
   78.81 -static unsigned char linux2scancode[KEY_MAX + 1];
   78.82 -
   78.83 -int xenfb_connect_vkbd(const char *path)
   78.84 -{
   78.85 -    kbd_path = strdup(path);
   78.86 -    return 0;
   78.87 -}
   78.88 -
   78.89 -int xenfb_connect_vfb(const char *path)
   78.90 -{
   78.91 -    fb_path = strdup(path);
   78.92 -    return 0;
   78.93 -}
   78.94 -
   78.95 -static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h)
   78.96 -{
   78.97 -    XenFBState *xs = ds->opaque;
   78.98 -    struct fbfront_dev *fb_dev = xs->fb_dev;
   78.99 -    if (!fb_dev)
  78.100 -        return;
  78.101 -    fbfront_update(fb_dev, x, y, w, h);
  78.102 -}
  78.103 -
  78.104 -static void xenfb_pv_resize(DisplayState *ds, int w, int h, int linesize)
  78.105 -{
  78.106 -    XenFBState *xs = ds->opaque;
  78.107 -    struct fbfront_dev *fb_dev = xs->fb_dev;
  78.108 -    fprintf(stderr,"resize to %dx%d, %d required\n", w, h, linesize);
  78.109 -    ds->width = w;
  78.110 -    ds->height = h;
  78.111 -    if (!linesize)
  78.112 -        ds->shared_buf = 0;
  78.113 -    if (!ds->shared_buf)
  78.114 -        linesize = w * 4;
  78.115 -    ds->linesize = linesize;
  78.116 -    if (!fb_dev)
  78.117 -        return;
  78.118 -    if (ds->shared_buf) {
  78.119 -        ds->data = NULL;
  78.120 -    } else {
  78.121 -        ds->data = xs->nonshared_vram;
  78.122 -        fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE);
  78.123 -    }
  78.124 -}
  78.125 -
  78.126 -static void xenfb_pv_colourdepth(DisplayState *ds, int depth)
  78.127 -{
  78.128 -    XenFBState *xs = ds->opaque;
  78.129 -    struct fbfront_dev *fb_dev = xs->fb_dev;
  78.130 -    static int lastdepth = -1;
  78.131 -    if (!depth) {
  78.132 -        ds->shared_buf = 0;
  78.133 -        ds->depth = 32;
  78.134 -    } else {
  78.135 -        ds->shared_buf = 1;
  78.136 -        ds->depth = depth;
  78.137 -    }
  78.138 -    if (depth != lastdepth) {
  78.139 -        fprintf(stderr,"redepth to %d required\n", depth);
  78.140 -        lastdepth = depth;
  78.141 -    } else return;
  78.142 -    if (!fb_dev)
  78.143 -        return;
  78.144 -    if (ds->shared_buf) {
  78.145 -        ds->data = NULL;
  78.146 -    } else {
  78.147 -        ds->data = xs->nonshared_vram;
  78.148 -        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, VGA_RAM_SIZE);
  78.149 -    }
  78.150 -}
  78.151 -
  78.152 -static void xenfb_pv_setdata(DisplayState *ds, void *pixels)
  78.153 -{
  78.154 -    XenFBState *xs = ds->opaque;
  78.155 -    struct fbfront_dev *fb_dev = xs->fb_dev;
  78.156 -    int offset = pixels - xs->vga_vram;
  78.157 -    ds->data = pixels;
  78.158 -    if (!fb_dev)
  78.159 -        return;
  78.160 -    fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
  78.161 -}
  78.162 -
  78.163 -static void xenfb_pv_refresh(DisplayState *ds)
  78.164 -{
  78.165 -    vga_hw_update();
  78.166 -}
  78.167 -
  78.168 -static void xenfb_fb_handler(void *opaque)
  78.169 -{
  78.170 -#define FB_NUM_BATCH 4
  78.171 -    union xenfb_in_event buf[FB_NUM_BATCH];
  78.172 -    int n, i;
  78.173 -    XenFBState *xs = opaque;
  78.174 -    DisplayState *ds = xs->ds;
  78.175 -
  78.176 -    n = fbfront_receive(xs->fb_dev, buf, FB_NUM_BATCH);
  78.177 -    for (i = 0; i < n; i++) {
  78.178 -        switch (buf[i].type) {
  78.179 -        case XENFB_TYPE_REFRESH_PERIOD:
  78.180 -            if (buf[i].refresh_period.period == XENFB_NO_REFRESH) {
  78.181 -                /* Sleeping interval */
  78.182 -                ds->idle = 1;
  78.183 -                ds->gui_timer_interval = 500;
  78.184 -            } else {
  78.185 -                /* Set interval */
  78.186 -                ds->idle = 0;
  78.187 -                ds->gui_timer_interval = buf[i].refresh_period.period;
  78.188 -            }
  78.189 -        default:
  78.190 -            /* ignore unknown events */
  78.191 -            break;
  78.192 -        }
  78.193 -    }
  78.194 -}
  78.195 -
  78.196 -static void xenfb_kbd_handler(void *opaque)
  78.197 -{
  78.198 -#define KBD_NUM_BATCH 64
  78.199 -    union xenkbd_in_event buf[KBD_NUM_BATCH];
  78.200 -    int n, i;
  78.201 -    XenFBState *xs = opaque;
  78.202 -    DisplayState *s = xs->ds;
  78.203 -    static int buttons;
  78.204 -    static int x, y;
  78.205 -
  78.206 -    n = kbdfront_receive(xs->kbd_dev, buf, KBD_NUM_BATCH);
  78.207 -    for (i = 0; i < n; i++) {
  78.208 -        switch (buf[i].type) {
  78.209 -
  78.210 -            case XENKBD_TYPE_MOTION:
  78.211 -                fprintf(stderr, "FB backend sent us relative mouse motion event!\n");
  78.212 -                break;
  78.213 -
  78.214 -            case XENKBD_TYPE_POS:
  78.215 -            {
  78.216 -                int new_x = buf[i].pos.abs_x;
  78.217 -                int new_y = buf[i].pos.abs_y;
  78.218 -                if (new_x >= s->width)
  78.219 -                    new_x = s->width - 1;
  78.220 -                if (new_y >= s->height)
  78.221 -                    new_y = s->height - 1;
  78.222 -                if (kbd_mouse_is_absolute()) {
  78.223 -                    kbd_mouse_event(
  78.224 -                            new_x * 0x7FFF / (s->width - 1),
  78.225 -                            new_y * 0x7FFF / (s->height - 1),
  78.226 -                            buf[i].pos.rel_z,
  78.227 -                            buttons);
  78.228 -                } else {
  78.229 -                    kbd_mouse_event(
  78.230 -                            new_x - x,
  78.231 -                            new_y - y,
  78.232 -                            buf[i].pos.rel_z,
  78.233 -                            buttons);
  78.234 -                }
  78.235 -                x = new_x;
  78.236 -                y = new_y;
  78.237 -                break;
  78.238 -            }
  78.239 -
  78.240 -            case XENKBD_TYPE_KEY:
  78.241 -            {
  78.242 -                int keycode = buf[i].key.keycode;
  78.243 -                int button = 0;
  78.244 -
  78.245 -                if (keycode == BTN_LEFT)
  78.246 -                    button = MOUSE_EVENT_LBUTTON;
  78.247 -                else if (keycode == BTN_RIGHT)
  78.248 -                    button = MOUSE_EVENT_RBUTTON;
  78.249 -                else if (keycode == BTN_MIDDLE)
  78.250 -                    button = MOUSE_EVENT_MBUTTON;
  78.251 -
  78.252 -                if (button) {
  78.253 -                    if (buf[i].key.pressed)
  78.254 -                        buttons |=  button;
  78.255 -                    else
  78.256 -                        buttons &= ~button;
  78.257 -                    if (kbd_mouse_is_absolute())
  78.258 -                        kbd_mouse_event(
  78.259 -                                x * 0x7FFF / (s->width - 1),
  78.260 -                                y * 0x7FFF / (s->height - 1),
  78.261 -                                0,
  78.262 -                                buttons);
  78.263 -                    else
  78.264 -                        kbd_mouse_event(0, 0, 0, buttons);
  78.265 -                } else {
  78.266 -                    int scancode = linux2scancode[keycode];
  78.267 -                    if (!scancode) {
  78.268 -                        fprintf(stderr, "Can't convert keycode %x to scancode\n", keycode);
  78.269 -                        break;
  78.270 -                    }
  78.271 -                    if (scancode & 0x80) {
  78.272 -                        kbd_put_keycode(0xe0);
  78.273 -                        scancode &= 0x7f;
  78.274 -                    }
  78.275 -                    if (!buf[i].key.pressed)
  78.276 -                        scancode |= 0x80;
  78.277 -                    kbd_put_keycode(scancode);
  78.278 -                }
  78.279 -                break;
  78.280 -            }
  78.281 -        }
  78.282 -    }
  78.283 -}
  78.284 -
  78.285 -static void kbdfront_thread(void *p)
  78.286 -{
  78.287 -    int scancode, keycode;
  78.288 -    XenFBState *xs = p;
  78.289 -    xs->kbd_dev = init_kbdfront(kbd_path, 1);
  78.290 -    if (!xs->kbd_dev) {
  78.291 -        fprintf(stderr,"can't open keyboard\n");
  78.292 -        exit(1);
  78.293 -    }
  78.294 -    up(&xs->kbd_sem);
  78.295 -    for (scancode = 0; scancode < 128; scancode++) {
  78.296 -        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode]];
  78.297 -        linux2scancode[keycode] = scancode;
  78.298 -        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode] | 0x80];
  78.299 -        linux2scancode[keycode] = scancode | 0x80;
  78.300 -    }
  78.301 -}
  78.302 -
  78.303 -int xenfb_pv_display_init(DisplayState *ds)
  78.304 -{
  78.305 -    if (!fb_path || !kbd_path)
  78.306 -        return -1;
  78.307 -
  78.308 -    xs = qemu_mallocz(sizeof(XenFBState));
  78.309 -    if (!xs)
  78.310 -        return -1;
  78.311 -
  78.312 -    init_SEMAPHORE(&xs->kbd_sem, 0);
  78.313 -    xs->ds = ds;
  78.314 -
  78.315 -    create_thread("kbdfront", kbdfront_thread, (void*) xs);
  78.316 -
  78.317 -    ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE);
  78.318 -    memset(ds->data, 0, VGA_RAM_SIZE);
  78.319 -    ds->opaque = xs;
  78.320 -    ds->depth = 32;
  78.321 -    ds->bgr = 0;
  78.322 -    ds->width = 640;
  78.323 -    ds->height = 400;
  78.324 -    ds->linesize = 640 * 4;
  78.325 -    ds->dpy_update = xenfb_pv_update;
  78.326 -    ds->dpy_resize = xenfb_pv_resize;
  78.327 -    ds->dpy_colourdepth = xenfb_pv_colourdepth;
  78.328 -    ds->dpy_setdata = xenfb_pv_setdata;
  78.329 -    ds->dpy_refresh = xenfb_pv_refresh;
  78.330 -    return 0;
  78.331 -}
  78.332 -
  78.333 -int xenfb_pv_display_start(void *data)
  78.334 -{
  78.335 -    DisplayState *ds;
  78.336 -    struct fbfront_dev *fb_dev;
  78.337 -    int kbd_fd, fb_fd;
  78.338 -    int offset = 0;
  78.339 -    unsigned long *mfns;
  78.340 -    int n = VGA_RAM_SIZE / PAGE_SIZE;
  78.341 -    int i;
  78.342 -
  78.343 -    if (!fb_path || !kbd_path)
  78.344 -        return 0;
  78.345 -
  78.346 -    ds = xs->ds;
  78.347 -    xs->vga_vram = data;
  78.348 -    mfns = malloc(2 * n * sizeof(*mfns));
  78.349 -    for (i = 0; i < n; i++)
  78.350 -        mfns[i] = virtual_to_mfn(xs->vga_vram + i * PAGE_SIZE);
  78.351 -    for (i = 0; i < n; i++)
  78.352 -        mfns[n + i] = virtual_to_mfn(xs->nonshared_vram + i * PAGE_SIZE);
  78.353 -
  78.354 -    fb_dev = init_fbfront(fb_path, mfns, ds->width, ds->height, ds->depth, ds->linesize, 2 * n);
  78.355 -    free(mfns);
  78.356 -    if (!fb_dev) {
  78.357 -        fprintf(stderr,"can't open frame buffer\n");
  78.358 -        exit(1);
  78.359 -    }
  78.360 -    free(fb_path);
  78.361 -
  78.362 -    if (ds->shared_buf) {
  78.363 -        offset = (void*) ds->data - xs->vga_vram;
  78.364 -    } else {
  78.365 -        offset = VGA_RAM_SIZE;
  78.366 -        ds->data = xs->nonshared_vram;
  78.367 -    }
  78.368 -    if (offset)
  78.369 -        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
  78.370 -
  78.371 -    down(&xs->kbd_sem);
  78.372 -    free(kbd_path);
  78.373 -
  78.374 -    kbd_fd = kbdfront_open(xs->kbd_dev);
  78.375 -    qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, xs);
  78.376 -
  78.377 -    fb_fd = fbfront_open(fb_dev);
  78.378 -    qemu_set_fd_handler(fb_fd, xenfb_fb_handler, NULL, xs);
  78.379 -
  78.380 -    xs->fb_dev = fb_dev;
  78.381 -    return 0;
  78.382 -}
  78.383 -#endif
  78.384 -
  78.385  /*
  78.386   * Local variables:
  78.387   *  c-indent-level: 8
    79.1 --- a/tools/ioemu/hw/xenfb.h	Tue Jun 10 16:00:33 2008 +0900
    79.2 +++ b/tools/ioemu/hw/xenfb.h	Thu Jun 19 12:46:26 2008 +0900
    79.3 @@ -9,5 +9,7 @@ struct xenfb;
    79.4  
    79.5  struct xenfb *xenfb_new(int domid, DisplayState *ds);
    79.6  void xenfb_shutdown(struct xenfb *xenfb);
    79.7 +extern const unsigned char atkbd_set2_keycode[512];
    79.8 +extern const unsigned char atkbd_unxlate_table[128];
    79.9  
   79.10  #endif
    80.1 --- a/tools/ioemu/monitor.c	Tue Jun 10 16:00:33 2008 +0900
    80.2 +++ b/tools/ioemu/monitor.c	Thu Jun 19 12:46:26 2008 +0900
    80.3 @@ -387,7 +387,7 @@ static void do_change_block(const char *
    80.4      }
    80.5      if (eject_device(bs, 0) < 0)
    80.6          return;
    80.7 -    bdrv_open(bs, filename, 0);
    80.8 +    bdrv_open2(bs, filename, 0, &bdrv_raw);
    80.9      if (bdrv_is_encrypted(bs)) {
   80.10          term_printf("%s is encrypted.\n", device);
   80.11          for(i = 0; i < 3; i++) {
    81.1 --- a/tools/ioemu/sdl.c	Tue Jun 10 16:00:33 2008 +0900
    81.2 +++ b/tools/ioemu/sdl.c	Thu Jun 19 12:46:26 2008 +0900
    81.3 @@ -50,6 +50,8 @@ static SDL_Cursor *sdl_cursor_hidden;
    81.4  static int absolute_enabled = 0;
    81.5  static int opengl_enabled;
    81.6  
    81.7 +static void sdl_colourdepth(DisplayState *ds, int depth);
    81.8 +
    81.9  #ifdef CONFIG_OPENGL
   81.10  static GLint tex_format;
   81.11  static GLint tex_type;
   81.12 @@ -211,12 +213,14 @@ static void sdl_setdata(DisplayState *ds
   81.13      ds->data = pixels;
   81.14  }
   81.15  
   81.16 -static void sdl_resize(DisplayState *ds, int w, int h, int linesize)
   81.17 +static void sdl_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
   81.18  {
   81.19      int flags;
   81.20  
   81.21      //    printf("resizing to %d %d\n", w, h);
   81.22  
   81.23 +    sdl_colourdepth(ds, depth);
   81.24 +
   81.25  #ifdef CONFIG_OPENGL
   81.26      if (ds->shared_buf && opengl_enabled)
   81.27          flags = SDL_OPENGL|SDL_RESIZABLE;
   81.28 @@ -245,7 +249,8 @@ static void sdl_resize(DisplayState *ds,
   81.29              opengl_enabled = 0;
   81.30              ds->dpy_update = sdl_update;
   81.31              ds->dpy_setdata = sdl_setdata;
   81.32 -            sdl_resize(ds, w, h, linesize);
   81.33 +            ds->dpy_resize_shared = sdl_resize_shared;
   81.34 +            sdl_resize_shared(ds, w, h, depth, linesize, pixels);
   81.35              return;
   81.36          }
   81.37          exit(1);
   81.38 @@ -272,6 +277,7 @@ static void sdl_resize(DisplayState *ds,
   81.39          } else {
   81.40              ds->bgr = 0;
   81.41          }
   81.42 +        shared = NULL;
   81.43          ds->data = screen->pixels;
   81.44          ds->linesize = screen->pitch;
   81.45      } else {
   81.46 @@ -296,21 +302,26 @@ static void sdl_resize(DisplayState *ds,
   81.47          };
   81.48  #endif
   81.49      }
   81.50 +    if (ds->shared_buf) ds->dpy_setdata(ds, pixels);
   81.51 +}
   81.52 +
   81.53 +static void sdl_resize(DisplayState *ds, int w, int h)
   81.54 +{
   81.55 +    sdl_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL);
   81.56  }
   81.57  
   81.58  static void sdl_colourdepth(DisplayState *ds, int depth)
   81.59  {
   81.60      if (!depth || !ds->depth) {
   81.61          ds->shared_buf = 0;
   81.62 +        ds->dpy_update = sdl_update;
   81.63          return;
   81.64      }
   81.65      ds->shared_buf = 1;
   81.66      ds->depth = depth;
   81.67 -    ds->linesize = width * depth / 8;
   81.68  #ifdef CONFIG_OPENGL
   81.69      if (opengl_enabled) {
   81.70          ds->dpy_update = opengl_update;
   81.71 -        ds->dpy_setdata = opengl_setdata;
   81.72      }
   81.73  #endif
   81.74  }
   81.75 @@ -517,8 +528,7 @@ static void sdl_send_mouse_event(int dx,
   81.76  static void toggle_full_screen(DisplayState *ds)
   81.77  {
   81.78      gui_fullscreen = !gui_fullscreen;
   81.79 -    sdl_resize(ds, ds->width, ds->height, ds->linesize);
   81.80 -    ds->dpy_setdata(ds, ds->data);
   81.81 +    sdl_resize_shared(ds, ds->width, ds->height, ds->depth, ds->linesize, ds->data);
   81.82      if (gui_fullscreen) {
   81.83          gui_saved_grab = gui_grab;
   81.84          sdl_grab_start();
   81.85 @@ -760,11 +770,16 @@ void sdl_display_init(DisplayState *ds, 
   81.86  
   81.87      ds->dpy_update = sdl_update;
   81.88      ds->dpy_resize = sdl_resize;
   81.89 +    ds->dpy_resize_shared = sdl_resize_shared;
   81.90      ds->dpy_refresh = sdl_refresh;
   81.91 -    ds->dpy_colourdepth = sdl_colourdepth;
   81.92 -    ds->dpy_setdata = sdl_setdata;
   81.93 +#ifdef CONFIG_OPENGL
   81.94 +    if (opengl_enabled)
   81.95 +        ds->dpy_setdata = opengl_setdata;
   81.96 +    else
   81.97 +        ds->dpy_setdata = sdl_setdata;
   81.98 +#endif
   81.99  
  81.100 -    sdl_resize(ds, 640, 400, 640 * 4);
  81.101 +    sdl_resize(ds, 640, 400);
  81.102      sdl_update_caption();
  81.103      SDL_EnableKeyRepeat(250, 50);
  81.104      SDL_EnableUNICODE(1);
    82.1 --- a/tools/ioemu/vl.c	Tue Jun 10 16:00:33 2008 +0900
    82.2 +++ b/tools/ioemu/vl.c	Thu Jun 19 12:46:26 2008 +0900
    82.3 @@ -137,6 +137,9 @@
    82.4  /* XXX: use a two level table to limit memory usage */
    82.5  #define MAX_IOPORTS 65536
    82.6  
    82.7 +/* Max number of PCI emulation */
    82.8 +#define MAX_PCI_EMULATION 32
    82.9 +
   82.10  const char *bios_dir = CONFIG_QEMU_SHAREDIR;
   82.11  void *ioport_opaque[MAX_IOPORTS];
   82.12  IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
   82.13 @@ -212,6 +215,8 @@ int xc_handle;
   82.14  char domain_name[64] = "Xen-no-name";
   82.15  extern int domid;
   82.16  
   82.17 +PCI_EMULATION_INFO *PciEmulationInfoHead = NULL;
   82.18 +
   82.19  /***********************************************************/
   82.20  /* x86 ISA bus support */
   82.21  
   82.22 @@ -4260,7 +4265,9 @@ static int usb_device_add(const char *de
   82.23      } else if (!strcmp(devname, "tablet")) {
   82.24  	dev = usb_tablet_init();
   82.25      } else if (strstart(devname, "disk:", &p)) {
   82.26 -        dev = usb_msd_init(p);
   82.27 +        dev = usb_msd_init(p, &bdrv_raw);
   82.28 +    } else if (strstart(devname, "disk-qcow:", &p)) {
   82.29 +        dev = usb_msd_init(p, 0);
   82.30      } else {
   82.31          return -1;
   82.32      }
   82.33 @@ -4399,6 +4406,17 @@ void do_pci_add(char *devname)
   82.34  #endif
   82.35  }
   82.36  
   82.37 +static int pci_emulation_add(char *config_text)
   82.38 +{
   82.39 +    PCI_EMULATION_INFO *new;
   82.40 +    if ((new = qemu_mallocz(sizeof(PCI_EMULATION_INFO))) == NULL) {
   82.41 +        return -1;
   82.42 +    }
   82.43 +    parse_pci_emulation_info(config_text, new);
   82.44 +    new->next = PciEmulationInfoHead;
   82.45 +    PciEmulationInfoHead = new;
   82.46 +    return 0;
   82.47 +}
   82.48  
   82.49  /***********************************************************/
   82.50  /* pid file */
   82.51 @@ -4463,7 +4481,6 @@ void dumb_display_init(DisplayState *ds)
   82.52      ds->depth = 0;
   82.53      ds->dpy_update = dumb_update;
   82.54      ds->dpy_resize = dumb_resize;
   82.55 -    ds->dpy_colourdepth = NULL;
   82.56      ds->dpy_refresh = dumb_refresh;
   82.57      ds->gui_timer_interval = 500;
   82.58      ds->idle = 1;
   82.59 @@ -6591,6 +6608,7 @@ void help(void)
   82.60  #endif
   82.61  	   "-option-rom rom load a file, rom, into the option ROM space\n"
   82.62             "-acpi           disable or enable ACPI of HVM domain \n"
   82.63 +           "-pciemulation       name:vendorid:deviceid:command:status:revision:classcode:headertype:subvendorid:subsystemid:interruputline:interruputpin\n"
   82.64             "\n"
   82.65             "During emulation, the following keys are useful:\n"
   82.66             "ctrl-alt-f      toggle full screen\n"
   82.67 @@ -6689,6 +6707,7 @@ enum {
   82.68      QEMU_OPTION_vncviewer,
   82.69      QEMU_OPTION_vncunused,
   82.70      QEMU_OPTION_pci,
   82.71 +    QEMU_OPTION_pci_emulation,
   82.72  };
   82.73  
   82.74  typedef struct QEMUOption {
   82.75 @@ -6790,6 +6809,7 @@ const QEMUOption qemu_options[] = {
   82.76      { "vcpus", 1, QEMU_OPTION_vcpus },
   82.77      { "acpi", 0, QEMU_OPTION_acpi },
   82.78      { "pci", HAS_ARG, QEMU_OPTION_pci},
   82.79 +    { "pciemulation", HAS_ARG, QEMU_OPTION_pci_emulation },
   82.80      { NULL },
   82.81  };
   82.82  
   82.83 @@ -7074,6 +7094,8 @@ int main(int argc, char **argv)
   82.84      sigset_t set;
   82.85      char qemu_dm_logfilename[128];
   82.86      const char *direct_pci = direct_pci_str;
   82.87 +    int nb_pci_emulation = 0;
   82.88 +    char pci_emulation_config_text[MAX_PCI_EMULATION][256];
   82.89  
   82.90  #if !defined(__sun__) && !defined(CONFIG_STUBDOM)
   82.91      /* Maximise rlimits. Needed where default constraints are tight (*BSD). */
   82.92 @@ -7599,6 +7621,16 @@ int main(int argc, char **argv)
   82.93              case QEMU_OPTION_vncunused:
   82.94                  vncunused++;
   82.95                  break;
   82.96 +            case QEMU_OPTION_pci_emulation:
   82.97 +                if (nb_pci_emulation >= MAX_PCI_EMULATION) {
   82.98 +                    fprintf(stderr, "Too many PCI emulations\n");
   82.99 +                    exit(1);
  82.100 +                }
  82.101 +                pstrcpy(pci_emulation_config_text[nb_pci_emulation],
  82.102 +                        sizeof(pci_emulation_config_text[0]),
  82.103 +                        optarg);
  82.104 +                nb_pci_emulation++;
  82.105 +                break;
  82.106              }
  82.107          }
  82.108      }
  82.109 @@ -7898,6 +7930,13 @@ int main(int argc, char **argv)
  82.110          }
  82.111      }
  82.112  
  82.113 +    for (i = 0; i < nb_pci_emulation; i++) {
  82.114 +        if(pci_emulation_add(pci_emulation_config_text[i]) < 0) {
  82.115 +            fprintf(stderr, "Warning: could not add PCI device %s\n",
  82.116 +                    pci_emulation_config_text[i]);
  82.117 +        }
  82.118 +    }
  82.119 +
  82.120      qemu_set_fd_handler(xenstore_fd(), xenstore_process_event, NULL, NULL);
  82.121  
  82.122      machine->init(ram_size, vga_ram_size, boot_device,
    83.1 --- a/tools/ioemu/vl.h	Tue Jun 10 16:00:33 2008 +0900
    83.2 +++ b/tools/ioemu/vl.h	Thu Jun 19 12:46:26 2008 +0900
    83.3 @@ -945,9 +945,9 @@ struct DisplayState {
    83.4      int shared_buf;
    83.5      
    83.6      void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
    83.7 -    void (*dpy_resize)(struct DisplayState *s, int w, int h, int linesize);
    83.8 -    void (*dpy_colourdepth)(struct DisplayState *s, int depth);
    83.9 +    void (*dpy_resize)(struct DisplayState *s, int w, int h);
   83.10      void (*dpy_setdata)(DisplayState *s, void *pixels);
   83.11 +    void (*dpy_resize_shared)(DisplayState *s, int w, int h, int depth, int linesize, void *pixels);
   83.12      void (*dpy_refresh)(struct DisplayState *s);
   83.13      void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y, int dst_x, int dst_y, int w, int h);
   83.14  };
   83.15 @@ -957,14 +957,14 @@ static inline void dpy_update(DisplaySta
   83.16      s->dpy_update(s, x, y, w, h);
   83.17  }
   83.18  
   83.19 -static inline void dpy_resize(DisplayState *s, int w, int h, int linesize)
   83.20 +static inline void dpy_resize(DisplayState *s, int w, int h)
   83.21  {
   83.22 -    s->dpy_resize(s, w, h, linesize);
   83.23 +    s->dpy_resize(s, w, h);
   83.24  }
   83.25  
   83.26 -static inline void dpy_colourdepth(struct DisplayState *s, int depth)
   83.27 +static inline void dpy_resize_shared(DisplayState *s, int w, int h, int depth, int linesize, void *pixels)
   83.28  {
   83.29 -    s->dpy_colourdepth(s, depth);
   83.30 +    s->dpy_resize_shared(s, w, h, depth, linesize, pixels);
   83.31  }
   83.32  
   83.33  static inline void dpy_setdata(DisplayState *s, void *pixels)
   83.34 @@ -1560,6 +1560,10 @@ void timeoffset_get(void);
   83.35  void pci_xen_platform_init(PCIBus *bus);
   83.36  #endif
   83.37  
   83.38 +/* pci_emulation.c */
   83.39 +#ifndef QEMU_TOOL
   83.40 +#include "hw/pci_emulation.h"
   83.41 +#endif
   83.42  
   83.43  void kqemu_record_dump(void);
   83.44  
    84.1 --- a/tools/ioemu/vnc.c	Tue Jun 10 16:00:33 2008 +0900
    84.2 +++ b/tools/ioemu/vnc.c	Thu Jun 19 12:46:26 2008 +0900
    84.3 @@ -277,6 +277,7 @@ static void enqueue_framebuffer_update(V
    84.4  static void dequeue_framebuffer_update(VncState *vs);
    84.5  static int is_empty_queue(VncState *vs);
    84.6  static void free_queue(VncState *vs);
    84.7 +static void vnc_colourdepth(DisplayState *ds, int depth);
    84.8  
    84.9  #if 0
   84.10  static inline void vnc_set_bit(uint32_t *d, int k)
   84.11 @@ -363,13 +364,14 @@ static void vnc_framebuffer_update(VncSt
   84.12      vnc_write_s32(vs, encoding);
   84.13  }
   84.14  
   84.15 -static void vnc_dpy_resize(DisplayState *ds, int w, int h, int linesize)
   84.16 +static void vnc_dpy_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
   84.17  {
   84.18      static int allocated;
   84.19      int size_changed;
   84.20      VncState *vs = ds->opaque;
   84.21      int o;
   84.22  
   84.23 +    vnc_colourdepth(ds, depth);
   84.24      if (!ds->shared_buf) {
   84.25          ds->linesize = w * vs->depth;
   84.26          if (allocated)
   84.27 @@ -419,6 +421,12 @@ static void vnc_dpy_resize(DisplayState 
   84.28      for (o = DIRTY_PIXEL_BITS; o < ds->width; o *= 2)
   84.29  	vs->dirty_pixel_shift++;
   84.30      framebuffer_set_updated(vs, 0, 0, ds->width, ds->height);
   84.31 +    if (ds->shared_buf) ds->data = pixels;
   84.32 +}
   84.33 +
   84.34 +static void vnc_dpy_resize(DisplayState *ds, int w, int h)
   84.35 +{
   84.36 +    vnc_dpy_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL);
   84.37  }
   84.38  
   84.39  /* fastest code */
   84.40 @@ -1640,7 +1648,7 @@ static void vnc_dpy_setdata(DisplayState
   84.41      ds->data = pixels;
   84.42  }
   84.43  
   84.44 -static void vnc_dpy_colourdepth(DisplayState *ds, int depth)
   84.45 +static void vnc_colourdepth(DisplayState *ds, int depth)
   84.46  {
   84.47      int host_big_endian_flag;
   84.48      struct VncState *vs = ds->opaque;
   84.49 @@ -1742,8 +1750,6 @@ static void vnc_dpy_colourdepth(DisplayS
   84.50              vs->write_pixels = vnc_write_pixels_generic;
   84.51          }
   84.52      }
   84.53 -
   84.54 -    vnc_dpy_resize(ds, ds->width, ds->height, ds->linesize);
   84.55  }
   84.56  
   84.57  static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
   84.58 @@ -2502,14 +2508,14 @@ void vnc_display_init(DisplayState *ds)
   84.59      vs->ds->data = NULL;
   84.60      vs->ds->dpy_update = vnc_dpy_update;
   84.61      vs->ds->dpy_resize = vnc_dpy_resize;
   84.62 -    vs->ds->dpy_colourdepth = vnc_dpy_colourdepth;
   84.63      vs->ds->dpy_setdata = vnc_dpy_setdata;
   84.64 +    vs->ds->dpy_resize_shared = vnc_dpy_resize_shared;
   84.65      vs->ds->dpy_refresh = vnc_dpy_refresh;
   84.66  
   84.67      vs->ds->width = 640;
   84.68      vs->ds->height = 400;
   84.69      vs->ds->linesize = 640 * 4;
   84.70 -    vnc_dpy_colourdepth(vs->ds, 24);
   84.71 +    vnc_dpy_resize_shared(ds, ds->width, ds->height, 24, ds->linesize, NULL);
   84.72  }
   84.73  
   84.74  #if CONFIG_VNC_TLS
    85.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.2 +++ b/tools/ioemu/xenfbfront.c	Thu Jun 19 12:46:26 2008 +0900
    85.3 @@ -0,0 +1,315 @@
    85.4 +#include <stdint.h>
    85.5 +#include <xen/io/fbif.h>
    85.6 +#include <xen/io/kbdif.h>
    85.7 +#include <semaphore.h>
    85.8 +#include <sched.h>
    85.9 +#include <fbfront.h>
   85.10 +
   85.11 +#include <hw/xenfb.h>
   85.12 +
   85.13 +#include "vl.h"
   85.14 +
   85.15 +typedef struct XenFBState {
   85.16 +    struct semaphore kbd_sem;
   85.17 +    struct kbdfront_dev *kbd_dev;
   85.18 +    struct fbfront_dev *fb_dev;
   85.19 +    void *vga_vram, *nonshared_vram;
   85.20 +    DisplayState *ds;
   85.21 +} XenFBState;
   85.22 +
   85.23 +XenFBState *xs;
   85.24 +
   85.25 +static char *kbd_path, *fb_path;
   85.26 +
   85.27 +static unsigned char linux2scancode[KEY_MAX + 1];
   85.28 +
   85.29 +int xenfb_connect_vkbd(const char *path)
   85.30 +{
   85.31 +    kbd_path = strdup(path);
   85.32 +    return 0;
   85.33 +}
   85.34 +
   85.35 +int xenfb_connect_vfb(const char *path)
   85.36 +{
   85.37 +    fb_path = strdup(path);
   85.38 +    return 0;
   85.39 +}
   85.40 +
   85.41 +static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h)
   85.42 +{
   85.43 +    XenFBState *xs = ds->opaque;
   85.44 +    struct fbfront_dev *fb_dev = xs->fb_dev;
   85.45 +    if (!fb_dev)
   85.46 +        return;
   85.47 +    fbfront_update(fb_dev, x, y, w, h);
   85.48 +}
   85.49 +
   85.50 +static void xenfb_pv_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels)
   85.51 +{
   85.52 +    XenFBState *xs = ds->opaque;
   85.53 +    struct fbfront_dev *fb_dev = xs->fb_dev;
   85.54 +    int offset;
   85.55 +
   85.56 +    fprintf(stderr,"resize to %dx%d@%d, %d required\n", w, h, depth, linesize);
   85.57 +    ds->width = w;
   85.58 +    ds->height = h;
   85.59 +    if (!depth) {
   85.60 +        ds->shared_buf = 0;
   85.61 +        ds->depth = 32;
   85.62 +    } else {
   85.63 +        ds->shared_buf = 1;
   85.64 +        ds->depth = depth;
   85.65 +    }
   85.66 +    if (!linesize)
   85.67 +        ds->shared_buf = 0;
   85.68 +    if (!ds->shared_buf)
   85.69 +        linesize = w * 4;
   85.70 +    ds->linesize = linesize;
   85.71 +    if (!fb_dev)
   85.72 +        return;
   85.73 +    if (ds->shared_buf) {
   85.74 +        offset = pixels - xs->vga_vram;
   85.75 +        ds->data = pixels;
   85.76 +        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
   85.77 +    } else {
   85.78 +        ds->data = xs->nonshared_vram;
   85.79 +        fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE);
   85.80 +    }
   85.81 +}
   85.82 +
   85.83 +static void xenfb_pv_resize(DisplayState *ds, int w, int h)
   85.84 +{
   85.85 +    xenfb_pv_resize_shared(ds, w, h, 0, 0, NULL);
   85.86 +}
   85.87 +
   85.88 +static void xenfb_pv_setdata(DisplayState *ds, void *pixels)
   85.89 +{
   85.90 +    XenFBState *xs = ds->opaque;
   85.91 +    struct fbfront_dev *fb_dev = xs->fb_dev;
   85.92 +    int offset = pixels - xs->vga_vram;
   85.93 +    ds->data = pixels;
   85.94 +    if (!fb_dev)
   85.95 +        return;
   85.96 +    fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
   85.97 +}
   85.98 +
   85.99 +static void xenfb_pv_refresh(DisplayState *ds)
  85.100 +{
  85.101 +    vga_hw_update();
  85.102 +}
  85.103 +
  85.104 +static void xenfb_fb_handler(void *opaque)
  85.105 +{
  85.106 +#define FB_NUM_BATCH 4
  85.107 +    union xenfb_in_event buf[FB_NUM_BATCH];
  85.108 +    int n, i;
  85.109 +    XenFBState *xs = opaque;
  85.110 +    DisplayState *ds = xs->ds;
  85.111 +
  85.112 +    n = fbfront_receive(xs->fb_dev, buf, FB_NUM_BATCH);
  85.113 +    for (i = 0; i < n; i++) {
  85.114 +        switch (buf[i].type) {
  85.115 +        case XENFB_TYPE_REFRESH_PERIOD:
  85.116 +            if (buf[i].refresh_period.period == XENFB_NO_REFRESH) {
  85.117 +                /* Sleeping interval */
  85.118 +                ds->idle = 1;
  85.119 +                ds->gui_timer_interval = 500;
  85.120 +            } else {
  85.121 +                /* Set interval */
  85.122 +                ds->idle = 0;
  85.123 +                ds->gui_timer_interval = buf[i].refresh_period.period;
  85.124 +            }
  85.125 +        default:
  85.126 +            /* ignore unknown events */
  85.127 +            break;
  85.128 +        }
  85.129 +    }
  85.130 +}
  85.131 +
  85.132 +static void xenfb_kbd_handler(void *opaque)
  85.133 +{
  85.134 +#define KBD_NUM_BATCH 64
  85.135 +    union xenkbd_in_event buf[KBD_NUM_BATCH];
  85.136 +    int n, i;
  85.137 +    XenFBState *xs = opaque;
  85.138 +    DisplayState *s = xs->ds;
  85.139 +    static int buttons;
  85.140 +    static int x, y;
  85.141 +
  85.142 +    n = kbdfront_receive(xs->kbd_dev, buf, KBD_NUM_BATCH);
  85.143 +    for (i = 0; i < n; i++) {
  85.144 +        switch (buf[i].type) {
  85.145 +
  85.146 +            case XENKBD_TYPE_MOTION:
  85.147 +                fprintf(stderr, "FB backend sent us relative mouse motion event!\n");
  85.148 +                break;
  85.149 +
  85.150 +            case XENKBD_TYPE_POS:
  85.151 +            {
  85.152 +                int new_x = buf[i].pos.abs_x;
  85.153 +                int new_y = buf[i].pos.abs_y;
  85.154 +                if (new_x >= s->width)
  85.155 +                    new_x = s->width - 1;
  85.156 +                if (new_y >= s->height)
  85.157 +                    new_y = s->height - 1;
  85.158 +                if (kbd_mouse_is_absolute()) {
  85.159 +                    kbd_mouse_event(
  85.160 +                            new_x * 0x7FFF / (s->width - 1),
  85.161 +                            new_y * 0x7FFF / (s->height - 1),
  85.162 +                            buf[i].pos.rel_z,
  85.163 +                            buttons);
  85.164 +                } else {
  85.165 +                    kbd_mouse_event(
  85.166 +                            new_x - x,
  85.167 +                            new_y - y,
  85.168 +                            buf[i].pos.rel_z,
  85.169 +                            buttons);
  85.170 +                }
  85.171 +                x = new_x;
  85.172 +                y = new_y;
  85.173 +                break;
  85.174 +            }
  85.175 +
  85.176 +            case XENKBD_TYPE_KEY:
  85.177 +            {
  85.178 +                int keycode = buf[i].key.keycode;
  85.179 +                int button = 0;
  85.180 +
  85.181 +                if (keycode == BTN_LEFT)
  85.182 +                    button = MOUSE_EVENT_LBUTTON;
  85.183 +                else if (keycode == BTN_RIGHT)
  85.184 +                    button = MOUSE_EVENT_RBUTTON;
  85.185 +                else if (keycode == BTN_MIDDLE)
  85.186 +                    button = MOUSE_EVENT_MBUTTON;
  85.187 +
  85.188 +                if (button) {
  85.189 +                    if (buf[i].key.pressed)
  85.190 +                        buttons |=  button;
  85.191 +                    else
  85.192 +                        buttons &= ~button;
  85.193 +                    if (kbd_mouse_is_absolute())
  85.194 +                        kbd_mouse_event(
  85.195 +                                x * 0x7FFF / (s->width - 1),
  85.196 +                                y * 0x7FFF / (s->height - 1),
  85.197 +                                0,
  85.198 +                                buttons);
  85.199 +                    else
  85.200 +                        kbd_mouse_event(0, 0, 0, buttons);
  85.201 +                } else {
  85.202 +                    int scancode = linux2scancode[keycode];
  85.203 +                    if (!scancode) {
  85.204 +                        fprintf(stderr, "Can't convert keycode %x to scancode\n", keycode);
  85.205 +                        break;
  85.206 +                    }
  85.207 +                    if (scancode & 0x80) {
  85.208 +                        kbd_put_keycode(0xe0);
  85.209 +                        scancode &= 0x7f;
  85.210 +                    }
  85.211 +                    if (!buf[i].key.pressed)
  85.212 +                        scancode |= 0x80;
  85.213 +                    kbd_put_keycode(scancode);
  85.214 +                }
  85.215 +                break;
  85.216 +            }
  85.217 +        }
  85.218 +    }
  85.219 +}
  85.220 +
  85.221 +static void kbdfront_thread(void *p)
  85.222 +{
  85.223 +    int scancode, keycode;
  85.224 +    XenFBState *xs = p;
  85.225 +    xs->kbd_dev = init_kbdfront(kbd_path, 1);
  85.226 +    if (!xs->kbd_dev) {
  85.227 +        fprintf(stderr,"can't open keyboard\n");
  85.228 +        exit(1);
  85.229 +    }
  85.230 +    up(&xs->kbd_sem);
  85.231 +    for (scancode = 0; scancode < 128; scancode++) {
  85.232 +        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode]];
  85.233 +        linux2scancode[keycode] = scancode;
  85.234 +        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode] | 0x80];
  85.235 +        linux2scancode[keycode] = scancode | 0x80;
  85.236 +    }
  85.237 +}
  85.238 +
  85.239 +int xenfb_pv_display_init(DisplayState *ds)
  85.240 +{
  85.241 +    if (!fb_path || !kbd_path)
  85.242 +        return -1;
  85.243 +
  85.244 +    xs = qemu_mallocz(sizeof(XenFBState));
  85.245 +    if (!xs)
  85.246 +        return -1;
  85.247 +
  85.248 +    init_SEMAPHORE(&xs->kbd_sem, 0);
  85.249 +    xs->ds = ds;
  85.250 +
  85.251 +    create_thread("kbdfront", kbdfront_thread, (void*) xs);
  85.252 +
  85.253 +    ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE);
  85.254 +    memset(ds->data, 0, VGA_RAM_SIZE);
  85.255 +    ds->opaque = xs;
  85.256 +    ds->depth = 32;
  85.257 +    ds->bgr = 0;
  85.258 +    ds->width = 640;
  85.259 +    ds->height = 400;
  85.260 +    ds->linesize = 640 * 4;
  85.261 +    ds->dpy_update = xenfb_pv_update;
  85.262 +    ds->dpy_resize = xenfb_pv_resize;
  85.263 +    ds->dpy_resize_shared = xenfb_pv_resize_shared;
  85.264 +    ds->dpy_setdata = xenfb_pv_setdata;
  85.265 +    ds->dpy_refresh = xenfb_pv_refresh;
  85.266 +    return 0;
  85.267 +}
  85.268 +
  85.269 +int xenfb_pv_display_start(void *data)
  85.270 +{
  85.271 +    DisplayState *ds;
  85.272 +    struct fbfront_dev *fb_dev;
  85.273 +    int kbd_fd, fb_fd;
  85.274 +    int offset = 0;
  85.275 +    unsigned long *mfns;
  85.276 +    int n = VGA_RAM_SIZE / PAGE_SIZE;
  85.277 +    int i;
  85.278 +
  85.279 +    if (!fb_path || !kbd_path)
  85.280 +        return 0;
  85.281 +
  85.282 +    ds = xs->ds;
  85.283 +    xs->vga_vram = data;
  85.284 +    mfns = malloc(2 * n * sizeof(*mfns));
  85.285 +    for (i = 0; i < n; i++)
  85.286 +        mfns[i] = virtual_to_mfn(xs->vga_vram + i * PAGE_SIZE);
  85.287 +    for (i = 0; i < n; i++)
  85.288 +        mfns[n + i] = virtual_to_mfn(xs->nonshared_vram + i * PAGE_SIZE);
  85.289 +
  85.290 +    fb_dev = init_fbfront(fb_path, mfns, ds->width, ds->height, ds->depth, ds->linesize, 2 * n);
  85.291 +    free(mfns);
  85.292 +    if (!fb_dev) {
  85.293 +        fprintf(stderr,"can't open frame buffer\n");
  85.294 +        exit(1);
  85.295 +    }
  85.296 +    free(fb_path);
  85.297 +
  85.298 +    if (ds->shared_buf) {
  85.299 +        offset = (void*) ds->data - xs->vga_vram;
  85.300 +    } else {
  85.301 +        offset = VGA_RAM_SIZE;
  85.302 +        ds->data = xs->nonshared_vram;
  85.303 +    }
  85.304 +    if (offset)
  85.305 +        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset);
  85.306 +
  85.307 +    down(&xs->kbd_sem);
  85.308 +    free(kbd_path);
  85.309 +
  85.310 +    kbd_fd = kbdfront_open(xs->kbd_dev);
  85.311 +    qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, xs);
  85.312 +
  85.313 +    fb_fd = fbfront_open(fb_dev);
  85.314 +    qemu_set_fd_handler(fb_fd, xenfb_fb_handler, NULL, xs);
  85.315 +
  85.316 +    xs->fb_dev = fb_dev;
  85.317 +    return 0;
  85.318 +}
    86.1 --- a/tools/libfsimage/ufs/fsys_ufs.c	Tue Jun 10 16:00:33 2008 +0900
    86.2 +++ b/tools/libfsimage/ufs/fsys_ufs.c	Thu Jun 19 12:46:26 2008 +0900
    86.3 @@ -32,8 +32,9 @@
    86.4  #define SUPERBLOCK ((struct fs *)(FSYS_BUF + 0x2000))
    86.5  #define	INODE ((struct icommon *)(FSYS_BUF + 0x1000))
    86.6  #define DIRENT (FSYS_BUF + 0x4000)
    86.7 +#define MAXBSIZE ((FSYS_BUFLEN - 0x4000) / 2)
    86.8  #define INDIRBLK1 ((grub_daddr32_t *)(FSYS_BUF + 0x4000)) /* 2+ indir blk */
    86.9 -#define	INDIRBLK0 ((grub_daddr32_t *)(FSYS_BUF+ 0x6000))  /* 1st indirect blk */
   86.10 +#define	INDIRBLK0 ((grub_daddr32_t *)(FSYS_BUF+ 0x4000 + MAXBSIZE))  /* 1st indirect blk */
   86.11  
   86.12  #define	indirblk0 (*fsig_int1(ffi))
   86.13  #define	indirblk1 (*fsig_int2(ffi))
   86.14 @@ -48,7 +49,8 @@ ufs_mount(fsi_file_t *ffi, const char *o
   86.15  {
   86.16  	if (/*! IS_PC_SLICE_TYPE_SOLARIS(current_slice) || */
   86.17  	    !devread(ffi, UFS_SBLOCK, 0, UFS_SBSIZE, (char *)SUPERBLOCK) ||
   86.18 -	    SUPERBLOCK->fs_magic != UFS_MAGIC)
   86.19 +	    SUPERBLOCK->fs_magic != UFS_MAGIC ||
   86.20 +	    MAXBSIZE < SUPERBLOCK->fs_bsize)
   86.21  		return 0;
   86.22  
   86.23  	return 1;
    87.1 --- a/tools/libfsimage/zfs/fsys_zfs.c	Tue Jun 10 16:00:33 2008 +0900
    87.2 +++ b/tools/libfsimage/zfs/fsys_zfs.c	Thu Jun 19 12:46:26 2008 +0900
    87.3 @@ -776,11 +776,11 @@ dnode_get_path(fsi_file_t *ffi, dnode_ph
    87.4  	while (*path == '/')
    87.5  		path++;
    87.6  
    87.7 -	while (*path && !isspace(*path)) {
    87.8 +	while (*path && !isspace((uint8_t)*path)) {
    87.9  
   87.10  		/* get the next component name */
   87.11  		cname = path;
   87.12 -		while (*path && !isspace(*path) && *path != '/')
   87.13 +		while (*path && !isspace((uint8_t)*path) && *path != '/')
   87.14  			path++;
   87.15  		ch = *path;
   87.16  		*path = 0;   /* ensure null termination */
   87.17 @@ -890,17 +890,17 @@ get_objset_mdn(fsi_file_t *ffi, dnode_ph
   87.18  	}
   87.19  
   87.20  	/* take out the pool name */
   87.21 -	while (*fsname && !isspace(*fsname) && *fsname != '/')
   87.22 +	while (*fsname && !isspace((uint8_t)*fsname) && *fsname != '/')
   87.23  		fsname++;
   87.24  
   87.25 -	while (*fsname && !isspace(*fsname)) {
   87.26 +	while (*fsname && !isspace((uint8_t)*fsname)) {
   87.27  		uint64_t childobj;
   87.28  
   87.29  		while (*fsname == '/')
   87.30  			fsname++;
   87.31  
   87.32  		cname = fsname;
   87.33 -		while (*fsname && !isspace(*fsname) && *fsname != '/')
   87.34 +		while (*fsname && !isspace((uint8_t)*fsname) && *fsname != '/')
   87.35  			fsname++;
   87.36  		ch = *fsname;
   87.37  		*fsname = 0;
   87.38 @@ -1336,7 +1336,7 @@ zfs_open(fsi_file_t *ffi, char *filename
   87.39  			char zfs_bootstr[] = "zfs-bootfs=";
   87.40  			char zfs_bootpath[] = ",bootpath='";
   87.41  
   87.42 -			sprintf(temp, "%llu", (unsigned long long)
   87.43 +			snprintf(temp, sizeof(temp), "%llu", (unsigned long long)
   87.44  			    current_bootfs_obj);
   87.45  			alloc_size = strlen(zfs_bootstr) +
   87.46  			    strlen(current_rootpool) +
    88.1 --- a/tools/libxc/Makefile	Tue Jun 10 16:00:33 2008 +0900
    88.2 +++ b/tools/libxc/Makefile	Thu Jun 19 12:46:26 2008 +0900
    88.3 @@ -32,7 +32,7 @@ GUEST_SRCS-y += xg_private.c
    88.4  GUEST_SRCS-$(CONFIG_MIGRATE) += xc_domain_restore.c xc_domain_save.c
    88.5  GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
    88.6  
    88.7 -VPATH = ../../xen/common/libelf
    88.8 +vpath %.c ../../xen/common/libelf
    88.9  CFLAGS += -I../../xen/common/libelf
   88.10  
   88.11  GUEST_SRCS-y += libelf-tools.c libelf-loader.c
    89.1 --- a/tools/libxc/ia64/dom_fw_acpi.c	Tue Jun 10 16:00:33 2008 +0900
    89.2 +++ b/tools/libxc/ia64/dom_fw_acpi.c	Thu Jun 19 12:46:26 2008 +0900
    89.3 @@ -1,14 +1,31 @@
    89.4  #include <inttypes.h>
    89.5  #include "xc_dom_ia64_util.h"
    89.6  #include <xen/acpi.h>
    89.7 +#include <acpi/actables.h>
    89.8  
    89.9 -uint8_t
   89.10 -generate_acpi_checksum(void *tbl, unsigned long len)
   89.11 -{
   89.12 -    uint8_t *ptr, sum = 0;
   89.13 +/* stolen from xen/drivers/acpi/tables/tbutils.c */
   89.14  
   89.15 -    for ( ptr = tbl; len > 0 ; len--, ptr++ )
   89.16 -        sum += *ptr;
   89.17 +/*******************************************************************************
   89.18 + *
   89.19 + * FUNCTION:    acpi_tb_checksum
   89.20 + *
   89.21 + * PARAMETERS:  Buffer          - Pointer to memory region to be checked
   89.22 + *              Length          - Length of this memory region
   89.23 + *
   89.24 + * RETURN:      Checksum (u8)
   89.25 + *
   89.26 + * DESCRIPTION: Calculates circular checksum of memory region.
   89.27 + *
   89.28 + ******************************************************************************/
   89.29  
   89.30 -    return 0 - sum;
   89.31 +u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length)
   89.32 +{
   89.33 +	u8 sum = 0;
   89.34 +	u8 *end = buffer + length;
   89.35 +
   89.36 +	while (buffer < end) {
   89.37 +		sum = (u8) (sum + *(buffer++));
   89.38 +	}
   89.39 +
   89.40 +	return sum;
   89.41  }
    90.1 --- a/tools/libxc/xc_cpuid_x86.c	Tue Jun 10 16:00:33 2008 +0900
    90.2 +++ b/tools/libxc/xc_cpuid_x86.c	Thu Jun 19 12:46:26 2008 +0900
    90.3 @@ -25,81 +25,17 @@
    90.4  #include <xen/hvm/params.h>
    90.5  
    90.6  #define bitmaskof(idx)      (1u << ((idx) & 31))
    90.7 -#define clear_bit(idx, dst) ((dst) &= ~(1u << (idx)))
    90.8 -#define set_bit(idx, dst)   ((dst) |= (1u << (idx)))
    90.9 +#define clear_bit(idx, dst) ((dst) &= ~(1u << ((idx) & 31)))
   90.10 +#define set_bit(idx, dst)   ((dst) |= (1u << ((idx) & 31)))
   90.11  
   90.12  #define DEF_MAX_BASE 0x00000004u
   90.13  #define DEF_MAX_EXT  0x80000008u
   90.14  
   90.15 -static void amd_xc_cpuid_policy(
   90.16 -    int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
   90.17 +static int hypervisor_is_64bit(int xc)
   90.18  {
   90.19 -    unsigned long pae = 0;
   90.20 -
   90.21 -    xc_get_hvm_param(xc, domid, HVM_PARAM_PAE_ENABLED, &pae);
   90.22 -
   90.23 -    switch ( input[0] )
   90.24 -    {
   90.25 -    case 0x00000001:
   90.26 -        /* Mask Intel-only features. */
   90.27 -        regs[2] &= ~(bitmaskof(X86_FEATURE_SSSE3) |
   90.28 -                     bitmaskof(X86_FEATURE_SSE4_1) |
   90.29 -                     bitmaskof(X86_FEATURE_SSE4_2));
   90.30 -        break;
   90.31 -
   90.32 -    case 0x00000002:
   90.33 -    case 0x00000004:
   90.34 -        regs[0] = regs[1] = regs[2] = 0;
   90.35 -        break;
   90.36 -
   90.37 -    case 0x80000001:
   90.38 -        if ( !pae )
   90.39 -            clear_bit(X86_FEATURE_PAE & 31, regs[3]);
   90.40 -        clear_bit(X86_FEATURE_PSE36 & 31, regs[3]);
   90.41 -
   90.42 -        /* Filter all other features according to a whitelist. */
   90.43 -        regs[2] &= (bitmaskof(X86_FEATURE_LAHF_LM) |
   90.44 -                    bitmaskof(X86_FEATURE_ALTMOVCR) |
   90.45 -                    bitmaskof(X86_FEATURE_ABM) |
   90.46 -                    bitmaskof(X86_FEATURE_SSE4A) |
   90.47 -                    bitmaskof(X86_FEATURE_MISALIGNSSE) |
   90.48 -                    bitmaskof(X86_FEATURE_3DNOWPF));
   90.49 -        regs[3] &= (0x0183f3ff | /* features shared with 0x00000001:EDX */
   90.50 -                    bitmaskof(X86_FEATURE_NX) |
   90.51 -                    bitmaskof(X86_FEATURE_LM) |
   90.52 -                    bitmaskof(X86_FEATURE_SYSCALL) |
   90.53 -                    bitmaskof(X86_FEATURE_MP) |
   90.54 -                    bitmaskof(X86_FEATURE_MMXEXT) |
   90.55 -                    bitmaskof(X86_FEATURE_FFXSR) |
   90.56 -                    bitmaskof(X86_FEATURE_3DNOW) |
   90.57 -                    bitmaskof(X86_FEATURE_3DNOWEXT));
   90.58 -        break;
   90.59 -    }
   90.60 -}
   90.61 -
   90.62 -static void intel_xc_cpuid_policy(
   90.63 -    int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
   90.64 -{
   90.65 -    switch ( input[0] )
   90.66 -    {
   90.67 -    case 0x00000001:
   90.68 -        /* Mask AMD-only features. */
   90.69 -        regs[2] &= ~(bitmaskof(X86_FEATURE_POPCNT));
   90.70 -        break;
   90.71 -
   90.72 -    case 0x00000004:
   90.73 -        regs[0] &= 0x3FF;
   90.74 -        regs[3] &= 0x3FF;
   90.75 -        break;
   90.76 -
   90.77 -    case 0x80000001:
   90.78 -        /* Only a few features are advertised in Intel's 0x80000001. */
   90.79 -        regs[2] &= (bitmaskof(X86_FEATURE_LAHF_LM));
   90.80 -        regs[3] &= (bitmaskof(X86_FEATURE_NX) |
   90.81 -                    bitmaskof(X86_FEATURE_LM) |
   90.82 -                    bitmaskof(X86_FEATURE_SYSCALL));
   90.83 -        break;
   90.84 -    }
   90.85 +    xen_capabilities_info_t xen_caps = "";
   90.86 +    return ((xc_version(xc, XENVER_capabilities, &xen_caps) == 0) &&
   90.87 +            (strstr(xen_caps, "x86_64") != NULL));
   90.88  }
   90.89  
   90.90  static void cpuid(const unsigned int *input, unsigned int *regs)
   90.91 @@ -129,15 +65,92 @@ static void xc_cpuid_brand_get(char *str
   90.92      str[12] = '\0';
   90.93  }
   90.94  
   90.95 -static void xc_cpuid_policy(
   90.96 +static void amd_xc_cpuid_policy(
   90.97 +    int xc, domid_t domid, const unsigned int *input, unsigned int *regs,
   90.98 +    int is_pae)
   90.99 +{
  90.100 +    switch ( input[0] )
  90.101 +    {
  90.102 +    case 0x00000001:
  90.103 +        /* Mask Intel-only features. */
  90.104 +        regs[2] &= ~(bitmaskof(X86_FEATURE_SSSE3) |
  90.105 +                     bitmaskof(X86_FEATURE_SSE4_1) |
  90.106 +                     bitmaskof(X86_FEATURE_SSE4_2));
  90.107 +        break;
  90.108 +
  90.109 +    case 0x00000002:
  90.110 +    case 0x00000004:
  90.111 +        regs[0] = regs[1] = regs[2] = 0;
  90.112 +        break;
  90.113 +
  90.114 +    case 0x80000001: {
  90.115 +        int is_64bit = hypervisor_is_64bit(xc) && is_pae;
  90.116 +
  90.117 +        if ( !is_pae )
  90.118 +            clear_bit(X86_FEATURE_PAE, regs[3]);
  90.119 +        clear_bit(X86_FEATURE_PSE36, regs[3]);
  90.120 +
  90.121 +        /* Filter all other features according to a whitelist. */
  90.122 +        regs[2] &= ((is_64bit ? bitmaskof(X86_FEATURE_LAHF_LM) : 0) |
  90.123 +                    bitmaskof(X86_FEATURE_ALTMOVCR) |
  90.124 +                    bitmaskof(X86_FEATURE_ABM) |
  90.125 +                    bitmaskof(X86_FEATURE_SSE4A) |
  90.126 +                    bitmaskof(X86_FEATURE_MISALIGNSSE) |
  90.127 +                    bitmaskof(X86_FEATURE_3DNOWPF));
  90.128 +        regs[3] &= (0x0183f3ff | /* features shared with 0x00000001:EDX */
  90.129 +                    (is_pae ? bitmaskof(X86_FEATURE_NX) : 0) |
  90.130 +                    (is_64bit ? bitmaskof(X86_FEATURE_LM) : 0) |
  90.131 +                    bitmaskof(X86_FEATURE_SYSCALL) |
  90.132 +                    bitmaskof(X86_FEATURE_MP) |
  90.133 +                    bitmaskof(X86_FEATURE_MMXEXT) |
  90.134 +                    bitmaskof(X86_FEATURE_FFXSR) |
  90.135 +                    bitmaskof(X86_FEATURE_3DNOW) |
  90.136 +                    bitmaskof(X86_FEATURE_3DNOWEXT));
  90.137 +        break;
  90.138 +    }
  90.139 +    }
  90.140 +}
  90.141 +
  90.142 +static void intel_xc_cpuid_policy(
  90.143 +    int xc, domid_t domid, const unsigned int *input, unsigned int *regs,
  90.144 +    int is_pae)
  90.145 +{
  90.146 +    switch ( input[0] )
  90.147 +    {
  90.148 +    case 0x00000001:
  90.149 +        /* Mask AMD-only features. */
  90.150 +        regs[2] &= ~(bitmaskof(X86_FEATURE_POPCNT));
  90.151 +        break;
  90.152 +
  90.153 +    case 0x00000004:
  90.154 +        regs[0] &= 0x3FF;
  90.155 +        regs[3] &= 0x3FF;
  90.156 +        break;
  90.157 +
  90.158 +    case 0x80000001: {
  90.159 +        int is_64bit = hypervisor_is_64bit(xc) && is_pae;
  90.160 +
  90.161 +        /* Only a few features are advertised in Intel's 0x80000001. */
  90.162 +        regs[2] &= (is_64bit ? bitmaskof(X86_FEATURE_LAHF_LM) : 0);
  90.163 +        regs[3] &= ((is_pae ? bitmaskof(X86_FEATURE_NX) : 0) |
  90.164 +                    (is_64bit ? bitmaskof(X86_FEATURE_LM) : 0) |
  90.165 +                    (is_64bit ? bitmaskof(X86_FEATURE_SYSCALL) : 0));
  90.166 +        break;
  90.167 +    }
  90.168 +    }
  90.169 +}
  90.170 +
  90.171 +static void xc_cpuid_hvm_policy(
  90.172      int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
  90.173  {
  90.174      char brand[13];
  90.175      unsigned long pae;
  90.176 +    int is_pae;
  90.177  
  90.178      xc_get_hvm_param(xc, domid, HVM_PARAM_PAE_ENABLED, &pae);
  90.179 +    is_pae = !!pae;
  90.180  
  90.181 -    switch( input[0] )
  90.182 +    switch ( input[0] )
  90.183      {
  90.184      case 0x00000000:
  90.185          if ( regs[0] > DEF_MAX_BASE )
  90.186 @@ -177,8 +190,8 @@ static void xc_cpuid_policy(
  90.187          /* We always support MTRR MSRs. */
  90.188          regs[3] |= bitmaskof(X86_FEATURE_MTRR);
  90.189  
  90.190 -        if ( !pae )
  90.191 -            clear_bit(X86_FEATURE_PAE & 31, regs[3]);
  90.192 +        if ( !is_pae )
  90.193 +            clear_bit(X86_FEATURE_PAE, regs[3]);
  90.194          break;
  90.195  
  90.196      case 0x80000000:
  90.197 @@ -187,8 +200,8 @@ static void xc_cpuid_policy(
  90.198          break;
  90.199  
  90.200      case 0x80000001:
  90.201 -        if ( !pae )
  90.202 -            clear_bit(X86_FEATURE_NX & 31, regs[3]);
  90.203 +        if ( !is_pae )
  90.204 +            clear_bit(X86_FEATURE_NX, regs[3]);
  90.205          break;
  90.206  
  90.207  
  90.208 @@ -212,9 +225,104 @@ static void xc_cpuid_policy(
  90.209  
  90.210      xc_cpuid_brand_get(brand);
  90.211      if ( strstr(brand, "AMD") )
  90.212 -        amd_xc_cpuid_policy(xc, domid, input, regs);
  90.213 +        amd_xc_cpuid_policy(xc, domid, input, regs, is_pae);
  90.214      else
  90.215 -        intel_xc_cpuid_policy(xc, domid, input, regs);
  90.216 +        intel_xc_cpuid_policy(xc, domid, input, regs, is_pae);
  90.217 +
  90.218 +}
  90.219 +
  90.220 +static void xc_cpuid_pv_policy(
  90.221 +    int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
  90.222 +{
  90.223 +    DECLARE_DOMCTL;
  90.224 +    int guest_64bit, xen_64bit = hypervisor_is_64bit(xc);
  90.225 +    char brand[13];
  90.226 +
  90.227 +    xc_cpuid_brand_get(brand);
  90.228 +
  90.229 +    memset(&domctl, 0, sizeof(domctl));
  90.230 +    domctl.domain = domid;
  90.231 +    domctl.cmd = XEN_DOMCTL_get_address_size;
  90.232 +    do_domctl(xc, &domctl);
  90.233 +    guest_64bit = (domctl.u.address_size.size == 64);
  90.234 +
  90.235 +    if ( (input[0] & 0x7fffffff) == 1 )
  90.236 +    {
  90.237 +        clear_bit(X86_FEATURE_VME, regs[3]);
  90.238 +        clear_bit(X86_FEATURE_PSE, regs[3]);
  90.239 +        clear_bit(X86_FEATURE_PGE, regs[3]);
  90.240 +        clear_bit(X86_FEATURE_MCE, regs[3]);
  90.241 +        clear_bit(X86_FEATURE_MCA, regs[3]);
  90.242 +        clear_bit(X86_FEATURE_MTRR, regs[3]);
  90.243 +        clear_bit(X86_FEATURE_PSE36, regs[3]);
  90.244 +    }
  90.245 +
  90.246 +    switch ( input[0] )
  90.247 +    {
  90.248 +    case 1:
  90.249 +        if ( !xen_64bit || strstr(brand, "AMD") )
  90.250 +            clear_bit(X86_FEATURE_SEP, regs[3]);
  90.251 +        clear_bit(X86_FEATURE_DS, regs[3]);
  90.252 +        clear_bit(X86_FEATURE_ACC, regs[3]);
  90.253 +        clear_bit(X86_FEATURE_PBE, regs[3]);
  90.254 +
  90.255 +        clear_bit(X86_FEATURE_DTES64, regs[2]);
  90.256 +        clear_bit(X86_FEATURE_MWAIT, regs[2]);
  90.257 +        clear_bit(X86_FEATURE_DSCPL, regs[2]);
  90.258 +        clear_bit(X86_FEATURE_VMXE, regs[2]);
  90.259 +        clear_bit(X86_FEATURE_SMXE, regs[2]);
  90.260 +        clear_bit(X86_FEATURE_EST, regs[2]);
  90.261 +        clear_bit(X86_FEATURE_TM2, regs[2]);
  90.262 +        if ( !guest_64bit )
  90.263 +            clear_bit(X86_FEATURE_CX16, regs[2]);
  90.264 +        clear_bit(X86_FEATURE_XTPR, regs[2]);
  90.265 +        clear_bit(X86_FEATURE_PDCM, regs[2]);
  90.266 +        clear_bit(X86_FEATURE_DCA, regs[2]);
  90.267 +        break;
  90.268 +    case 0x80000001:
  90.269 +        if ( !guest_64bit )
  90.270 +        {
  90.271 +            clear_bit(X86_FEATURE_LM, regs[3]);
  90.272 +            clear_bit(X86_FEATURE_LAHF_LM, regs[2]);
  90.273 +            if ( !strstr(brand, "AMD") )
  90.274 +                clear_bit(X86_FEATURE_SYSCALL, regs[3]);
  90.275 +        }
  90.276 +        else
  90.277 +        {
  90.278 +            set_bit(X86_FEATURE_SYSCALL, regs[3]);
  90.279 +        }
  90.280 +        clear_bit(X86_FEATURE_PAGE1GB, regs[3]);
  90.281 +        clear_bit(X86_FEATURE_RDTSCP, regs[3]);
  90.282 +
  90.283 +        clear_bit(X86_FEATURE_SVME, regs[2]);
  90.284 +        clear_bit(X86_FEATURE_OSVW, regs[2]);
  90.285 +        clear_bit(X86_FEATURE_IBS, regs[2]);
  90.286 +        clear_bit(X86_FEATURE_SKINIT, regs[2]);
  90.287 +        clear_bit(X86_FEATURE_WDT, regs[2]);
  90.288 +        break;
  90.289 +    case 5: /* MONITOR/MWAIT */
  90.290 +    case 0xa: /* Architectural Performance Monitor Features */
  90.291 +    case 0x8000000a: /* SVM revision and features */
  90.292 +    case 0x8000001b: /* Instruction Based Sampling */
  90.293 +        regs[0] = regs[1] = regs[2] = regs[3] = 0;
  90.294 +        break;
  90.295 +    }
  90.296 +}
  90.297 +
  90.298 +static int xc_cpuid_policy(
  90.299 +    int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
  90.300 +{
  90.301 +    xc_dominfo_t        info;
  90.302 +
  90.303 +    if ( xc_domain_getinfo(xc, domid, 1, &info) == 0 )
  90.304 +        return -EINVAL;
  90.305 +
  90.306 +    if ( info.hvm )
  90.307 +        xc_cpuid_hvm_policy(xc, domid, input, regs);
  90.308 +    else
  90.309 +        xc_cpuid_pv_policy(xc, domid, input, regs);
  90.310 +
  90.311 +    return 0;
  90.312  }
  90.313  
  90.314  static int xc_cpuid_do_domctl(
    91.1 --- a/tools/libxc/xc_dom.h	Tue Jun 10 16:00:33 2008 +0900
    91.2 +++ b/tools/libxc/xc_dom.h	Thu Jun 19 12:46:26 2008 +0900
    91.3 @@ -107,6 +107,8 @@ struct xc_dom_image {
    91.4  
    91.5      /* kernel loader */
    91.6      struct xc_dom_arch *arch_hooks;
    91.7 +    /* allocate up to virt_alloc_end */
    91.8 +    int (*allocate) (struct xc_dom_image * dom, xen_vaddr_t up_to);
    91.9  };
   91.10  
   91.11  /* --- pluggable kernel loader ------------------------------------- */
   91.12 @@ -167,6 +169,7 @@ int xc_dom_ramdisk_mem(struct xc_dom_ima
   91.13                         size_t memsize);
   91.14  
   91.15  int xc_dom_parse_image(struct xc_dom_image *dom);
   91.16 +struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type);
   91.17  int xc_dom_build_image(struct xc_dom_image *dom);
   91.18  int xc_dom_update_guest_p2m(struct xc_dom_image *dom);
   91.19  
    92.1 --- a/tools/libxc/xc_dom_core.c	Tue Jun 10 16:00:33 2008 +0900
    92.2 +++ b/tools/libxc/xc_dom_core.c	Thu Jun 19 12:46:26 2008 +0900
    92.3 @@ -409,6 +409,8 @@ int xc_dom_alloc_segment(struct xc_dom_i
    92.4      seg->vend = start + pages * page_size;
    92.5      seg->pfn = (seg->vstart - dom->parms.virt_base) / page_size;
    92.6      dom->virt_alloc_end = seg->vend;
    92.7 +    if (dom->allocate)
    92.8 +        dom->allocate(dom, dom->virt_alloc_end);
    92.9  
   92.10      xc_dom_printf("%-20s:   %-12s : 0x%" PRIx64 " -> 0x%" PRIx64
   92.11                    "  (pfn 0x%" PRIpfn " + 0x%" PRIpfn " pages)\n",
   92.12 @@ -431,6 +433,8 @@ int xc_dom_alloc_page(struct xc_dom_imag
   92.13  
   92.14      start = dom->virt_alloc_end;
   92.15      dom->virt_alloc_end += page_size;
   92.16 +    if (dom->allocate)
   92.17 +        dom->allocate(dom, dom->virt_alloc_end);
   92.18      pfn = (start - dom->parms.virt_base) / page_size;
   92.19  
   92.20      xc_dom_printf("%-20s:   %-12s : 0x%" PRIx64 " (pfn 0x%" PRIpfn ")\n",
   92.21 @@ -506,7 +510,7 @@ void xc_dom_register_arch_hooks(struct x
   92.22      first_hook = hooks;
   92.23  }
   92.24  
   92.25 -static struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type)
   92.26 +struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type)
   92.27  {
   92.28      struct xc_dom_arch *hooks = first_hook;
   92.29  
    93.1 --- a/tools/libxc/xc_dom_x86.c	Tue Jun 10 16:00:33 2008 +0900
    93.2 +++ b/tools/libxc/xc_dom_x86.c	Thu Jun 19 12:46:26 2008 +0900
    93.3 @@ -418,7 +418,7 @@ static int start_info_x86_32(struct xc_d
    93.4      xc_dom_printf("%s: called\n", __FUNCTION__);
    93.5  
    93.6      memset(start_info, 0, sizeof(*start_info));
    93.7 -    sprintf(start_info->magic, dom->guest_type);
    93.8 +    snprintf(start_info->magic, sizeof(start_info->magic), dom->guest_type);
    93.9      start_info->nr_pages = dom->total_pages;
   93.10      start_info->shared_info = shinfo << PAGE_SHIFT_X86;
   93.11      start_info->pt_base = dom->pgtables_seg.vstart;
   93.12 @@ -457,7 +457,7 @@ static int start_info_x86_64(struct xc_d
   93.13      xc_dom_printf("%s: called\n", __FUNCTION__);
   93.14  
   93.15      memset(start_info, 0, sizeof(*start_info));
   93.16 -    sprintf(start_info->magic, dom->guest_type);
   93.17 +    snprintf(start_info->magic, sizeof(start_info->magic), dom->guest_type);
   93.18      start_info->nr_pages = dom->total_pages;
   93.19      start_info->shared_info = shinfo << PAGE_SHIFT_X86;
   93.20      start_info->pt_base = dom->pgtables_seg.vstart;
    94.1 --- a/tools/libxc/xc_domain_restore.c	Tue Jun 10 16:00:33 2008 +0900
    94.2 +++ b/tools/libxc/xc_domain_restore.c	Thu Jun 19 12:46:26 2008 +0900
    94.3 @@ -474,6 +474,22 @@ int xc_domain_restore(int xc_handle, int
    94.4              continue;
    94.5          }
    94.6  
    94.7 +        if ( j == -3 )
    94.8 +        {
    94.9 +            uint64_t ident_pt;
   94.10 +
   94.11 +            /* Skip padding 4 bytes then read the EPT identity PT location. */
   94.12 +            if ( read_exact(io_fd, &ident_pt, sizeof(uint32_t)) ||
   94.13 +                 read_exact(io_fd, &ident_pt, sizeof(uint64_t)) )
   94.14 +            {
   94.15 +                ERROR("error read the address of the EPT identity map");
   94.16 +                goto out;
   94.17 +            }
   94.18 +
   94.19 +            xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IDENT_PT, ident_pt);
   94.20 +            continue;
   94.21 +        }
   94.22 +
   94.23          if ( j == 0 )
   94.24              break;  /* our work here is done */
   94.25  
    95.1 --- a/tools/libxc/xc_domain_save.c	Tue Jun 10 16:00:33 2008 +0900
    95.2 +++ b/tools/libxc/xc_domain_save.c	Thu Jun 19 12:46:26 2008 +0900
    95.3 @@ -1429,6 +1429,25 @@ int xc_domain_save(int xc_handle, int io
    95.4          }
    95.5      }
    95.6  
    95.7 +    if ( hvm )
    95.8 +    {
    95.9 +        struct {
   95.10 +            int minusthree;
   95.11 +            uint32_t pad;
   95.12 +            uint64_t ident_pt;
   95.13 +        } chunk = { -3, 0 };
   95.14 +
   95.15 +        xc_get_hvm_param(xc_handle, dom, HVM_PARAM_IDENT_PT,
   95.16 +                         (unsigned long *)&chunk.ident_pt);
   95.17 +
   95.18 +        if ( (chunk.ident_pt != 0) &&
   95.19 +             write_exact(io_fd, &chunk, sizeof(chunk)) )
   95.20 +        {
   95.21 +            PERROR("Error when writing the ident_pt for EPT guest");
   95.22 +            goto out;
   95.23 +        }
   95.24 +    }
   95.25 +
   95.26      /* Zero terminate */
   95.27      i = 0;
   95.28      if ( write_exact(io_fd, &i, sizeof(int)) )
    96.1 --- a/tools/libxc/xc_netbsd.c	Tue Jun 10 16:00:33 2008 +0900
    96.2 +++ b/tools/libxc/xc_netbsd.c	Thu Jun 19 12:46:26 2008 +0900
    96.3 @@ -142,9 +142,13 @@ static int do_privcmd(int xc_handle, uns
    96.4  
    96.5  int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
    96.6  {
    96.7 -    return do_privcmd(xc_handle,
    96.8 +    int error = do_privcmd(xc_handle,
    96.9                        IOCTL_PRIVCMD_HYPERCALL,
   96.10                        (unsigned long)hypercall);
   96.11 +    if (error)
   96.12 +       return error;
   96.13 +    else
   96.14 +       return (hypercall->retval);
   96.15  }
   96.16  
   96.17  #define EVTCHN_DEV_NAME  "/dev/xenevt"
    97.1 --- a/tools/misc/Makefile	Tue Jun 10 16:00:33 2008 +0900
    97.2 +++ b/tools/misc/Makefile	Thu Jun 19 12:46:26 2008 +0900
    97.3 @@ -21,6 +21,11 @@ SUBDIRS := $(SUBDIRS-y)
    97.4  INSTALL_BIN  = $(TARGETS) xencons
    97.5  INSTALL_SBIN = netfix xm xen-bugtool xen-python-path xend xenperf xsview
    97.6  
    97.7 +DEFAULT_PYTHON_PATH := $(shell $(XEN_ROOT)/tools/python/get-path)
    97.8 +PYTHON_PATH ?= $(DEFAULT_PYTHON_PATH)
    97.9 +INSTALL_PYTHON_PROG = $(XEN_ROOT)/tools/python/install-wrap \
   97.10 +"$(PYTHON_PATH)" $(INSTALL_PROG)
   97.11 +
   97.12  .PHONY: all
   97.13  all: build
   97.14  
   97.15 @@ -32,8 +37,8 @@ build: $(TARGETS)
   97.16  install: build
   97.17  	$(INSTALL_DIR) $(DESTDIR)$(BINDIR)
   97.18  	$(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
   97.19 -	$(INSTALL_PROG) $(INSTALL_BIN) $(DESTDIR)$(BINDIR)
   97.20 -	$(INSTALL_PROG) $(INSTALL_SBIN) $(DESTDIR)$(SBINDIR)
   97.21 +	$(INSTALL_PYTHON_PROG) $(INSTALL_BIN) $(DESTDIR)$(BINDIR)
   97.22 +	$(INSTALL_PYTHON_PROG) $(INSTALL_SBIN) $(DESTDIR)$(SBINDIR)
   97.23  	set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d install-recurse; done
   97.24  
   97.25  .PHONY: clean
    98.1 --- a/tools/misc/nsplitd/nsplitd.c	Tue Jun 10 16:00:33 2008 +0900
    98.2 +++ b/tools/misc/nsplitd/nsplitd.c	Thu Jun 19 12:46:26 2008 +0900
    98.3 @@ -106,7 +106,7 @@ static void fault(char *format, ...)
    98.4      
    98.5      /* XXX This is a bit dubious, but there is no vsyslog */
    98.6      va_start(ap, format);
    98.7 -    vsprintf(logbuf, format, ap);
    98.8 +    vsnprintf(logbuf, sizeof(logbuf), format, ap);
    98.9      syslog(LOG_ERR, logbuf);
   98.10      va_end(ap);
   98.11      exit(1);
    99.1 --- a/tools/misc/xenperf.c	Tue Jun 10 16:00:33 2008 +0900
    99.2 +++ b/tools/misc/xenperf.c	Thu Jun 19 12:46:26 2008 +0900
    99.3 @@ -202,7 +202,7 @@ int main(int argc, char *argv[])
    99.4                          strncpy(hypercall_name, hypercall_name_table[j],
    99.5                                  sizeof(hypercall_name));
    99.6                      else
    99.7 -                        sprintf(hypercall_name, "[%d]", j);
    99.8 +                        snprintf(hypercall_name, sizeof(hypercall_name), "[%d]", j);
    99.9                      hypercall_name[sizeof(hypercall_name)-1]='\0';
   99.10                      printf("%-35s ", hypercall_name);
   99.11                      printf("%12u\n", (unsigned int)val[j]);
   100.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   100.2 +++ b/tools/python/get-path	Thu Jun 19 12:46:26 2008 +0900
   100.3 @@ -0,0 +1,22 @@
   100.4 +#! /usr/bin/env bash
   100.5 +set -e
   100.6 +
   100.7 +check () {
   100.8 +	set +e
   100.9 +	p=`type -p python$v`
  100.10 +	r=$?
  100.11 +	set -e
  100.12 +	if [ $r = 0 ]; then
  100.13 +		echo >&2 "${0##*/}: will use #!$p for python programs"
  100.14 +		printf "%s\n" "$p"
  100.15 +		exit 0
  100.16 +	fi
  100.17 +}
  100.18 +
  100.19 +v="$(python -V 2>&1)"
  100.20 +v="${v#* }"
  100.21 +check
  100.22 +v="${v%.*}"
  100.23 +check
  100.24 +echo >&2 'python version not determined, will use env to find python at runtime'
  100.25 +printf "/usr/bin/env python\n"
   101.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   101.2 +++ b/tools/python/install-wrap	Thu Jun 19 12:46:26 2008 +0900
   101.3 @@ -0,0 +1,44 @@
   101.4 +#! /usr/bin/env bash
   101.5 +# usage:
   101.6 +#  .../install-wrap $(PYTHON_PATH) install <options-to-install> <src>... <dest>
   101.7 +# where
   101.8 +#  PYTHON_PATH is what to put after #! and may be `/usr/bin/env python'
   101.9 +#
  101.10 +# Used via $(INSTALL_PYTHON_PROG) in Rules.mk; PYTHON_PATH comes from
  101.11 +# .../get-path alongside this script
  101.12 +
  101.13 +set -e
  101.14 +if [ $# -lt 2 ]; then echo >&2 "${0##*/}: too few arguments"; exit 1; fi
  101.15 +pythonpath="$1"; shift
  101.16 +
  101.17 +install=("$1"); shift
  101.18 +srcs=()
  101.19 +
  101.20 +while [ $# != 0 ]; do
  101.21 +	case "$1" in
  101.22 +	-|--)	install=("${install[@]}" "$1"); shift; break ;;
  101.23 +	-*)	install=("${install[@]}" "$1"); shift ;;
  101.24 +	*)	break ;;
  101.25 +	esac
  101.26 +done
  101.27 +while [ $# -gt 1 ]; do
  101.28 +	srcs=("${srcs[@]}" "$1"); shift
  101.29 +done
  101.30 +dest="$1"; shift
  101.31 +
  101.32 +destf="$dest"
  101.33 +for srcf in "${srcs[@]}"; do
  101.34 +	if test -d "$dest"; then
  101.35 +		destf="$dest/${srcf%%*/}";
  101.36 +	fi
  101.37 +	org="$(sed -n '2q; /^#! *\/usr\/bin\/env python *$/p' $srcf)"
  101.38 +	if [ "x$org" = x ]; then
  101.39 +		"${install[@]}" "$srcf" "$destf"
  101.40 +		continue
  101.41 +	fi
  101.42 +	tmpf="$destf.tmp"
  101.43 +	"${install[@]}" "$srcf" "$tmpf"
  101.44 +	printf >"$tmpf" "#!%s\n" "$pythonpath"
  101.45 +	sed -e 1d "$srcf" >>"$tmpf"
  101.46 +	mv -f "$tmpf" "$destf"
  101.47 +done
   102.1 --- a/tools/python/xen/lowlevel/acm/acm.c	Tue Jun 10 16:00:33 2008 +0900
   102.2 +++ b/tools/python/xen/lowlevel/acm/acm.c	Thu Jun 19 12:46:26 2008 +0900
   102.3 @@ -29,11 +29,10 @@
   102.4  #include <arpa/inet.h>
   102.5  #include <sys/ioctl.h>
   102.6  #include <netinet/in.h>
   102.7 +#include <xenctrl.h>
   102.8  #include <xen/xsm/acm.h>
   102.9  #include <xen/xsm/acm_ops.h>
  102.10  
  102.11 -#include <xenctrl.h>
  102.12 -
  102.13  #define PERROR(_m, _a...) \
  102.14  fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a ,    \
  102.15      errno, strerror(errno))
   103.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Tue Jun 10 16:00:33 2008 +0900
   103.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Thu Jun 19 12:46:26 2008 +0900
   103.3 @@ -298,7 +298,8 @@ static PyObject *pyxc_domain_getinfo(XcO
   103.4                                        &first_dom, &max_doms) )
   103.5          return NULL;
   103.6  
   103.7 -    if ( (info = malloc(max_doms * sizeof(xc_dominfo_t))) == NULL )
   103.8 +    info = calloc(max_doms, sizeof(xc_dominfo_t));
   103.9 +    if (info == NULL)
  103.10          return PyErr_NoMemory();
  103.11  
  103.12      nr_doms = xc_domain_getinfo(self->xc_handle, first_dom, max_doms, info);
  103.13 @@ -664,9 +665,9 @@ static PyObject *pyxc_get_device_group(X
  103.14      /* Maximum allowed siblings device number per group */
  103.15      max_sdevs = 1024;
  103.16  
  103.17 -    if ( (sdev_array = malloc(max_sdevs * sizeof(*sdev_array))) == NULL )
  103.18 +    sdev_array = calloc(max_sdevs, sizeof(*sdev_array));
  103.19 +    if (sdev_array == NULL)
  103.20          return PyErr_NoMemory();
  103.21 -    memset(sdev_array, 0, max_sdevs * sizeof(*sdev_array));
  103.22  
  103.23      bdf |= (bus & 0xff) << 16;
  103.24      bdf |= (dev & 0x1f) << 11;
  103.25 @@ -687,16 +688,16 @@ static PyObject *pyxc_get_device_group(X
  103.26         return Py_BuildValue("s", "");
  103.27      }
  103.28  
  103.29 -    if ( (group_str = malloc(num_sdevs * sizeof(dev_str))) == NULL )
  103.30 +    group_str = calloc(num_sdevs, sizeof(dev_str));
  103.31 +    if (group_str == NULL)
  103.32          return PyErr_NoMemory();
  103.33 -    memset(group_str, '\0', num_sdevs * sizeof(dev_str));
  103.34  
  103.35      for ( i = 0; i < num_sdevs; i++ )
  103.36      {
  103.37          bus = (sdev_array[i] >> 16) & 0xff;
  103.38          dev = (sdev_array[i] >> 11) & 0x1f;
  103.39          func = (sdev_array[i] >> 8) & 0x7;
  103.40 -        sprintf(dev_str, "%02x:%02x.%x,", bus, dev, func);
  103.41 +        snprintf(dev_str, sizeof(dev_str), "%02x:%02x.%x,", bus, dev, func);
  103.42          strcat(group_str, dev_str);
  103.43      }
  103.44  
  103.45 @@ -1116,7 +1117,7 @@ static PyObject *pyxc_xeninfo(XcObject *
  103.46      if ( xc_version(self->xc_handle, XENVER_platform_parameters, &p_parms) != 0 )
  103.47          return pyxc_error_to_exception();
  103.48  
  103.49 -    sprintf(str, "virt_start=0x%lx", p_parms.virt_start);
  103.50 +    snprintf(str, sizeof(str), "virt_start=0x%lx", p_parms.virt_start);
  103.51  
  103.52      xen_pagesize = xc_version(self->xc_handle, XENVER_pagesize, NULL);
  103.53      if (xen_pagesize < 0 )
   104.1 --- a/tools/python/xen/lowlevel/xs/xs.c	Tue Jun 10 16:00:33 2008 +0900
   104.2 +++ b/tools/python/xen/lowlevel/xs/xs.c	Thu Jun 19 12:46:26 2008 +0900
   104.3 @@ -415,7 +415,7 @@ static PyObject *xspy_watch(XsHandle *se
   104.4      if (i == PyList_Size(self->watches))
   104.5          PyList_Append(self->watches, token);
   104.6  
   104.7 -    sprintf(token_str, "%li", (unsigned long)token);
   104.8 +    snprintf(token_str, sizeof(token_str), "%li", (unsigned long)token);
   104.9      Py_BEGIN_ALLOW_THREADS
  104.10      result = xs_watch(xh, path, token_str);
  104.11      Py_END_ALLOW_THREADS
  104.12 @@ -500,7 +500,7 @@ static PyObject *xspy_unwatch(XsHandle *
  104.13      if (!PyArg_ParseTuple(args, "sO", &path, &token))
  104.14          return NULL;
  104.15  
  104.16 -    sprintf(token_str, "%li", (unsigned long)token);
  104.17 +    snprintf(token_str, sizeof(token_str), "%li", (unsigned long)token);
  104.18      Py_BEGIN_ALLOW_THREADS
  104.19      result = xs_unwatch(xh, path, token_str);
  104.20      Py_END_ALLOW_THREADS
  104.21 @@ -535,7 +535,7 @@ static PyObject *xspy_transaction_start(
  104.22          return NULL;
  104.23      }
  104.24  
  104.25 -    sprintf(thstr, "%lX", (unsigned long)th);
  104.26 +    snprintf(thstr, sizeof(thstr), "%lX", (unsigned long)th);
  104.27      return PyString_FromString(thstr);
  104.28  }
  104.29  
   105.1 --- a/tools/python/xen/util/acmpolicy.py	Tue Jun 10 16:00:33 2008 +0900
   105.2 +++ b/tools/python/xen/util/acmpolicy.py	Thu Jun 19 12:46:26 2008 +0900
   105.3 @@ -507,7 +507,7 @@ class ACMPolicy(XSPolicy):
   105.4              rc = self.compile()
   105.5          return rc, errors
   105.6  
   105.7 -    def force_default_policy(klass):
   105.8 +    def force_default_policy(klass, policy_ref):
   105.9          """
  105.10             Force the installation of the DEFAULT policy if for
  105.11             example no XML of the current policy is available and
  105.12 @@ -518,7 +518,7 @@ class ACMPolicy(XSPolicy):
  105.13          """
  105.14          errors = ""
  105.15  
  105.16 -        acmpol_new = ACMPolicy(xml = get_DEFAULT_policy())
  105.17 +        acmpol_new = ACMPolicy(xml = get_DEFAULT_policy(), ref=policy_ref)
  105.18  
  105.19          from xen.lowlevel import acm
  105.20          dom0_ssidref = acm.getssid(0)
  105.21 @@ -1323,6 +1323,13 @@ class ACMPolicy(XSPolicy):
  105.22          if ACM_LABEL_UNLABELED in resnames:
  105.23              resnames.remove(ACM_LABEL_UNLABELED)
  105.24  
  105.25 +        # check for duplicate labels
  105.26 +        if len(vmlabels) != len(set(vmlabels)) or \
  105.27 +           len(resnames) != len(set(resnames)) or \
  105.28 +           len(stes)     != len(set(stes))     or \
  105.29 +           len(chws)     != len(set(chws)):
  105.30 +            return -xsconstants.XSERR_POLICY_HAS_DUPLICATES, "", ""
  105.31 +
  105.32          max_chw_ssids = 1 + len(vms_with_chws)
  105.33          max_chw_types = 1 + len(vms_with_chws)
  105.34          max_ste_ssids = 1 + len(vms_with_stes) + len(resnames)
   106.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   106.2 +++ b/tools/python/xen/util/oshelp.py	Thu Jun 19 12:46:26 2008 +0900
   106.3 @@ -0,0 +1,20 @@
   106.4 +import fcntl
   106.5 +import os
   106.6 +
   106.7 +def fcntl_setfd_cloexec(file, bool):
   106.8 +        f = fcntl.fcntl(file, fcntl.F_GETFD)
   106.9 +        if bool: f |= fcntl.FD_CLOEXEC
  106.10 +        else: f &= ~fcntl.FD_CLOEXEC
  106.11 +        fcntl.fcntl(file, fcntl.F_SETFD)
  106.12 +
  106.13 +def waitstatus_description(st):
  106.14 +        if os.WIFEXITED(st):
  106.15 +                es = os.WEXITSTATUS(st)
  106.16 +                if es: return "exited with nonzero status %i" % es
  106.17 +                else: return "exited"
  106.18 +        elif os.WIFSIGNALED(st):
  106.19 +                s = "died due to signal %i" % os.WTERMSIG(st)
  106.20 +                if os.WCOREDUMP(st): s += " (core dumped)"
  106.21 +                return s
  106.22 +        else:
  106.23 +                return "failed with unexpected wait status %i" % st
   107.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   107.2 +++ b/tools/python/xen/util/utils.py	Thu Jun 19 12:46:26 2008 +0900
   107.3 @@ -0,0 +1,6 @@
   107.4 +import traceback
   107.5 +import sys
   107.6 +
   107.7 +def exception_string(e):
   107.8 +        (ty,v,tb) = sys.exc_info()
   107.9 +        return traceback.format_exception_only(ty,v)
   108.1 --- a/tools/python/xen/util/xsconstants.py	Tue Jun 10 16:00:33 2008 +0900
   108.2 +++ b/tools/python/xen/util/xsconstants.py	Thu Jun 19 12:46:26 2008 +0900
   108.3 @@ -59,7 +59,8 @@ XSERR_HV_OP_FAILED             = 24 + XS
   108.4  XSERR_BOOTPOLICY_INSTALL_ERROR = 25 + XSERR_BASE
   108.5  XSERR_VM_NOT_AUTHORIZED        = 26 + XSERR_BASE
   108.6  XSERR_VM_IN_CONFLICT           = 27 + XSERR_BASE
   108.7 -XSERR_LAST                     = 27 + XSERR_BASE ## KEEP LAST
   108.8 +XSERR_POLICY_HAS_DUPLICATES    = 28 + XSERR_BASE
   108.9 +XSERR_LAST                     = 28 + XSERR_BASE ## KEEP LAST
  108.10  
  108.11  XSERR_MESSAGES = [
  108.12      '',
  108.13 @@ -89,7 +90,8 @@ XSERR_MESSAGES = [
  108.14      'Operation failed in hypervisor',
  108.15      'Boot policy installation error',
  108.16      'VM is not authorized to run',
  108.17 -    'VM label conflicts with another VM'
  108.18 +    'VM label conflicts with another VM',
  108.19 +    'Duplicate labels or types in policy'
  108.20  ]
  108.21  
  108.22  def xserr2string(err):
  108.23 @@ -101,8 +103,10 @@ def xserr2string(err):
  108.24      return "Unknown XSERR code '%s'." % (hex(err))
  108.25  
  108.26  # Policy identifiers used in labels
  108.27 -ACM_POLICY_ID = "ACM"
  108.28 +ACM_POLICY_ID = 'ACM'
  108.29  
  108.30 -INVALID_POLICY_PREFIX = "INV_"
  108.31 +INVALID_POLICY_PREFIX = 'INV_'
  108.32  
  108.33  INVALID_SSIDREF = 0xFFFFFFFF
  108.34 +
  108.35 +XS_INACCESSIBLE_LABEL = '__INACCESSIBLE__'
   109.1 --- a/tools/python/xen/util/xsm/acm/acm.py	Tue Jun 10 16:00:33 2008 +0900
   109.2 +++ b/tools/python/xen/util/xsm/acm/acm.py	Thu Jun 19 12:46:26 2008 +0900
   109.3 @@ -720,19 +720,24 @@ def list_labels(policy_name, ltype):
   109.4      else:
   109.5          err("Unknown label type \'" + ltype + "\'")
   109.6  
   109.7 -    (primary, secondary, f, pol_exists) = getmapfile(policy_name)
   109.8 -    if not f:
   109.9 -        if pol_exists:
  109.10 -            err("Cannot find mapfile for policy \'" + policy_name + "\'.\n")
  109.11 -        else:
  109.12 -            err("Unknown policy \'" + policy_name + "\'")
  109.13 +    try:
  109.14 +        mapfile_lock()
  109.15  
  109.16 -    labels = []
  109.17 -    for line in f:
  109.18 -        if condition.match(line):
  109.19 -            label = line.split()[3]
  109.20 -            if label not in labels:
  109.21 -                labels.append(label)
  109.22 +        (primary, secondary, f, pol_exists) = getmapfile(policy_name)
  109.23 +        if not f:
  109.24 +            if pol_exists:
  109.25 +                err("Cannot find mapfile for policy \'" + policy_name + "\'.\n")
  109.26 +            else:
  109.27 +                err("Unknown policy \'" + policy_name + "\'")
  109.28 +
  109.29 +        labels = []
  109.30 +        for line in f:
  109.31 +            if condition.match(line):
  109.32 +                label = line.split()[3]
  109.33 +                if label not in labels:
  109.34 +                    labels.append(label)
  109.35 +    finally:
  109.36 +        mapfile_unlock()
  109.37  
  109.38      if '__NULL_LABEL__' in labels:
  109.39          labels.remove('__NULL_LABEL__')
  109.40 @@ -778,8 +783,6 @@ def get_res_security_details(resource):
  109.41          policy = active_policy
  109.42          return (label, ssidref, policy)
  109.43  
  109.44 -    (label, ssidref, policy) = default_security_details()
  109.45 -
  109.46      # find the entry associated with this resource
  109.47      (policytype, label, policy) = get_res_label(resource)
  109.48      if policy == 'NULL':
  109.49 @@ -793,6 +796,8 @@ def get_res_security_details(resource):
  109.50      # is this resource label for the running policy?
  109.51      if policy == active_policy:
  109.52          ssidref = label2ssidref(label, policy, 'res')
  109.53 +    elif label == xsconstants.XS_INACCESSIBLE_LABEL:
  109.54 +        ssidref = NULL_SSIDREF
  109.55      else:
  109.56          log.info("Resource label not for active policy, using DEFAULT.")
  109.57          return default_security_details()
  109.58 @@ -916,6 +921,8 @@ def res_security_check_xapi(rlabel, rssi
  109.59      rtnval = 1
  109.60      # if security is on, ask the hypervisor for a decision
  109.61      if on():
  109.62 +        if rlabel == xsconstants.XS_INACCESSIBLE_LABEL:
  109.63 +            return 0
  109.64          typ, dpolicy, domain_label = xapi_dom_label.split(":")
  109.65          if not dpolicy or not domain_label:
  109.66              raise VmError("VM security label in wrong format.")
  109.67 @@ -973,6 +980,8 @@ def validate_label(policytype, policyref
  109.68      if not policytype or not label:
  109.69          return -xsconstants.XSERR_BAD_LABEL_FORMAT
  109.70      rc = xsconstants.XSERR_SUCCESS
  109.71 +    if label == xsconstants.XS_INACCESSIBLE_LABEL:
  109.72 +        return rc
  109.73      from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance
  109.74      curpol = XSPolicyAdminInstance().get_loaded_policy()
  109.75      if not curpol or curpol.get_name() != policyref:
  109.76 @@ -1197,20 +1206,23 @@ def set_resource_label(resource, policyt
  109.77      @return Success (0) or failure value (< 0)
  109.78      """
  109.79  
  109.80 -    if reslabel != "":
  109.81 -        ssidref = label2ssidref(reslabel, policyref, 'res')
  109.82  
  109.83      try:
  109.84          resource = unify_resname(resource, mustexist=False)
  109.85      except Exception:
  109.86          return -xsconstants.XSERR_BAD_RESOURCE_FORMAT
  109.87  
  109.88 -    domains = is_resource_in_use(resource)
  109.89 -    if len(domains) > 0:
  109.90 -        return -xsconstants.XSERR_RESOURCE_IN_USE
  109.91 -
  109.92      try:
  109.93          resfile_lock()
  109.94 +        mapfile_lock()
  109.95 +
  109.96 +        if reslabel not in [ '', xsconstants.XS_INACCESSIBLE_LABEL ]:
  109.97 +            ssidref = label2ssidref(reslabel, policyref, 'res')
  109.98 +
  109.99 +        domains = is_resource_in_use(resource)
 109.100 +        if len(domains) > 0:
 109.101 +            return -xsconstants.XSERR_RESOURCE_IN_USE
 109.102 +
 109.103          access_control = {}
 109.104          try:
 109.105               access_control = dictio.dict_read("resources", res_label_filename)
 109.106 @@ -1229,6 +1241,11 @@ def set_resource_label(resource, policyt
 109.107                  if value == tuple([policytype, policyref, reslabel]) and \
 109.108                     key.startswith('vlan:'):
 109.109                      return -xsconstants.XSERR_BAD_LABEL
 109.110 +
 109.111 +        if reslabel == xsconstants.XS_INACCESSIBLE_LABEL:
 109.112 +            policytype = xsconstants.ACM_POLICY_ID
 109.113 +            policyref  = '*'
 109.114 +
 109.115          if reslabel != "":
 109.116              new_entry = { resource : tuple([policytype, policyref, reslabel])}
 109.117              access_control.update(new_entry)
 109.118 @@ -1243,6 +1260,7 @@ def set_resource_label(resource, policyt
 109.119          dictio.dict_write(access_control, "resources", res_label_filename)
 109.120      finally:
 109.121          resfile_unlock()
 109.122 +        mapfile_unlock()
 109.123      return xsconstants.XSERR_SUCCESS
 109.124  
 109.125  def rm_resource_label(resource, oldlabel_xapi):
   110.1 --- a/tools/python/xen/xend/XendAPI.py	Tue Jun 10 16:00:33 2008 +0900
   110.2 +++ b/tools/python/xen/xend/XendAPI.py	Thu Jun 19 12:46:26 2008 +0900
   110.3 @@ -1707,11 +1707,13 @@ class XendAPI(object):
   110.4