[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User Isaku Yamahata <yamahata@xxxxxxxxxxxxx> # Date 1213847186 -32400 # Node ID 0034766b45c27400b334fd202eb397d30776e06a # Parent 1201c765783217371166062621e8926cb7643cfd # Parent b55f6d42668d862170df03dc42995a0600f93fc6 merge with xen-unstable.hg --- xen/drivers/acpi/utglobal.c | 136 - .hgignore | 7 buildconfigs/select-repository | 57 extras/mini-os/Makefile | 41 extras/mini-os/arch/ia64/Makefile | 7 extras/mini-os/arch/ia64/common.c | 6 extras/mini-os/arch/ia64/time.c | 6 extras/mini-os/arch/x86/Makefile | 10 extras/mini-os/arch/x86/mm.c | 10 extras/mini-os/arch/x86/setup.c | 10 extras/mini-os/arch/x86/time.c | 9 extras/mini-os/arch/x86/traps.c | 4 extras/mini-os/arch/x86/x86_32.S | 2 extras/mini-os/blkfront.c | 55 extras/mini-os/console/console.c | 12 extras/mini-os/console/xencons_ring.c | 44 extras/mini-os/events.c | 35 extras/mini-os/fbfront.c | 52 extras/mini-os/fs-front.c | 2 extras/mini-os/gnttab.c | 14 extras/mini-os/include/blkfront.h | 7 extras/mini-os/include/byteswap.h | 39 extras/mini-os/include/console.h | 10 extras/mini-os/include/events.h | 1 extras/mini-os/include/gnttab.h | 1 extras/mini-os/include/ia64/os.h | 3 extras/mini-os/include/ia64/traps.h | 4 extras/mini-os/include/kernel.h | 7 extras/mini-os/include/mm.h | 1 extras/mini-os/include/netfront.h | 1 extras/mini-os/include/time.h | 1 extras/mini-os/include/wait.h | 2 extras/mini-os/include/x86/arch_mm.h | 24 extras/mini-os/include/x86/os.h | 4 extras/mini-os/include/xenbus.h | 3 extras/mini-os/kernel.c | 48 extras/mini-os/lib/sys.c | 48 extras/mini-os/lwip-net.c | 6 extras/mini-os/main.c | 39 extras/mini-os/minios.mk | 6 extras/mini-os/mm.c | 4 extras/mini-os/netfront.c | 21 extras/mini-os/xenbus/xenbus.c | 17 stubdom/Makefile | 106 - stubdom/README | 70 stubdom/c/Makefile | 5 stubdom/caml/Makefile | 5 stubdom/grub.patches/10graphics.diff | 772 +++++++++ stubdom/grub.patches/20print_func.diff | 47 stubdom/grub.patches/30savedefault.diff | 60 stubdom/grub.patches/40ext3_256byte_inode.diff | 51 stubdom/grub.patches/99minios | 1085 ++++++++++++++ stubdom/grub/Makefile | 76 stubdom/grub/boot-x86_32.S | 112 + stubdom/grub/boot-x86_64.S | 108 + stubdom/grub/config.h | 11 stubdom/grub/kexec.c | 324 ++++ stubdom/grub/mini-os.c | 702 +++++++++ stubdom/grub/mini-os.h | 5 stubdom/grub/osdep.h | 30 tools/console/daemon/io.c | 3 tools/examples/xmexample.hvm | 10 tools/firmware/rombios/rombios.c | 45 tools/fs-back/fs-ops.c | 21 tools/fs-back/fs-xenbus.c | 22 tools/include/xen-sys/NetBSD/privcmd.h | 1 tools/ioemu/Makefile.target | 11 tools/ioemu/cocoa.m | 2 tools/ioemu/hw/pc.c | 7 tools/ioemu/hw/pci_emulation.c | 118 + tools/ioemu/hw/pci_emulation.h | 24 tools/ioemu/hw/pl110.c | 4 tools/ioemu/hw/tcx.c | 2 tools/ioemu/hw/usb-msd.c | 4 tools/ioemu/hw/usb.h | 2 tools/ioemu/hw/vga.c | 153 + tools/ioemu/hw/vga_int.h | 1 tools/ioemu/hw/xenfb.c | 343 ---- tools/ioemu/hw/xenfb.h | 2 tools/ioemu/monitor.c | 2 tools/ioemu/sdl.c | 35 tools/ioemu/vl.c | 43 tools/ioemu/vl.h | 24 tools/ioemu/vnc.c | 18 tools/ioemu/xenfbfront.c | 315 ++++ tools/libfsimage/ufs/fsys_ufs.c | 6 tools/libfsimage/zfs/fsys_zfs.c | 12 tools/libxc/Makefile | 2 tools/libxc/ia64/dom_fw_acpi.c | 29 tools/libxc/xc_cpuid_x86.c | 268 ++- tools/libxc/xc_dom.h | 3 tools/libxc/xc_dom_core.c | 6 tools/libxc/xc_dom_x86.c | 4 tools/libxc/xc_domain_restore.c | 16 tools/libxc/xc_domain_save.c | 19 tools/libxc/xc_netbsd.c | 6 tools/misc/Makefile | 9 tools/misc/nsplitd/nsplitd.c | 2 tools/misc/xenperf.c | 2 tools/python/get-path | 22 tools/python/install-wrap | 44 tools/python/xen/lowlevel/acm/acm.c | 3 tools/python/xen/lowlevel/xc/xc.c | 15 tools/python/xen/lowlevel/xs/xs.c | 6 tools/python/xen/util/acmpolicy.py | 11 tools/python/xen/util/oshelp.py | 20 tools/python/xen/util/utils.py | 6 tools/python/xen/util/xsconstants.py | 12 tools/python/xen/util/xsm/acm/acm.py | 60 tools/python/xen/xend/XendAPI.py | 6 tools/python/xen/xend/XendConfig.py | 7 tools/python/xen/xend/XendDomain.py | 4 tools/python/xen/xend/XendDomainInfo.py | 4 tools/python/xen/xend/XendLogging.py | 6 tools/python/xen/xend/XendOptions.py | 4 tools/python/xen/xend/XendXSPolicyAdmin.py | 2 tools/python/xen/xend/balloon.py | 2 tools/python/xen/xend/image.py | 255 ++- tools/python/xen/xend/server/blkif.py | 2 tools/python/xen/xm/create.py | 2 tools/python/xen/xm/main.py | 8 tools/python/xen/xm/xenapi_create.py | 113 + tools/vnet/vnet-module/varp_util.h | 6 tools/vnet/vnet-module/vnet.c | 2 tools/vtpm_manager/migration/vtpm_migratord_handler.c | 22 tools/xenmon/xenbaked.c | 8 tools/xenstat/libxenstat/src/xenstat_linux.c | 31 tools/xenstat/xentop/xentop.c | 7 tools/xenstore/hashtable.c | 25 tools/xenstore/list.h | 4 tools/xentrace/formats | 57 tools/xentrace/xentrace_format | 24 unmodified_drivers/linux-2.6/platform-pci/panic-handler.c | 28 xen/arch/ia64/xen/acpi.c | 36 xen/arch/ia64/xen/dom_fw_common.c | 21 xen/arch/ia64/xen/dom_fw_dom0.c | 84 - xen/arch/ia64/xen/machine_kexec.c | 9 xen/arch/ia64/xen/mm.c | 2 xen/arch/ia64/xen/xenmem.c | 2 xen/arch/x86/acpi/boot.c | 114 - xen/arch/x86/acpi/cpu_idle.c | 45 xen/arch/x86/domain.c | 150 - xen/arch/x86/domain_build.c | 14 xen/arch/x86/hpet.c | 24 xen/arch/x86/hvm/hvm.c | 61 xen/arch/x86/hvm/svm/intr.c | 16 xen/arch/x86/hvm/svm/svm.c | 28 xen/arch/x86/hvm/vlapic.c | 2 xen/arch/x86/hvm/vmsi.c | 14 xen/arch/x86/hvm/vmx/vmcs.c | 29 xen/arch/x86/hvm/vmx/vmx.c | 39 xen/arch/x86/machine_kexec.c | 13 xen/arch/x86/mm.c | 209 +- xen/arch/x86/mm/p2m.c | 4 xen/arch/x86/mm/shadow/common.c | 11 xen/arch/x86/mm/shadow/multi.c | 11 xen/arch/x86/shutdown.c | 218 +- xen/arch/x86/time.c | 4 xen/arch/x86/trace.c | 16 xen/arch/x86/traps.c | 100 - xen/arch/x86/x86_32/traps.c | 53 xen/arch/x86/x86_64/compat/mm.c | 8 xen/arch/x86/x86_64/cpu_idle.c | 2 xen/arch/x86/x86_64/mm.c | 47 xen/arch/x86/x86_64/traps.c | 70 xen/arch/x86/x86_emulate/x86_emulate.c | 30 xen/common/compat/domain.c | 2 xen/common/compat/grant_table.c | 2 xen/common/compat/memory.c | 13 xen/common/kexec.c | 65 xen/common/keyhandler.c | 21 xen/common/memory.c | 13 xen/common/page_alloc.c | 2 xen/common/schedule.c | 3 xen/drivers/acpi/Makefile | 5 xen/drivers/acpi/numa.c | 54 xen/drivers/acpi/osl.c | 54 xen/drivers/acpi/reboot.c | 37 xen/drivers/acpi/tables.c | 773 ++------- xen/drivers/acpi/tables/Makefile | 5 xen/drivers/acpi/tables/tbfadt.c | 458 +++++ xen/drivers/acpi/tables/tbinstal.c | 150 + xen/drivers/acpi/tables/tbutils.c | 560 +++++++ xen/drivers/acpi/tables/tbxface.c | 261 +++ xen/drivers/acpi/tables/tbxfroot.c | 275 +++ xen/drivers/acpi/utilities/Makefile | 2 xen/drivers/acpi/utilities/utglobal.c | 740 +++++++++ xen/drivers/acpi/utilities/utmisc.c | 229 ++ xen/drivers/char/console.c | 6 xen/drivers/char/serial.c | 70 xen/drivers/passthrough/amd/iommu_acpi.c | 5 xen/drivers/passthrough/amd/pci_amd_iommu.c | 2 xen/drivers/passthrough/io.c | 7 xen/drivers/passthrough/iommu.c | 16 xen/drivers/passthrough/vtd/dmar.c | 21 xen/drivers/passthrough/vtd/intremap.c | 8 xen/drivers/passthrough/vtd/iommu.c | 67 xen/include/acpi/acnamesp.h | 305 +++ xen/include/acpi/actables.h | 118 + xen/include/acpi/platform/aclinux.h | 64 xen/include/asm-ia64/bug.h | 3 xen/include/asm-ia64/config.h | 3 xen/include/asm-ia64/mm.h | 3 xen/include/asm-ia64/xenprocessor.h | 2 xen/include/asm-x86/config.h | 10 xen/include/asm-x86/domain.h | 14 xen/include/asm-x86/guest_access.h | 55 xen/include/asm-x86/hpet.h | 1 xen/include/asm-x86/hvm/guest_access.h | 2 xen/include/asm-x86/hvm/svm/amd-iommu-proto.h | 2 xen/include/asm-x86/hvm/trace.h | 252 +-- xen/include/asm-x86/hvm/vmx/vmx.h | 2 xen/include/asm-x86/mm.h | 20 xen/include/asm-x86/percpu.h | 2 xen/include/asm-x86/perfc_defn.h | 5 xen/include/asm-x86/softirq.h | 4 xen/include/asm-x86/uaccess.h | 4 xen/include/asm-x86/x86_32/uaccess.h | 2 xen/include/asm-x86/x86_64/uaccess.h | 20 xen/include/public/kexec.h | 22 xen/include/public/trace.h | 11 xen/include/xen/acpi.h | 82 - xen/include/xen/compat.h | 16 xen/include/xen/compiler.h | 6 xen/include/xen/mm.h | 2 xen/include/xen/serial.h | 8 xen/include/xen/xencomm.h | 1 xen/tools/get-fields.sh | 4 228 files changed, 10302 insertions(+), 2964 deletions(-) diff -r 1201c7657832 -r 0034766b45c2 .hgignore --- a/.hgignore Tue Jun 10 16:00:33 2008 +0900 +++ b/.hgignore Thu Jun 19 12:46:26 2008 +0900 @@ -1,6 +1,7 @@ .*\.a$ .*\.cmi$ .*\.cmo$ +.*\.cmx$ .*\.d$ .*\.o$ .*\.opic$ @@ -62,6 +63,7 @@ ^extras/mini-os/h/hypervisor-ifs$ ^extras/mini-os/h/xen-public$ ^extras/mini-os/mini-os.*$ +^extras/mini-os/*-stubdom.*$ ^install/.*$ ^linux-[^/]*-paravirt/.*$ ^linux-2.6[^/]*/.*$ @@ -88,10 +90,13 @@ ^stubdom/ioemu$ ^stubdom/libxc$ ^stubdom/lwip-.*$ -^stubdom/mini-os$ +^stubdom/mini-os-.*$ ^stubdom/newlib-.*$ ^stubdom/pciutils-.*$ ^stubdom/zlib-.*$ +^stubdom/grub-cvs$ +^stubdom/grub/stage2$ +^stubdom/grub/netboot$ ^tools/.*/TAGS$ ^tools/.*/build/lib.*/.*\.py$ ^tools/blktap/Makefile\.smh$ diff -r 1201c7657832 -r 0034766b45c2 buildconfigs/select-repository --- a/buildconfigs/select-repository Tue Jun 10 16:00:33 2008 +0900 +++ b/buildconfigs/select-repository Thu Jun 19 12:46:26 2008 +0900 @@ -32,31 +32,38 @@ if [ X"${LINUX_SRC_PATH}" != X ] ; then IFS="$IFS_saved" fi -XEN=$(hg -R ${XEN_ROOT} path default) -if [ $? -ne 0 ] || [ X"$XEN" = "X" ] ; then - echo "$ME: Unable to determine Xen repository parent." 1>&2 - exit 1; +if [ -d ${XEN_ROOT}/.hgxxx ] ; then + XEN=$(hg -R ${XEN_ROOT} path default) + if [ $? -ne 0 ] || [ X"$XEN" = "X" ] ; then + echo "$ME: Unable to determine Xen repository parent." 1>&2 + exit 1; + fi + + BASE=$(dirname ${XEN}) + if [ $? -ne 0 ] || [ X"$BASE" = "X" ] ; then + echo "$ME: Unable to determine Xen repository base." 1>&2 + exit 1; + fi + if [ -d "$XEN" ] && [ ! -d "$BASE/$REPO" ] ; then + echo "$ME: No such dir: $BASE/$REPO" 1>&2 + exit 1 + fi + + echo "$ME: Found ${BASE}/${REPO}" 1>&2 + + # If ${BASE}/${REPO} is a local directory then prepend file:// so that + # the test in src.hg-clone will fail and we will clone instead of + # linking this repository. We only want to link repositories which + # were found via LINUX_SRC_PATH. + if [ -d "${BASE}/${REPO}" ] ; then + echo "file://${BASE}/${REPO}" + else + echo ${BASE}/${REPO} + fi +else + echo "Unable to determine path to Linux source tree." 1>&2 + echo "Falling back to linux-2.6.18-xen Mercurial repository." 1>&2 + echo http://xenbits.xensource.com/linux-2.6.18-xen.hg fi -BASE=$(dirname ${XEN}) -if [ $? -ne 0 ] || [ X"$BASE" = "X" ] ; then - echo "$ME: Unable to determine Xen repository base." 1>&2 - exit 1; -fi -if [ -d "$XEN" ] && [ ! -d "$BASE/$REPO" ] ; then - echo "$ME: No such dir: $BASE/$REPO" 1>&2 - exit 1 -fi - -echo "$ME: Found ${BASE}/${REPO}" 1>&2 - -# If ${BASE}/${REPO} is a local directory then prepend file:// so that -# the test in src.hg-clone will fail and we will clone instead of -# linking this repository. We only want to link repositories which -# were found via LINUX_SRC_PATH. -if [ -d "${BASE}/${REPO}" ] ; then - echo "file://${BASE}/${REPO}" -else - echo ${BASE}/${REPO} -fi exit 0 diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/Makefile --- a/extras/mini-os/Makefile Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/Makefile Thu Jun 19 12:46:26 2008 +0900 @@ -6,6 +6,7 @@ export XEN_ROOT = ../.. include $(XEN_ROOT)/Config.mk +OBJ_DIR ?= $(CURDIR) ifneq ($(stubdom),y) include Config.mk @@ -20,7 +21,7 @@ include minios.mk # Define some default flags for linking. LDLIBS := APP_LDLIBS := -LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME) +LDARCHLIB := -L$(OBJ_DIR)/$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME) LDFLAGS_FINAL := -T $(TARGET_ARCH_DIR)/minios-$(XEN_TARGET_ARCH).lds # Prefix for global API names. All other symbols are localised before @@ -35,14 +36,14 @@ SUBDIRS := lib xenbus console # The common mini-os objects to build. APP_OBJS := -OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) -OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c)) -OBJS += $(patsubst %.c,%.o,$(wildcard xenbus/*.c)) -OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c)) +OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard *.c)) +OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard lib/*.c)) +OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard xenbus/*.c)) +OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard console/*.c)) .PHONY: default -default: $(TARGET) +default: $(OBJ_DIR)/$(TARGET) # Create special architecture specific links. The function arch_links # has to be defined in arch.mk (see include above). @@ -57,7 +58,7 @@ links: $(ARCH_LINKS) .PHONY: arch_lib arch_lib: - $(MAKE) --directory=$(TARGET_ARCH_DIR) || exit 1; + $(MAKE) --directory=$(TARGET_ARCH_DIR) OBJ_DIR=$(OBJ_DIR)/$(TARGET_ARCH_DIR) || exit 1; ifeq ($(lwip),y) # lwIP library @@ -66,14 +67,14 @@ LWC += lwip-arch.c lwip-net.c LWC += lwip-arch.c lwip-net.c LWO := $(patsubst %.c,%.o,$(LWC)) -lwip.a: $(LWO) +$(OBJ_DIR)/lwip.a: $(LWO) $(RM) $@ $(AR) cqs $@ $^ -OBJS += lwip.a +OBJS += $(OBJ_DIR)/lwip.a endif -OBJS := $(filter-out main.o lwip%.o $(LWO), $(OBJS)) +OBJS := $(filter-out $(OBJ_DIR)/lwip%.o $(LWO), $(OBJS)) ifeq ($(libc),y) APP_LDLIBS += -L$(XEN_ROOT)/stubdom/libxc -whole-archive -lxenguest -lxenctrl -no-whole-archive @@ -84,14 +85,14 @@ endif endif ifneq ($(APP_OBJS)-$(lwip),-y) -OBJS := $(filter-out daytime.o, $(OBJS)) +OBJS := $(filter-out $(OBJ_DIR)/daytime.o, $(OBJS)) endif -$(TARGET)_app.o: $(APP_OBJS) app.lds - $(LD) -r -d $(LDFLAGS) $^ $(APP_LDLIBS) --undefined app_main -o $@ +$(OBJ_DIR)/$(TARGET)_app.o: $(APP_OBJS) app.lds + $(LD) -r -d $(LDFLAGS) $^ $(APP_LDLIBS) --undefined main -o $@ -$(TARGET): links $(OBJS) $(TARGET)_app.o arch_lib - $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(TARGET)_app.o $(OBJS) $(LDARCHLIB) $(LDLIBS) -o $@.o +$(OBJ_DIR)/$(TARGET): links $(OBJS) $(OBJ_DIR)/$(TARGET)_app.o arch_lib + $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJ_DIR)/$(TARGET)_app.o $(OBJS) $(LDARCHLIB) $(LDLIBS) -o $@.o $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o $(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@ gzip -f -9 -c $@ >$@.gz @@ -99,15 +100,15 @@ endif .PHONY: clean arch_clean arch_clean: - $(MAKE) --directory=$(TARGET_ARCH_DIR) clean || exit 1; + $(MAKE) --directory=$(TARGET_ARCH_DIR) OBJ_DIR=$(OBJ_DIR)/$(TARGET_ARCH_DIR) clean || exit 1; clean: arch_clean - for dir in $(SUBDIRS); do \ + for dir in $(addprefix $(OBJ_DIR)/,$(SUBDIRS)); do \ rm -f $$dir/*.o; \ done - rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz - find . -type l | xargs rm -f - $(RM) lwip.a $(LWO) + rm -f $(OBJ_DIR)/*.o *~ $(OBJ_DIR)/core $(OBJ_DIR)/$(TARGET).elf $(OBJ_DIR)/$(TARGET).raw $(OBJ_DIR)/$(TARGET) $(OBJ_DIR)/$(TARGET).gz + find . $(OBJ_DIR) -type l | xargs rm -f + $(RM) $(OBJ_DIR)/lwip.a $(LWO) rm -f tags TAGS diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/ia64/Makefile --- a/extras/mini-os/arch/ia64/Makefile Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/arch/ia64/Makefile Thu Jun 19 12:46:26 2008 +0900 @@ -40,12 +40,13 @@ ARCH_OBJS += __udivdi3.o ARCH_OBJS += __udivdi3.o ARCH_OBJS += __udivsi3.o ARCH_OBJS += __divdi3.o +ARCH_OBJS := $(addprefix $(OBJ_DIR)/,$(ARCH_OBJS)) GEN_OFF_SRC := gen_off.c GEN_OFF_ASM := gen_off.s GEN_OFF_H := $(MINI-OS_ROOT)/include/$(ARCH_INC)/offsets.h -all: $(ARCH_LIB) +all: $(OBJ_DIR)/$(ARCH_LIB) $(GEN_OFF_ASM): $(GEN_OFF_SRC) $(CC) -S -o $@ $(CPPFLAGS) $< @@ -53,10 +54,10 @@ all: $(ARCH_LIB) $(GEN_OFF_H): $(GEN_OFF_ASM) sed -ne "/^->/ {s/->/#define /; p}" < $< > $@ -$(ARCH_LIB): $(GEN_OFF_H) $(ARCH_OBJS) $(HEAD_ARCH_OBJ) +$(OBJ_DIR)/$(ARCH_LIB): $(GEN_OFF_H) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ) $(AR) rv $(ARCH_LIB) $(ARCH_OBJS) clean: - rm -f $(ARCH_LIB) $(ARCH_OBJS) $(HEAD_ARCH_OBJ) + rm -f $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ) rm -f $(GEN_OFF_ASM) rm -f $(GEN_OFF_H) diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/ia64/common.c --- a/extras/mini-os/arch/ia64/common.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/arch/ia64/common.c Thu Jun 19 12:46:26 2008 +0900 @@ -236,6 +236,12 @@ arch_init(start_info_t *si) } void +arch_fini(void) +{ + /* TODO */ +} + +void arch_print_info(void) { int major, minor; diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/ia64/time.c --- a/extras/mini-os/arch/ia64/time.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/arch/ia64/time.c Thu Jun 19 12:46:26 2008 +0900 @@ -280,3 +280,9 @@ init_time(void) ia64_set_itm(new); ia64_srlz_d(); } + +void +fini_time(void) +{ + /* TODO */ +} diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/x86/Makefile --- a/extras/mini-os/arch/x86/Makefile Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/arch/x86/Makefile Thu Jun 19 12:46:26 2008 +0900 @@ -17,15 +17,15 @@ ARCH_SRCS := $(wildcard *.c) ARCH_SRCS := $(wildcard *.c) # The objects built from the sources. -ARCH_OBJS := $(patsubst %.c,%.o,$(ARCH_SRCS)) +ARCH_OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(ARCH_SRCS)) -all: $(ARCH_LIB) +all: $(OBJ_DIR)/$(ARCH_LIB) # $(HEAD_ARCH_OBJ) is only build here, needed on linking # in ../../Makefile. -$(ARCH_LIB): $(ARCH_OBJS) $(HEAD_ARCH_OBJ) - $(AR) rv $(ARCH_LIB) $(ARCH_OBJS) +$(OBJ_DIR)/$(ARCH_LIB): $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ) + $(AR) rv $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) clean: - rm -f $(ARCH_LIB) $(ARCH_OBJS) $(HEAD_ARCH_OBJ) + rm -f $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ) diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/x86/mm.c --- a/extras/mini-os/arch/x86/mm.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/arch/x86/mm.c Thu Jun 19 12:46:26 2008 +0900 @@ -59,7 +59,7 @@ void new_pt_frame(unsigned long *pt_pfn, { pgentry_t *tab = (pgentry_t *)start_info.pt_base; unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn); - unsigned long prot_e, prot_t; + pgentry_t prot_e, prot_t; mmu_update_t mmu_updates[1]; prot_e = prot_t = 0; @@ -69,7 +69,7 @@ void new_pt_frame(unsigned long *pt_pfn, /* We need to clear the page, otherwise we might fail to map it as a page table page */ - memset((unsigned long*)pfn_to_virt(*pt_pfn), 0, PAGE_SIZE); + memset((void*) pt_page, 0, PAGE_SIZE); switch ( level ) { @@ -99,7 +99,7 @@ void new_pt_frame(unsigned long *pt_pfn, #endif tab = pte_to_virt(tab[l3_table_offset(pt_page)]); - mmu_updates[0].ptr = ((pgentry_t)tab[l2_table_offset(pt_page)] & PAGE_MASK) + + mmu_updates[0].ptr = (tab[l2_table_offset(pt_page)] & PAGE_MASK) + sizeof(pgentry_t) * l1_table_offset(pt_page); mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | (prot_e & ~_PAGE_RW); @@ -372,7 +372,7 @@ static pgentry_t *get_pgt(unsigned long return &tab[offset]; } -static pgentry_t *need_pgt(unsigned long addr) +pgentry_t *need_pgt(unsigned long addr) { unsigned long mfn; pgentry_t *tab; @@ -474,7 +474,7 @@ void do_map_frames(unsigned long addr, if (!pgt || !(addr & L1_MASK)) pgt = need_pgt(addr); mmu_updates[i].ptr = virt_to_mach(pgt); - mmu_updates[i].val = ((f[(done + i) * stride] + (done + i) * increment) << PAGE_SHIFT) | prot; + mmu_updates[i].val = ((pgentry_t)(f[(done + i) * stride] + (done + i) * increment) << PAGE_SHIFT) | prot; } rc = HYPERVISOR_mmu_update(mmu_updates, todo, NULL, id); diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/x86/setup.c --- a/extras/mini-os/arch/x86/setup.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/arch/x86/setup.c Thu Jun 19 12:46:26 2008 +0900 @@ -100,6 +100,16 @@ arch_init(start_info_t *si) } void +arch_fini(void) +{ +#ifdef __i386__ + HYPERVISOR_set_callbacks(0, 0, 0, 0); +#else + HYPERVISOR_set_callbacks(0, 0, 0); +#endif +} + +void arch_print_info(void) { printk(" stack: %p-%p\n", stack, stack + sizeof(stack)); diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/x86/time.c --- a/extras/mini-os/arch/x86/time.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/arch/x86/time.c Thu Jun 19 12:46:26 2008 +0900 @@ -222,10 +222,17 @@ static void timer_handler(evtchn_port_t +static evtchn_port_t port; void init_time(void) { - evtchn_port_t port; printk("Initialising timer interface\n"); port = bind_virq(VIRQ_TIMER, &timer_handler, NULL); unmask_evtchn(port); } + +void fini_time(void) +{ + /* Clear any pending timer */ + HYPERVISOR_set_timer_op(0); + unbind_evtchn(port); +} diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/x86/traps.c --- a/extras/mini-os/arch/x86/traps.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/arch/x86/traps.c Thu Jun 19 12:46:26 2008 +0900 @@ -268,3 +268,7 @@ void trap_init(void) HYPERVISOR_set_trap_table(trap_table); } +void trap_fini(void) +{ + HYPERVISOR_set_trap_table(NULL); +} diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/x86/x86_32.S --- a/extras/mini-os/arch/x86/x86_32.S Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/arch/x86/x86_32.S Thu Jun 19 12:46:26 2008 +0900 @@ -8,7 +8,7 @@ .ascii ",VIRT_BASE=0x0" /* &_text from minios_x86_32.lds */ .ascii ",ELF_PADDR_OFFSET=0x0" .ascii ",HYPERCALL_PAGE=0x2" - .ascii ",PAE=yes" + .ascii ",PAE=yes[extended-cr3]" .ascii ",LOADER=generic" .byte 0 .text diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/blkfront.c --- a/extras/mini-os/blkfront.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/blkfront.c Thu Jun 19 12:46:26 2008 +0900 @@ -63,7 +63,8 @@ void blkfront_handler(evtchn_port_t port struct blkfront_dev *dev = data; int fd = dev->fd; - files[fd].read = 1; + if (fd != -1) + files[fd].read = 1; #endif wake_up(&blkfront_queue); } @@ -105,6 +106,9 @@ struct blkfront_dev *init_blkfront(char dev = malloc(sizeof(*dev)); memset(dev, 0, sizeof(*dev)); dev->nodename = strdup(nodename); +#ifdef HAVE_LIBC + dev->fd = -1; +#endif snprintf(path, sizeof(path), "%s/backend-id", nodename); dev->dom = xenbus_read_integer(path); @@ -238,7 +242,15 @@ void shutdown_blkfront(struct blkfront_d err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); xenbus_wait_for_value(path, "6", &dev->events); + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1); + xenbus_wait_for_value(path, "2", &dev->events); + xenbus_unwatch_path(XBT_NIL, path); + + snprintf(path, sizeof(path), "%s/ring-ref", nodename); + xenbus_rm(XBT_NIL, path); + snprintf(path, sizeof(path), "%s/event-channel", nodename); + xenbus_rm(XBT_NIL, path); free_blkfront(dev); } @@ -323,14 +335,33 @@ void blkfront_aio(struct blkfront_aiocb if(notify) notify_remote_via_evtchn(dev->evtchn); } -void blkfront_aio_write(struct blkfront_aiocb *aiocbp) -{ - blkfront_aio(aiocbp, 1); -} - -void blkfront_aio_read(struct blkfront_aiocb *aiocbp) -{ - blkfront_aio(aiocbp, 0); +static void blkfront_aio_cb(struct blkfront_aiocb *aiocbp, int ret) +{ + aiocbp->data = (void*) 1; +} + +void blkfront_io(struct blkfront_aiocb *aiocbp, int write) +{ + unsigned long flags; + ASSERT(!aiocbp->aio_cb); + aiocbp->aio_cb = blkfront_aio_cb; + blkfront_aio(aiocbp, write); + aiocbp->data = NULL; + + local_irq_save(flags); + DEFINE_WAIT(w); + while (1) { + blkfront_aio_poll(aiocbp->aio_dev); + if (aiocbp->data) + break; + + add_waiter(w, blkfront_queue); + local_irq_restore(flags); + schedule(); + local_irq_save(flags); + } + remove_waiter(w); + local_irq_restore(flags); } static void blkfront_push_operation(struct blkfront_dev *dev, uint8_t op, uint64_t id) @@ -397,8 +428,10 @@ int blkfront_aio_poll(struct blkfront_de moretodo: #ifdef HAVE_LIBC - files[dev->fd].read = 0; - mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */ + if (dev->fd != -1) { + files[dev->fd].read = 0; + mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */ + } #endif rp = dev->ring.sring->rsp_prod; diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/console/console.c --- a/extras/mini-os/console/console.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/console/console.c Thu Jun 19 12:46:26 2008 +0900 @@ -49,17 +49,13 @@ of standard dom0 handled console */ #define USE_XEN_CONSOLE -/* Low level functions defined in xencons_ring.c */ -extern int xencons_ring_init(void); -extern int xencons_ring_send(const char *data, unsigned len); -extern int xencons_ring_send_no_notify(const char *data, unsigned len); - /* If console not initialised the printk will be sent to xen serial line NOTE: you need to enable verbose in xen/Rules.mk for it to work. */ static int console_initialised = 0; +#ifndef HAVE_LIBC void xencons_rx(char *buf, unsigned len, struct pt_regs *regs) { if(len > 0) @@ -77,6 +73,7 @@ void xencons_tx(void) { /* Do nothing, handled by _rx */ } +#endif void console_print(char *data, int length) @@ -153,3 +150,8 @@ void init_console(void) /* This is also required to notify the daemon */ printk("done.\n"); } + +void fini_console(void) +{ + /* Destruct the console and get the parameters of the restarted one */ +} diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/console/xencons_ring.c --- a/extras/mini-os/console/xencons_ring.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/console/xencons_ring.c Thu Jun 19 12:46:26 2008 +0900 @@ -8,6 +8,7 @@ #include <xenbus.h> #include <xen/io/console.h> +DECLARE_WAIT_QUEUE_HEAD(console_queue); static inline struct xencons_interface *xencons_interface(void) { @@ -52,6 +53,9 @@ int xencons_ring_send(const char *data, static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *ign) { +#ifdef HAVE_LIBC + wake_up(&console_queue); +#else struct xencons_interface *intf = xencons_interface(); XENCONS_RING_IDX cons, prod; @@ -71,7 +75,47 @@ static void handle_input(evtchn_port_t p notify_daemon(); xencons_tx(); +#endif } + +#ifdef HAVE_LIBC +int xencons_ring_avail(void) +{ + struct xencons_interface *intf = xencons_interface(); + XENCONS_RING_IDX cons, prod; + + cons = intf->in_cons; + prod = intf->in_prod; + mb(); + BUG_ON((prod - cons) > sizeof(intf->in)); + + return prod - cons; +} + +int xencons_ring_recv(char *data, unsigned len) +{ + struct xencons_interface *intf = xencons_interface(); + XENCONS_RING_IDX cons, prod; + unsigned filled = 0; + + cons = intf->in_cons; + prod = intf->in_prod; + mb(); + BUG_ON((prod - cons) > sizeof(intf->in)); + + while (filled < len && cons + filled != prod) { + data[filled] = *(intf->in + MASK_XENCONS_IDX(cons + filled, intf->in)); + filled++; + } + + mb(); + intf->in_cons = cons + filled; + + notify_daemon(); + + return filled; +} +#endif int xencons_ring_init(void) { diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/events.c --- a/extras/mini-os/events.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/events.c Thu Jun 19 12:46:26 2008 +0900 @@ -39,19 +39,29 @@ void unbind_all_ports(void) void unbind_all_ports(void) { int i; + int cpu = 0; + shared_info_t *s = HYPERVISOR_shared_info; + vcpu_info_t *vcpu_info = &s->vcpu_info[cpu]; for (i = 0; i < NR_EVS; i++) { + if (i == start_info.console.domU.evtchn || + i == start_info.store_evtchn) + continue; if (test_and_clear_bit(i, bound_ports)) { struct evtchn_close close; + printk("port %d still bound!\n", i); mask_evtchn(i); close.port = i; HYPERVISOR_event_channel_op(EVTCHNOP_close, &close); + clear_evtchn(i); } } -} - + vcpu_info->evtchn_upcall_pending = 0; + vcpu_info->evtchn_pending_sel = 0; +} + /* * Demux events to different handlers. */ @@ -86,17 +96,27 @@ evtchn_port_t bind_evtchn(evtchn_port_t ev_actions[port].data = data; wmb(); ev_actions[port].handler = handler; + set_bit(port, bound_ports); return port; } void unbind_evtchn(evtchn_port_t port ) { + struct evtchn_close close; + if (ev_actions[port].handler == default_handler) printk("WARN: No handler for port %d when unbinding\n", port); + mask_evtchn(port); + clear_evtchn(port); + ev_actions[port].handler = default_handler; wmb(); ev_actions[port].data = NULL; + clear_bit(port, bound_ports); + + close.port = port; + HYPERVISOR_event_channel_op(EVTCHNOP_close, &close); } evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data) @@ -112,7 +132,6 @@ evtchn_port_t bind_virq(uint32_t virq, e printk("Failed to bind virtual IRQ %d\n", virq); return -1; } - set_bit(op.port,bound_ports); bind_evtchn(op.port, handler, data); return op.port; } @@ -145,6 +164,15 @@ void init_events(void) ev_actions[i].handler = default_handler; mask_evtchn(i); } +} + +void fini_events(void) +{ + /* Dealloc all events */ + unbind_all_ports(); +#if defined(__x86_64__) + wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */ +#endif } void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore) @@ -185,7 +213,6 @@ int evtchn_bind_interdomain(domid_t pal, int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op); if (err) return err; - set_bit(op.local_port,bound_ports); evtchn_port_t port = op.local_port; *local_port = bind_evtchn(port, handler, data); return err; diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/fbfront.c --- a/extras/mini-os/fbfront.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/fbfront.c Thu Jun 19 12:46:26 2008 +0900 @@ -44,7 +44,8 @@ void kbdfront_handler(evtchn_port_t port struct kbdfront_dev *dev = data; int fd = dev->fd; - files[fd].read = 1; + if (fd != -1) + files[fd].read = 1; #endif wake_up(&kbdfront_queue); } @@ -83,6 +84,9 @@ struct kbdfront_dev *init_kbdfront(char dev = malloc(sizeof(*dev)); dev->nodename = strdup(nodename); +#ifdef HAVE_LIBC + dev->fd = -1; +#endif snprintf(path, sizeof(path), "%s/backend-id", nodename); dev->dom = xenbus_read_integer(path); @@ -179,8 +183,10 @@ int kbdfront_receive(struct kbdfront_dev int i; #ifdef HAVE_LIBC - files[dev->fd].read = 0; - mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */ + if (dev->fd != -1) { + files[dev->fd].read = 0; + mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */ + } #endif prod = page->in_prod; @@ -198,7 +204,7 @@ int kbdfront_receive(struct kbdfront_dev notify_remote_via_evtchn(dev->evtchn); #ifdef HAVE_LIBC - if (cons != prod) + if (cons != prod && dev->fd != -1) /* still some events to read */ files[dev->fd].read = 1; #endif @@ -223,7 +229,18 @@ void shutdown_kbdfront(struct kbdfront_d err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); xenbus_wait_for_value(path, "6", &dev->events); + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1); + // does not work yet. + //xenbus_wait_for_value(path, "2", &dev->events); + xenbus_unwatch_path(XBT_NIL, path); + + snprintf(path, sizeof(path), "%s/page-ref", nodename); + xenbus_rm(XBT_NIL, path); + snprintf(path, sizeof(path), "%s/event-channel", nodename); + xenbus_rm(XBT_NIL, path); + snprintf(path, sizeof(path), "%s/request-abs-pointer", nodename); + xenbus_rm(XBT_NIL, path); free_kbdfront(dev); } @@ -279,7 +296,8 @@ void fbfront_handler(evtchn_port_t port, struct fbfront_dev *dev = data; int fd = dev->fd; - files[fd].read = 1; + if (fd != -1) + files[fd].read = 1; #endif wake_up(&fbfront_queue); } @@ -305,8 +323,10 @@ int fbfront_receive(struct fbfront_dev * int i; #ifdef HAVE_LIBC - files[dev->fd].read = 0; - mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */ + if (dev->fd != -1) { + files[dev->fd].read = 0; + mb(); /* Make sure to let the handler set read to 1 before we start looking at the ring */ + } #endif prod = page->in_prod; @@ -324,7 +344,7 @@ int fbfront_receive(struct fbfront_dev * notify_remote_via_evtchn(dev->evtchn); #ifdef HAVE_LIBC - if (cons != prod) + if (cons != prod && dev->fd != -1) /* still some events to read */ files[dev->fd].read = 1; #endif @@ -352,6 +372,9 @@ struct fbfront_dev *init_fbfront(char *n dev = malloc(sizeof(*dev)); dev->nodename = strdup(nodename); +#ifdef HAVE_LIBC + dev->fd = -1; +#endif snprintf(path, sizeof(path), "%s/backend-id", nodename); dev->dom = xenbus_read_integer(path); @@ -547,7 +570,20 @@ void shutdown_fbfront(struct fbfront_dev err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); xenbus_wait_for_value(path, "6", &dev->events); + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1); + // does not work yet + //xenbus_wait_for_value(path, "2", &dev->events); + xenbus_unwatch_path(XBT_NIL, path); + + snprintf(path, sizeof(path), "%s/page-ref", nodename); + xenbus_rm(XBT_NIL, path); + snprintf(path, sizeof(path), "%s/event-channel", nodename); + xenbus_rm(XBT_NIL, path); + snprintf(path, sizeof(path), "%s/protocol", nodename); + xenbus_rm(XBT_NIL, path); + snprintf(path, sizeof(path), "%s/feature-update", nodename); + xenbus_rm(XBT_NIL, path); unbind_evtchn(dev->evtchn); diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/fs-front.c --- a/extras/mini-os/fs-front.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/fs-front.c Thu Jun 19 12:46:26 2008 +0900 @@ -1127,3 +1127,5 @@ void init_fs_frontend(void) if (!fs_import) printk("No FS import\n"); } + +/* TODO: shutdown */ diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/gnttab.c --- a/extras/mini-os/gnttab.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/gnttab.c Thu Jun 19 12:46:26 2008 +0900 @@ -35,7 +35,7 @@ static grant_ref_t gnttab_list[NR_GRANT_ #ifdef GNT_DEBUG static char inuse[NR_GRANT_ENTRIES]; #endif -static __DECLARE_SEMAPHORE_GENERIC(gnttab_sem, NR_GRANT_ENTRIES); +static __DECLARE_SEMAPHORE_GENERIC(gnttab_sem, 0); static void put_free_entry(grant_ref_t ref) @@ -60,6 +60,7 @@ get_free_entry(void) down(&gnttab_sem); local_irq_save(flags); ref = gnttab_list[0]; + BUG_ON(ref < NR_RESERVED_ENTRIES || ref >= NR_GRANT_ENTRIES); gnttab_list[0] = gnttab_list[ref]; #ifdef GNT_DEBUG BUG_ON(inuse[ref]); @@ -193,3 +194,14 @@ init_gnttab(void) gnttab_table = map_frames(frames, NR_GRANT_FRAMES); printk("gnttab_table mapped at %p.\n", gnttab_table); } + +void +fini_gnttab(void) +{ + struct gnttab_setup_table setup; + + setup.dom = DOMID_SELF; + setup.nr_frames = 0; + + HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1); +} diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/blkfront.h --- a/extras/mini-os/include/blkfront.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/blkfront.h Thu Jun 19 12:46:26 2008 +0900 @@ -29,8 +29,11 @@ int blkfront_open(struct blkfront_dev *d int blkfront_open(struct blkfront_dev *dev); #endif void blkfront_aio(struct blkfront_aiocb *aiocbp, int write); -void blkfront_aio_read(struct blkfront_aiocb *aiocbp); -void blkfront_aio_write(struct blkfront_aiocb *aiocbp); +#define blkfront_aio_read(aiocbp) blkfront_aio(aiocbp, 0) +#define blkfront_aio_write(aiocbp) blkfront_aio(aiocbp, 1) +void blkfront_io(struct blkfront_aiocb *aiocbp, int write); +#define blkfront_read(aiocbp) blkfront_io(aiocbp, 0) +#define blkfront_write(aiocbp) blkfront_io(aiocbp, 1) void blkfront_aio_push_operation(struct blkfront_aiocb *aiocbp, uint8_t op); int blkfront_aio_poll(struct blkfront_dev *dev); void blkfront_sync(struct blkfront_dev *dev); diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/byteswap.h --- a/extras/mini-os/include/byteswap.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/byteswap.h Thu Jun 19 12:46:26 2008 +0900 @@ -2,21 +2,32 @@ #define _BYTESWAP_H_ /* Unfortunately not provided by newlib. */ -#define bswap_16(x) \ - ((((x) & 0xff00) >> 8) | (((x) & 0xff) << 8)) -#define bswap_32(x) \ - ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ - (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) +#include <types.h> +static inline uint16_t bswap_16(uint16_t x) +{ + return + ((((x) & 0xff00) >> 8) | (((x) & 0xff) << 8)); +} -#define bswap_64(x) \ - ((((x) & 0xff00000000000000ULL) >> 56) | \ - (((x) & 0x00ff000000000000ULL) >> 40) | \ - (((x) & 0x0000ff0000000000ULL) >> 24) | \ - (((x) & 0x000000ff00000000ULL) >> 8) | \ - (((x) & 0x00000000ff000000ULL) << 8) | \ - (((x) & 0x0000000000ff0000ULL) << 24) | \ - (((x) & 0x000000000000ff00ULL) << 40) | \ - (((x) & 0x00000000000000ffULL) << 56)) +static inline uint32_t bswap_32(uint32_t x) +{ + return + ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | + (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)); +} + +static inline uint64_t bswap_64(uint64_t x) +{ + return + ((((x) & 0xff00000000000000ULL) >> 56) | + (((x) & 0x00ff000000000000ULL) >> 40) | + (((x) & 0x0000ff0000000000ULL) >> 24) | + (((x) & 0x000000ff00000000ULL) >> 8) | + (((x) & 0x00000000ff000000ULL) << 8) | + (((x) & 0x0000000000ff0000ULL) << 24) | + (((x) & 0x000000000000ff00ULL) << 40) | + (((x) & 0x00000000000000ffULL) << 56)); +} #endif /* _BYTESWAP_H */ diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/console.h --- a/extras/mini-os/include/console.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/console.h Thu Jun 19 12:46:26 2008 +0900 @@ -51,5 +51,15 @@ void xencons_tx(void); void init_console(void); void console_print(char *data, int length); +void fini_console(void); + +/* Low level functions defined in xencons_ring.c */ +extern struct wait_queue_head console_queue; +int xencons_ring_init(void); +int xencons_ring_send(const char *data, unsigned len); +int xencons_ring_send_no_notify(const char *data, unsigned len); +int xencons_ring_avail(void); +int xencons_ring_recv(char *data, unsigned len); + #endif /* _LIB_CONSOLE_H_ */ diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/events.h --- a/extras/mini-os/include/events.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/events.h Thu Jun 19 12:46:26 2008 +0900 @@ -45,5 +45,6 @@ static inline int notify_remote_via_evtc return HYPERVISOR_event_channel_op(EVTCHNOP_send, &op); } +void fini_events(void); #endif /* _EVENTS_H_ */ diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/gnttab.h --- a/extras/mini-os/include/gnttab.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/gnttab.h Thu Jun 19 12:46:26 2008 +0900 @@ -11,5 +11,6 @@ unsigned long gnttab_end_transfer(grant_ unsigned long gnttab_end_transfer(grant_ref_t gref); int gnttab_end_access(grant_ref_t ref); const char *gnttabop_error(int16_t status); +void fini_gnttab(void); #endif /* !__GNTTAB_H__ */ diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/ia64/os.h --- a/extras/mini-os/include/ia64/os.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/ia64/os.h Thu Jun 19 12:46:26 2008 +0900 @@ -35,6 +35,7 @@ #include "sal.h" #include "pal.h" #include "hypervisor.h" +#include <kernel.h> typedef uint64_t paddr_t; /* Physical address. */ @@ -46,9 +47,9 @@ typedef uint64_t caddr_t; /* rr7/kernel #include "mm.h" -void do_exit(void) __attribute__((noreturn)); void arch_init(start_info_t *si); /* in common.c */ void arch_print_info(void); /* in common.c */ +void arch_fini(void); /* Size of xen_ia64_boot_param.command_line */ diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/ia64/traps.h --- a/extras/mini-os/include/ia64/traps.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/ia64/traps.h Thu Jun 19 12:46:26 2008 +0900 @@ -38,6 +38,10 @@ inline static void trap_init(void) { //printk("trap_init() until now not needed!\n"); } +inline static void trap_fini(void) +{ + //printk("trap_fini() until now not needed!\n"); +} #endif /* !defined(__ASSEMBLY__) */ diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/kernel.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/extras/mini-os/include/kernel.h Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,7 @@ +#ifndef _KERNEL_H_ +#define _KERNEL_H_ + +extern void do_exit(void) __attribute__((noreturn)); +extern void stop_kernel(void); + +#endif /* _KERNEL_H_ */ diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/mm.h --- a/extras/mini-os/include/mm.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/mm.h Thu Jun 19 12:46:26 2008 +0900 @@ -75,5 +75,6 @@ extern unsigned long heap, brk, heap_map #endif int free_physical_pages(xen_pfn_t *mfns, int n); +void fini_mm(void); #endif /* _MM_H_ */ diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/netfront.h --- a/extras/mini-os/include/netfront.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/netfront.h Thu Jun 19 12:46:26 2008 +0900 @@ -18,6 +18,7 @@ extern struct wait_queue_head netfront_q * N.B. _must_ be called from a thread; it's not safe to call this from * app_main(). */ void start_networking(void); +void stop_networking(void); void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, struct ip_addr *gw); #endif diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/time.h --- a/extras/mini-os/include/time.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/time.h Thu Jun 19 12:46:26 2008 +0900 @@ -54,6 +54,7 @@ typedef long suseconds_t; /* prototypes */ void init_time(void); +void fini_time(void); s_time_t get_s_time(void); s_time_t get_v_time(void); u64 monotonic_clock(void); diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/wait.h --- a/extras/mini-os/include/wait.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/wait.h Thu Jun 19 12:46:26 2008 +0900 @@ -87,9 +87,9 @@ static inline void wake_up(struct wait_q #define wait_event_deadline(wq, condition, deadline) do { \ unsigned long flags; \ + DEFINE_WAIT(__wait); \ if(condition) \ break; \ - DEFINE_WAIT(__wait); \ for(;;) \ { \ /* protect the list */ \ diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/x86/arch_mm.h --- a/extras/mini-os/include/x86/arch_mm.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/x86/arch_mm.h Thu Jun 19 12:46:26 2008 +0900 @@ -109,16 +109,16 @@ typedef unsigned long pgentry_t; (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1)) #endif -#define _PAGE_PRESENT 0x001UL -#define _PAGE_RW 0x002UL -#define _PAGE_USER 0x004UL -#define _PAGE_PWT 0x008UL -#define _PAGE_PCD 0x010UL -#define _PAGE_ACCESSED 0x020UL -#define _PAGE_DIRTY 0x040UL -#define _PAGE_PAT 0x080UL -#define _PAGE_PSE 0x080UL -#define _PAGE_GLOBAL 0x100UL +#define _PAGE_PRESENT 0x001ULL +#define _PAGE_RW 0x002ULL +#define _PAGE_USER 0x004ULL +#define _PAGE_PWT 0x008ULL +#define _PAGE_PCD 0x010ULL +#define _PAGE_ACCESSED 0x020ULL +#define _PAGE_DIRTY 0x040ULL +#define _PAGE_PAT 0x080ULL +#define _PAGE_PSE 0x080ULL +#define _PAGE_GLOBAL 0x100ULL #if defined(__i386__) #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) @@ -140,7 +140,7 @@ typedef unsigned long pgentry_t; #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT) #define PFN_DOWN(x) ((x) >> L1_PAGETABLE_SHIFT) -#define PFN_PHYS(x) ((x) << L1_PAGETABLE_SHIFT) +#define PFN_PHYS(x) ((uint64_t)(x) << L1_PAGETABLE_SHIFT) #define PHYS_PFN(x) ((x) >> L1_PAGETABLE_SHIFT) /* to align the pointer to the (next) page boundary */ @@ -221,4 +221,6 @@ static __inline__ paddr_t machine_to_phy #define map_zero(n, a) map_frames_ex(&mfn_zero, n, 0, 0, a, DOMID_SELF, 0, L1_PROT_RO) #define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0, DOMID_SELF, 0, L1_PROT_RO) +pgentry_t *need_pgt(unsigned long addr); + #endif /* _ARCH_MM_H_ */ diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/x86/os.h --- a/extras/mini-os/include/x86/os.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/x86/os.h Thu Jun 19 12:46:26 2008 +0900 @@ -18,10 +18,10 @@ #ifndef __ASSEMBLY__ #include <types.h> #include <hypervisor.h> +#include <kernel.h> #define USED __attribute__ ((used)) -extern void do_exit(void) __attribute__((noreturn)); #define BUG do_exit #endif @@ -61,9 +61,11 @@ extern shared_info_t *HYPERVISOR_shared_ extern shared_info_t *HYPERVISOR_shared_info; void trap_init(void); +void trap_fini(void); void arch_init(start_info_t *si); void arch_print_info(void); +void arch_fini(void); diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/xenbus.h --- a/extras/mini-os/include/xenbus.h Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/include/xenbus.h Thu Jun 19 12:46:26 2008 +0900 @@ -90,4 +90,7 @@ char* xenbus_printf(xenbus_transaction_t char* node, char* path, char* fmt, ...); +/* Reset the XenBus system. */ +void fini_xenbus(void); + #endif /* XENBUS_H__ */ diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/kernel.c --- a/extras/mini-os/kernel.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/kernel.c Thu Jun 19 12:46:26 2008 +0900 @@ -46,6 +46,7 @@ #include <xen/features.h> #include <xen/version.h> +static struct netfront_dev *net_dev; u8 xen_features[XENFEAT_NR_SUBMAPS * 32]; @@ -87,7 +88,7 @@ static void periodic_thread(void *p) static void netfront_thread(void *p) { - init_netfront(NULL, NULL, NULL, NULL); + net_dev = init_netfront(NULL, NULL, NULL, NULL); } static struct blkfront_dev *blk_dev; @@ -347,9 +348,9 @@ static void refresh_cursor(int new_x, in fbfront_update(fb_dev, new_x, new_y, 9, 9); } +static struct kbdfront_dev *kbd_dev; static void kbdfront_thread(void *p) { - struct kbdfront_dev *kbd_dev; DEFINE_WAIT(w); int x = WIDTH / 2, y = HEIGHT / 2, z = 0; @@ -509,6 +510,49 @@ void start_kernel(start_info_t *si) run_idle_thread(); } +void stop_kernel(void) +{ + if (net_dev) + shutdown_netfront(net_dev); + + if (blk_dev) + shutdown_blkfront(blk_dev); + + if (fb_dev) + shutdown_fbfront(fb_dev); + + if (kbd_dev) + shutdown_kbdfront(kbd_dev); + + /* TODO: fs import */ + + local_irq_disable(); + + /* Reset grant tables */ + fini_gnttab(); + + /* Reset the console driver. */ + fini_console(); + /* TODO: record new ring mfn & event in start_info */ + + /* Reset XenBus */ + fini_xenbus(); + + /* Reset timers */ + fini_time(); + + /* Reset memory management. */ + fini_mm(); + + /* Reset events. */ + fini_events(); + + /* Reset traps */ + trap_fini(); + + /* Reset arch details */ + arch_fini(); +} /* * do_exit: This is called whenever an IRET fails in entry.S. diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/lib/sys.c --- a/extras/mini-os/lib/sys.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/lib/sys.c Thu Jun 19 12:46:26 2008 +0900 @@ -43,7 +43,9 @@ #include <stdlib.h> #include <math.h> +#ifdef HAVE_LWIP #include <lwip/sockets.h> +#endif #include <fs.h> #define debug(fmt, ...) \ @@ -213,8 +215,19 @@ int read(int fd, void *buf, size_t nbyte int read(int fd, void *buf, size_t nbytes) { switch (files[fd].type) { - case FTYPE_CONSOLE: - return 0; + case FTYPE_CONSOLE: { + int ret; + DEFINE_WAIT(w); + while(1) { + add_waiter(w, console_queue); + ret = xencons_ring_recv(buf, nbytes); + if (ret) + break; + schedule(); + } + remove_waiter(w); + return ret; + } case FTYPE_FILE: { ssize_t ret; if (nbytes > PAGE_SIZE) @@ -229,8 +242,10 @@ int read(int fd, void *buf, size_t nbyte } return 0; } +#ifdef HAVE_LWIP case FTYPE_SOCKET: return lwip_read(files[fd].socket.fd, buf, nbytes); +#endif case FTYPE_TAP: { ssize_t ret; ret = netfront_receive(files[fd].tap.dev, buf, nbytes); @@ -288,8 +303,10 @@ int write(int fd, const void *buf, size_ } return 0; } +#ifdef HAVE_LWIP case FTYPE_SOCKET: return lwip_write(files[fd].socket.fd, (void*) buf, nbytes); +#endif case FTYPE_TAP: netfront_xmit(files[fd].tap.dev, (void*) buf, nbytes); return nbytes; @@ -356,7 +373,7 @@ int close(int fd) { printk("close(%d)\n", fd); switch (files[fd].type) { - case FTYPE_CONSOLE: + default: files[fd].type = FTYPE_NONE; return 0; case FTYPE_FILE: { @@ -371,11 +388,13 @@ int close(int fd) case FTYPE_XENBUS: xs_daemon_close((void*)(intptr_t) fd); return 0; +#ifdef HAVE_LWIP case FTYPE_SOCKET: { int res = lwip_close(files[fd].socket.fd); files[fd].type = FTYPE_NONE; return res; } +#endif case FTYPE_XC: xc_interface_close(fd); return 0; @@ -544,6 +563,7 @@ int fcntl(int fd, int cmd, ...) va_end(ap); switch (cmd) { +#ifdef HAVE_LWIP case F_SETFL: if (files[fd].type == FTYPE_SOCKET && !(arg & ~O_NONBLOCK)) { /* Only flag supported: non-blocking mode */ @@ -551,6 +571,7 @@ int fcntl(int fd, int cmd, ...) return lwip_ioctl(files[fd].socket.fd, FIONBIO, &nblock); } /* Fallthrough */ +#endif default: printk("fcntl(%d, %d, %lx/%lo)\n", fd, cmd, arg, arg); errno = ENOSYS; @@ -655,9 +676,12 @@ static void dump_set(int nfds, fd_set *r /* Just poll without blocking */ static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds) { - int i, n = 0, sock_n, sock_nfds = 0; + int i, n = 0; +#ifdef HAVE_LWIP + int sock_n, sock_nfds = 0; fd_set sock_readfds, sock_writefds, sock_exceptfds; struct timeval timeout = { .tv_sec = 0, .tv_usec = 0}; +#endif #ifdef LIBC_VERBOSE static int nb; @@ -667,6 +691,7 @@ static int select_poll(int nfds, fd_set nb++; #endif +#ifdef HAVE_LWIP /* first poll network */ FD_ZERO(&sock_readfds); FD_ZERO(&sock_writefds); @@ -693,6 +718,7 @@ static int select_poll(int nfds, fd_set sock_n = lwip_select(sock_nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout); dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout); DEBUG("\n"); +#endif /* Then see others as well. */ for (i = 0; i < nfds; i++) { @@ -707,7 +733,12 @@ static int select_poll(int nfds, fd_set FD_CLR(i, exceptfds); break; case FTYPE_CONSOLE: - FD_CLR(i, readfds); + if (FD_ISSET(i, writefds)) { + if (xencons_ring_avail()) + n++; + else + FD_CLR(i, readfds); + } if (FD_ISSET(i, writefds)) n++; FD_CLR(i, exceptfds); @@ -736,6 +767,7 @@ static int select_poll(int nfds, fd_set FD_CLR(i, writefds); FD_CLR(i, exceptfds); break; +#ifdef HAVE_LWIP case FTYPE_SOCKET: if (FD_ISSET(i, readfds)) { /* Optimize no-network-packet case. */ @@ -757,6 +789,7 @@ static int select_poll(int nfds, fd_set FD_CLR(i, exceptfds); } break; +#endif } #ifdef LIBC_VERBOSE if (FD_ISSET(i, readfds)) @@ -809,6 +842,7 @@ int select(int nfds, fd_set *readfds, fd DEFINE_WAIT(w3); DEFINE_WAIT(w4); DEFINE_WAIT(w5); + DEFINE_WAIT(w6); assert(thread == main_thread); @@ -830,6 +864,7 @@ int select(int nfds, fd_set *readfds, fd add_waiter(w3, blkfront_queue); add_waiter(w4, xenbus_watch_queue); add_waiter(w5, kbdfront_queue); + add_waiter(w6, console_queue); if (readfds) myread = *readfds; @@ -916,9 +951,11 @@ out: remove_waiter(w3); remove_waiter(w4); remove_waiter(w5); + remove_waiter(w6); return ret; } +#ifdef HAVE_LWIP int socket(int domain, int type, int protocol) { int fd, res; @@ -970,6 +1007,7 @@ LWIP_STUB(ssize_t, send, (int s, void *b LWIP_STUB(ssize_t, send, (int s, void *buf, size_t len, int flags), (s, buf, len, flags)) 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)) LWIP_STUB(int, getsockname, (int s, struct sockaddr *name, socklen_t *namelen), (s, name, namelen)) +#endif int nanosleep(const struct timespec *req, struct timespec *rem) { diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/lwip-net.c --- a/extras/mini-os/lwip-net.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/lwip-net.c Thu Jun 19 12:46:26 2008 +0900 @@ -376,3 +376,9 @@ void start_networking(void) tprintk("Network is ready.\n"); } + +/* Shut down the network */ +void stop_networking(void) +{ + shutdown_netfront(dev); +} diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/main.c --- a/extras/mini-os/main.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/main.c Thu Jun 19 12:46:26 2008 +0900 @@ -4,6 +4,7 @@ * Samuel Thibault <Samuel.Thibault@xxxxxxxxxxxxx>, October 2007 */ +#ifdef HAVE_LIBC #include <os.h> #include <sched.h> #include <console.h> @@ -41,24 +42,30 @@ extern char __app_bss_start, __app_bss_e extern char __app_bss_start, __app_bss_end; static void call_main(void *p) { - char *args, /**path,*/ *msg, *c; + char *c; #ifdef CONFIG_QEMU - char *domargs; + char *domargs, *msg; #endif int argc; char **argv; char *envp[] = { NULL }; +#ifdef CONFIG_QEMU char *vm; + char path[128]; +#endif int i; - char path[128]; /* Let other parts initialize (including console output) before maybe * crashing. */ //sleep(1); +#ifndef CONFIG_GRUB sparse((unsigned long) &__app_bss_start, &__app_bss_end - &__app_bss_start); +#ifdef HAVE_LWIP start_networking(); +#endif init_fs_frontend(); +#endif #ifdef CONFIG_QEMU if (!fs_import) { @@ -92,22 +99,6 @@ static void call_main(void *p) } #endif - msg = xenbus_read(XBT_NIL, "vm", &vm); - if (msg) { - printk("Couldn't read vm path\n"); - do_exit(); - } - - printk("my vm is at %s\n", vm); - snprintf(path, sizeof(path), "%s/image/cmdline", vm); - free(vm); - msg = xenbus_read(XBT_NIL, path, &args); - - if (msg) { - printk("Couldn't get my args: %s\n", msg); - args = strdup(""); - } - argc = 1; #define PARSE_ARGS(ARGS,START,END) \ @@ -124,7 +115,7 @@ static void call_main(void *p) } \ } - PARSE_ARGS(args, argc++, ); + PARSE_ARGS((char*)start_info.cmd_line, argc++, ); #ifdef CONFIG_QEMU PARSE_ARGS(domargs, argc++, ); #endif @@ -133,7 +124,7 @@ static void call_main(void *p) argv[0] = "main"; argc = 1; - PARSE_ARGS(args, argv[argc++] = c, *c++ = 0) + PARSE_ARGS((char*)start_info.cmd_line, argv[argc++] = c, *c++ = 0) #ifdef CONFIG_QEMU PARSE_ARGS(domargs, argv[argc++] = c, *c++ = 0) #endif @@ -162,7 +153,10 @@ void _exit(int ret) close_all_files(); __libc_fini_array(); printk("main returned %d\n", ret); - unbind_all_ports(); +#ifdef HAVE_LWIP + stop_networking(); +#endif + stop_kernel(); if (!ret) { /* No problem, just shutdown. */ struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff }; @@ -177,3 +171,4 @@ int app_main(start_info_t *si) main_thread = create_thread("main", call_main, si); return 0; } +#endif diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/minios.mk --- a/extras/mini-os/minios.mk Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/minios.mk Thu Jun 19 12:46:26 2008 +0900 @@ -57,13 +57,13 @@ ARCH_LIB := lib$(ARCH_LIB_NAME).a # This object contains the entrypoint for startup from Xen. # $(HEAD_ARCH_OBJ) has to be built in the architecture specific directory. HEAD_ARCH_OBJ := $(XEN_TARGET_ARCH).o -HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ) +HEAD_OBJ := $(OBJ_DIR)/$(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ) -%.o: %.c $(HDRS) Makefile $(EXTRA_DEPS) +$(OBJ_DIR)/%.o: %.c $(HDRS) Makefile $(EXTRA_DEPS) $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@ -%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS) +$(OBJ_DIR)/%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS) $(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@ diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/mm.c --- a/extras/mini-os/mm.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/mm.c Thu Jun 19 12:46:26 2008 +0900 @@ -419,6 +419,10 @@ void init_mm(void) arch_init_demand_mapping_area(max_pfn); } +void fini_mm(void) +{ +} + void sanity_check(void) { int x; diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/netfront.c --- a/extras/mini-os/netfront.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/netfront.c Thu Jun 19 12:46:26 2008 +0900 @@ -259,7 +259,8 @@ void netfront_select_handler(evtchn_port network_tx_buf_gc(dev); local_irq_restore(flags); - files[fd].read = 1; + if (fd != -1) + files[fd].read = 1; wake_up(&netfront_queue); } #endif @@ -323,6 +324,9 @@ struct netfront_dev *init_netfront(char dev = malloc(sizeof(*dev)); memset(dev, 0, sizeof(*dev)); dev->nodename = strdup(nodename); +#ifdef HAVE_LIBC + dev->fd = -1; +#endif printk("net TX ring size %d\n", NET_TX_RING_SIZE); printk("net RX ring size %d\n", NET_RX_RING_SIZE); @@ -493,13 +497,26 @@ void shutdown_netfront(struct netfront_d printk("close network: backend at %s\n",dev->backend); snprintf(path, sizeof(path), "%s/state", dev->backend); + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */ xenbus_wait_for_value(path, "5", &dev->events); err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6); xenbus_wait_for_value(path, "6", &dev->events); + err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1); + xenbus_wait_for_value(path, "2", &dev->events); + xenbus_unwatch_path(XBT_NIL, path); + + snprintf(path, sizeof(path), "%s/tx-ring-ref", nodename); + xenbus_rm(XBT_NIL, path); + snprintf(path, sizeof(path), "%s/rx-ring-ref", nodename); + xenbus_rm(XBT_NIL, path); + snprintf(path, sizeof(path), "%s/event-channel", nodename); + xenbus_rm(XBT_NIL, path); + snprintf(path, sizeof(path), "%s/request-rx-copy", nodename); + xenbus_rm(XBT_NIL, path); free_netfront(dev); } @@ -597,7 +614,7 @@ ssize_t netfront_receive(struct netfront local_irq_save(flags); network_rx(dev); - if (!dev->rlen) + if (!dev->rlen && fd != -1) /* No data for us, make select stop returning */ files[fd].read = 0; /* Before re-enabling the interrupts, in case a packet just arrived in the diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/xenbus/xenbus.c --- a/extras/mini-os/xenbus/xenbus.c Tue Jun 10 16:00:33 2008 +0900 +++ b/extras/mini-os/xenbus/xenbus.c Thu Jun 19 12:46:26 2008 +0900 @@ -124,7 +124,7 @@ static void xenbus_thread_func(void *ign static void xenbus_thread_func(void *ign) { struct xsd_sockmsg msg; - unsigned prod = 0; + unsigned prod = xenstore_buf->rsp_prod; for (;;) { @@ -174,9 +174,14 @@ static void xenbus_thread_func(void *ign break; } - event->next = *events; - *events = event; - wake_up(&xenbus_watch_queue); + if (events) { + event->next = *events; + *events = event; + wake_up(&xenbus_watch_queue); + } else { + printk("unexpected watch token %s\n", event->token); + free(event); + } } else @@ -263,6 +268,10 @@ void init_xenbus(void) NULL); unmask_evtchn(start_info.store_evtchn); DEBUG("xenbus on irq %d\n", err); +} + +void fini_xenbus(void) +{ } /* Send data to xenbus. This can block. All of the requests are seen diff -r 1201c7657832 -r 0034766b45c2 stubdom/Makefile --- a/stubdom/Makefile Tue Jun 10 16:00:33 2008 +0900 +++ b/stubdom/Makefile Thu Jun 19 12:46:26 2008 +0900 @@ -1,4 +1,5 @@ XEN_ROOT = .. XEN_ROOT = .. +MINI_OS = $(XEN_ROOT)/extras/mini-os export XEN_OS=MiniOS @@ -12,7 +13,8 @@ ZLIB_VERSION=1.2.3 ZLIB_VERSION=1.2.3 LIBPCI_VERSION=2.2.9 NEWLIB_DATE=2008-01-01 -LWIP_DATE=2008-02-08 +LWIP_DATE=2008-06-01 +GRUB_DATE=2008-06-01 WGET=wget -c @@ -23,9 +25,11 @@ endif ifeq ($(GNU_TARGET_ARCH), i686) TARGET_CFLAGS= +NEWLIB_CFLAGS+=-D_I386MACH_ALLOW_HW_INTERRUPTS endif ifeq ($(GNU_TARGET_ARCH), x86_64) TARGET_CFLAGS=-mno-red-zone +NEWLIB_CFLAGS+=-D_I386MACH_ALLOW_HW_INTERRUPTS endif ifeq ($(GNU_TARGET_ARCH), ia64) TARGET_CFLAGS=-mconstant-gp @@ -36,8 +40,10 @@ export CROSS_COMPILE=$(GNU_TARGET_ARCH)- export CROSS_COMPILE=$(GNU_TARGET_ARCH)-xen-elf- export PATH:=$(CROSS_PREFIX)/bin:$(PATH) +TARGETS=ioemu c caml grub + .PHONY: all -all: ioemu-stubdom c-stubdom +all: ioemu-stubdom c-stubdom pv-grub ################ # Cross-binutils @@ -46,8 +52,8 @@ binutils-$(BINUTILS_VERSION).tar.bz2: binutils-$(BINUTILS_VERSION).tar.bz2: $(WGET) http://ftp.gnu.org/gnu/binutils/$@ binutils-$(BINUTILS_VERSION): binutils-$(BINUTILS_VERSION).tar.bz2 - tar xjf $@.tar.bz2 - ( cd binutils-$(BINUTILS_VERSION) && patch -p1 < ../binutils.patch ) + tar xjf $< + patch -d $@ -p1 < binutils.patch touch $@ BINUTILS_STAMPFILE=$(CROSS_ROOT)/bin/$(GNU_TARGET_ARCH)-xen-elf-ar @@ -68,10 +74,10 @@ gcc-$(GCC_VERSION).tar.bz2: gcc-$(GCC_VERSION).tar.bz2: $(WGET) http://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)/gcc-$(GCC_VERSION).tar.bz2 gcc-$(GCC_VERSION): gcc-$(GCC_VERSION).tar.bz2 - tar xjf gcc-$(GCC_VERSION).tar.bz2 - ( cd gcc-$(GCC_VERSION) && patch -p1 < ../gcc.patch ) + tar xjf $< + patch -d $@ -p1 < gcc.patch touch $@ - + GCC_STAMPFILE=$(CROSS_ROOT)/bin/$(GNU_TARGET_ARCH)-xen-elf-gcc-$(GCC_VERSION) .PHONY: cross-gcc cross-gcc: $(GCC_STAMPFILE) @@ -89,7 +95,7 @@ newlib-cvs: newlib-cvs: cvs -z 9 -d :pserver:anoncvs@xxxxxxxxxxxxxxxxxx:/cvs/src co -D $(NEWLIB_DATE) newlib mv src newlib-cvs - ( cd newlib-cvs && patch -p0 < ../newlib.patch) + patch -d $@ -p0 < newlib.patch NEWLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libc.a .PHONY: cross-newlib @@ -97,7 +103,7 @@ cross-newlib: $(NEWLIB_STAMPFILE) $(NEWLIB_STAMPFILE): newlib-cvs $(GCC_STAMPFILE) mkdir -p newlib-build ( cd newlib-build && \ - 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 && \ + 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 && \ $(MAKE) && \ $(MAKE) install ) @@ -145,8 +151,7 @@ cross-libpci: $(LIBPCI_STAMPFILE) ###### lwip-cvs: - cvs -z 9 -d :pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/lwip co -D $(LWIP_DATE) lwip - mv lwip lwip-cvs + cvs -z 9 -d :pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/lwip co -D $(LWIP_DATE) -d $@ lwip ####### # Links @@ -160,29 +165,36 @@ mk-symlinks: [ -h include ] || ln -sf ../tools/include . mkdir -p libxc [ -h libxc/Makefile ] || ( cd libxc && \ - ln -sf ../../tools/libxc/*.h . && \ - ln -sf ../../tools/libxc/*.c . && \ - ln -sf ../../tools/libxc/Makefile . ) + ln -sf ../$(XEN_ROOT)/tools/libxc/*.h . && \ + ln -sf ../$(XEN_ROOT)/tools/libxc/*.c . && \ + ln -sf ../$(XEN_ROOT)/tools/libxc/Makefile . ) mkdir -p libxc/$(XEN_TARGET_ARCH) [ -h libxc/$(XEN_TARGET_ARCH) ] || ( cd libxc/$(XEN_TARGET_ARCH) && \ - ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/*.c . && \ - ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/*.h . && \ - ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/Makefile . ) + ln -sf ../$(XEN_ROOT)/tools/libxc/$(XEN_TARGET_ARCH)/*.c . && \ + ln -sf ../$(XEN_ROOT)/tools/libxc/$(XEN_TARGET_ARCH)/*.h . && \ + ln -sf ../$(XEN_ROOT)/tools/libxc/$(XEN_TARGET_ARCH)/Makefile . ) mkdir -p ioemu [ -h ioemu/Makefile ] || ( cd ioemu && \ - ln -sf ../../tools/ioemu/* . && \ + ln -sf ../$(XEN_ROOT)/tools/ioemu/* . && \ ([ ! -h config-host.h ] || rm -f config-host.h) && \ ([ ! -h config-host.mak ] || rm -f config-host.mak) ) - [ -h mini-os ] || ln -sf ../extras/mini-os . - [ -h mini-os/include/xen ] || ln -sf ../../../xen/include/public mini-os/include/xen + $(MAKE) -C $(MINI_OS) links + +TARGETS_MINIOS=$(addprefix mini-os-,$(TARGETS)) +$(TARGETS_MINIOS): mini-os-%: + [ -d $@ ] || \ + for i in $$(cd $(MINI_OS) ; find . -type d) ; do \ + mkdir -p $@/$$i ; \ + done ####### # libxc ####### .PHONY: libxc -libxc: cross-zlib mk-symlinks - $(MAKE) -C $@ +libxc: libxc/libxenctrl.a libxc/libxenguest.a +libxc/libxenctrl.a libxc/libxenguest.a: cross-zlib mk-symlinks + $(MAKE) -C libxc ####### # ioemu @@ -199,7 +211,7 @@ ioemu: cross-zlib cross-libpci mk-symlin ###### .PHONY: caml -caml: mk-symlinks +caml: cross-newlib mk-symlinks $(MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip-cvs ### @@ -207,33 +219,56 @@ caml: mk-symlinks ### .PHONY: c -c: mk-symlinks +c: cross-newlib mk-symlinks $(MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip-cvs + +###### +# Grub +###### + +grub-cvs: + cvs -z 9 -d :pserver:anonymous@xxxxxxxxxxxxxx:/sources/grub co -D $(GRUB_DATE) -d $@ grub + for i in grub.patches/* ; do \ + patch -d $@ -p1 < $$i ; \ + done + +.PHONY: grub +grub: grub-cvs cross-newlib mk-symlinks + $(MAKE) -C $@ ######## # minios ######## .PHONY: ioemu-stubdom -ioemu-stubdom: lwip-cvs libxc ioemu - $(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" +ioemu-stubdom: mini-os-ioemu lwip-cvs libxc ioemu + 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" CAMLLIB = $(shell ocamlc -where) .PHONY: caml-stubdom -caml-stubdom: lwip-cvs libxc caml - $(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" +caml-stubdom: mini-os-caml lwip-cvs libxc caml + 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" .PHONY: c-stubdom -c-stubdom: lwip-cvs libxc c - $(MAKE) -C mini-os TARGET=$@ LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS=$(CURDIR)/c/main.a +c-stubdom: mini-os-c lwip-cvs libxc c + DEF_CFLAGS=-DCONFIG_C $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS=$(CURDIR)/c/main.a + +.PHONY: pv-grub +pv-grub: mini-os-grub libxc grub + DEF_CFLAGS=-DCONFIG_GRUB $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< APP_OBJS=$(CURDIR)/grub/main.a ######### # install ######### -install: mini-os/ioemu-stubdom.gz +install: install-ioemu install-grub + +install-ioemu: mini-os-ioemu/mini-os.gz $(INSTALL_PROG) stubdom-dm "$(DESTDIR)/usr/lib/xen/bin" - $(INSTALL_PROG) $< "$(DESTDIR)/usr/lib/xen/boot/stubdom.gz" + $(INSTALL_PROG) $< "$(DESTDIR)/usr/lib/xen/boot/ioemu-stubdom.gz" + +install-grub: mini-os-grub/mini-os.gz + $(INSTALL_PROG) $< "$(DESTDIR)/usr/lib/xen/boot/pv-grub.gz" ####### # clean @@ -242,9 +277,13 @@ install: mini-os/ioemu-stubdom.gz # Only clean the libxc/ioemu/mini-os part .PHONY: clean clean: - -$(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip-cvs clean + rm -fr mini-os-ioemu + rm -fr mini-os-c + rm -fr mini-os-caml + rm -fr mini-os-grub $(MAKE) -C caml clean $(MAKE) -C c clean + $(MAKE) -C grub clean rm -fr libxc ioemu mini-os include # clean the cross-compilation result @@ -261,6 +300,7 @@ patchclean: crossclean rm -fr gcc-$(GCC_VERSION) rm -fr newlib-cvs rm -fr lwip-cvs + rm -fr grub-cvs # clean downloads .PHONY: downloadclean diff -r 1201c7657832 -r 0034766b45c2 stubdom/README --- a/stubdom/README Tue Jun 10 16:00:33 2008 +0900 +++ b/stubdom/README Thu Jun 19 12:46:26 2008 +0900 @@ -6,12 +6,19 @@ Then make install to install the result. Also, run make and make install in $XEN_ROOT/tools/fs-back + + + IOEMU stubdom + ============= + + This boosts HVM performance by putting ioemu in its own lightweight domain. + General Configuration ===================== In your HVM config "hvmconfig", -- use /usr/lib/xen/bin/stubdom-dm as dm script +- use /usr/lib/xen/bin/stubdom-dm as dm script: device_model = '/usr/lib/xen/bin/stubdom-dm' @@ -19,11 +26,13 @@ device_model = '/usr/lib/xen/bin/stubdom #disk = [ 'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ] +- disable anything related to dom0, like pty serial assignments + Create /etc/xen/stubdom-hvmconfig (where "hvmconfig" is the name of your HVM guest) with -kernel = "/usr/lib/xen/boot/stubdom.gz" +kernel = "/usr/lib/xen/boot/ioemu-stubdom.gz" vif = [ '', 'ip=10.0.1.1,mac=aa:00:00:12:23:34'] disk = [ 'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ] @@ -40,34 +49,36 @@ There are three posibilities * Using SDL -In hvmconfig, disable vnc: + - In hvmconfig, disable vnc and sdl: vnc = 0 +sdl = 0 -In stubdom-hvmconfig, set a vfb: + - In stubdom-hvmconfig, set an sdl vfb: vfb = [ 'type=sdl' ] * Using a VNC server in the stub domain -In hvmconfig, set vnclisten to "172.30.206.1" for instance. Do not use a host -name as Mini-OS does not have a name resolver. Do not use 127.0.0.1 since then -you will not be able to connect to it. + - In hvmconfig, set vnclisten to "172.30.206.1" for instance. Do not use a +host name as Mini-OS does not have a name resolver. Do not use 127.0.0.1 since +then you will not be able to connect to it. vnc = 1 vnclisten = "172.30.206.1" -In stubdom-hvmconfig, fill the reserved vif with the same IP, for instance: + - In stubdom-hvmconfig, fill the reserved vif with the same IP, for instance: vif = [ 'ip=172.30.206.1', 'ip=10.0.1.1,mac=aa:00:00:12:23:34'] * Using a VNC server in dom0 -In hvmconfig, disable vnc: + - In hvmconfig, disable vnc and sdl: vnc = 0 +sdl = 0 -In stubdom-hvmconfig, set a vfb: + - In stubdom-hvmconfig, set a vnc vfb: vfb = [ 'type=vnc' ] @@ -83,3 +94,43 @@ ln -s /var/lib/xen /exports/var/lib /usr/sbin/fs-backend & xm create hvmconfig + + + + PV-GRUB + ======= + + This replaces pygrub to boot domU images safely: it runs the regular grub +inside the created domain itself and uses regular domU facilities to read the +disk / fetch files from network etc. ; it eventually loads the PV kernel and +chain-boots it. + +Configuration +============= + +In your PV config, + +- use /usr/lib/xen/boot/pv-grub.gz as kernel: + +kernel = "/usr/lib/xen/boot/pv-grub.gz" + +- set the path to menu.lst, as seen from the domU, in extra: + +extra = "(hd0,0)/boot/grub/menu.lst" + +you can also use a tftp path (dhcp will be automatically performed): + +extra = "(nd)/somepath/menu.lst" + +or you can set it in option 150 of your dhcp server and leave extra empty + +Limitations +=========== + +- You can not boot a 64bit kernel with a 32bit-compiled PV-GRUB and vice-versa. +To cross-compile a 32bit PV-GRUB, + +export XEN_TARGET_ARCH=x86_32 + +- bootsplash is supported, but the ioemu backend does not yet support restart +for use by the booted kernel. diff -r 1201c7657832 -r 0034766b45c2 stubdom/c/Makefile --- a/stubdom/c/Makefile Tue Jun 10 16:00:33 2008 +0900 +++ b/stubdom/c/Makefile Thu Jun 19 12:46:26 2008 +0900 @@ -4,10 +4,7 @@ include $(XEN_ROOT)/Config.mk all: main.a -main-c.c: - ln -sf $(XEN_ROOT)/extras/mini-os/main.c $@ - -main.a: main-c.o main.o +main.a: main.o $(AR) cr $@ $^ clean: diff -r 1201c7657832 -r 0034766b45c2 stubdom/caml/Makefile --- a/stubdom/caml/Makefile Tue Jun 10 16:00:33 2008 +0900 +++ b/stubdom/caml/Makefile Thu Jun 19 12:46:26 2008 +0900 @@ -11,10 +11,7 @@ OBJS := hello.cmx OBJS := hello.cmx LIBS := -all: main-c.o main-caml.o caml.o - -main-c.c: - ln -sf $(XEN_ROOT)/extras/mini-os/main.c $@ +all: main-caml.o caml.o %.cmx: %.ml $(OCAMLFIND) $(OCAMLOPT) -c $< -o $@ diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub.patches/10graphics.diff --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/grub.patches/10graphics.diff Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,2299 @@ +diff -Naur grub-0.97.orig/configure.ac grub-0.97/configure.ac +--- grub-0.97.orig/configure.ac 2005-05-07 23:36:03.000000000 -0300 ++++ grub-0.97/configure.ac 2005-06-12 20:56:49.000000000 -0300 +@@ -595,6 +595,11 @@ + [ --enable-diskless enable diskless support]) + AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes) + ++dnl Graphical splashscreen support ++AC_ARG_ENABLE(graphics, ++ [ --disable-graphics disable graphics terminal support]) ++AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno) ++ + dnl Hercules terminal + AC_ARG_ENABLE(hercules, + [ --disable-hercules disable hercules terminal support]) +diff -Naur grub-0.97.orig/stage2/asm.S grub-0.97/stage2/asm.S +--- grub-0.97.orig/stage2/asm.S 2004-06-19 13:55:22.000000000 -0300 ++++ grub-0.97/stage2/asm.S 2005-06-13 14:05:31.000000000 -0300 +@@ -2216,7 +2216,304 @@ + pop %ebx + pop %ebp + ret +- ++ ++ ++/* graphics mode functions */ ++#ifdef SUPPORT_GRAPHICS ++VARIABLE(cursorX) ++.word 0 ++VARIABLE(cursorY) ++.word 0 ++VARIABLE(cursorCount) ++.word 0 ++VARIABLE(cursorBuf) ++.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ++ ++ ++/* ++ * set_int1c_handler(void) ++ */ ++ENTRY(set_int1c_handler) ++ pushl %edi ++ ++ /* save the original int1c handler */ ++ movl $0x70, %edi ++ movw (%edi), %ax ++ movw %ax, ABS(int1c_offset) ++ movw 2(%edi), %ax ++ movw %ax, ABS(int1c_segment) ++ ++ /* save the new int1c handler */ ++ movw $ABS(int1c_handler), %ax ++ movw %ax, (%edi) ++ xorw %ax, %ax ++ movw %ax, 2(%edi) ++ ++ popl %edi ++ ret ++ ++ ++/* ++ * unset_int1c_handler(void) ++ */ ++ENTRY(unset_int1c_handler) ++ pushl %edi ++ ++ /* check if int1c_handler is set */ ++ movl $0x70, %edi ++ movw $ABS(int1c_handler), %ax ++ cmpw %ax, (%edi) ++ jne int1c_1 ++ xorw %ax, %ax ++ cmpw %ax, 2(%edi) ++ jne int1c_1 ++ ++ /* restore the original */ ++ movw ABS(int1c_offset), %ax ++ movw %ax, (%edi) ++ movw ABS(int1c_segment), %ax ++ movw %ax, 2(%edi) ++ ++int1c_1: ++ popl %edi ++ ret ++ ++ ++/* ++ * blinks graphics cursor ++ */ ++ .code16 ++write_data: ++ movw $0, %ax ++ movw %ax, %ds ++ ++ mov $0xA000, %ax /* video in es:di */ ++ mov %ax, %es ++ mov $80, %ax ++ movw $ABS(cursorY), %si ++ mov %ds:(%si), %bx ++ mul %bx ++ movw $ABS(cursorX), %si ++ mov %ds:(%si), %bx ++ shr $3, %bx /* %bx /= 8 */ ++ add %bx, %ax ++ mov %ax, %di ++ ++ movw $ABS(cursorBuf), %si /* fontBuf in ds:si */ ++ ++ /* prepare for data moving */ ++ mov $16, %dx /* altura da fonte */ ++ mov $80, %bx /* bytes por linha */ ++ ++write_loop: ++ movb %ds:(%si), %al ++ xorb $0xff, %al ++ movb %al, %ds:(%si) /* invert cursorBuf */ ++ movb %al, %es:(%di) /* write to video */ ++ add %bx, %di ++ inc %si ++ dec %dx ++ jg write_loop ++ ret ++ ++int1c_handler: ++ pusha ++ mov $0, %ax ++ mov %ax, %ds ++ mov $ABS(cursorCount), %si ++ mov %ds:(%si), %ax ++ inc %ax ++ mov %ax, %ds:(%si) ++ cmp $9, %ax ++ jne int1c_done ++ ++ mov $0, %ax ++ mov %ax, %ds:(%si) ++ call write_data ++ ++int1c_done: ++ popa ++ iret ++ /* call previous int1c handler */ ++ /* ljmp */ ++ .byte 0xea ++int1c_offset: .word 0 ++int1c_segment: .word 0 ++ .code32 ++ ++ ++/* ++ * unsigned char set_videomode(unsigned char mode) ++ * BIOS call "INT 10H Function 0h" to set video mode ++ * Call with %ah = 0x0 ++ * %al = video mode ++ * Returns old videomode. ++ */ ++ENTRY(set_videomode) ++ pushl %ebp ++ movl %esp,%ebp ++ pushl %ebx ++ pushl %ecx ++ ++ movb 8(%ebp), %cl ++ ++ call EXT_C(prot_to_real) ++ .code16 ++ ++ xorb %al, %al ++ movb $0xf, %ah ++ int $0x10 /* Get Current Video mode */ ++ movb %al, %ch ++ xorb %ah, %ah ++ movb %cl, %al ++ int $0x10 /* Set Video mode */ ++ ++ DATA32 call EXT_C(real_to_prot) ++ .code32 ++ ++ xorl %eax, %eax ++ movb %ch, %al ++ ++ popl %ecx ++ popl %ebx ++ popl %ebp ++ ret ++ ++ ++/* ++ * int get_videomode() ++ * BIOS call "INT 10H Function 0Fh" to get current video mode ++ * Call with %al = 0x0 ++ * %ah = 0xF ++ * Returns current videomode. ++ */ ++ENTRY(get_videomode) ++ pushl %ebp ++ movl %esp,%ebp ++ pushl %ebx ++ pushl %ecx ++ ++ call EXT_C(prot_to_real) ++ .code16 ++ ++ xorb %al, %al ++ movb $0xF, %ah ++ int $0x10 /* Get Current Video mode */ ++ movb %al, %cl /* For now we only want display mode */ ++ ++ DATA32 call EXT_C(real_to_prot) ++ .code32 ++ ++ xorl %eax, %eax ++ movb %cl, %al ++ ++ popl %ecx ++ popl %ebx ++ popl %ebp ++ ret ++ ++ ++/* ++ * unsigned char * graphics_get_font() ++ * BIOS call "INT 10H Function 11h" to set font ++ * Call with %ah = 0x11 ++ */ ++ENTRY(graphics_get_font) ++ push %ebp ++ push %ebx ++ push %ecx ++ push %edx ++ ++ call EXT_C(prot_to_real) ++ .code16 ++ ++ movw $0x1130, %ax ++ movb $6, %bh /* font 8x16 */ ++ int $0x10 ++ movw %bp, %dx ++ movw %es, %cx ++ ++ DATA32 call EXT_C(real_to_prot) ++ .code32 ++ ++ xorl %eax, %eax ++ movw %cx, %ax ++ shll $4, %eax ++ movw %dx, %ax ++ ++ pop %edx ++ pop %ecx ++ pop %ebx ++ pop %ebp ++ ret ++ ++ ++/* ++ * graphics_set_palette(index, red, green, blue) ++ * BIOS call "INT 10H Function 10h" to set individual dac register ++ * Call with %ah = 0x10 ++ * %bx = register number ++ * %ch = new value for green (0-63) ++ * %cl = new value for blue (0-63) ++ * %dh = new value for red (0-63) ++ */ ++ ++ENTRY(graphics_set_palette) ++ push %ebp ++ push %eax ++ push %ebx ++ push %ecx ++ push %edx ++ ++ movw $0x3c8, %bx /* address write mode register */ ++ ++ /* wait vertical retrace */ ++ movw $0x3da, %dx ++l1b: ++ inb %dx, %al /* wait vertical active display */ ++ test $8, %al ++ jnz l1b ++ ++l2b: ++ inb %dx, %al /* wait vertical retrace */ ++ test $8, %al ++ jnz l2b ++ ++ mov %bx, %dx ++ movb 0x18(%esp), %al /* index */ ++ outb %al, %dx ++ inc %dx ++ ++ movb 0x1c(%esp), %al /* red */ ++ outb %al, %dx ++ ++ movb 0x20(%esp), %al /* green */ ++ outb %al, %dx ++ ++ movb 0x24(%esp), %al /* blue */ ++ outb %al, %dx ++ ++ movw 0x18(%esp), %bx ++ ++ call EXT_C(prot_to_real) ++ .code16 ++ ++ movb %bl, %bh ++ movw $0x1000, %ax ++ int $0x10 ++ ++ DATA32 call EXT_C(real_to_prot) ++ .code32 ++ ++ pop %edx ++ pop %ecx ++ pop %ebx ++ pop %eax ++ pop %ebp ++ ret ++#endif /* SUPPORT_GRAPHICS */ ++ ++ + /* + * getrtsecs() + * if a seconds value can be read, read it and return it (BCD), +diff -Naur grub-0.97.orig/stage2/builtins.c grub-0.97/stage2/builtins.c +--- grub-0.97.orig/stage2/builtins.c 2005-02-15 19:58:23.000000000 -0200 ++++ grub-0.97/stage2/builtins.c 2005-06-13 18:44:03.000000000 -0300 +@@ -28,6 +28,10 @@ + #include <filesys.h> + #include <term.h> + ++#ifdef SUPPORT_GRAPHICS ++# include <graphics.h> ++#endif ++ + #ifdef SUPPORT_NETBOOT + # define GRUB 1 + # include <etherboot.h> +@@ -237,12 +241,22 @@ + static int + boot_func (char *arg, int flags) + { ++ struct term_entry *prev_term = current_term; + /* Clear the int15 handler if we can boot the kernel successfully. + This assumes that the boot code never fails only if KERNEL_TYPE is + not KERNEL_TYPE_NONE. Is this assumption is bad? */ + if (kernel_type != KERNEL_TYPE_NONE) + unset_int15_handler (); + ++ /* if our terminal needed initialization, we should shut it down ++ * before booting the kernel, but we want to save what it was so ++ * we can come back if needed */ ++ if (current_term->shutdown) ++ { ++ current_term->shutdown(); ++ current_term = term_table; /* assumption: console is first */ ++ } ++ + #ifdef SUPPORT_NETBOOT + /* Shut down the networking. */ + cleanup_net (); +@@ -306,6 +320,13 @@ + return 1; + } + ++ /* if we get back here, we should go back to what our term was before */ ++ current_term = prev_term; ++ if (current_term->startup) ++ /* if our terminal fails to initialize, fall back to console since ++ * it should always work */ ++ if (current_term->startup() == 0) ++ current_term = term_table; /* we know that console is first */ + return 0; + } + +@@ -852,6 +873,251 @@ + }; + #endif /* SUPPORT_NETBOOT */ + ++#ifdef SUPPORT_GRAPHICS ++ ++static int splashimage_func(char *arg, int flags) { ++ int i; ++ ++ /* filename can only be 256 characters due to our buffer size */ ++ if (grub_strlen(arg) > 256) { ++ grub_printf("Splash image filename too large\n"); ++ grub_printf("Press any key to continue..."); ++ getkey(); ++ return 1; ++ } ++ ++ /* get rid of TERM_NEED_INIT from the graphics terminal. */ ++ for (i = 0; term_table[i].name; i++) { ++ if (grub_strcmp (term_table[i].name, "graphics") == 0) { ++ term_table[i].flags &= ~TERM_NEED_INIT; ++ break; ++ } ++ } ++ ++ graphics_set_splash(arg); ++ ++ if (flags == BUILTIN_CMDLINE && graphics_inited) { ++ graphics_end(); ++ if (graphics_init() == 0) { ++ /* Fallback to default term */ ++ current_term = term_table; ++ max_lines = current_term->max_lines; ++ if (current_term->cls) ++ current_term->cls(); ++ grub_printf("Failed to set splash image and/or graphics mode\n"); ++ return 1; ++ } ++ graphics_cls(); ++ } ++ ++ if (flags == BUILTIN_MENU) ++ current_term = term_table + i; ++ ++ return 0; ++} ++ ++static struct builtin builtin_splashimage = ++{ ++ "splashimage", ++ splashimage_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, ++ "splashimage FILE", ++ "Load FILE as the background image when in graphics mode." ++}; ++ ++ ++/* shade */ ++static int ++shade_func(char *arg, int flags) ++{ ++ int new_shade; ++ ++ if (!arg || safe_parse_maxint(&arg, &new_shade) == 0) ++ return (1); ++ ++ if (shade != new_shade) { ++ shade = new_shade; ++ if (flags == BUILTIN_CMDLINE && graphics_inited) { ++ graphics_end(); ++ graphics_init(); ++ graphics_cls(); ++ } ++ } ++ ++ return 0; ++} ++ ++static struct builtin builtin_shade = ++{ ++ "shade", ++ shade_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, ++ "shade INTEGER", ++ "If set to 0, disables the use of shaded text, else enables it." ++}; ++ ++ ++/* foreground */ ++static int ++foreground_func(char *arg, int flags) ++{ ++ if (grub_strlen(arg) == 6) { ++ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; ++ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; ++ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; ++ ++ foreground = (r << 16) | (g << 8) | b; ++ if (graphics_inited) ++ graphics_set_palette(15, r, g, b); ++ ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static struct builtin builtin_foreground = ++{ ++ "foreground", ++ foreground_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, ++ "foreground RRGGBB", ++ "Sets the foreground color when in graphics mode." ++ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." ++}; ++ ++ ++/* background */ ++static int ++background_func(char *arg, int flags) ++{ ++ if (grub_strlen(arg) == 6) { ++ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; ++ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; ++ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; ++ ++ background = (r << 16) | (g << 8) | b; ++ if (graphics_inited) ++ graphics_set_palette(0, r, g, b); ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static struct builtin builtin_background = ++{ ++ "background", ++ background_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, ++ "background RRGGBB", ++ "Sets the background color when in graphics mode." ++ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." ++}; ++ ++ ++/* border */ ++static int ++border_func(char *arg, int flags) ++{ ++ if (grub_strlen(arg) == 6) { ++ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2; ++ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2; ++ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2; ++ ++ window_border = (r << 16) | (g << 8) | b; ++ if (graphics_inited) ++ graphics_set_palette(0x11, r, g, b); ++ ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static struct builtin builtin_border = ++{ ++ "border", ++ border_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, ++ "border RRGGBB", ++ "Sets the border video color when in graphics mode." ++ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal." ++}; ++ ++ ++/* viewport */ ++static int ++viewport_func (char *arg, int flags) ++{ ++ int i; ++ int x0 = 0, y0 = 0, x1 = 80, y1 = 30; ++ int *pos[4] = { &x0, &y0, &x1, &y1 }; ++ ++ if (!arg) ++ return (1); ++ for (i = 0; i < 4; i++) { ++ if (!*arg) ++ return (1); ++ while (*arg && (*arg == ' ' || *arg == '\t')) ++ ++arg; ++ if (!safe_parse_maxint(&arg, pos[i])) ++ return (1); ++ while (*arg && (*arg != ' ' && *arg != '\t')) ++ ++arg; ++ } ++ ++ /* minimum size is 65 colums and 16 rows */ ++ if (x0 > x1 - 66 || y0 > y1 - 16 || x0 < 0 || y0 < 0 || x1 > 80 || y1 > 30) ++ return 1; ++ ++ view_x0 = x0; ++ view_y0 = y0; ++ view_x1 = x1; ++ view_y1 = y1; ++ ++ if (flags == BUILTIN_CMDLINE && graphics_inited) { ++ graphics_end(); ++ graphics_init(); ++ graphics_cls(); ++ } ++ ++ return 0; ++} ++ ++static struct builtin builtin_viewport = ++{ ++ "viewport", ++ viewport_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, ++ "viewport x0 y0 x1 y1", ++ "Changes grub internals to output text in the window defined by" ++ " four parameters. The x and y parameters are 0 based. This option" ++ " only works with the graphics interface." ++}; ++ ++#endif /* SUPPORT_GRAPHICS */ ++ ++ ++/* clear */ ++static int ++clear_func() ++{ ++ if (current_term->cls) ++ current_term->cls(); ++ ++ return 0; ++} ++ ++static struct builtin builtin_clear = ++{ ++ "clear", ++ clear_func, ++ BUILTIN_CMDLINE | BUILTIN_HELP_LIST, ++ "clear", ++ "Clear the screen" ++}; ++ + + /* displayapm */ + static int +@@ -1454,14 +1720,20 @@ + + + /* help */ +-#define MAX_SHORT_DOC_LEN 39 +-#define MAX_LONG_DOC_LEN 66 +- + static int + help_func (char *arg, int flags) + { +- int all = 0; +- ++ int all = 0, max_short_doc_len, max_long_doc_len; ++ max_short_doc_len = 39; ++ max_long_doc_len = 66; ++#ifdef SUPPORT_GRAPHICS ++ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0) ++ { ++ max_short_doc_len = (view_x1 - view_x0 + 1) / 2 - 1; ++ max_long_doc_len = (view_x1 - view_x0) - 14; ++ } ++#endif ++ + if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0) + { + all = 1; +@@ -1491,13 +1763,13 @@ + + len = grub_strlen ((*builtin)->short_doc); + /* If the length of SHORT_DOC is too long, truncate it. */ +- if (len > MAX_SHORT_DOC_LEN - 1) +- len = MAX_SHORT_DOC_LEN - 1; ++ if (len > max_short_doc_len - 1) ++ len = max_short_doc_len - 1; + + for (i = 0; i < len; i++) + grub_putchar ((*builtin)->short_doc[i]); + +- for (; i < MAX_SHORT_DOC_LEN; i++) ++ for (; i < max_short_doc_len; i++) + grub_putchar (' '); + + if (! left) +@@ -1546,10 +1818,10 @@ + int i; + + /* If LEN is too long, fold DOC. */ +- if (len > MAX_LONG_DOC_LEN) ++ if (len > max_long_doc_len) + { + /* Fold this line at the position of a space. */ +- for (len = MAX_LONG_DOC_LEN; len > 0; len--) ++ for (len = max_long_doc_len; len > 0; len--) + if (doc[len - 1] == ' ') + break; + } +@@ -4085,7 +4357,7 @@ + }; + + +-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) ++#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) + /* terminal */ + static int + terminal_func (char *arg, int flags) +@@ -4244,17 +4516,29 @@ + end: + current_term = term_table + default_term; + current_term->flags = term_flags; +- ++ + if (lines) + max_lines = lines; + else +- /* 24 would be a good default value. */ +- max_lines = 24; +- ++ max_lines = current_term->max_lines; ++ + /* If the interface is currently the command-line, + restart it to repaint the screen. */ +- if (current_term != prev_term && (flags & BUILTIN_CMDLINE)) ++ if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){ ++ if (prev_term->shutdown) ++ prev_term->shutdown(); ++ if (current_term->startup) { ++ /* If startup fails, return to previous term */ ++ if (current_term->startup() == 0) { ++ current_term = prev_term; ++ max_lines = current_term->max_lines; ++ if (current_term->cls) { ++ current_term->cls(); ++ } ++ } ++ } + grub_longjmp (restart_cmdline_env, 0); ++ } + + return 0; + } +@@ -4264,7 +4548,7 @@ + "terminal", + terminal_func, + BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST, +- "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]", ++ "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]", + "Select a terminal. When multiple terminals are specified, wait until" + " you push any key to continue. If both console and serial are specified," + " the terminal to which you input a key first will be selected. If no" +@@ -4276,7 +4560,7 @@ + " seconds. The option --lines specifies the maximum number of lines." + " The option --silent is used to suppress messages." + }; +-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ ++#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */ + + + #ifdef SUPPORT_SERIAL +@@ -4795,13 +5079,20 @@ + /* The table of builtin commands. Sorted in dictionary order. */ + struct builtin *builtin_table[] = + { ++#ifdef SUPPORT_GRAPHICS ++ &builtin_background, ++#endif + &builtin_blocklist, + &builtin_boot, + #ifdef SUPPORT_NETBOOT + &builtin_bootp, + #endif /* SUPPORT_NETBOOT */ ++#ifdef SUPPORT_GRAPHICS ++ &builtin_border, ++#endif + &builtin_cat, + &builtin_chainloader, ++ &builtin_clear, + &builtin_cmp, + &builtin_color, + &builtin_configfile, +@@ -4821,6 +5112,9 @@ + &builtin_embed, + &builtin_fallback, + &builtin_find, ++#ifdef SUPPORT_GRAPHICS ++ &builtin_foreground, ++#endif + &builtin_fstest, + &builtin_geometry, + &builtin_halt, +@@ -4864,9 +5158,13 @@ + #endif /* SUPPORT_SERIAL */ + &builtin_setkey, + &builtin_setup, +-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) ++#ifdef SUPPORT_GRAPHICS ++ &builtin_shade, ++ &builtin_splashimage, ++#endif /* SUPPORT_GRAPHICS */ ++#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) + &builtin_terminal, +-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */ ++#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */ + #ifdef SUPPORT_SERIAL + &builtin_terminfo, + #endif /* SUPPORT_SERIAL */ +@@ -4880,5 +5178,8 @@ + &builtin_unhide, + &builtin_uppermem, + &builtin_vbeprobe, ++#ifdef SUPPORT_GRAPHICS ++ &builtin_viewport, ++#endif + 0 + }; +diff -Naur grub-0.97.orig/stage2/char_io.c grub-0.97/stage2/char_io.c +--- grub-0.97.orig/stage2/char_io.c 2005-02-01 18:51:23.000000000 -0200 ++++ grub-0.97/stage2/char_io.c 2005-06-12 20:56:49.000000000 -0300 +@@ -29,12 +29,17 @@ + # include <serial.h> + #endif + ++#ifdef SUPPORT_GRAPHICS ++# include <graphics.h> ++#endif ++ + #ifndef STAGE1_5 + struct term_entry term_table[] = + { + { + "console", + 0, ++ 24, + console_putchar, + console_checkkey, + console_getkey, +@@ -43,13 +48,16 @@ + console_cls, + console_setcolorstate, + console_setcolor, +- console_setcursor ++ console_setcursor, ++ 0, ++ 0 + }, + #ifdef SUPPORT_SERIAL + { + "serial", + /* A serial device must be initialized. */ + TERM_NEED_INIT, ++ 24, + serial_putchar, + serial_checkkey, + serial_getkey, +@@ -58,6 +66,8 @@ + serial_cls, + serial_setcolorstate, + 0, ++ 0, ++ 0, + 0 + }, + #endif /* SUPPORT_SERIAL */ +@@ -65,6 +75,7 @@ + { + "hercules", + 0, ++ 24, + hercules_putchar, + console_checkkey, + console_getkey, +@@ -73,11 +84,30 @@ + hercules_cls, + hercules_setcolorstate, + hercules_setcolor, +- hercules_setcursor ++ hercules_setcursor, ++ 0, ++ 0 + }, + #endif /* SUPPORT_HERCULES */ ++#ifdef SUPPORT_GRAPHICS ++ { "graphics", ++ TERM_NEED_INIT, /* flags */ ++ 30, /* number of lines */ ++ graphics_putchar, /* putchar */ ++ console_checkkey, /* checkkey */ ++ console_getkey, /* getkey */ ++ graphics_getxy, /* getxy */ ++ graphics_gotoxy, /* gotoxy */ ++ graphics_cls, /* cls */ ++ graphics_setcolorstate, /* setcolorstate */ ++ graphics_setcolor, /* setcolor */ ++ graphics_setcursor, /* nocursor */ ++ graphics_init, /* initialize */ ++ graphics_end /* shutdown */ ++ }, ++#endif /* SUPPORT_GRAPHICS */ + /* This must be the last entry. */ +- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } + }; + + /* This must be console. */ +@@ -305,9 +335,10 @@ + + /* XXX: These should be defined in shared.h, but I leave these here, + until this code is freezed. */ +-#define CMDLINE_WIDTH 78 + #define CMDLINE_MARGIN 10 +- ++ ++ /* command-line limits */ ++ int cmdline_width = 78, col_start = 0; + int xpos, lpos, c, section; + /* The length of PROMPT. */ + int plen; +@@ -338,7 +369,7 @@ + + /* If the cursor is in the first section, display the first section + instead of the second. */ +- if (section == 1 && plen + lpos < CMDLINE_WIDTH) ++ if (section == 1 && plen + lpos < cmdline_width) + cl_refresh (1, 0); + else if (xpos - count < 1) + cl_refresh (1, 0); +@@ -354,7 +385,7 @@ + grub_putchar ('\b'); + } + else +- gotoxy (xpos, getxy () & 0xFF); ++ gotoxy (xpos + col_start, getxy () & 0xFF); + } + } + +@@ -364,7 +395,7 @@ + lpos += count; + + /* If the cursor goes outside, scroll the screen to the right. */ +- if (xpos + count >= CMDLINE_WIDTH) ++ if (xpos + count >= cmdline_width) + cl_refresh (1, 0); + else + { +@@ -383,7 +414,7 @@ + } + } + else +- gotoxy (xpos, getxy () & 0xFF); ++ gotoxy (xpos + col_start, getxy () & 0xFF); + } + } + +@@ -398,14 +429,14 @@ + if (full) + { + /* Recompute the section number. */ +- if (lpos + plen < CMDLINE_WIDTH) ++ if (lpos + plen < cmdline_width) + section = 0; + else +- section = ((lpos + plen - CMDLINE_WIDTH) +- / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1); ++ section = ((lpos + plen - cmdline_width) ++ / (cmdline_width - 1 - CMDLINE_MARGIN) + 1); + + /* From the start to the end. */ +- len = CMDLINE_WIDTH; ++ len = cmdline_width; + pos = 0; + grub_putchar ('\r'); + +@@ -445,8 +476,8 @@ + if (! full) + offset = xpos - 1; + +- start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) +- + CMDLINE_WIDTH - plen - CMDLINE_MARGIN); ++ start = ((section - 1) * (cmdline_width - 1 - CMDLINE_MARGIN) ++ + cmdline_width - plen - CMDLINE_MARGIN); + xpos = lpos + 1 - start; + start += offset; + } +@@ -471,7 +502,7 @@ + + /* If the cursor is at the last position, put `>' or a space, + depending on if there are more characters in BUF. */ +- if (pos == CMDLINE_WIDTH) ++ if (pos == cmdline_width) + { + if (start + len < llen) + grub_putchar ('>'); +@@ -488,7 +519,7 @@ + grub_putchar ('\b'); + } + else +- gotoxy (xpos, getxy () & 0xFF); ++ gotoxy (xpos + col_start, getxy () & 0xFF); + } + + /* Initialize the command-line. */ +@@ -518,10 +549,10 @@ + + llen += l; + lpos += l; +- if (xpos + l >= CMDLINE_WIDTH) ++ if (xpos + l >= cmdline_width) + cl_refresh (1, 0); +- else if (xpos + l + llen - lpos > CMDLINE_WIDTH) +- cl_refresh (0, CMDLINE_WIDTH - xpos); ++ else if (xpos + l + llen - lpos > cmdline_width) ++ cl_refresh (0, cmdline_width - xpos); + else + cl_refresh (0, l + llen - lpos); + } +@@ -533,12 +564,22 @@ + grub_memmove (buf + lpos, buf + lpos + count, llen - count + 1); + llen -= count; + +- if (xpos + llen + count - lpos > CMDLINE_WIDTH) +- cl_refresh (0, CMDLINE_WIDTH - xpos); ++ if (xpos + llen + count - lpos > cmdline_width) ++ cl_refresh (0, cmdline_width - xpos); + else + cl_refresh (0, llen + count - lpos); + } + ++ max_lines = current_term->max_lines; ++#ifdef SUPPORT_GRAPHICS ++ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0) ++ { ++ cmdline_width = (view_x1 - view_x0) - 2; ++ col_start = view_x0; ++ max_lines = view_y1 - view_y0; ++ } ++#endif ++ + plen = grub_strlen (prompt); + llen = grub_strlen (cmdline); + +@@ -1006,6 +1047,48 @@ + } + #endif /* ! STAGE1_5 */ + ++#ifndef STAGE1_5 ++/* Internal pager. */ ++int ++do_more (void) ++{ ++ if (count_lines >= 0) ++ { ++ count_lines++; ++ if (count_lines >= max_lines - 2) ++ { ++ int tmp; ++ ++ /* It's important to disable the feature temporarily, because ++ the following grub_printf call will print newlines. */ ++ count_lines = -1; ++ ++ grub_printf("\n"); ++ if (current_term->setcolorstate) ++ current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); ++ ++ grub_printf ("[Hit return to continue]"); ++ ++ if (current_term->setcolorstate) ++ current_term->setcolorstate (COLOR_STATE_NORMAL); ++ ++ ++ do ++ { ++ tmp = ASCII_CHAR (getkey ()); ++ } ++ while (tmp != '\n' && tmp != '\r'); ++ grub_printf ("\r \r"); ++ ++ /* Restart to count lines. */ ++ count_lines = 0; ++ return 1; ++ } ++ } ++ return 0; ++} ++#endif ++ + /* Display an ASCII character. */ + void + grub_putchar (int c) +@@ -1034,38 +1117,11 @@ + + if (c == '\n') + { ++ int flag; + /* Internal `more'-like feature. */ +- if (count_lines >= 0) +- { +- count_lines++; +- if (count_lines >= max_lines - 2) +- { +- int tmp; +- +- /* It's important to disable the feature temporarily, because +- the following grub_printf call will print newlines. */ +- count_lines = -1; +- +- if (current_term->setcolorstate) +- current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); +- +- grub_printf ("\n[Hit return to continue]"); +- +- if (current_term->setcolorstate) +- current_term->setcolorstate (COLOR_STATE_NORMAL); +- +- do +- { +- tmp = ASCII_CHAR (getkey ()); +- } +- while (tmp != '\n' && tmp != '\r'); +- grub_printf ("\r \r"); +- +- /* Restart to count lines. */ +- count_lines = 0; +- return; +- } +- } ++ flag = do_more (); ++ if (flag) ++ return; + } + + current_term->putchar (c); +@@ -1090,7 +1146,7 @@ + cls (void) + { + /* If the terminal is dumb, there is no way to clean the terminal. */ +- if (current_term->flags & TERM_DUMB) ++ if (current_term->flags & TERM_DUMB) + grub_putchar ('\n'); + else + current_term->cls (); +@@ -1217,6 +1273,16 @@ + return ! errnum; + } + ++void ++grub_memcpy(void *dest, const void *src, int len) ++{ ++ int i; ++ register char *d = (char*)dest, *s = (char*)src; ++ ++ for (i = 0; i < len; i++) ++ d[i] = s[i]; ++} ++ + void * + grub_memmove (void *to, const void *from, int len) + { +diff -Naur grub-0.97.orig/stage2/cmdline.c grub-0.97/stage2/cmdline.c +--- grub-0.97.orig/stage2/cmdline.c 2004-08-16 20:23:01.000000000 -0300 ++++ grub-0.97/stage2/cmdline.c 2005-06-12 20:56:49.000000000 -0300 +@@ -50,10 +50,11 @@ + void + print_cmdline_message (int forever) + { +- printf (" [ Minimal BASH-like line editing is supported. For the first word, TAB\n" +- " lists possible command completions. Anywhere else TAB lists the possible\n" +- " completions of a device/filename.%s ]\n", +- (forever ? "" : " ESC at any time exits.")); ++ grub_printf(" [ Minimal BASH-like line editing is supported. For\n" ++ " the first word, TAB lists possible command\n" ++ " completions. Anywhere else TAB lists the possible\n" ++ " completions of a device/filename.%s ]\n", ++ (forever ? "" : " ESC at any time\n exits.")); + } + + /* Find the builtin whose command name is COMMAND and return the +diff -Naur grub-0.97.orig/stage2/graphics.c grub-0.97/stage2/graphics.c +--- grub-0.97.orig/stage2/graphics.c 1969-12-31 21:00:00.000000000 -0300 ++++ grub-0.97/stage2/graphics.c 2005-06-13 19:13:31.000000000 -0300 +@@ -0,0 +1,585 @@ ++/* ++ * graphics.c - graphics mode support for GRUB ++ * Implemented as a terminal type by Jeremy Katz <katzj@xxxxxxxxxx> based ++ * on a patch by Paulo César Pereira de Andrade <pcpa@xxxxxxxxxxxxxxxx> ++ * Options and enhancements made by Herton Ronaldo Krzesinski ++ * <herton@xxxxxxxxxxxx> ++ * ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2001,2002 Red Hat, Inc. ++ * Portions copyright (C) 2000 Conectiva, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifdef SUPPORT_GRAPHICS ++ ++#include <term.h> ++#include <shared.h> ++#include <graphics.h> ++ ++int saved_videomode; ++unsigned char *font8x16; ++ ++int graphics_inited = 0; ++static char splashimage[256]; ++ ++int shade = 1, no_cursor = 0; ++ ++#define VSHADOW VSHADOW1 ++unsigned char VSHADOW1[38400]; ++unsigned char VSHADOW2[38400]; ++unsigned char VSHADOW4[38400]; ++unsigned char VSHADOW8[38400]; ++ ++/* define the default viewable area */ ++int view_x0 = 0; ++int view_y0 = 0; ++int view_x1 = 80; ++int view_y1 = 30; ++ ++/* text buffer has to be kept around so that we can write things as we ++ * scroll and the like */ ++unsigned short text[80 * 30]; ++ ++/* graphics options */ ++int foreground = (63 << 16) | (63 << 8) | (63), background = 0, window_border = 0; ++ ++/* current position */ ++static int fontx = 0; ++static int fonty = 0; ++ ++/* global state so that we don't try to recursively scroll or cursor */ ++static int no_scroll = 0; ++ ++/* color state */ ++static int graphics_standard_color = A_NORMAL; ++static int graphics_normal_color = A_NORMAL; ++static int graphics_highlight_color = A_REVERSE; ++static int graphics_current_color = A_NORMAL; ++static color_state graphics_color_state = COLOR_STATE_STANDARD; ++ ++static inline void outb(unsigned short port, unsigned char val) ++{ ++ __asm __volatile ("outb %0,%1"::"a" (val), "d" (port)); ++} ++ ++static void MapMask(int value) { ++ outb(0x3c4, 2); ++ outb(0x3c5, value); ++} ++ ++/* bit mask register */ ++static void BitMask(int value) { ++ outb(0x3ce, 8); ++ outb(0x3cf, value); ++} ++ ++/* move the graphics cursor location to col, row */ ++static void graphics_setxy(int col, int row) { ++ if (col >= view_x0 && col < view_x1) { ++ fontx = col; ++ cursorX = col << 3; ++ } ++ if (row >= view_y0 && row < view_y1) { ++ fonty = row; ++ cursorY = row << 4; ++ } ++} ++ ++/* scroll the screen */ ++static void graphics_scroll() { ++ int i, j, k; ++ ++ /* we don't want to scroll recursively... that would be bad */ ++ if (no_scroll) ++ return; ++ no_scroll = 1; ++ ++ /* disable pager temporarily */ ++ k = count_lines; ++ count_lines = -1; ++ ++ /* move everything up a line */ ++ for (j = view_y0 + 1; j < view_y1; j++) { ++ graphics_gotoxy(view_x0, j - 1); ++ for (i = view_x0; i < view_x1; i++) { ++ graphics_putchar(text[j * 80 + i]); ++ } ++ } ++ ++ /* last line should be blank */ ++ graphics_gotoxy(view_x0, view_y1 - 1); ++ for (i = view_x0; i < view_x1; i++) ++ graphics_putchar(' '); ++ graphics_setxy(view_x0, view_y1 - 1); ++ ++ count_lines = k; ++ ++ no_scroll = 0; ++} ++ ++/* Set the splash image */ ++void graphics_set_splash(char *splashfile) { ++ grub_strcpy(splashimage, splashfile); ++} ++ ++/* Get the current splash image */ ++char *graphics_get_splash(void) { ++ return splashimage; ++} ++ ++/* ++ * Initialize a vga16 graphics display with the palette based off of ++ * the image in splashimage. If the image doesn't exist, leave graphics ++ * mode. The mode initiated is 12h. From "Ralf Brown's Interrupt List": ++ * text/ text pixel pixel colors disply scrn system ++ * grph resol box resolution pages addr ++ * 12h G 80x30 8x16 640x480 16/256K . A000 VGA,ATI VIP ++ * G 80x30 8x16 640x480 16/64 . A000 ATI EGA Wonder ++ * G . . 640x480 16 . . UltraVision+256K EGA ++ */ ++int graphics_init() ++{ ++ if (!graphics_inited) { ++ saved_videomode = set_videomode(0x12); ++ if (get_videomode() != 0x12) { ++ set_videomode(saved_videomode); ++ return 0; ++ } ++ graphics_inited = 1; ++ } ++ else ++ return 1; ++ ++ font8x16 = (unsigned char*)graphics_get_font(); ++ ++ /* make sure that the highlight color is set correctly */ ++ graphics_highlight_color = ((graphics_normal_color >> 4) | ++ ((graphics_normal_color & 0xf) << 4)); ++ ++ graphics_cls(); ++ ++ if (!read_image(splashimage)) { ++ grub_printf("Failed to read splash image (%s)\n", splashimage); ++ grub_printf("Press any key to continue..."); ++ getkey(); ++ set_videomode(saved_videomode); ++ graphics_inited = 0; ++ return 0; ++ } ++ ++ set_int1c_handler(); ++ ++ return 1; ++} ++ ++/* Leave graphics mode */ ++void graphics_end(void) ++{ ++ if (graphics_inited) { ++ unset_int1c_handler(); ++ set_videomode(saved_videomode); ++ graphics_inited = 0; ++ no_cursor = 0; ++ } ++} ++ ++/* Print ch on the screen. Handle any needed scrolling or the like */ ++void graphics_putchar(int ch) { ++ ch &= 0xff; ++ ++ graphics_cursor(0); ++ ++ if (ch == '\n') { ++ if (fonty + 1 < view_y1) ++ graphics_setxy(fontx, fonty + 1); ++ else ++ graphics_scroll(); ++ graphics_cursor(1); ++ return; ++ } else if (ch == '\r') { ++ graphics_setxy(view_x0, fonty); ++ graphics_cursor(1); ++ return; ++ } ++ ++ graphics_cursor(0); ++ ++ text[fonty * 80 + fontx] = ch; ++ text[fonty * 80 + fontx] &= 0x00ff; ++ if (graphics_current_color & 0xf0) ++ text[fonty * 80 + fontx] |= 0x100; ++ ++ graphics_cursor(0); ++ ++ if ((fontx + 1) >= view_x1) { ++ graphics_setxy(view_x0, fonty); ++ if (fonty + 1 < view_y1) ++ graphics_setxy(view_x0, fonty + 1); ++ else ++ graphics_scroll(); ++ graphics_cursor(1); ++ do_more (); ++ graphics_cursor(0); ++ } else { ++ graphics_setxy(fontx + 1, fonty); ++ } ++ ++ graphics_cursor(1); ++} ++ ++/* get the current location of the cursor */ ++int graphics_getxy(void) { ++ return (fontx << 8) | fonty; ++} ++ ++void graphics_gotoxy(int x, int y) { ++ graphics_cursor(0); ++ ++ graphics_setxy(x, y); ++ ++ graphics_cursor(1); ++} ++ ++void graphics_cls(void) { ++ int i; ++ unsigned char *mem, *s1, *s2, *s4, *s8; ++ ++ graphics_cursor(0); ++ graphics_gotoxy(view_x0, view_y0); ++ ++ mem = (unsigned char*)VIDEOMEM; ++ s1 = (unsigned char*)VSHADOW1; ++ s2 = (unsigned char*)VSHADOW2; ++ s4 = (unsigned char*)VSHADOW4; ++ s8 = (unsigned char*)VSHADOW8; ++ ++ for (i = 0; i < 80 * 30; i++) ++ text[i] = ' '; ++ graphics_cursor(1); ++ ++ BitMask(0xff); ++ ++ /* plane 1 */ ++ MapMask(1); ++ grub_memcpy(mem, s1, 38400); ++ ++ /* plane 2 */ ++ MapMask(2); ++ grub_memcpy(mem, s2, 38400); ++ ++ /* plane 3 */ ++ MapMask(4); ++ grub_memcpy(mem, s4, 38400); ++ ++ /* plane 4 */ ++ MapMask(8); ++ grub_memcpy(mem, s8, 38400); ++ ++ MapMask(15); ++ ++ if (no_cursor) { ++ no_cursor = 0; ++ set_int1c_handler(); ++ } ++} ++ ++void graphics_setcolorstate (color_state state) { ++ switch (state) { ++ case COLOR_STATE_STANDARD: ++ graphics_current_color = graphics_standard_color; ++ break; ++ case COLOR_STATE_NORMAL: ++ graphics_current_color = graphics_normal_color; ++ break; ++ case COLOR_STATE_HIGHLIGHT: ++ graphics_current_color = graphics_highlight_color; ++ break; ++ default: ++ graphics_current_color = graphics_standard_color; ++ break; ++ } ++ ++ graphics_color_state = state; ++} ++ ++void graphics_setcolor (int normal_color, int highlight_color) { ++ graphics_normal_color = normal_color; ++ graphics_highlight_color = highlight_color; ++ ++ graphics_setcolorstate (graphics_color_state); ++} ++ ++int graphics_setcursor (int on) { ++ if (!no_cursor && !on) { ++ no_cursor = 1; ++ unset_int1c_handler(); ++ graphics_cursor(0); ++ } ++ else if(no_cursor && on) { ++ no_cursor = 0; ++ set_int1c_handler(); ++ graphics_cursor(1); ++ } ++ return 0; ++} ++ ++/* Read in the splashscreen image and set the palette up appropriately. ++ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and ++ * 640x480. */ ++int read_image(char *s) ++{ ++ char buf[32], pal[16], c; ++ unsigned char base, mask, *s1, *s2, *s4, *s8; ++ unsigned i, len, idx, colors, x, y, width, height; ++ ++ if (!grub_open(s)) ++ return 0; ++ ++ /* read header */ ++ if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) { ++ grub_close(); ++ return 0; ++ } ++ ++ /* parse info */ ++ while (grub_read(&c, 1)) { ++ if (c == '"') ++ break; ++ } ++ ++ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) ++ ; ++ ++ i = 0; ++ width = c - '0'; ++ while (grub_read(&c, 1)) { ++ if (c >= '0' && c <= '9') ++ width = width * 10 + c - '0'; ++ else ++ break; ++ } ++ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) ++ ; ++ ++ height = c - '0'; ++ while (grub_read(&c, 1)) { ++ if (c >= '0' && c <= '9') ++ height = height * 10 + c - '0'; ++ else ++ break; ++ } ++ while (grub_read(&c, 1) && (c == ' ' || c == '\t')) ++ ; ++ ++ colors = c - '0'; ++ while (grub_read(&c, 1)) { ++ if (c >= '0' && c <= '9') ++ colors = colors * 10 + c - '0'; ++ else ++ break; ++ } ++ ++ base = 0; ++ while (grub_read(&c, 1) && c != '"') ++ ; ++ ++ /* palette */ ++ for (i = 0, idx = 1; i < colors; i++) { ++ len = 0; ++ ++ while (grub_read(&c, 1) && c != '"') ++ ; ++ grub_read(&c, 1); /* char */ ++ base = c; ++ grub_read(buf, 4); /* \t c # */ ++ ++ while (grub_read(&c, 1) && c != '"') { ++ if (len < sizeof(buf)) ++ buf[len++] = c; ++ } ++ ++ if (len == 6 && idx < 15) { ++ int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2; ++ int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2; ++ int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2; ++ ++ pal[idx] = base; ++ graphics_set_palette(idx, r, g, b); ++ ++idx; ++ } ++ } ++ ++ x = y = len = 0; ++ ++ s1 = (unsigned char*)VSHADOW1; ++ s2 = (unsigned char*)VSHADOW2; ++ s4 = (unsigned char*)VSHADOW4; ++ s8 = (unsigned char*)VSHADOW8; ++ ++ for (i = 0; i < 38400; i++) ++ s1[i] = s2[i] = s4[i] = s8[i] = 0; ++ ++ /* parse xpm data */ ++ while (y < height) { ++ while (1) { ++ if (!grub_read(&c, 1)) { ++ grub_close(); ++ return 0; ++ } ++ if (c == '"') ++ break; ++ } ++ ++ while (grub_read(&c, 1) && c != '"') { ++ for (i = 1; i < 15; i++) ++ if (pal[i] == c) { ++ c = i; ++ break; ++ } ++ ++ mask = 0x80 >> (x & 7); ++ if (c & 1) ++ s1[len + (x >> 3)] |= mask; ++ if (c & 2) ++ s2[len + (x >> 3)] |= mask; ++ if (c & 4) ++ s4[len + (x >> 3)] |= mask; ++ if (c & 8) ++ s8[len + (x >> 3)] |= mask; ++ ++ if (++x >= 640) { ++ x = 0; ++ ++ if (y < 480) ++ len += 80; ++ ++y; ++ } ++ } ++ } ++ ++ grub_close(); ++ ++ graphics_set_palette(0, (background >> 16), (background >> 8) & 63, ++ background & 63); ++ graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63, ++ foreground & 63); ++ graphics_set_palette(0x11, (window_border >> 16), (window_border >> 8) & 63, ++ window_border & 63); ++ ++ return 1; ++} ++ ++/* Convert a character which is a hex digit to the appropriate integer */ ++int hex(int v) ++{ ++ if (v >= 'A' && v <= 'F') ++ return (v - 'A' + 10); ++ if (v >= 'a' && v <= 'f') ++ return (v - 'a' + 10); ++ return (v - '0'); ++} ++ ++void graphics_cursor(int set) { ++ unsigned char *pat, *mem, *ptr, chr[16 << 2]; ++ int i, ch, invert, offset; ++ ++ if (set && (no_cursor || no_scroll)) ++ return; ++ ++ offset = cursorY * 80 + fontx; ++ ch = text[fonty * 80 + fontx] & 0xff; ++ invert = (text[fonty * 80 + fontx] & 0xff00) != 0; ++ pat = font8x16 + (ch << 4); ++ ++ mem = (unsigned char*)VIDEOMEM + offset; ++ ++ if (!set) { ++ for (i = 0; i < 16; i++) { ++ unsigned char mask = pat[i]; ++ ++ if (!invert) { ++ chr[i ] = ((unsigned char*)VSHADOW1)[offset]; ++ chr[16 + i] = ((unsigned char*)VSHADOW2)[offset]; ++ chr[32 + i] = ((unsigned char*)VSHADOW4)[offset]; ++ chr[48 + i] = ((unsigned char*)VSHADOW8)[offset]; ++ ++ if (shade) { ++ if (ch == DISP_VERT || ch == DISP_LL || ++ ch == DISP_UR || ch == DISP_LR) { ++ unsigned char pmask = ~(pat[i] >> 1); ++ ++ chr[i ] &= pmask; ++ chr[16 + i] &= pmask; ++ chr[32 + i] &= pmask; ++ chr[48 + i] &= pmask; ++ } ++ if (i > 0 && ch != DISP_VERT) { ++ unsigned char pmask = ~(pat[i - 1] >> 1); ++ ++ chr[i ] &= pmask; ++ chr[16 + i] &= pmask; ++ chr[32 + i] &= pmask; ++ chr[48 + i] &= pmask; ++ if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) { ++ pmask = ~pat[i - 1]; ++ ++ chr[i ] &= pmask; ++ chr[16 + i] &= pmask; ++ chr[32 + i] &= pmask; ++ chr[48 + i] &= pmask; ++ } ++ } ++ } ++ chr[i ] |= mask; ++ chr[16 + i] |= mask; ++ chr[32 + i] |= mask; ++ chr[48 + i] |= mask; ++ ++ offset += 80; ++ } ++ else { ++ chr[i ] = mask; ++ chr[16 + i] = mask; ++ chr[32 + i] = mask; ++ chr[48 + i] = mask; ++ } ++ } ++ } ++ else { ++ MapMask(15); ++ ptr = mem; ++ for (i = 0; i < 16; i++, ptr += 80) { ++ cursorBuf[i] = pat[i]; ++ *ptr = ~pat[i]; ++ } ++ return; ++ } ++ ++ offset = 0; ++ for (i = 1; i < 16; i <<= 1, offset += 16) { ++ int j; ++ ++ MapMask(i); ++ ptr = mem; ++ for (j = 0; j < 16; j++, ptr += 80) ++ *ptr = chr[j + offset]; ++ } ++ ++ MapMask(15); ++} ++ ++#endif /* SUPPORT_GRAPHICS */ +diff -Naur grub-0.97.orig/stage2/graphics.h grub-0.97/stage2/graphics.h +--- grub-0.97.orig/stage2/graphics.h 1969-12-31 21:00:00.000000000 -0300 ++++ grub-0.97/stage2/graphics.h 2005-06-12 20:56:49.000000000 -0300 +@@ -0,0 +1,44 @@ ++/* graphics.h - graphics console interface */ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2002 Free Software Foundation, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#ifndef GRAPHICS_H ++#define GRAPHICS_H ++ ++/* magic constant */ ++#define VIDEOMEM 0xA0000 ++ ++/* function prototypes */ ++char *graphics_get_splash(void); ++ ++int read_image(char *s); ++void graphics_cursor(int set); ++ ++/* function prototypes for asm functions */ ++void * graphics_get_font(); ++void graphics_set_palette(int idx, int red, int green, int blue); ++void set_int1c_handler(); ++void unset_int1c_handler(); ++ ++extern short cursorX, cursorY; ++extern char cursorBuf[16]; ++extern int shade; ++extern int view_x0, view_y0, view_x1, view_y1; ++ ++#endif /* GRAPHICS_H */ +diff -Naur grub-0.97.orig/stage2/Makefile.am grub-0.97/stage2/Makefile.am +--- grub-0.97.orig/stage2/Makefile.am 2005-02-02 18:37:35.000000000 -0200 ++++ grub-0.97/stage2/Makefile.am 2005-06-12 20:56:49.000000000 -0300 +@@ -7,7 +7,7 @@ + fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \ + imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \ + nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \ +- terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h ++ terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h + EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS) + + # For <stage1.h>. +@@ -19,7 +19,7 @@ + disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \ + fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \ + fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \ +- terminfo.c tparm.c ++ terminfo.c tparm.c graphics.c + libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \ + -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \ + -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \ +@@ -79,8 +79,14 @@ + HERCULES_FLAGS = + endif + ++if GRAPHICS_SUPPORT ++GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1 ++else ++GRAPHICS_FLAGS = ++endif ++ + STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \ +- $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) ++ $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS) + + STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000 + STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1 +@@ -90,7 +96,8 @@ + cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \ + fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \ + fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \ +- hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c ++ hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \ ++ graphics.c + pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) + pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) + pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK) +diff -Naur grub-0.97.orig/stage2/shared.h grub-0.97/stage2/shared.h +--- grub-0.97.orig/stage2/shared.h 2004-06-19 13:40:09.000000000 -0300 ++++ grub-0.97/stage2/shared.h 2005-06-12 20:56:49.000000000 -0300 +@@ -792,6 +792,11 @@ + /* Set the cursor position. */ + void gotoxy (int x, int y); + ++/* Internal pager ++ Returns 1 = if pager was used ++ 0 = if pager wasn't used */ ++int do_more (void); ++ + /* Displays an ASCII character. IBM displays will translate some + characters to special graphical ones (see the DISP_* constants). */ + void grub_putchar (int c); +@@ -871,6 +876,7 @@ + int grub_tolower (int c); + int grub_isspace (int c); + int grub_strncat (char *s1, const char *s2, int n); ++void grub_memcpy(void *dest, const void *src, int len); + void *grub_memmove (void *to, const void *from, int len); + void *grub_memset (void *start, int c, int len); + int grub_strncat (char *s1, const char *s2, int n); +diff -Naur grub-0.97.orig/stage2/stage2.c grub-0.97/stage2/stage2.c +--- grub-0.97.orig/stage2/stage2.c 2005-03-19 14:51:57.000000000 -0300 ++++ grub-0.97/stage2/stage2.c 2005-06-13 22:38:08.000000000 -0300 +@@ -20,6 +20,12 @@ + #include <shared.h> + #include <term.h> + ++#ifdef SUPPORT_GRAPHICS ++# include <graphics.h> ++#endif ++ ++int col_start, col_end, row_start, box_size; ++ + grub_jmp_buf restart_env; + + #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS) +@@ -105,13 +111,13 @@ + if (highlight && current_term->setcolorstate) + current_term->setcolorstate (COLOR_STATE_HIGHLIGHT); + +- gotoxy (2, y); ++ gotoxy (2 + col_start, y); + grub_putchar (' '); +- for (x = 3; x < 75; x++) ++ for (x = 3 + col_start; x < (col_end - 5); x++) + { +- if (*entry && x <= 72) ++ if (*entry && x <= (col_end - 8)) + { +- if (x == 72) ++ if (x == (col_end - 8)) + grub_putchar (DISP_RIGHT); + else + grub_putchar (*entry++); +@@ -119,7 +125,7 @@ + else + grub_putchar (' '); + } +- gotoxy (74, y); ++ gotoxy ((col_end - 6), y); + + if (current_term->setcolorstate) + current_term->setcolorstate (COLOR_STATE_STANDARD); +@@ -131,7 +137,7 @@ + { + int i; + +- gotoxy (77, y + 1); ++ gotoxy ((col_end - 3), y + 1); + + if (first) + grub_putchar (DISP_UP); +@@ -151,14 +157,14 @@ + menu_entries++; + } + +- gotoxy (77, y + size); ++ gotoxy ((col_end - 3), y + size); + + if (*menu_entries) + grub_putchar (DISP_DOWN); + else + grub_putchar (' '); + +- gotoxy (74, y + entryno + 1); ++ gotoxy ((col_end - 6), y + entryno + 1); + } + + static void +@@ -196,30 +202,30 @@ + if (current_term->setcolorstate) + current_term->setcolorstate (COLOR_STATE_NORMAL); + +- gotoxy (1, y); ++ gotoxy (1 + col_start, y); + + grub_putchar (DISP_UL); +- for (i = 0; i < 73; i++) ++ for (i = col_start; i < (col_end - 7); i++) + grub_putchar (DISP_HORIZ); + grub_putchar (DISP_UR); + + i = 1; + while (1) + { +- gotoxy (1, y + i); ++ gotoxy (1 + col_start, y + i); + + if (i > size) + break; + + grub_putchar (DISP_VERT); +- gotoxy (75, y + i); ++ gotoxy ((col_end - 5), y + i); + grub_putchar (DISP_VERT); + + i++; + } + + grub_putchar (DISP_LL); +- for (i = 0; i < 73; i++) ++ for (i = col_start; i < (col_end - 7); i++) + grub_putchar (DISP_HORIZ); + grub_putchar (DISP_LR); + +@@ -233,6 +239,7 @@ + { + int c, time1, time2 = -1, first_entry = 0; + char *cur_entry = 0; ++ struct term_entry *prev_term = NULL; + + /* + * Main loop for menu UI. +@@ -250,6 +257,22 @@ + } + } + ++ col_start = 0; ++ col_end = 80; ++ row_start = 0; ++ box_size = 12; ++ /* if we're using viewport we need to make sure to setup ++ coordinates correctly. */ ++#ifdef SUPPORT_GRAPHICS ++ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0) ++ { ++ col_start = view_x0; ++ col_end = view_x1; ++ row_start = view_y0; ++ box_size = (view_y1 - view_y0) - 13; ++ } ++#endif ++ + /* If the timeout was expired or wasn't set, force to show the menu + interface. */ + if (grub_timeout < 0) +@@ -302,36 +325,36 @@ + if (current_term->flags & TERM_DUMB) + print_entries_raw (num_entries, first_entry, menu_entries); + else +- print_border (3, 12); ++ print_border (3 + row_start, box_size); + + grub_printf ("\n\ +- Use the %c and %c keys to select which entry is highlighted.\n", ++ Use the %c and %c keys to select which entry is highlighted.\n", + DISP_UP, DISP_DOWN); + + if (! auth && password) + { + printf ("\ +- Press enter to boot the selected OS or \'p\' to enter a\n\ +- password to unlock the next set of features."); ++ Press enter to boot the selected OS or \'p\' to enter a\n\ ++ password to unlock the next set of features."); + } + else + { + if (config_entries) + printf ("\ +- Press enter to boot the selected OS, \'e\' to edit the\n\ +- commands before booting, or \'c\' for a command-line."); ++ Press enter to boot the selected OS, \'e\' to edit the\n\ ++ commands before booting, or \'c\' for a command-line."); + else + printf ("\ +- Press \'b\' to boot, \'e\' to edit the selected command in the\n\ +- boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\ +- after (\'O\' for before) the selected line, \'d\' to remove the\n\ +- selected line, or escape to go back to the main menu."); ++ Press \'b\' to boot, \'e\' to edit the selected command in the\n\ ++ boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\ ++ after (\'O\' for before) the selected line, \'d\' to remove the\n\ ++ selected line, or escape to go back to the main menu."); + } + + if (current_term->flags & TERM_DUMB) + grub_printf ("\n\nThe selected entry is %d ", entryno); + else +- print_entries (3, 12, first_entry, entryno, menu_entries); ++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); + } + + /* XX using RT clock now, need to initialize value */ +@@ -358,10 +381,10 @@ + entryno, grub_timeout); + else + { +- gotoxy (3, 22); +- grub_printf ("The highlighted entry will be booted automatically in %d seconds. ", ++ gotoxy (3 + col_start, 10 + box_size + row_start); ++ grub_printf (" The highlighted entry will be booted automatically in %d seconds. ", + grub_timeout); +- gotoxy (74, 4 + entryno); ++ gotoxy ((col_end - 6), 4 + entryno + row_start); + } + + grub_timeout--; +@@ -387,12 +410,12 @@ + if (current_term->flags & TERM_DUMB) + grub_putchar ('\r'); + else +- gotoxy (3, 22); ++ gotoxy (3 + col_start, 10 + box_size + row_start); + printf (" "); + grub_timeout = -1; + fallback_entryno = -1; + if (! (current_term->flags & TERM_DUMB)) +- gotoxy (74, 4 + entryno); ++ gotoxy ((col_end - 6), 4 + entryno + row_start); + } + + /* We told them above (at least in SUPPORT_SERIAL) to use +@@ -408,12 +431,12 @@ + { + if (entryno > 0) + { +- print_entry (4 + entryno, 0, ++ print_entry (4 + entryno + row_start, 0, + get_entry (menu_entries, + first_entry + entryno, + 0)); + entryno--; +- print_entry (4 + entryno, 1, ++ print_entry (4 + entryno + row_start, 1, + get_entry (menu_entries, + first_entry + entryno, + 0)); +@@ -421,7 +444,7 @@ + else if (first_entry > 0) + { + first_entry--; +- print_entries (3, 12, first_entry, entryno, ++ print_entries (3 + row_start, box_size, first_entry, entryno, + menu_entries); + } + } +@@ -433,29 +456,29 @@ + entryno++; + else + { +- if (entryno < 11) ++ if (entryno < (box_size - 1)) + { +- print_entry (4 + entryno, 0, ++ print_entry (4 + entryno + row_start, 0, + get_entry (menu_entries, + first_entry + entryno, + 0)); + entryno++; +- print_entry (4 + entryno, 1, ++ print_entry (4 + entryno + row_start, 1, + get_entry (menu_entries, + first_entry + entryno, + 0)); + } +- else if (num_entries > 12 + first_entry) ++ else if (num_entries > box_size + first_entry) + { + first_entry++; +- print_entries (3, 12, first_entry, entryno, menu_entries); ++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); + } + } + } + else if (c == 7) + { + /* Page Up */ +- first_entry -= 12; ++ first_entry -= box_size; + if (first_entry < 0) + { + entryno += first_entry; +@@ -463,20 +486,20 @@ + if (entryno < 0) + entryno = 0; + } +- print_entries (3, 12, first_entry, entryno, menu_entries); ++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); + } + else if (c == 3) + { + /* Page Down */ +- first_entry += 12; ++ first_entry += box_size; + if (first_entry + entryno + 1 >= num_entries) + { +- first_entry = num_entries - 12; ++ first_entry = num_entries - box_size; + if (first_entry < 0) + first_entry = 0; + entryno = num_entries - first_entry - 1; + } +- print_entries (3, 12, first_entry, entryno, menu_entries); ++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); + } + + if (config_entries) +@@ -489,7 +512,7 @@ + if ((c == 'd') || (c == 'o') || (c == 'O')) + { + if (! (current_term->flags & TERM_DUMB)) +- print_entry (4 + entryno, 0, ++ print_entry (4 + entryno + row_start, 0, + get_entry (menu_entries, + first_entry + entryno, + 0)); +@@ -537,7 +560,7 @@ + + if (entryno >= num_entries) + entryno--; +- if (first_entry && num_entries < 12 + first_entry) ++ if (first_entry && num_entries < box_size + first_entry) + first_entry--; + } + +@@ -549,7 +572,7 @@ + grub_printf ("\n"); + } + else +- print_entries (3, 12, first_entry, entryno, menu_entries); ++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries); + } + + cur_entry = menu_entries; +@@ -570,7 +593,7 @@ + if (current_term->flags & TERM_DUMB) + grub_printf ("\r "); + else +- gotoxy (1, 21); ++ gotoxy (1 + col_start, 9 + box_size + row_start); + + /* Wipe out the previously entered password */ + grub_memset (entered, 0, sizeof (entered)); +@@ -714,6 +737,15 @@ + + cls (); + setcursor (1); ++ /* if our terminal needed initialization, we should shut it down ++ * before booting the kernel, but we want to save what it was so ++ * we can come back if needed */ ++ prev_term = current_term; ++ if (current_term->shutdown) ++ { ++ current_term->shutdown(); ++ current_term = term_table; /* assumption: console is first */ ++ } + + while (1) + { +@@ -748,6 +780,13 @@ + break; + } + ++ /* if we get back here, we should go back to what our term was before */ ++ current_term = prev_term; ++ if (current_term->startup) ++ /* if our terminal fails to initialize, fall back to console since ++ * it should always work */ ++ if (current_term->startup() == 0) ++ current_term = term_table; /* we know that console is first */ + show_menu = 1; + goto restart; + } +@@ -1050,6 +1089,16 @@ + while (is_preset); + } + ++ /* go ahead and make sure the terminal is setup */ ++ if (current_term->startup) ++ { ++ /* If initialization fails, go back to default terminal */ ++ if (current_term->startup() == 0) ++ { ++ current_term = term_table; ++ } ++ } ++ + if (! num_entries) + { + /* If no acceptable config file, goto command-line, starting +diff -Naur grub-0.97.orig/stage2/term.h grub-0.97/stage2/term.h +--- grub-0.97.orig/stage2/term.h 2003-07-09 08:45:53.000000000 -0300 ++++ grub-0.97/stage2/term.h 2005-06-13 14:07:40.000000000 -0300 +@@ -60,6 +60,8 @@ + const char *name; + /* The feature flags defined above. */ + unsigned long flags; ++ /* Default for maximum number of lines if not specified */ ++ unsigned short max_lines; + /* Put a character. */ + void (*putchar) (int c); + /* Check if any input character is available. */ +@@ -79,6 +81,10 @@ + void (*setcolor) (int normal_color, int highlight_color); + /* Turn on/off the cursor. */ + int (*setcursor) (int on); ++ /* function to start a terminal */ ++ int (*startup) (void); ++ /* function to use to shutdown a terminal */ ++ void (*shutdown) (void); + }; + + /* This lists up available terminals. */ +@@ -124,4 +130,24 @@ + int hercules_setcursor (int on); + #endif + ++#ifdef SUPPORT_GRAPHICS ++extern int foreground, background, window_border, graphics_inited, saved_videomode; ++ ++void graphics_set_splash(char *splashfile); ++int set_videomode(int mode); ++int get_videomode(void); ++void graphics_putchar (int c); ++int graphics_getxy(void); ++void graphics_gotoxy(int x, int y); ++void graphics_cls(void); ++void graphics_setcolorstate (color_state state); ++void graphics_setcolor (int normal_color, int highlight_color); ++int graphics_setcursor (int on); ++int graphics_init(void); ++void graphics_end(void); ++ ++int hex(int v); ++void graphics_set_palette(int idx, int red, int green, int blue); ++#endif /* SUPPORT_GRAPHICS */ ++ + #endif /* ! GRUB_TERM_HEADER */ diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub.patches/20print_func.diff --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/grub.patches/20print_func.diff Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,80 @@ +2006-01-05 Otavio Salvador <otavio@xxxxxxxxxx> + + * Rediff. + +2005-16-10 Samuel Thibault <samuel.thibault@xxxxxxxxxxxx> + + * docs/grub.texi: Added print command description. + * stage2/builtins.c(print_func): New function. + (builtin_print): New variable. + (builtin_table): Added builtin_print in table. + +Debian Status Following: + Added by: Otavio Salvador + Date: 2006-01-05 + +diff -Nur grub-0.97-bkp/docs/grub.texi grub-0.97/docs/grub.texi +--- grub-0.97-bkp/docs/grub.texi 2006-01-05 10:59:05.564347912 -0200 ++++ grub-0.97/docs/grub.texi 2006-01-05 11:18:59.033912960 -0200 +@@ -2685,6 +2685,7 @@ + * module:: Load a module + * modulenounzip:: Load a module without decompression + * pause:: Wait for a key press ++* print:: Print a message + * quit:: Exit from the grub shell + * reboot:: Reboot your computer + * read:: Read data from memory +@@ -3091,6 +3092,16 @@ + @end deffn + + ++@node print ++@subsection print ++ ++@deffn Command print message @dots{} ++Print the @var{message}. Note that placing @key{^G} (ASCII code 7) in the ++message will cause the speaker to emit the standard beep sound, which is ++useful for visually impaired people. ++@end deffn ++ ++ + @node quit + @subsection quit + +diff -Nur grub-0.97-bkp/stage2/builtins.c grub-0.97/stage2/builtins.c +--- grub-0.97-bkp/stage2/builtins.c 2006-01-05 10:59:05.550350040 -0200 ++++ grub-0.97/stage2/builtins.c 2006-01-05 11:19:28.422445224 -0200 +@@ -2323,6 +2323,25 @@ + "Probe I/O ports used for the drive DRIVE." + }; + ++/* print */ ++static int ++print_func (char *arg, int flags) ++{ ++ printf("%s\n", arg); ++ ++ return 0; ++} ++ ++static struct builtin builtin_print = ++{ ++ "print", ++ print_func, ++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_NO_ECHO, ++ "print [MESSAGE ...]", ++ "Print MESSAGE." ++}; ++ ++ + + /* kernel */ + static int +@@ -4848,6 +4867,7 @@ + &builtin_parttype, + &builtin_password, + &builtin_pause, ++ &builtin_print, + #ifdef GRUB_UTIL + &builtin_quit, + #endif /* GRUB_UTIL */ diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub.patches/30savedefault.diff --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/grub.patches/30savedefault.diff Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,186 @@ +Index: grub/stage2/builtins.c +=================================================================== +--- grub.orig/stage2/builtins.c 2008-06-02 18:06:08.942580000 +0100 ++++ grub/stage2/builtins.c 2008-06-06 18:35:07.548390000 +0100 +@@ -86,6 +86,10 @@ + inside other functions. */ + static int configfile_func (char *arg, int flags); + ++static int savedefault_helper (char *arg, int flags); ++ ++static int savedefault_shell (char *arg, int flags); ++ + /* Initialize the data for builtins. */ + void + init_builtins (void) +@@ -3512,7 +3516,109 @@ + static int + savedefault_func (char *arg, int flags) + { +-#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL) ++#if !defined(SUPPORT_DISKLESS) ++ #if !defined(GRUB_UTIL) ++ return savedefault_helper(arg, flags); ++ #else ++ return savedefault_shell(arg, flags); ++ #endif ++#else /* !SUPPORT_DISKLESS */ ++ errnum = ERR_UNRECOGNIZED; ++ return 1; ++#endif /* !SUPPORT_DISKLESS */ ++} ++ ++#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL) ++/* savedefault_shell */ ++static int ++savedefault_shell(char *arg, int flags) ++ { ++ int once_only = 0; ++ int new_default; ++ int curr_default = -1; ++ int curr_prev_default = -1; ++ int new_prev_default = -1; ++ FILE *fp; ++ size_t bytes = 10; ++ char line[bytes]; ++ char *default_file = (char *) DEFAULT_FILE_BUF; ++ char buf[bytes]; ++ int i; ++ ++ while (1) ++ { ++ if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0) ++ { ++ char *p = arg + sizeof ("--default=") - 1; ++ if (! safe_parse_maxint (&p, &new_default)) ++ return 1; ++ arg = skip_to (0, arg); ++ } ++ else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0) ++ { ++ once_only = 1; ++ arg = skip_to (0, arg); ++ } ++ else ++ break; ++ } ++ ++ *default_file = 0; ++ grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN); ++ for (i = grub_strlen(default_file); i >= 0; i--) ++ if (default_file[i] == '/') ++ { ++ i++; ++ break; ++ } ++ default_file[i] = 0; ++ grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i); ++ ++ if(!(fp = fopen(default_file,"r"))) ++ { ++ errnum = ERR_READ; ++ goto fail; ++ } ++ ++ fgets(line, bytes, fp); ++ fclose(fp); ++ ++ sscanf(line, "%d:%d", &curr_prev_default, &curr_default); ++ ++ if(curr_default != -1) ++ new_prev_default = curr_default; ++ else ++ { ++ if(curr_prev_default != -1) ++ new_prev_default = curr_prev_default; ++ else ++ new_prev_default = 0; ++ } ++ ++ if(once_only) ++ sprintf(buf, "%d:%d", new_prev_default, new_default); ++ else ++ sprintf(buf, "%d", new_default); ++ ++ if(!(fp = fopen(default_file,"w"))) ++ { ++ errnum = ERR_READ; ++ goto fail; ++ } ++ ++ fprintf(fp, buf); ++ ++fail: ++ fclose(fp); ++ return errnum; ++} ++#endif ++ ++/* savedefault_helper */ ++static int ++savedefault_helper (char *arg, int flags) ++{ ++#if !defined(SUPPORT_DISKLESS) + unsigned long tmp_drive = saved_drive; + unsigned long tmp_partition = saved_partition; + char *default_file = (char *) DEFAULT_FILE_BUF; +@@ -3588,22 +3694,26 @@ + + disk_read_hook = disk_read_savesect_func; + len = grub_read (buf, sizeof (buf)); ++ buf[9]='\0';/* Make sure grub_strstr() below terminates */ + disk_read_hook = 0; + grub_close (); + +- if (len != sizeof (buf)) +- { +- /* This is too small. Do not modify the file manually, please! */ +- errnum = ERR_READ; +- goto fail; +- } +- + if (sector_count > 2) + { + /* Is this possible?! Too fragmented! */ + errnum = ERR_FSYS_CORRUPT; + goto fail; + } ++ ++ char *tmp; ++ if((tmp = grub_strstr(buf, ":")) != NULL) ++ { ++ int f_len = grub_strlen(buf) - grub_strlen(tmp); ++ char *def; ++ buf[f_len] = '\0'; ++ def = buf; ++ safe_parse_maxint (&def, &entryno); ++ } + + /* Set up a string to be written. */ + grub_memset (buf, '\n', sizeof (buf)); +Index: grub/stage2/stage2.c +=================================================================== +--- grub.orig/stage2/stage2.c 2008-06-02 18:06:08.858579000 +0100 ++++ grub/stage2/stage2.c 2008-06-06 18:04:03.585354000 +0100 +@@ -49,7 +49,8 @@ + return 0; + #endif /* GRUB_UTIL */ + +- preset_menu_offset = 0; ++ if (preset_menu_offset) ++ return 0; + return preset_menu != 0; + } + +@@ -934,7 +935,11 @@ + len = grub_read (buf, sizeof (buf)); + if (len > 0) + { ++ char *tmp; + buf[sizeof (buf) - 1] = 0; ++ if((tmp = grub_strstr(p, ":")) != NULL) ++ p = tmp + 1; ++ + safe_parse_maxint (&p, &saved_entryno); + } + diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub.patches/40ext3_256byte_inode.diff --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/grub.patches/40ext3_256byte_inode.diff Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,114 @@ + +Patch from Red Hat. See #463236, #463123. + +Index: grub/stage2/fsys_ext2fs.c +=================================================================== +--- grub.orig/stage2/fsys_ext2fs.c 2008-05-27 18:47:19.045183000 +0100 ++++ grub/stage2/fsys_ext2fs.c 2008-05-27 19:09:21.293187000 +0100 +@@ -79,7 +79,52 @@ + __u32 s_rev_level; /* Revision level */ + __u16 s_def_resuid; /* Default uid for reserved blocks */ + __u16 s_def_resgid; /* Default gid for reserved blocks */ +- __u32 s_reserved[235]; /* Padding to the end of the block */ ++ /* ++ * These fields are for EXT2_DYNAMIC_REV superblocks only. ++ * ++ * Note: the difference between the compatible feature set and ++ * the incompatible feature set is that if there is a bit set ++ * in the incompatible feature set that the kernel doesn't ++ * know about, it should refuse to mount the filesystem. ++ * ++ * e2fsck's requirements are more strict; if it doesn't know ++ * about a feature in either the compatible or incompatible ++ * feature set, it must abort and not try to meddle with ++ * things it doesn't understand... ++ */ ++ __u32 s_first_ino; /* First non-reserved inode */ ++ __u16 s_inode_size; /* size of inode structure */ ++ __u16 s_block_group_nr; /* block group # of this superblock */ ++ __u32 s_feature_compat; /* compatible feature set */ ++ __u32 s_feature_incompat; /* incompatible feature set */ ++ __u32 s_feature_ro_compat; /* readonly-compatible feature set */ ++ __u8 s_uuid[16]; /* 128-bit uuid for volume */ ++ char s_volume_name[16]; /* volume name */ ++ char s_last_mounted[64]; /* directory where last mounted */ ++ __u32 s_algorithm_usage_bitmap; /* For compression */ ++ /* ++ * Performance hints. Directory preallocation should only ++ * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on. ++ */ ++ __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ ++ __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ ++ __u16 s_reserved_gdt_blocks;/* Per group table for online growth */ ++ /* ++ * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set. ++ */ ++ __u8 s_journal_uuid[16]; /* uuid of journal superblock */ ++ __u32 s_journal_inum; /* inode number of journal file */ ++ __u32 s_journal_dev; /* device number of journal file */ ++ __u32 s_last_orphan; /* start of list of inodes to delete */ ++ __u32 s_hash_seed[4]; /* HTREE hash seed */ ++ __u8 s_def_hash_version; /* Default hash version to use */ ++ __u8 s_jnl_backup_type; /* Default type of journal backup */ ++ __u16 s_reserved_word_pad; ++ __u32 s_default_mount_opts; ++ __u32 s_first_meta_bg; /* First metablock group */ ++ __u32 s_mkfs_time; /* When the filesystem was created */ ++ __u32 s_jnl_blocks[17]; /* Backup of the journal inode */ ++ __u32 s_reserved[172]; /* Padding to the end of the block */ + }; + + struct ext2_group_desc +@@ -218,6 +263,9 @@ + #define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) + #define EXT2_ADDR_PER_BLOCK_BITS(s) (log2(EXT2_ADDR_PER_BLOCK(s))) + ++#define EXT2_INODE_SIZE(s) (SUPERBLOCK->s_inode_size) ++#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s)) ++ + /* linux/ext2_fs.h */ + #define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) + /* kind of from ext2/super.c */ +@@ -242,7 +290,14 @@ + static __inline__ unsigned long + ffz (unsigned long word) + { +- __asm__ ("bsfl %1,%0" ++ __asm__ ("bsf" ++#ifdef __i386__ ++ "l" ++#endif ++#ifdef __x86_64__ ++ "q" ++#endif ++ " %1,%0" + : "=r" (word) + : "r" (~word)); + return word; +@@ -553,7 +608,7 @@ + gdp = GROUP_DESC; + ino_blk = gdp[desc].bg_inode_table + + (((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group)) +- >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode))); ++ >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK))); + #ifdef E2DEBUG + printf ("inode table fsblock=%d\n", ino_blk); + #endif /* E2DEBUG */ +@@ -565,13 +620,12 @@ + /* reset indirect blocks! */ + mapblock2 = mapblock1 = -1; + +- raw_inode = INODE + +- ((current_ino - 1) +- & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1)); ++ raw_inode = (struct ext2_inode *)((char *)INODE + ++ ((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1)) * ++ EXT2_INODE_SIZE (SUPERBLOCK)); + #ifdef E2DEBUG + printf ("ipb=%d, sizeof(inode)=%d\n", +- (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)), +- sizeof (struct ext2_inode)); ++ EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK)); + printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode); + printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE); + for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode; diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub.patches/99minios --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/grub.patches/99minios Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,1456 @@ +Index: grub/stage2/builtins.c +=================================================================== +--- grub.orig/stage2/builtins.c 2008-06-16 15:18:14.649009000 +0100 ++++ grub/stage2/builtins.c 2008-06-16 15:18:14.719009000 +0100 +@@ -45,8 +45,10 @@ + #ifdef GRUB_UTIL + # include <device.h> + #else /* ! GRUB_UTIL */ ++#ifndef __MINIOS + # include <apic.h> + # include <smp-imps.h> ++#endif + #endif /* ! GRUB_UTIL */ + + #ifdef USE_MD5_PASSWORDS +@@ -246,11 +248,13 @@ + boot_func (char *arg, int flags) + { + struct term_entry *prev_term = current_term; ++#ifndef __MINIOS__ + /* Clear the int15 handler if we can boot the kernel successfully. + This assumes that the boot code never fails only if KERNEL_TYPE is + not KERNEL_TYPE_NONE. Is this assumption is bad? */ + if (kernel_type != KERNEL_TYPE_NONE) + unset_int15_handler (); ++#endif + + /* if our terminal needed initialization, we should shut it down + * before booting the kernel, but we want to save what it was so +@@ -261,13 +265,21 @@ + current_term = term_table; /* assumption: console is first */ + } + ++#ifndef __MINIOS__ + #ifdef SUPPORT_NETBOOT + /* Shut down the networking. */ + cleanup_net (); + #endif ++#endif + + switch (kernel_type) + { ++#ifdef __MINIOS__ ++ case KERNEL_TYPE_PV: ++ /* Paravirtualized */ ++ pv_boot(); ++ break; ++#else + case KERNEL_TYPE_FREEBSD: + case KERNEL_TYPE_NETBSD: + /* *BSD */ +@@ -319,6 +331,7 @@ + multi_boot ((int) entry_addr, (int) &mbi); + break; + ++#endif + default: + errnum = ERR_BOOT_COMMAND; + return 1; +@@ -1123,6 +1136,7 @@ + }; + + ++#ifndef __MINIOS__ + /* displayapm */ + static int + displayapm_func (char *arg, int flags) +@@ -1163,8 +1177,10 @@ + "displayapm", + "Display APM BIOS information." + }; ++#endif + + ++#ifndef __MINIOS__ + /* displaymem */ + static int + displaymem_func (char *arg, int flags) +@@ -1218,6 +1234,7 @@ + "Display what GRUB thinks the system address space map of the" + " machine is, including all regions of physical RAM installed." + }; ++#endif + + + /* dump FROM TO */ +@@ -1280,6 +1297,7 @@ + #endif /* GRUB_UTIL */ + + ++#ifndef __MINIOS__ + static char embed_info[32]; + /* embed */ + /* Embed a Stage 1.5 in the first cylinder after MBR or in the +@@ -1413,6 +1431,7 @@ + " is a drive, or in the \"bootloader\" area if DEVICE is a FFS partition." + " Print the number of sectors which STAGE1_5 occupies if successful." + }; ++#endif + + + /* fallback */ +@@ -1956,6 +1975,7 @@ + #endif /* SUPPORT_NETBOOT */ + + ++#ifndef __MINIOS__ + /* impsprobe */ + static int + impsprobe_func (char *arg, int flags) +@@ -1982,6 +2002,7 @@ + " configuration table and boot the various CPUs which are found into" + " a tight loop." + }; ++#endif + + + /* initrd */ +@@ -1992,6 +2013,7 @@ + { + case KERNEL_TYPE_LINUX: + case KERNEL_TYPE_BIG_LINUX: ++ case KERNEL_TYPE_PV: + if (! load_initrd (arg)) + return 1; + break; +@@ -2015,6 +2037,7 @@ + }; + + ++#ifndef __MINIOS__ + /* install */ + static int + install_func (char *arg, int flags) +@@ -2555,8 +2578,10 @@ + " for LBA mode. If the option `--stage2' is specified, rewrite the Stage" + " 2 via your OS's filesystem instead of the raw device." + }; ++#endif + + ++#ifndef __MINIOS__ + /* ioprobe */ + static int + ioprobe_func (char *arg, int flags) +@@ -2598,6 +2623,7 @@ + "ioprobe DRIVE", + "Probe I/O ports used for the drive DRIVE." + }; ++#endif + + /* print */ + static int +@@ -3776,6 +3802,7 @@ + }; + + ++#ifndef __MINIOS__ + #ifdef SUPPORT_SERIAL + /* serial */ + static int +@@ -3927,8 +3954,10 @@ + " default values are COM1, 9600, 8N1." + }; + #endif /* SUPPORT_SERIAL */ ++#endif + + ++#ifndef __MINIOS__ + /* setkey */ + struct keysym + { +@@ -4174,8 +4203,10 @@ + " is a digit), and delete. If no argument is specified, reset key" + " mappings." + }; ++#endif + + ++#ifndef __MINIOS__ + /* setup */ + static int + setup_func (char *arg, int flags) +@@ -4484,6 +4515,7 @@ + " partition where GRUB images reside, specify the option `--stage2'" + " to tell GRUB the file name under your OS." + }; ++#endif + + + #if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS) +@@ -4788,6 +4820,7 @@ + #endif /* SUPPORT_SERIAL */ + + ++#ifndef __MINIOS__ + /* testload */ + static int + testload_func (char *arg, int flags) +@@ -4874,8 +4907,10 @@ + " consistent offset error. If this test succeeds, then a good next" + " step is to try loading a kernel." + }; ++#endif + + ++#ifndef __MINIOS__ + /* testvbe MODE */ + static int + testvbe_func (char *arg, int flags) +@@ -4979,6 +5014,7 @@ + "testvbe MODE", + "Test the VBE mode MODE. Hit any key to return." + }; ++#endif + + + #ifdef SUPPORT_NETBOOT +@@ -5075,6 +5111,7 @@ + }; + + ++#ifndef __MINIOS__ + /* uppermem */ + static int + uppermem_func (char *arg, int flags) +@@ -5095,8 +5132,10 @@ + "Force GRUB to assume that only KBYTES kilobytes of upper memory are" + " installed. Any system address range maps are discarded." + }; ++#endif + + ++#ifndef __MINIOS__ + /* vbeprobe */ + static int + vbeprobe_func (char *arg, int flags) +@@ -5203,6 +5242,7 @@ + "Probe VBE information. If the mode number MODE is specified, show only" + " the information about only the mode." + }; ++#endif + + + /* The table of builtin commands. Sorted in dictionary order. */ +@@ -5233,12 +5273,16 @@ + #ifdef SUPPORT_NETBOOT + &builtin_dhcp, + #endif /* SUPPORT_NETBOOT */ ++#ifndef __MINIOS__ + &builtin_displayapm, + &builtin_displaymem, ++#endif + #ifdef GRUB_UTIL + &builtin_dump, + #endif /* GRUB_UTIL */ ++#ifndef __MINIOS__ + &builtin_embed, ++#endif + &builtin_fallback, + &builtin_find, + #ifdef SUPPORT_GRAPHICS +@@ -5253,10 +5297,14 @@ + #ifdef SUPPORT_NETBOOT + &builtin_ifconfig, + #endif /* SUPPORT_NETBOOT */ ++#ifndef __MINIOS__ + &builtin_impsprobe, ++#endif + &builtin_initrd, ++#ifndef __MINIOS__ + &builtin_install, + &builtin_ioprobe, ++#endif + &builtin_kernel, + &builtin_lock, + &builtin_makeactive, +@@ -5283,11 +5331,13 @@ + &builtin_root, + &builtin_rootnoverify, + &builtin_savedefault, ++#ifndef __MINIOS__ + #ifdef SUPPORT_SERIAL + &builtin_serial, + #endif /* SUPPORT_SERIAL */ + &builtin_setkey, + &builtin_setup, ++#endif + #ifdef SUPPORT_GRAPHICS + &builtin_shade, + &builtin_splashimage, +@@ -5298,16 +5348,20 @@ + #ifdef SUPPORT_SERIAL + &builtin_terminfo, + #endif /* SUPPORT_SERIAL */ ++#ifndef __MINIOS__ + &builtin_testload, + &builtin_testvbe, ++#endif + #ifdef SUPPORT_NETBOOT + &builtin_tftpserver, + #endif /* SUPPORT_NETBOOT */ + &builtin_timeout, + &builtin_title, + &builtin_unhide, ++#ifndef __MINIOS__ + &builtin_uppermem, + &builtin_vbeprobe, ++#endif + #ifdef SUPPORT_GRAPHICS + &builtin_viewport, + #endif +Index: grub/stage2/char_io.c +=================================================================== +--- grub.orig/stage2/char_io.c 2008-06-16 15:18:14.516009000 +0100 ++++ grub/stage2/char_io.c 2008-06-16 15:18:14.726009000 +0100 +@@ -20,6 +20,7 @@ + + #include <shared.h> + #include <term.h> ++#include <stdarg.h> + + #ifdef SUPPORT_HERCULES + # include <hercules.h> +@@ -36,6 +37,7 @@ + #ifndef STAGE1_5 + struct term_entry term_table[] = + { ++#ifdef SUPPORT_CONSOLE + { + "console", + 0, +@@ -52,6 +54,7 @@ + 0, + 0 + }, ++#endif + #ifdef SUPPORT_SERIAL + { + "serial", +@@ -131,9 +134,9 @@ + } + + char * +-convert_to_ascii (char *buf, int c,...) ++convert_to_ascii (char *buf, int c, int _num) + { +- unsigned long num = *((&c) + 1), mult = 10; ++ unsigned long num = _num, mult = 10; + char *ptr = buf; + + #ifndef STAGE1_5 +@@ -182,11 +185,11 @@ + void + grub_printf (const char *format,...) + { +- int *dataptr = (int *) &format; ++ va_list ap; + char c, str[16]; +- +- dataptr++; + ++ va_start(ap, format); ++ + while ((c = *(format++)) != 0) + { + if (c != '%') +@@ -200,21 +203,32 @@ + case 'X': + #endif + case 'u': +- *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0; ++ { ++ unsigned i = va_arg(ap, unsigned); ++ *convert_to_ascii (str, c, i) = 0; + grub_putstr (str); + break; ++ } + + #ifndef STAGE1_5 + case 'c': +- grub_putchar ((*(dataptr++)) & 0xff); ++ { ++ int c = va_arg(ap, int); ++ grub_putchar (c & 0xff); + break; ++ } + + case 's': +- grub_putstr ((char *) *(dataptr++)); ++ { ++ char *s = va_arg(ap, char*); ++ grub_putstr (s); + break; ++ } + #endif + } + } ++ ++ va_end(ap); + } + + #ifndef STAGE1_5 +@@ -223,11 +237,11 @@ + { + /* XXX hohmuth + ugly hack -- should unify with printf() */ +- int *dataptr = (int *) &format; ++ va_list ap; + char c, *ptr, str[16]; + char *bp = buffer; + +- dataptr++; ++ va_start(ap, format); + + while ((c = *format++) != 0) + { +@@ -237,20 +251,27 @@ + switch (c = *(format++)) + { + case 'd': case 'u': case 'x': +- *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0; ++ { ++ unsigned i = va_arg(ap, unsigned); ++ *convert_to_ascii (str, c, i) = 0; + + ptr = str; + + while (*ptr) + *bp++ = *(ptr++); /* putchar(*(ptr++)); */ + break; ++ } + +- case 'c': *bp++ = (*(dataptr++))&0xff; ++ case 'c': ++ { ++ int c = va_arg(ap, int); ++ *bp++ = c&0xff; + /* putchar((*(dataptr++))&0xff); */ + break; ++ } + + case 's': +- ptr = (char *) (*(dataptr++)); ++ ptr = va_arg(ap, char *); + + while ((c = *ptr++) != 0) + *bp++ = c; /* putchar(c); */ +@@ -258,6 +279,8 @@ + } + } + ++ va_end(ap); ++ + *bp = 0; + return bp - buffer; + } +@@ -1263,12 +1286,14 @@ + return ! errnum; + #endif /* GRUB_UTIL */ + ++#ifndef __MINIOS__ + if ((addr < RAW_ADDR (0x1000)) + || (addr < RAW_ADDR (0x100000) + && RAW_ADDR (mbi.mem_lower * 1024) < (addr + len)) + || (addr >= RAW_ADDR (0x100000) + && RAW_ADDR (mbi.mem_upper * 1024) < ((addr - 0x100000) + len))) + errnum = ERR_WONT_FIT; ++#endif + + return ! errnum; + } +@@ -1342,7 +1367,7 @@ + } + #endif /* ! STAGE1_5 */ + +-#ifndef GRUB_UTIL ++#if !defined(GRUB_UTIL) && !defined(__MINIOS__) + # undef memcpy + /* GCC emits references to memcpy() for struct copies etc. */ + void *memcpy (void *dest, const void *src, int n) __attribute__ ((alias ("grub_memmove"))); +Index: grub/stage2/disk_io.c +=================================================================== +--- grub.orig/stage2/disk_io.c 2008-06-16 15:18:03.327932000 +0100 ++++ grub/stage2/disk_io.c 2008-06-16 15:18:14.733009000 +0100 +@@ -130,7 +130,14 @@ + static inline unsigned long + log2 (unsigned long word) + { +- asm volatile ("bsfl %1,%0" ++ asm volatile ("bsf" ++#ifdef __i386__ ++ "l" ++#endif ++#ifdef __x86_64__ ++ "q" ++#endif ++ " %1,%0" + : "=r" (word) + : "r" (word)); + return word; +Index: grub/stage2/fsys_fat.c +=================================================================== +--- grub.orig/stage2/fsys_fat.c 2008-06-16 15:18:03.337934000 +0100 ++++ grub/stage2/fsys_fat.c 2008-06-16 15:18:14.737009000 +0100 +@@ -57,7 +57,14 @@ + static __inline__ unsigned long + log2 (unsigned long word) + { +- __asm__ ("bsfl %1,%0" ++ __asm__ ("bsf" ++#ifdef __i386__ ++ "l" ++#endif ++#ifdef __x86_64__ ++ "q" ++#endif ++ " %1,%0" + : "=r" (word) + : "r" (word)); + return word; +Index: grub/stage2/pc_slice.h +=================================================================== +--- grub.orig/stage2/pc_slice.h 2008-06-16 15:18:03.347932000 +0100 ++++ grub/stage2/pc_slice.h 2008-06-16 15:18:14.746009000 +0100 +@@ -38,50 +38,50 @@ + */ + + #define PC_MBR_CHECK_SIG(mbr_ptr) \ +- ( *( (unsigned short *) (((int) mbr_ptr) + PC_MBR_SIG_OFFSET) ) \ ++ ( *( (unsigned short *) (((long) mbr_ptr) + PC_MBR_SIG_OFFSET) ) \ + == PC_MBR_SIGNATURE ) + + #define PC_MBR_SIG(mbr_ptr) \ +- ( *( (unsigned short *) (((int) mbr_ptr) + PC_MBR_SIG_OFFSET) ) ) ++ ( *( (unsigned short *) (((long) mbr_ptr) + PC_MBR_SIG_OFFSET) ) ) + + #define PC_SLICE_FLAG(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET \ + + (part << 4)) ) ) + + #define PC_SLICE_HEAD(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 1 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 1 \ + + (part << 4)) ) ) + + #define PC_SLICE_SEC(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 2 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 2 \ + + (part << 4)) ) ) + + #define PC_SLICE_CYL(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 3 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 3 \ + + (part << 4)) ) ) + + #define PC_SLICE_TYPE(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 4 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 4 \ + + (part << 4)) ) ) + + #define PC_SLICE_EHEAD(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 5 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 5 \ + + (part << 4)) ) ) + + #define PC_SLICE_ESEC(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 6 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 6 \ + + (part << 4)) ) ) + + #define PC_SLICE_ECYL(mbr_ptr, part) \ +- ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 7 \ ++ ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 7 \ + + (part << 4)) ) ) + + #define PC_SLICE_START(mbr_ptr, part) \ +- ( *( (unsigned long *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 8 \ ++ ( *( (unsigned long *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 8 \ + + (part << 4)) ) ) + + #define PC_SLICE_LENGTH(mbr_ptr, part) \ +- ( *( (unsigned long *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 12 \ ++ ( *( (unsigned long *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 12 \ + + (part << 4)) ) ) + + +Index: grub/stage2/shared.h +=================================================================== +--- grub.orig/stage2/shared.h 2008-06-16 15:18:14.537009000 +0100 ++++ grub/stage2/shared.h 2008-06-17 14:25:08.443906000 +0100 +@@ -39,6 +39,10 @@ + extern char *grub_scratch_mem; + # define RAW_ADDR(x) ((x) + (int) grub_scratch_mem) + # define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4) ++#elif defined(__MINIOS__) ++extern char grub_scratch_mem[]; ++# define RAW_ADDR(x) ((x) + (int) grub_scratch_mem) ++# define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4) + #else + # define RAW_ADDR(x) (x) + # define RAW_SEG(x) (x) +@@ -707,7 +711,9 @@ + + /* Halt the system, using APM if possible. If NO_APM is true, don't use + APM even if it is available. */ ++#ifndef __MINIOS__ + void grub_halt (int no_apm) __attribute__ ((noreturn)); ++#endif + + /* Copy MAP to the drive map and set up int13_handler. */ + void set_int13_handler (unsigned short *map); +@@ -857,7 +863,8 @@ + KERNEL_TYPE_BIG_LINUX, /* Big Linux. */ + KERNEL_TYPE_FREEBSD, /* FreeBSD. */ + KERNEL_TYPE_NETBSD, /* NetBSD. */ +- KERNEL_TYPE_CHAINLOADER /* Chainloader. */ ++ KERNEL_TYPE_CHAINLOADER, /* Chainloader. */ ++ KERNEL_TYPE_PV /* Paravirtualized. */ + } + kernel_t; + +@@ -890,7 +897,7 @@ + int grub_strlen (const char *str); + char *grub_strcpy (char *dest, const char *src); + +-#ifndef GRUB_UTIL ++#if !defined(GRUB_UTIL) && !defined(__MINIOS__) + typedef unsigned long grub_jmp_buf[6]; + #else + /* In the grub shell, use the libc jmp_buf instead. */ +@@ -898,7 +905,7 @@ + # define grub_jmp_buf jmp_buf + #endif + +-#ifdef GRUB_UTIL ++#if defined(GRUB_UTIL) || defined(__MINIOS__) + # define grub_setjmp setjmp + # define grub_longjmp longjmp + #else /* ! GRUB_UTIL */ +@@ -914,7 +921,7 @@ + /* misc */ + void init_page (void); + void print_error (void); +-char *convert_to_ascii (char *buf, int c, ...); ++char *convert_to_ascii (char *buf, int c, int num); + int get_cmdline (char *prompt, char *cmdline, int maxlen, + int echo_char, int history); + int substring (const char *s1, const char *s2); +Index: grub/netboot/etherboot.h +=================================================================== +--- grub.orig/netboot/etherboot.h 2008-06-16 15:18:03.446934000 +0100 ++++ grub/netboot/etherboot.h 2008-06-16 15:18:14.760009000 +0100 +@@ -246,7 +246,7 @@ + + typedef struct + { +- unsigned long s_addr; ++ unsigned int s_addr; + } + in_addr; + +@@ -302,7 +302,7 @@ + char bp_htype; + char bp_hlen; + char bp_hops; +- unsigned long bp_xid; ++ unsigned int bp_xid; + unsigned short bp_secs; + unsigned short unused; + in_addr bp_ciaddr; +@@ -411,25 +411,25 @@ + + struct + { +- long id; +- long type; +- long rpcvers; +- long prog; +- long vers; +- long proc; +- long data[1]; ++ int id; ++ int type; ++ int rpcvers; ++ int prog; ++ int vers; ++ int proc; ++ int data[1]; + } + call; + + struct + { +- long id; +- long type; +- long rstatus; +- long verifier; +- long v2; +- long astatus; +- long data[1]; ++ int id; ++ int type; ++ int rstatus; ++ int verifier; ++ int v2; ++ int astatus; ++ int data[1]; + } + reply; + } +@@ -517,7 +517,9 @@ + + /* misc.c */ + extern void twiddle (void); ++#ifndef __MINIOS__ + extern void sleep (int secs); ++#endif + extern int getdec (char **s); + extern void etherboot_printf (const char *, ...); + extern int etherboot_sprintf (char *, const char *, ...); +Index: grub/stage2/common.c +=================================================================== +--- grub.orig/stage2/common.c 2008-06-16 15:18:03.366934000 +0100 ++++ grub/stage2/common.c 2008-06-16 15:18:14.764009000 +0100 +@@ -137,6 +137,7 @@ + } + #endif /* ! STAGE1_5 */ + ++#ifndef __MINIOS__ + /* This queries for BIOS information. */ + void + init_bios_info (void) +@@ -335,3 +336,4 @@ + /* Start main routine here. */ + cmain (); + } ++#endif +Index: grub/stage2/serial.c +=================================================================== +--- grub.orig/stage2/serial.c 2008-06-16 15:18:03.376934000 +0100 ++++ grub/stage2/serial.c 2008-06-16 15:18:14.769009000 +0100 +@@ -37,7 +37,7 @@ + + /* Hardware-dependent definitions. */ + +-#ifndef GRUB_UTIL ++#if !defined(GRUB_UTIL) && !defined(__MINIOS__) + /* The structure for speed vs. divisor. */ + struct divisor + { +@@ -222,6 +222,8 @@ + {('3' | ('~' << 8)), 4}, + {('5' | ('~' << 8)), 7}, + {('6' | ('~' << 8)), 3}, ++ {('7' | ('~' << 8)), 1}, ++ {('8' | ('~' << 8)), 5}, + }; + + /* The buffer must start with ``ESC [''. */ +Index: grub/stage2/tparm.c +=================================================================== +--- grub.orig/stage2/tparm.c 2008-06-16 15:18:03.390933000 +0100 ++++ grub/stage2/tparm.c 2008-06-16 15:18:14.774010000 +0100 +@@ -48,6 +48,7 @@ + #include "shared.h" + + #include "tparm.h" ++#include <stdarg.h> + + /* + * Common/troublesome character definitions +@@ -320,7 +321,7 @@ + #define isLOWER(c) ((c) >= 'a' && (c) <= 'z') + + static inline char * +-tparam_internal(const char *string, int *dataptr) ++tparam_internal(const char *string, va_list ap) + { + #define NUM_VARS 26 + char *p_is_s[9]; +@@ -461,9 +462,9 @@ + * a char* and an int may not be the same size on the stack. + */ + if (p_is_s[i] != 0) { +- p_is_s[i] = (char *)(*(dataptr++)); ++ p_is_s[i] = va_arg(ap, char *); + } else { +- param[i] = (int)(*(dataptr++)); ++ param[i] = va_arg(ap, int); + } + } + +@@ -716,11 +717,13 @@ + grub_tparm(const char *string,...) + { + char *result; +- int *dataptr = (int *) &string; ++ va_list ap; + +- dataptr++; ++ va_start(ap, string); + +- result = tparam_internal(string, dataptr); ++ result = tparam_internal(string, ap); ++ ++ va_end(ap); + + return result; + } +Index: grub/stage2/fsys_iso9660.c +=================================================================== +--- grub.orig/stage2/fsys_iso9660.c 2008-06-16 15:18:03.400933000 +0100 ++++ grub/stage2/fsys_iso9660.c 2008-06-16 15:18:14.779009000 +0100 +@@ -59,7 +59,14 @@ + static inline unsigned long + log2 (unsigned long word) + { +- asm volatile ("bsfl %1,%0" ++ asm volatile ("bsf" ++#ifdef __i386__ ++ "l" ++#endif ++#ifdef __x86_64__ ++ "q" ++#endif ++ " %1,%0" + : "=r" (word) + : "r" (word)); + return word; +Index: grub/stage2/fsys_reiserfs.c +=================================================================== +--- grub.orig/stage2/fsys_reiserfs.c 2008-06-16 15:18:03.410933000 +0100 ++++ grub/stage2/fsys_reiserfs.c 2008-06-16 15:18:14.786009000 +0100 +@@ -369,7 +369,14 @@ + static __inline__ unsigned long + log2 (unsigned long word) + { +- __asm__ ("bsfl %1,%0" ++ __asm__ ("bsf" ++#ifdef __i386__ ++ "l" ++#endif ++#ifdef __x86_64__ ++ "q" ++#endif ++ " %1,%0" + : "=r" (word) + : "r" (word)); + return word; +Index: grub/netboot/misc.c +=================================================================== +--- grub.orig/netboot/misc.c 2008-06-16 15:18:03.456934000 +0100 ++++ grub/netboot/misc.c 2008-06-16 15:18:14.790009000 +0100 +@@ -21,7 +21,9 @@ + + #define GRUB 1 + #include <etherboot.h> ++#include <stdarg.h> + ++#ifndef __MINIOS__ + void + sleep (int secs) + { +@@ -30,6 +32,7 @@ + while (currticks () < tmo) + ; + } ++#endif + + void + twiddle (void) +@@ -71,7 +74,7 @@ + Note: width specification not supported + **************************************************************************/ + static int +-etherboot_vsprintf (char *buf, const char *fmt, const int *dp) ++etherboot_vsprintf (char *buf, const char *fmt, va_list ap) + { + char *p, *s; + +@@ -86,7 +89,7 @@ + + if (*++fmt == 's') + { +- for (p = (char *) *dp++; *p != '\0'; p++) ++ for (p = va_arg(ap, char *); *p != '\0'; p++) + buf ? *s++ = *p : grub_putchar (*p); + } + else +@@ -121,11 +124,9 @@ + if ((*fmt | 0x20) == 'x') + { + /* With x86 gcc, sizeof(long) == sizeof(int) */ +- const long *lp = (const long *) dp; +- long h = *lp++; ++ long h = va_arg(ap, int); + int ncase = (*fmt & 0x20); + +- dp = (const int *) lp; + if (alt) + { + *q++ = '0'; +@@ -136,7 +137,7 @@ + } + else if (*fmt == 'd') + { +- int i = *dp++; ++ int i = va_arg(ap, int); + char *r; + + if (i < 0) +@@ -171,10 +172,8 @@ + unsigned char c[4]; + } + u; +- const long *lp = (const long *) dp; + +- u.l = *lp++; +- dp = (const int *) lp; ++ u.l = va_arg(ap, int); + + for (r = &u.c[0]; r < &u.c[4]; ++r) + q += etherboot_sprintf (q, "%d.", *r); +@@ -184,7 +183,7 @@ + else if (*fmt == '!') + { + char *r; +- p = (char *) *dp++; ++ p = va_arg(ap, char *); + + for (r = p + ETH_ALEN; p < r; ++p) + q += etherboot_sprintf (q, "%hhX:", *p); +@@ -192,7 +191,7 @@ + --q; + } + else if (*fmt == 'c') +- *q++ = *dp++; ++ *q++ = va_arg(ap, int); + else + *q++ = *fmt; + +@@ -211,13 +210,21 @@ + int + etherboot_sprintf (char *buf, const char *fmt, ...) + { +- return etherboot_vsprintf (buf, fmt, ((const int *) &fmt) + 1); ++ va_list ap; ++ int ret; ++ va_start(ap, fmt); ++ ret = etherboot_vsprintf (buf, fmt, ap); ++ va_end(ap); ++ return ret; + } + + void + etherboot_printf (const char *fmt, ...) + { +- (void) etherboot_vsprintf (0, fmt, ((const int *) &fmt) + 1); ++ va_list ap; ++ va_start(ap, fmt); ++ etherboot_vsprintf (0, fmt, ap); ++ va_end(ap); + } + + int +Index: grub/netboot/main.c +=================================================================== +--- grub.orig/netboot/main.c 2008-06-16 15:18:03.470932000 +0100 ++++ grub/netboot/main.c 2008-06-16 15:18:14.797009000 +0100 +@@ -55,7 +55,7 @@ + static int vendorext_isvalid; + static unsigned long netmask; + static struct bootpd_t bootp_data; +-static unsigned long xid; ++static unsigned int xid; + + #define BOOTP_DATA_ADDR (&bootp_data) + +@@ -778,7 +778,7 @@ + + arpreply = (struct arprequest *) &nic.packet[ETH_HLEN]; + +- if (arpreply->opcode == htons (ARP_REPLY) ++ if (arpreply->opcode == htons (ARP_REPLY) && ptr + && ! grub_memcmp (arpreply->sipaddr, ptr, sizeof (in_addr)) + && type == AWAIT_ARP) + { +@@ -827,7 +827,7 @@ + { + arpreply = (struct arprequest *) &nic.packet[ETH_HLEN]; + +- if (arpreply->opcode == htons (RARP_REPLY) ++ if (arpreply->opcode == htons (RARP_REPLY) && ptr + && ! grub_memcmp (arpreply->thwaddr, ptr, ETH_ALEN)) + { + grub_memmove ((char *) arptable[ARP_SERVER].node, +@@ -1135,7 +1135,7 @@ + long + rfc2131_sleep_interval (int base, int exp) + { +- static long seed = 0; ++ static unsigned seed = 0; + long q; + unsigned long tmo; + +Index: grub/stage2/graphics.c +=================================================================== +--- grub.orig/stage2/graphics.c 2008-06-16 15:18:14.524009000 +0100 ++++ grub/stage2/graphics.c 2008-06-17 14:29:05.204328000 +0100 +@@ -30,7 +30,29 @@ + #include <shared.h> + #include <graphics.h> + ++#ifdef __MINIOS__ ++#include <stdint.h> ++typedef uint8_t Bit8u; ++#include <vgafonts.h> ++#include <fbfront.h> ++#include <malloc.h> ++#define set_int1c_handler() (void)0 ++#define unset_int1c_handler() (void)0 ++static uint32_t *VIDEOMEM; ++static struct fbfront_dev *fb_dev; ++static uint32_t palette[17]; ++short cursorX, cursorY; ++/* TODO: blink */ ++uint32_t cursorBuf32[16*8]; ++#define WIDTH 640 ++#define HEIGHT 480 ++#define DEPTH 32 ++#define RAMSIZE (WIDTH * HEIGHT * (DEPTH / 8)) ++#else ++#define fbfront_update(dev, x, y, w, h) (void)0 + int saved_videomode; ++#endif ++ + unsigned char *font8x16; + + int graphics_inited = 0; +@@ -38,11 +60,15 @@ + + int shade = 1, no_cursor = 0; + ++#ifdef __MINIOS__ ++uint32_t VSHADOW[RAMSIZE]; ++#else + #define VSHADOW VSHADOW1 + unsigned char VSHADOW1[38400]; + unsigned char VSHADOW2[38400]; + unsigned char VSHADOW4[38400]; + unsigned char VSHADOW8[38400]; ++#endif + + /* define the default viewable area */ + int view_x0 = 0; +@@ -129,6 +155,8 @@ + count_lines = k; + + no_scroll = 0; ++ ++ fbfront_update(fb_dev, view_x0 * 8, view_y0 * 16, (view_x1 - view_x0) * 8, (view_y1 - view_y0) * 16); + } + + /* Set the splash image */ +@@ -154,17 +182,29 @@ + int graphics_init() + { + if (!graphics_inited) { ++#ifdef __MINIOS__ ++ VIDEOMEM = memalign(PAGE_SIZE, RAMSIZE); ++ if (!(fb_dev = fb_open(VIDEOMEM, WIDTH, HEIGHT, DEPTH))) { ++ free(VIDEOMEM); ++ return 0; ++ } ++#else + saved_videomode = set_videomode(0x12); + if (get_videomode() != 0x12) { + set_videomode(saved_videomode); + return 0; + } ++#endif + graphics_inited = 1; + } + else + return 1; + ++#ifdef __MINIOS__ ++ font8x16 = vgafont16; ++#else + font8x16 = (unsigned char*)graphics_get_font(); ++#endif + + /* make sure that the highlight color is set correctly */ + graphics_highlight_color = ((graphics_normal_color >> 4) | +@@ -176,7 +216,11 @@ + grub_printf("Failed to read splash image (%s)\n", splashimage); + grub_printf("Press any key to continue..."); + getkey(); ++#ifdef __MINIOS__ ++ fb_close(); ++#else + set_videomode(saved_videomode); ++#endif + graphics_inited = 0; + return 0; + } +@@ -190,8 +234,13 @@ + void graphics_end(void) + { + if (graphics_inited) { ++#ifdef __MINIOS__ ++ fb_close(); ++ free(VIDEOMEM); ++#else + unset_int1c_handler(); + set_videomode(saved_videomode); ++#endif + graphics_inited = 0; + no_cursor = 0; + } +@@ -204,15 +253,19 @@ + graphics_cursor(0); + + if (ch == '\n') { ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + if (fonty + 1 < view_y1) + graphics_setxy(fontx, fonty + 1); + else + graphics_scroll(); + graphics_cursor(1); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + return; + } else if (ch == '\r') { ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + graphics_setxy(view_x0, fonty); + graphics_cursor(1); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + return; + } + +@@ -224,6 +277,7 @@ + text[fonty * 80 + fontx] |= 0x100; + + graphics_cursor(0); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + + if ((fontx + 1) >= view_x1) { + graphics_setxy(view_x0, fonty); +@@ -232,13 +286,16 @@ + else + graphics_scroll(); + graphics_cursor(1); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + do_more (); + graphics_cursor(0); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + } else { + graphics_setxy(fontx + 1, fonty); + } + + graphics_cursor(1); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + } + + /* get the current location of the cursor */ +@@ -248,10 +305,12 @@ + + void graphics_gotoxy(int x, int y) { + graphics_cursor(0); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + + graphics_setxy(x, y); + + graphics_cursor(1); ++ fbfront_update(fb_dev, cursorX, cursorY, 8, 16); + } + + void graphics_cls(void) { +@@ -262,15 +321,21 @@ + graphics_gotoxy(view_x0, view_y0); + + mem = (unsigned char*)VIDEOMEM; ++#ifndef __MINIOS__ + s1 = (unsigned char*)VSHADOW1; + s2 = (unsigned char*)VSHADOW2; + s4 = (unsigned char*)VSHADOW4; + s8 = (unsigned char*)VSHADOW8; ++#endif + + for (i = 0; i < 80 * 30; i++) + text[i] = ' '; + graphics_cursor(1); + ++#ifdef __MINIOS__ ++ memcpy(mem, VSHADOW, RAMSIZE); ++ fbfront_update(fb_dev, 0, 0, 640, 480); ++#else + BitMask(0xff); + + /* plane 1 */ +@@ -290,6 +355,7 @@ + grub_memcpy(mem, s8, 38400); + + MapMask(15); ++#endif + + if (no_cursor) { + no_cursor = 0; +@@ -337,6 +403,11 @@ + return 0; + } + ++void graphics_set_palette(int idx, int red, int green, int blue) ++{ ++ palette[idx] = (red << (16 + 2)) | (green << (8 + 2)) | (blue << 2); ++} ++ + /* Read in the splashscreen image and set the palette up appropriately. + * Format of splashscreen is an xpm (can be gzipped) with 16 colors and + * 640x480. */ +@@ -413,18 +484,19 @@ + } + + if (len == 6 && idx < 15) { +- int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2; +- int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2; +- int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2; ++ int r = ((hex(buf[0]) << 4) | hex(buf[1])); ++ int g = ((hex(buf[2]) << 4) | hex(buf[3])); ++ int b = ((hex(buf[4]) << 4) | hex(buf[5])); + + pal[idx] = base; +- graphics_set_palette(idx, r, g, b); ++ graphics_set_palette(idx, r / 4, g / 4, b / 4); + ++idx; + } + } + + x = y = len = 0; + ++#ifndef __MINIOS__ + s1 = (unsigned char*)VSHADOW1; + s2 = (unsigned char*)VSHADOW2; + s4 = (unsigned char*)VSHADOW4; +@@ -432,6 +504,7 @@ + + for (i = 0; i < 38400; i++) + s1[i] = s2[i] = s4[i] = s8[i] = 0; ++#endif + + /* parse xpm data */ + while (y < height) { +@@ -451,6 +524,9 @@ + break; + } + ++#ifdef __MINIOS__ ++ VSHADOW[x + y * 640] = palette[i]; ++#else + mask = 0x80 >> (x & 7); + if (c & 1) + s1[len + (x >> 3)] |= mask; +@@ -460,6 +536,7 @@ + s4[len + (x >> 3)] |= mask; + if (c & 8) + s8[len + (x >> 3)] |= mask; ++#endif + + if (++x >= 640) { + x = 0; +@@ -494,7 +571,13 @@ + } + + void graphics_cursor(int set) { +- unsigned char *pat, *mem, *ptr, chr[16 << 2]; ++ unsigned char *pat; ++#ifdef __MINIOS__ ++ uint32_t *mem, *ptr, chr[16 * 8]; ++ int j; ++#else ++ unsigned char *mem, *ptr, chr[16 << 2]; ++#endif + int i, ch, invert, offset; + + if (set && (no_cursor || no_scroll)) +@@ -505,71 +588,127 @@ + invert = (text[fonty * 80 + fontx] & 0xff00) != 0; + pat = font8x16 + (ch << 4); + +- mem = (unsigned char*)VIDEOMEM + offset; ++ mem = (unsigned char*)VIDEOMEM + offset ++#ifdef __MINIOS__ ++ * 8 * 4 ++#endif ++ ; + + if (!set) { + for (i = 0; i < 16; i++) { + unsigned char mask = pat[i]; + + if (!invert) { ++#ifdef __MINIOS__ ++ memcpy(chr + i * 8, VSHADOW + offset * 8, 8 * 4); ++#else + chr[i ] = ((unsigned char*)VSHADOW1)[offset]; + chr[16 + i] = ((unsigned char*)VSHADOW2)[offset]; + chr[32 + i] = ((unsigned char*)VSHADOW4)[offset]; + chr[48 + i] = ((unsigned char*)VSHADOW8)[offset]; ++#endif + + if (shade) { + if (ch == DISP_VERT || ch == DISP_LL || + ch == DISP_UR || ch == DISP_LR) { + unsigned char pmask = ~(pat[i] >> 1); + ++#ifdef __MINIOS__ ++ for (j = 0; j < 8; j++) ++ if (!(pmask & (1U << j))) ++ chr[i * 8 + (7 - j)] = palette[0]; ++#else + chr[i ] &= pmask; + chr[16 + i] &= pmask; + chr[32 + i] &= pmask; + chr[48 + i] &= pmask; ++#endif + } + if (i > 0 && ch != DISP_VERT) { + unsigned char pmask = ~(pat[i - 1] >> 1); + ++#ifdef __MINIOS__ ++ for (j = 0; j < 8; j++) ++ if (!(pmask & (1U << j))) ++ chr[i * 8 + (7 - j)] = palette[0]; ++#else + chr[i ] &= pmask; + chr[16 + i] &= pmask; + chr[32 + i] &= pmask; + chr[48 + i] &= pmask; ++#endif + if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) { + pmask = ~pat[i - 1]; + ++#ifdef __MINIOS__ ++ for (j = 0; j < 8; j++) ++ if (!(pmask & (1U << j))) ++ chr[i * 8 + (7 - j)] = palette[0]; ++#else + chr[i ] &= pmask; + chr[16 + i] &= pmask; + chr[32 + i] &= pmask; + chr[48 + i] &= pmask; ++#endif + } + } + } ++#ifdef __MINIOS__ ++ for (j = 0; j < 8; j++) ++ if (mask & (1U << j)) ++ chr[i * 8 + (7 - j)] = palette[15]; ++#else + chr[i ] |= mask; + chr[16 + i] |= mask; + chr[32 + i] |= mask; + chr[48 + i] |= mask; ++#endif + + offset += 80; + } + else { ++#ifdef __MINIOS__ ++ for (j = 0; j < 8; j++) ++ if (mask & (1U << j)) ++ chr[i * 8 + (7 - j)] = palette[15]; ++ else ++ chr[i * 8 + (7 - j)] = palette[0]; ++#else + chr[i ] = mask; + chr[16 + i] = mask; + chr[32 + i] = mask; + chr[48 + i] = mask; ++#endif + } + } + } + else { ++#ifdef __MINIOS__ ++ ptr = mem; ++ for (i = 0; i < 16; i++, ptr += 80 * 8) ++ for (j = 0; j < 8; j++) { ++ if (pat[i] & (1U << (7 - j))) ++ cursorBuf32[i * 8 + j] = ptr[j] = palette[0]; ++ else ++ cursorBuf32[i * 8 + j] = ptr[j] = palette[15]; ++ } ++#else + MapMask(15); + ptr = mem; + for (i = 0; i < 16; i++, ptr += 80) { + cursorBuf[i] = pat[i]; + *ptr = ~pat[i]; + } ++#endif + return; + } + + offset = 0; ++#ifdef __MINIOS__ ++ ptr = mem; ++ for (j = 0; j < 16; j++, ptr += 80 * 8) ++ memcpy(ptr, chr + j * 8 + offset * 8, 8 * 4); ++#else + for (i = 1; i < 16; i <<= 1, offset += 16) { + int j; + +@@ -580,6 +719,7 @@ + } + + MapMask(15); ++#endif + } + + #endif /* SUPPORT_GRAPHICS */ +Index: grub/stage2/graphics.h +=================================================================== +--- grub.orig/stage2/graphics.h 2008-06-16 15:18:14.527010000 +0100 ++++ grub/stage2/graphics.h 2008-06-16 15:18:14.805010000 +0100 +@@ -21,8 +21,10 @@ + #ifndef GRAPHICS_H + #define GRAPHICS_H + ++#ifndef __MINIOS__ + /* magic constant */ + #define VIDEOMEM 0xA0000 ++#endif + + /* function prototypes */ + char *graphics_get_splash(void); +Index: grub/stage2/stage2.c +=================================================================== +--- grub.orig/stage2/stage2.c 2008-06-17 11:06:47.873523000 +0100 ++++ grub/stage2/stage2.c 2008-06-17 11:07:05.225628000 +0100 +@@ -31,10 +31,10 @@ + #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS) + + # if defined(PRESET_MENU_STRING) +-static const char *preset_menu = PRESET_MENU_STRING; ++const char *preset_menu = PRESET_MENU_STRING; + # elif defined(SUPPORT_DISKLESS) + /* Execute the command "bootp" automatically. */ +-static const char *preset_menu = "bootp\n"; ++const char *preset_menu = "bootp\n"; + # endif /* SUPPORT_DISKLESS */ + + static int preset_menu_offset; diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/grub/Makefile Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,76 @@ +XEN_ROOT = ../.. + +include $(XEN_ROOT)/Config.mk +vpath %.c ../grub-cvs + +BOOT=boot-$(XEN_TARGET_ARCH).o + +DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/libxc -I. +DEF_CPPFLAGS += -I../grub-cvs/stage1 +DEF_CPPFLAGS += -I../grub-cvs/stage2 +DEF_CPPFLAGS += -I../grub-cvs/netboot +DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/firmware/vgabios +DEF_CPPFLAGS += -DWITHOUT_LIBC_STUBS +DEF_CPPFLAGS += -DSUPPORT_NETBOOT +DEF_CPPFLAGS += -DSUPPORT_GRAPHICS +DEF_CPPFLAGS += -DSUPPORT_SERIAL +DEF_CPPFLAGS += -DPRESET_MENU_STRING='""' +DEF_CPPFLAGS += -DPACKAGE='"grubdom"' -DVERSION='"0.97"' + +all: main.a + +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 + +NETBOOT_SOURCES=fsys_tftp.c main.c misc.c +CPPFLAGS += -DFSYS_TFTP=1 + +STAGE2_SOURCES+=fsys_ext2fs.c +CPPFLAGS += -DFSYS_EXT2FS=1 + +STAGE2_SOURCES+=fsys_fat.c +CPPFLAGS += -DFSYS_FAT=1 + +STAGE2_SOURCES+=fsys_ffs.c +CPPFLAGS += -DFSYS_FFS=1 + +STAGE2_SOURCES+=fsys_iso9660.c +CPPFLAGS += -DFSYS_ISO9660=1 + +STAGE2_SOURCES+=fsys_jfs.c +CPPFLAGS += -DFSYS_JFS=1 + +STAGE2_SOURCES+=fsys_minix.c +CPPFLAGS += -DFSYS_MINIX=1 + +STAGE2_SOURCES+=fsys_reiserfs.c +CPPFLAGS += -DFSYS_REISERFS=1 + +STAGE2_SOURCES+=fsys_ufs2.c +CPPFLAGS += -DFSYS_UFS2=1 + +STAGE2_SOURCES+=fsys_vstafs.c +CPPFLAGS += -DFSYS_VSTAFS=1 + +ifeq (0,1) +STAGE2_SOURCES+=fsys_xfs.c +CPPFLAGS += -DFSYS_XFS=1 +endif + +STAGE2_SOURCES:=$(addprefix stage2/,$(STAGE2_SOURCES)) +NETBOOT_SOURCES:=$(addprefix netboot/,$(NETBOOT_SOURCES)) + +$(BOOT): DEF_CPPFLAGS+=-D__ASSEMBLY__ + +OBJS = $(NETBOOT_SOURCES:.c=.o) $(STAGE2_SOURCES:.c=.o) kexec.o mini-os.o + +dirs: + mkdir -p netboot stage2 + touch $@ + +$(OBJS): dirs + +main.a: $(BOOT) $(OBJS) + $(AR) cr $@ $^ + +clean: + rm -fr dirs *.a *.o stage2 netboot diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/boot-x86_32.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/grub/boot-x86_32.S Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,112 @@ +#include <os.h> +#include <arch_limits.h> +#include <xen/arch-x86_32.h> + +/* For simplicity, we keep all of this into just one data page */ +.data +.globl _boot_page +_boot_page: + .align __PAGE_SIZE + +/* + * The following data is initialized from C code + */ + +/* Pte of this page */ +.globl _boot_page_entry +_boot_page_entry: +_boot_page_entry_lo: + .long 0 +_boot_page_entry_hi: + .long 0 + +/* mmuext_op structure */ +/* Set new page directory */ +_boot_mmuext: + /* Op # */ + .long MMUEXT_NEW_BASEPTR + + /* MFN of target page table directory */ +.globl _boot_pdmfn +_boot_pdmfn: + .long 0 + + /* Unused */ + .long 0 + +/* Unpin old page directory */ + /* Op # */ + .long MMUEXT_UNPIN_TABLE + + /* MFN of old page table directory */ +.globl _boot_oldpdmfn +_boot_oldpdmfn: + .long 0 + + /* Unused */ + .long 0 + +/* Target stack address, also target virtual address of this page */ +.globl _boot_stack +_boot_stack: + .long 0 + .long __KERNEL_SS +.globl _boot_target +_boot_target: + .long 0 + +/* Target start info */ +.globl _boot_start_info +_boot_start_info: + .long 0 + +/* Target start address */ +.globl _boot_start +_boot_start: + .long 0 + +/* + * Boot target OS, does not return + */ +.globl _boot +_boot: + /* Project ourselves at the target place. */ + movl _boot_target, %ebx + movl %ebx, %ebp /* also keep it in ebp for relative addressing */ + movl _boot_page_entry_lo, %ecx + movl _boot_page_entry_hi, %edx + movl $2, %esi /* UVMF_INVLPG */ + movl $__HYPERVISOR_update_va_mapping, %eax + int $0x82 + testl %eax, %eax + jz 0f + ud2 + +0: + /* Go there. */ + movl $(0f - _boot_page), %eax + movl _boot_target, %ebx + addl %ebx, %eax + jmpl *%eax +0: + + /* Load target page table and unpin old page table. */ + /* We shouldn't have any problem since in the new page table our page is + mapped at the same place. */ + leal (_boot_mmuext-_boot_page)(%ebp), %ebx + movl $2, %ecx + xorl %edx, %edx + movl $0x7FF0, %esi /* DOMID_SELF */ + movl $__HYPERVISOR_mmuext_op, %eax + int $0x82 + testl %eax, %eax + jns 0f + ud2 + +0: + /* Initialize registers. */ + lss (_boot_stack-_boot_page)(%ebp), %esp + movl (_boot_start_info-_boot_page)(%ebp), %esi + + /* Jump! */ + jmpl *(_boot_start-_boot_page)(%ebp) diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/boot-x86_64.S --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/grub/boot-x86_64.S Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,108 @@ +#include <os.h> +#include <arch_limits.h> +#include <xen/arch-x86_64.h> + +/* For simplicity, we keep all of this into just one data page */ +.data +.globl _boot_page +_boot_page: + .align __PAGE_SIZE + +/* + * The following data is initialized from C code + */ + +/* Pte of this page */ +.globl _boot_page_entry +_boot_page_entry: + .quad 0 + +/* mmuext_op structure */ +/* Set new page directory */ +_boot_mmuext: + /* Op # */ + .long MMUEXT_NEW_BASEPTR + .long 0 /* pad */ + + /* MFN of target page table directory */ +.globl _boot_pdmfn +_boot_pdmfn: + .quad 0 + + /* Unused */ + .quad 0 + +/* Unpin old page directory */ + /* Op # */ + .long MMUEXT_UNPIN_TABLE + .long 0 /* pad */ + + /* MFN of old page table directory */ +.globl _boot_oldpdmfn +_boot_oldpdmfn: + .quad 0 + + /* Unused */ + .quad 0 + +/* Target stack address, also target virtual address of this page */ +.globl _boot_stack +_boot_stack: + .quad 0 +.globl _boot_target +_boot_target: + .quad 0 + +/* Target start info */ +.globl _boot_start_info +_boot_start_info: + .quad 0 + +/* Target start address */ +.globl _boot_start +_boot_start: + .quad 0 + +/* + * Boot target OS, does not return + */ +.globl _boot +_boot: + /* Project ourselves at the target place. */ + movq _boot_target, %rdi + movq _boot_page_entry, %rsi + movq $2, %rdx /* UVMF_INVLPG */ + movq $__HYPERVISOR_update_va_mapping, %rax + syscall + testq %rax, %rax + jz 0f + ud2 + +0: + /* Go there. */ + movq $(0f - _boot_page), %rax + movq _boot_target, %rbx + addq %rbx, %rax + jmpq *%rax +0: + + /* Load target page table and unpin old page table. */ + /* We shouldn't have any problem since in the new page table our page is + mapped at the same place. */ + leaq _boot_mmuext(%rip), %rdi + movq $2, %rsi + xorq %rdx, %rdx + movq $0x7FF0, %r10 /* DOMID_SELF */ + movq $__HYPERVISOR_mmuext_op, %rax + syscall + testq %rax, %rax + jns 0f + ud2 + +0: + /* Initialize registers. */ + movq _boot_stack(%rip), %rsp + movq _boot_start_info(%rip), %rsi + + /* Jump! */ + jmpq *_boot_start(%rip) diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/config.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/grub/config.h Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,11 @@ +#include <stdio.h> +#undef putchar +#include <ctype.h> +#include <string.h> +#define debug _debug +#define grub_halt(a) do_exit() +#define printf grub_printf +void kexec(void *kernel, long kernel_size, void *module, long module_size, char *cmdline); +struct fbfront_dev *fb_open(void *fb, int width, int height, int depth); +void fb_close(void); +void pv_boot (void); diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/kexec.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/grub/kexec.c Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,324 @@ +/* + * This supports booting another PV kernel from Mini-OS + * + * The idea is to setup it using libxc, answer to day0 memory allocation + * requests, and using a trampoline boot page to switch to the new page table. + * + * The procedure of the boot page is: + * - map itself at the target position (that may overwrite some C stuff, but we + * do not care any more) + * - jump there + * - switch to the target page table + * - unpin the old page table + * - jump to the new kernel + * + * Samuel Thibault <Samuel.Thibault@xxxxxxxxxxxxx>, May 2008 + */ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/mman.h> + +#include <xenctrl.h> +#include <xc_dom.h> + +#include <kernel.h> +#include <console.h> +#include <os.h> +#include <blkfront.h> +#include <netfront.h> +#include <fbfront.h> +#include <shared.h> + +#include "mini-os.h" + +#if 0 +#define DEBUG(fmt, ...) printk(fmt, ## __VA_ARGS__) +#else +#define DEBUG(fmt, ...) (void)0 +#endif + +/* Assembly boot page from boot.S */ +extern void _boot_page; +extern pgentry_t _boot_page_entry; +extern unsigned long _boot_pdmfn; +extern unsigned long _boot_stack, _boot_target, _boot_start_info, _boot_start; +extern xen_pfn_t _boot_oldpdmfn; +extern void _boot(void); + +static unsigned long *pages; +static unsigned long *pages_mfns; +static unsigned long allocated; + +int pin_table(int xc_handle, unsigned int type, unsigned long mfn, + domid_t dom); + +/* We need mfn to appear as target_pfn, so exchange with the MFN there */ +static void do_exchange(struct xc_dom_image *dom, xen_pfn_t target_pfn, xen_pfn_t source_mfn) +{ + xen_pfn_t source_pfn; + xen_pfn_t target_mfn; + + for (source_pfn = 0; source_pfn < start_info.nr_pages; source_pfn++) + if (dom->p2m_host[source_pfn] == source_mfn) + break; + ASSERT(source_pfn < start_info.nr_pages); + + target_mfn = dom->p2m_host[target_pfn]; + + /* Put target MFN at source PFN */ + dom->p2m_host[source_pfn] = target_mfn; + + /* Put source MFN at target PFN */ + dom->p2m_host[target_pfn] = source_mfn; +} + +int kexec_allocate(struct xc_dom_image *dom, xen_vaddr_t up_to) +{ + unsigned long new_allocated = (up_to - dom->parms.virt_base) / PAGE_SIZE; + unsigned long i; + + pages = realloc(pages, new_allocated * sizeof(*pages)); + pages_mfns = realloc(pages_mfns, new_allocated * sizeof(*pages_mfns)); + for (i = allocated; i < new_allocated; i++) { + /* Exchange old page of PFN i with a newly allocated page. */ + xen_pfn_t old_mfn = dom->p2m_host[i]; + xen_pfn_t new_pfn; + xen_pfn_t new_mfn; + + pages[i] = alloc_page(); + memset((void*) pages[i], 0, PAGE_SIZE); + new_pfn = PHYS_PFN(to_phys(pages[i])); + pages_mfns[i] = new_mfn = pfn_to_mfn(new_pfn); + + /* Put old page at new PFN */ + dom->p2m_host[new_pfn] = old_mfn; + + /* Put new page at PFN i */ + dom->p2m_host[i] = new_mfn; + } + + allocated = new_allocated; + + return 0; +} + +void kexec(void *kernel, long kernel_size, void *module, long module_size, char *cmdline) +{ + struct xc_dom_image *dom; + int rc; + domid_t domid = DOMID_SELF; + xen_pfn_t pfn; + int xc_handle; + unsigned long i; + void *seg; + xen_pfn_t boot_page_mfn = virt_to_mfn(&_boot_page); + char features[] = ""; + struct mmu_update *m2p_updates; + unsigned long nr_m2p_updates; + + DEBUG("booting with cmdline %s\n", cmdline); + xc_handle = xc_interface_open(); + + dom = xc_dom_allocate(cmdline, features); + dom->allocate = kexec_allocate; + + dom->kernel_blob = kernel; + dom->kernel_size = kernel_size; + + dom->ramdisk_blob = module; + dom->ramdisk_size = module_size; + + dom->flags = 0; + dom->console_evtchn = start_info.console.domU.evtchn; + dom->xenstore_evtchn = start_info.store_evtchn; + + if ( (rc = xc_dom_boot_xen_init(dom, xc_handle, domid)) != 0 ) { + grub_printf("xc_dom_boot_xen_init returned %d\n", rc); + errnum = ERR_BOOT_FAILURE; + goto out; + } + if ( (rc = xc_dom_parse_image(dom)) != 0 ) { + grub_printf("xc_dom_parse_image returned %d\n", rc); + errnum = ERR_BOOT_FAILURE; + goto out; + } + +#ifdef __i386__ + if (strcmp(dom->guest_type, "xen-3.0-x86_32p")) { + grub_printf("can only boot x86 32 PAE kernels, not %s\n", dom->guest_type); + errnum = ERR_EXEC_FORMAT; + goto out; + } +#endif +#ifdef __x86_64__ + if (strcmp(dom->guest_type, "xen-3.0-x86_64")) { + grub_printf("can only boot x86 64 kernels, not %s\n", dom->guest_type); + errnum = ERR_EXEC_FORMAT; + goto out; + } +#endif + + /* equivalent of xc_dom_mem_init */ + dom->arch_hooks = xc_dom_find_arch_hooks(dom->guest_type); + dom->total_pages = start_info.nr_pages; + + /* equivalent of arch_setup_meminit */ + + /* setup initial p2m */ + dom->p2m_host = malloc(sizeof(*dom->p2m_host) * dom->total_pages); + + /* Start with our current P2M */ + for (i = 0; i < dom->total_pages; i++) + dom->p2m_host[i] = pfn_to_mfn(i); + + if ( (rc = xc_dom_build_image(dom)) != 0 ) { + grub_printf("xc_dom_build_image returned %d\n", rc); + errnum = ERR_BOOT_FAILURE; + goto out; + } + + /* copy hypercall page */ + /* TODO: domctl instead, but requires privileges */ + if (dom->parms.virt_hypercall != -1) { + pfn = PHYS_PFN(dom->parms.virt_hypercall - dom->parms.virt_base); + memcpy((void *) pages[pfn], hypercall_page, PAGE_SIZE); + } + + /* Equivalent of xc_dom_boot_image */ + dom->shared_info_mfn = PHYS_PFN(start_info.shared_info); + + if (!xc_dom_compat_check(dom)) { + grub_printf("xc_dom_compat_check failed\n"); + errnum = ERR_EXEC_FORMAT; + goto out; + } + + /* Move current console, xenstore and boot MFNs to the allocated place */ + do_exchange(dom, dom->console_pfn, start_info.console.domU.mfn); + do_exchange(dom, dom->xenstore_pfn, start_info.store_mfn); + DEBUG("virt base at %llx\n", dom->parms.virt_base); + DEBUG("bootstack_pfn %lx\n", dom->bootstack_pfn); + _boot_target = dom->parms.virt_base + PFN_PHYS(dom->bootstack_pfn); + DEBUG("_boot_target %lx\n", _boot_target); + do_exchange(dom, PHYS_PFN(_boot_target - dom->parms.virt_base), + virt_to_mfn(&_boot_page)); + + /* Make sure the bootstrap page table does not RW-map any of our current + * page table frames */ + kexec_allocate(dom, dom->virt_pgtab_end); + + if ( (rc = xc_dom_update_guest_p2m(dom))) { + grub_printf("xc_dom_update_guest_p2m returned %d\n", rc); + errnum = ERR_BOOT_FAILURE; + goto out; + } + + if ( dom->arch_hooks->setup_pgtables ) + if ( (rc = dom->arch_hooks->setup_pgtables(dom))) { + grub_printf("setup_pgtables returned %d\n", rc); + errnum = ERR_BOOT_FAILURE; + goto out; + } + + /* start info page */ +#undef start_info + if ( dom->arch_hooks->start_info ) + dom->arch_hooks->start_info(dom); +#define start_info (start_info_union.start_info) + + xc_dom_log_memory_footprint(dom); + + /* Unmap libxc's projection of the boot page table */ + seg = xc_dom_seg_to_ptr(dom, &dom->pgtables_seg); + munmap(seg, dom->pgtables_seg.vend - dom->pgtables_seg.vstart); + + /* Unmap day0 pages to avoid having a r/w mapping of the future page table */ + for (pfn = 0; pfn < allocated; pfn++) + munmap((void*) pages[pfn], PAGE_SIZE); + + /* Pin the boot page table base */ + if ( (rc = pin_table(dom->guest_xc, +#ifdef __i386__ + MMUEXT_PIN_L3_TABLE, +#endif +#ifdef __x86_64__ + MMUEXT_PIN_L4_TABLE, +#endif + xc_dom_p2m_host(dom, dom->pgtables_seg.pfn), + dom->guest_domid)) != 0 ) { + grub_printf("pin_table(%lx) returned %d\n", xc_dom_p2m_host(dom, + dom->pgtables_seg.pfn), rc); + errnum = ERR_BOOT_FAILURE; + goto out_remap; + } + + /* We populate the Mini-OS page table here so that boot.S can just call + * update_va_mapping to project itself there. */ + need_pgt(_boot_target); + DEBUG("day0 pages %lx\n", allocated); + DEBUG("boot target page %lx\n", _boot_target); + DEBUG("boot page %p\n", &_boot_page); + DEBUG("boot page mfn %lx\n", boot_page_mfn); + _boot_page_entry = PFN_PHYS(boot_page_mfn) | L1_PROT; + DEBUG("boot page entry %llx\n", _boot_page_entry); + _boot_oldpdmfn = virt_to_mfn(start_info.pt_base); + DEBUG("boot old pd mfn %lx\n", _boot_oldpdmfn); + DEBUG("boot pd virt %lx\n", dom->pgtables_seg.vstart); + _boot_pdmfn = dom->p2m_host[PHYS_PFN(dom->pgtables_seg.vstart - dom->parms.virt_base)]; + DEBUG("boot pd mfn %lx\n", _boot_pdmfn); + _boot_stack = _boot_target + PAGE_SIZE; + DEBUG("boot stack %lx\n", _boot_stack); + _boot_start_info = dom->parms.virt_base + PFN_PHYS(dom->start_info_pfn); + DEBUG("boot start info %lx\n", _boot_start_info); + _boot_start = dom->parms.virt_entry; + DEBUG("boot start %lx\n", _boot_start); + + /* Keep only useful entries */ + for (nr_m2p_updates = pfn = 0; pfn < start_info.nr_pages; pfn++) + if (dom->p2m_host[pfn] != pfn_to_mfn(pfn)) + nr_m2p_updates++; + + m2p_updates = malloc(sizeof(*m2p_updates) * nr_m2p_updates); + for (i = pfn = 0; pfn < start_info.nr_pages; pfn++) + if (dom->p2m_host[pfn] != pfn_to_mfn(pfn)) { + m2p_updates[i].ptr = PFN_PHYS(dom->p2m_host[pfn]) | MMU_MACHPHYS_UPDATE; + m2p_updates[i].val = pfn; + i++; + } + + for (i = 0; i < blk_nb; i++) + shutdown_blkfront(blk_dev[i]); + if (net_dev) + shutdown_netfront(net_dev); + if (kbd_dev) + shutdown_kbdfront(kbd_dev); + stop_kernel(); + + /* Update M2P */ + if ((rc = HYPERVISOR_mmu_update(m2p_updates, nr_m2p_updates, NULL, DOMID_SELF)) < 0) { + xprintk("Could not update M2P\n"); + ASSERT(0); + } + + xprintk("go!\n"); + + /* Jump to trampoline boot page */ + _boot(); + + ASSERT(0); + +out_remap: + for (pfn = 0; pfn < allocated; pfn++) + do_map_frames(pages[pfn], &pages_mfns[pfn], 1, 0, 0, DOMID_SELF, 0, L1_PROT); +out: + xc_dom_release(dom); + for (pfn = 0; pfn < allocated; pfn++) + free_page((void*)pages[pfn]); + free(pages); + free(pages_mfns); + pages = NULL; + pages_mfns = NULL; + allocated = 0; + xc_interface_close(xc_handle ); +} diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/mini-os.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/grub/mini-os.c Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,702 @@ +/* + * Mini-OS support for GRUB. + * + * Samuel Thibault <Samuel.Thibault@xxxxxxxxxxxxx>, May 2008 + */ +#include <sys/types.h> +#include <sys/time.h> +#include <stdarg.h> +#include <stdlib.h> +#include <malloc.h> +#include <unistd.h> + +#include <hypervisor.h> +#include <blkfront.h> +#include <netfront.h> +#include <fbfront.h> +#include <semaphore.h> + +#include <osdep.h> +#include <shared.h> +#include <nic.h> +#include <etherboot.h> +#include <terminfo.h> +#include <term.h> + +#include "mini-os.h" + +extern const char *preset_menu; +char config_file[DEFAULT_FILE_BUFLEN] = "(hd0,0)/boot/grub/menu.lst"; +unsigned long boot_drive = NETWORK_DRIVE; +unsigned long install_partition = 0xFFFFFF; + +char version_string[] = VERSION; + +/* Variables from asm.S */ +int saved_entryno; + +/* + * Disk + */ + +struct blkfront_dev **blk_dev; +int blk_nb; +static struct blkfront_info *blk_info; + +static int vbdcmp(const void *_vbd1, const void *_vbd2) { + char *vbd1 = *(char **)_vbd1; + char *vbd2 = *(char **)_vbd2; + int vbdn1 = atoi(vbd1); + int vbdn2 = atoi(vbd2); + return vbdn1 - vbdn2; +} + +void init_disk (void) +{ + char **list; + char *msg; + int i; + char *path; + + msg = xenbus_ls(XBT_NIL, "device/vbd", &list); + if (msg) { + printk("Error %s while reading list of disks\n", msg); + free(msg); + return; + } + blk_nb = 0; + while (list[blk_nb]) + blk_nb++; + blk_dev = malloc(blk_nb * sizeof(*blk_dev)); + blk_info = malloc(blk_nb * sizeof(*blk_info)); + + qsort(list, blk_nb, sizeof(*list), vbdcmp); + + for (i = 0; i < blk_nb; i++) { + printk("vbd %s is hd%d\n", list[i], i); + asprintf(&path, "device/vbd/%s", list[i]); + blk_dev[i] = init_blkfront(path, &blk_info[i]); + free(path); + free(list[i]); + } +} + +/* Return the geometry of DRIVE in GEOMETRY. If an error occurs, return + non-zero, otherwise zero. */ +int get_diskinfo (int drive, struct geometry *geometry) +{ + int i; + if (!(drive & 0x80)) + return -1; + + i = drive - 0x80; + if (i >= blk_nb) + return -1; + + /* Bogus geometry */ + geometry->cylinders = 65535; + geometry->heads = 255; + geometry->sectors = 63; + + geometry->total_sectors = blk_info[i].sectors; + geometry->sector_size = blk_info[i].sector_size; + geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION; + if (blk_info[i].info & VDISK_CDROM) + geometry->flags |= BIOSDISK_FLAG_CDROM; + return 0; +} + +/* Read/write NSEC sectors starting from SECTOR in DRIVE disk with GEOMETRY + from/into SEGMENT segment. If READ is BIOSDISK_READ, then read it, + else if READ is BIOSDISK_WRITE, then write it. If an geometry error + occurs, return BIOSDISK_ERROR_GEOMETRY, and if other error occurs, then + return the error number. Otherwise, return 0. */ +int +biosdisk (int read, int drive, struct geometry *geometry, + unsigned int sector, int nsec, int segment) +{ + void *addr = (void *) ((unsigned long)segment << 4); + struct blkfront_aiocb aiocb; + int i; + + if (!(drive & 0x80)) + return -1; + + i = drive - 0x80; + if (i >= blk_nb) + return -1; + + aiocb.aio_dev = blk_dev[i]; + aiocb.aio_buf = addr; + aiocb.aio_nbytes = (size_t)nsec * blk_info[i].sector_size; + aiocb.aio_offset = (off_t)sector * blk_info[i].sector_size; + aiocb.aio_cb = NULL; + + blkfront_io(&aiocb, read == BIOSDISK_WRITE); + + return 0; +} + +static int +load_file(char *name, void **ptr, long *size) +{ + char *buf = NULL; + int allocated = 1 * 1024 * 1024; + int len, filled = 0; + + if (!grub_open (name)) + return -1; + + buf = malloc(allocated); + + errnum = 0; + while (1) { + len = grub_read (buf + filled, allocated - filled); + if (! len) { + if (!errnum) + break; + grub_close (); + return -1; + } + filled += len; + if (filled < allocated) + break; + allocated *= 2; + buf = realloc(buf, allocated); + } + grub_close (); + *ptr = buf; + *size = filled; + return 0; +} + +void *kernel_image, *module_image; +long kernel_size, module_size; +char *kernel_arg, *module_arg; + +kernel_t +load_image (char *kernel, char *arg, kernel_t suggested_type, + unsigned long load_flags) +{ + arg = skip_to(0, arg); + if (kernel_image) + free(kernel_image); + kernel_image = NULL; + if (load_file (kernel, &kernel_image, &kernel_size)) + return KERNEL_TYPE_NONE; + if (kernel_arg) + free(kernel_arg); + kernel_arg = strdup(arg); + return KERNEL_TYPE_PV; +} + +int +load_initrd (char *initrd) +{ + if (module_image) + free(module_image); + module_image = NULL; + load_file (initrd, &module_image, &module_size); + return ! errnum; +} + +int +load_module (char *module, char *arg) +{ + if (module_image) + free(module_image); + module_image = NULL; + load_file (module, &module_image, &module_size); + if (module_arg) + free(module_arg); + module_arg = strdup(arg); + return ! errnum; +} + +void +pv_boot (void) +{ + kexec(kernel_image, kernel_size, module_image, module_size, kernel_arg); +} + +/* + * Network + */ + +struct netfront_dev *net_dev; + +int +minios_probe (struct nic *nic) +{ + char *ip; + + if (net_dev) + return 1; + + /* Clear the ARP table. */ + grub_memset ((char *) arptable, 0, + MAX_ARP * sizeof (struct arptable_t)); + + net_dev = init_netfront(NULL, (void*) -1, nic->node_addr, &ip); + if (!net_dev) + return 0; + + return 1; +} + +/* reset adapter */ +static void minios_reset(struct nic *nic) +{ + /* TODO? */ +} + +static void minios_disable(struct nic *nic) +{ +} + +/* Wait for a frame */ +static int minios_poll(struct nic *nic) +{ + return !! (nic->packetlen = netfront_receive(net_dev, (void*) nic->packet, ETH_FRAME_LEN)); +} + +/* Transmit a frame */ +struct frame { + uint8_t dest[ETH_ALEN]; + uint8_t src[ETH_ALEN]; + uint16_t type; + unsigned char data[]; +}; +static void minios_transmit (struct nic *nic, const char *d, unsigned int t, + unsigned int s, const char *p) +{ + struct frame *frame = alloca(sizeof(frame) + s); + + memcpy(frame->dest, d, ETH_ALEN); + memcpy(frame->src, nic->node_addr, ETH_ALEN); + frame->type = htons(t); + memcpy(frame->data, p, s); + + netfront_xmit(net_dev, (void*) frame, sizeof(*frame) + s); +} + +static char packet[ETH_FRAME_LEN]; + +struct nic nic = { + .reset = minios_reset, + .poll = minios_poll, + .transmit = minios_transmit, + .disable = minios_disable, + .flags = 0, + .rom_info = NULL, + .node_addr = arptable[ARP_CLIENT].node, + .packet = packet, + .packetlen = 0, + .priv_data = NULL, +}; + +int +eth_probe (void) +{ + return minios_probe(&nic); +} + +int +eth_poll (void) +{ + return minios_poll (&nic); +} + +void +eth_disable (void) +{ + minios_disable (&nic); +} + +void +eth_transmit (const char *d, unsigned int t, + unsigned int s, const void *p) +{ + minios_transmit (&nic, d, t, s, p); + if (t == IP) + twiddle(); +} + +/* + * Console + */ +void +serial_hw_put (int _c) +{ + char c = _c; + console_print(&c, 1); +} + +int +serial_hw_fetch (void) +{ + char key; + + if (!xencons_ring_avail()) + return -1; + + read(STDIN_FILENO, &key, 1); + switch (key) { + case 0x7f: key = '\b'; break; + } + return key; +} + +/* + * PVFB + */ +struct kbdfront_dev *kbd_dev; +struct fbfront_dev *fb_dev; +static union xenkbd_in_event ev; +static int has_ev; +int console_checkkey (void) +{ + if (has_ev) + return 1; + has_ev = kbdfront_receive(kbd_dev, &ev, 1); + return has_ev; +} + +/* static QWERTY layout, that's what most PC BIOSes do anyway */ +static char linux2ascii[] = { + [ 1 ] = 27, + [ 2 ] = '1', + [ 3 ] = '2', + [ 4 ] = '3', + [ 5 ] = '4', + [ 6 ] = '5', + [ 7 ] = '6', + [ 8 ] = '7', + [ 9 ] = '8', + [ 10 ] = '9', + [ 11 ] = '0', + [ 12 ] = '-', + [ 13 ] = '=', + [ 14 ] = '\b', + [ 15 ] = '\t', + [ 16 ] = 'q', + [ 17 ] = 'w', + [ 18 ] = 'e', + [ 19 ] = 'r', + [ 20 ] = 't', + [ 21 ] = 'y', + [ 22 ] = 'u', + [ 23 ] = 'i', + [ 24 ] = 'o', + [ 25 ] = 'p', + [ 26 ] = '[', + [ 27 ] = ']', + [ 28 ] = '\n', + + [ 30 ] = 'a', + [ 31 ] = 's', + [ 32 ] = 'd', + [ 33 ] = 'f', + [ 34 ] = 'g', + [ 35 ] = 'h', + [ 36 ] = 'j', + [ 37 ] = 'k', + [ 38 ] = 'l', + [ 39 ] = ';', + [ 40 ] = '\'', + [ 41 ] = '`', + + [ 43 ] = '\\', + [ 44 ] = 'z', + [ 45 ] = 'x', + [ 46 ] = 'c', + [ 47 ] = 'v', + [ 48 ] = 'b', + [ 49 ] = 'n', + [ 50 ] = 'm', + [ 51 ] = ',', + [ 52 ] = '.', + [ 53 ] = '/', + + [ 55 ] = '*', + [ 57 ] = ' ', + + [ 71 ] = '7', + [ 72 ] = '8', + [ 73 ] = '9', + [ 74 ] = '-', + [ 75 ] = '4', + [ 76 ] = '5', + [ 77 ] = '6', + [ 78 ] = '+', + [ 79 ] = '1', + [ 80 ] = '2', + [ 81 ] = '3', + [ 82 ] = '0', + [ 83 ] = '.', + + [ 86 ] = '<', + + [ 96 ] = '\n', + + [ 98 ] = '/', + + [ 102 ] = 1, /* home */ + [ 103 ] = 16, /* up */ + [ 104 ] = 7, /* page up */ + [ 105 ] = 2, /* left */ + [ 106 ] = 6, /* right */ + [ 107 ] = 5, /* end */ + [ 108 ] = 14, /* down */ + [ 109 ] = 3, /* page down */ + + [ 111 ] = 4, /* delete */ +}; + +static char linux2ascii_shifted[] = { + [ 1 ] = 27, + [ 2 ] = '!', + [ 3 ] = '@', + [ 4 ] = '#', + [ 5 ] = '$', + [ 6 ] = '%', + [ 7 ] = '^', + [ 8 ] = '&', + [ 9 ] = '*', + [ 10 ] = '(', + [ 11 ] = ')', + [ 12 ] = '_', + [ 13 ] = '+', + [ 14 ] = '\b', + [ 15 ] = '\t', + [ 16 ] = 'Q', + [ 17 ] = 'W', + [ 18 ] = 'E', + [ 19 ] = 'R', + [ 20 ] = 'T', + [ 21 ] = 'Y', + [ 22 ] = 'U', + [ 23 ] = 'I', + [ 24 ] = 'O', + [ 25 ] = 'P', + [ 26 ] = '{', + [ 27 ] = '}', + [ 28 ] = '\n', + + [ 30 ] = 'A', + [ 31 ] = 'S', + [ 32 ] = 'D', + [ 33 ] = 'F', + [ 34 ] = 'G', + [ 35 ] = 'H', + [ 36 ] = 'J', + [ 37 ] = 'K', + [ 38 ] = 'L', + [ 39 ] = ':', + [ 40 ] = '"', + [ 41 ] = '~', + + [ 43 ] = '|', + [ 44 ] = 'Z', + [ 45 ] = 'X', + [ 46 ] = 'C', + [ 47 ] = 'V', + [ 48 ] = 'B', + [ 49 ] = 'N', + [ 50 ] = 'M', + [ 51 ] = '<', + [ 52 ] = '>', + [ 53 ] = '?', + + [ 55 ] = '*', + [ 57 ] = ' ', + + [ 71 ] = '7', + [ 72 ] = '8', + [ 73 ] = '9', + [ 74 ] = '-', + [ 75 ] = '4', + [ 76 ] = '5', + [ 77 ] = '6', + [ 78 ] = '+', + [ 79 ] = '1', + [ 80 ] = '2', + [ 81 ] = '3', + [ 82 ] = '0', + [ 83 ] = '.', + + [ 86 ] = '>', + + [ 96 ] = '\n', + + [ 98 ] = '/', + + [ 102 ] = 1, /* home */ + [ 103 ] = 16, /* up */ + [ 104 ] = 7, /* page up */ + [ 105 ] = 2, /* left */ + [ 106 ] = 6, /* right */ + [ 107 ] = 5, /* end */ + [ 108 ] = 14, /* down */ + [ 109 ] = 3, /* page down */ + + [ 111 ] = 4, /* delete */ +}; + +int console_getkey (void) +{ + static int shift, control, alt, caps_lock; + + if (!has_ev) + has_ev = kbdfront_receive(kbd_dev, &ev, 1); + if (!has_ev) + return 0; + + has_ev = 0; + if (ev.type != XENKBD_TYPE_KEY) + return 0; + + if (ev.key.keycode == 42 || ev.key.keycode == 54) { + caps_lock = 0; + shift = ev.key.pressed; + return 0; + } + if (ev.key.keycode == 58) { + caps_lock ^= 1; + return 0; + } + if (ev.key.keycode == 29 || ev.key.keycode == 97) { + control = ev.key.pressed; + return 0; + } + if (ev.key.keycode == 56) { + alt = ev.key.pressed; + return 0; + } + + if (!ev.key.pressed) + return 0; + + if (ev.key.keycode < sizeof(linux2ascii) / sizeof(*linux2ascii)) { + char val; + if (shift || caps_lock) + val = linux2ascii_shifted[ev.key.keycode]; + else + val = linux2ascii[ev.key.keycode]; + if (control) + val &= ~0x60; + return val; + } + + return 0; +} + +static void kbd_thread(void *p) +{ + struct semaphore *sem = p; + + kbd_dev = init_kbdfront(NULL, 1); + up(sem); +} + +struct fbfront_dev *fb_open(void *fb, int width, int height, int depth) +{ + unsigned long *mfns; + int linesize = width * (depth / 8); + int memsize = linesize * height; + int numpages = (memsize + PAGE_SIZE - 1) / PAGE_SIZE; + DECLARE_MUTEX_LOCKED(sem); + int i; + + create_thread("kbdfront", kbd_thread, &sem); + + mfns = malloc(numpages * sizeof(*mfns)); + for (i = 0; i < numpages; i++) { + memset(fb + i * PAGE_SIZE, 0, PAGE_SIZE); + mfns[i] = virtual_to_mfn(fb + i * PAGE_SIZE); + } + fb_dev = init_fbfront(NULL, mfns, width, height, depth, linesize, numpages); + free(mfns); + + if (!fb_dev) + return NULL; + + down(&sem); + if (!kbd_dev) + return NULL; + + return fb_dev; +} + +void kbd_close(void *foo) +{ + shutdown_kbdfront(kbd_dev); + kbd_dev = NULL; +} + +void fb_close(void) +{ + create_thread("kbdfront close", kbd_close, NULL); + shutdown_fbfront(fb_dev); + fb_dev = NULL; +} + +/* + * Misc + */ + +int getrtsecs (void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec; +} + +int currticks (void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return ((tv.tv_sec * 1000000ULL + tv.tv_usec) * TICKS_PER_SEC) / 1000000; +} + +void __attribute__ ((noreturn)) grub_reboot (void) +{ + for ( ;; ) + { + struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_reboot }; + HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown); + } +} + +#define SCRATCH_MEMSIZE (4 * 1024 * 1024) + +/* Note: not allocating it dynamically permits to make sure it lays below 4G + * for grub's 32bit pointers to work */ +char grub_scratch_mem[SCRATCH_MEMSIZE] __attribute__((aligned(PAGE_SIZE))); + +int main(int argc, char *argv[]) +{ + if (argc > 1) { + strncpy(config_file, argv[1], sizeof(config_file) - 1); + config_file[sizeof(config_file) - 1] = 0; + if (!strncmp(config_file, "(nd)", 4)) + preset_menu = "dhcp"; + } else + preset_menu = "dhcp --with-configfile"; + + mbi.drives_addr = BOOTSEC_LOCATION + (60 * 1024); + mbi.drives_length = 0; + + mbi.boot_loader_name = (unsigned long) "GNU GRUB " VERSION; + mbi.mem_lower = (start_info.nr_pages * PAGE_SIZE) / 1024; + mbi.mem_upper = 0; + saved_drive = boot_drive; + saved_partition = install_partition; + + init_disk(); + + /* Try to make sure the client part got launched */ + sleep(1); + cmain(); + printk("cmain returned!\n"); +} diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/mini-os.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/grub/mini-os.h Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,5 @@ +extern int blk_nb; +extern struct blkfront_dev **blk_dev; +extern struct netfront_dev *net_dev; +extern struct kbdfront_dev *kbd_dev; +extern struct fbfront_dev *fb_dev; diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/osdep.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stubdom/grub/osdep.h Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,30 @@ +#ifndef __OSDEP_H__ +#define __OSDEP_H__ + +#include <byteswap.h> +#define swap32(x) bswap_32(x) +#define swap16(x) bswap_16(x) + +#include <machine/endian.h> +#if BYTE_ORDER == BIG_ENDIAN +#define htons(x) (x) +#define ntohs(x) (x) +#define htonl(x) (x) +#define ntohl(x) (x) +#else +#define htons(x) swap16(x) +#define ntohs(x) swap16(x) +#define htonl(x) swap32(x) +#define ntohl(x) swap32(x) +#endif + +typedef unsigned long Address; + +/* ANSI prototyping macro */ +#ifdef __STDC__ +#define P(x) x +#else +#define P(x) () +#endif + +#endif diff -r 1201c7657832 -r 0034766b45c2 tools/console/daemon/io.c --- a/tools/console/daemon/io.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/console/daemon/io.c Thu Jun 19 12:46:26 2008 +0900 @@ -525,7 +525,8 @@ static int domain_create_ring(struct dom } else dom->use_consolepath = 0; - sprintf(path, "%s/type", dom->use_consolepath ? dom->conspath: dom->serialpath); + snprintf(path, sizeof(path), "%s/type", + dom->use_consolepath ? dom->conspath: dom->serialpath); type = xs_read(xs, XBT_NULL, path, NULL); if (type && strcmp(type, "xenconsoled") != 0) { free(type); diff -r 1201c7657832 -r 0034766b45c2 tools/examples/xmexample.hvm --- a/tools/examples/xmexample.hvm Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/examples/xmexample.hvm Thu Jun 19 12:46:26 2008 +0900 @@ -256,16 +256,16 @@ serial='pty' #vcpus=5 # # Downgrade the cpuid to make a better compatibility for migration : -# Look like a PIII : -# cpuid = [ '0:eax=0x3', +# Look like a generic 686 : +# cpuid = [ '0:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0', # '1:eax=0x06b1, # ecx=xxxxxxxxxx0000xx00xxx0000000xx0, # edx=xx00000xxxxxxx0xxxxxxxxx0xxxxxx', -# '4:eax=0x3,ebx=0x756e6547,ecx=0x6c65746e,edx=0x49656e69', -# '0x80000000:eax=0x3,ebx=0x756e6547,ecx=0x6c65746e,edx=0x49656e69'] +# '4:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0', +# '0x80000000:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0'] # with the highest leaf # - CPUID.0[EAX] : Set the highest leaf -# - CPUID.1[EAX] : Pentium III +# - CPUID.1[EAX] : 686 # - CPUID.1[ECX] : Mask some features # - CPUID.1[EDX] : Mask some features # - CPUID.4 : Reply like the highest leaf, in our case CPUID.3 diff -r 1201c7657832 -r 0034766b45c2 tools/firmware/rombios/rombios.c --- a/tools/firmware/rombios/rombios.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/firmware/rombios/rombios.c Thu Jun 19 12:46:26 2008 +0900 @@ -2311,10 +2311,31 @@ debugger_off() #define ACPI_FACS_OFFSET 0x10 /* S3 resume status in CMOS 0Fh shutdown status byte*/ +Bit32u facs_get32(offs) +Bit16u offs; +{ +ASM_START + push bp + mov bp, sp + + push ds + mov ax, #(ACPI_FACS_ADDRESS >> 4) + mov ds, ax + + mov bx, 4[bp] + mov ax, [bx] + mov dx, 2[bx] + pop ds + + pop bp +ASM_END +} + + void s3_resume() { - Bit16u s3_wakeup_vector; + Bit32u s3_wakeup_vector; extern Bit16u s3_wakeup_ip; extern Bit16u s3_wakeup_cs; extern Bit8u s3_resume_flag; @@ -2330,19 +2351,14 @@ ASM_END } s3_resume_flag = 0; -ASM_START - mov ax, #0x0 - mov ds, ax -ASM_END - /* get x_firmware_waking_vector */ - s3_wakeup_vector = *((Bit16u*)(ACPI_FACS_ADDRESS+ACPI_FACS_OFFSET+24)); - if (s3_wakeup_vector == 0){ + s3_wakeup_vector = facs_get32(ACPI_FACS_OFFSET+24); + if (!s3_wakeup_vector) { /* get firmware_waking_vector */ - s3_wakeup_vector = *((Bit16u*)(ACPI_FACS_ADDRESS+ACPI_FACS_OFFSET+12)); - if (s3_wakeup_vector == 0){ + s3_wakeup_vector = facs_get32(ACPI_FACS_OFFSET+12); + if (!s3_wakeup_vector) { goto s3_out; - } + } } /* setup wakeup vector */ @@ -2350,13 +2366,6 @@ ASM_END s3_wakeup_cs = s3_wakeup_vector >> 4; ASM_START - mov bx, [_s3_wakeup_cs] - mov dx, [_s3_wakeup_ip] - - mov ax, #0xF000 - mov ds, ax - mov [_s3_wakeup_cs], bx - mov [_s3_wakeup_ip], dx jmpf [_s3_wakeup_ip] ; S3 data diff -r 1201c7657832 -r 0034766b45c2 tools/fs-back/fs-ops.c --- a/tools/fs-back/fs-ops.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/fs-back/fs-ops.c Thu Jun 19 12:46:26 2008 +0900 @@ -55,7 +55,8 @@ void dispatch_file_open(struct mount *mo printf("File open issued for %s\n", file_name); assert(BUFFER_SIZE > strlen(file_name) + strlen(mount->export->export_path) + 1); - sprintf(full_path, "%s/%s", mount->export->export_path, file_name); + snprintf(full_path, sizeof(full_path), "%s/%s", + mount->export->export_path, file_name); assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0); printf("Issuing open for %s\n", full_path); fd = open(full_path, O_RDWR); @@ -311,7 +312,8 @@ void dispatch_remove(struct mount *mount printf("File remove issued for %s\n", file_name); assert(BUFFER_SIZE > strlen(file_name) + strlen(mount->export->export_path) + 1); - sprintf(full_path, "%s/%s", mount->export->export_path, file_name); + snprintf(full_path, sizeof(full_path), "%s/%s", + mount->export->export_path, file_name); assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0); printf("Issuing remove for %s\n", full_path); ret = remove(full_path); @@ -355,8 +357,10 @@ void dispatch_rename(struct mount *mount strlen(old_file_name) + strlen(mount->export->export_path) + 1); assert(BUFFER_SIZE > strlen(new_file_name) + strlen(mount->export->export_path) + 1); - sprintf(old_full_path, "%s/%s", mount->export->export_path, old_file_name); - sprintf(new_full_path, "%s/%s", mount->export->export_path, new_file_name); + snprintf(old_full_path, sizeof(old_full_path), "%s/%s", + mount->export->export_path, old_file_name); + snprintf(new_full_path, sizeof(new_full_path), "%s/%s", + mount->export->export_path, new_file_name); assert(xc_gnttab_munmap(mount->gnth, buf, 1) == 0); printf("Issuing rename for %s -> %s\n", old_full_path, new_full_path); ret = rename(old_full_path, new_full_path); @@ -398,7 +402,8 @@ void dispatch_create(struct mount *mount printf("File create issued for %s\n", file_name); assert(BUFFER_SIZE > strlen(file_name) + strlen(mount->export->export_path) + 1); - sprintf(full_path, "%s/%s", mount->export->export_path, file_name); + snprintf(full_path, sizeof(full_path), "%s/%s", + mount->export->export_path, file_name); assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0); /* We can advance the request consumer index, from here on, the request * should not be used (it may be overrinden by a response) */ @@ -447,7 +452,8 @@ void dispatch_list(struct mount *mount, printf("Dir list issued for %s\n", file_name); assert(BUFFER_SIZE > strlen(file_name) + strlen(mount->export->export_path) + 1); - sprintf(full_path, "%s/%s", mount->export->export_path, file_name); + snprintf(full_path, sizeof(full_path), "%s/%s", + mount->export->export_path, file_name); /* We can advance the request consumer index, from here on, the request * should not be used (it may be overrinden by a response) */ mount->ring.req_cons++; @@ -540,7 +546,8 @@ void dispatch_fs_space(struct mount *mou printf("Fs space issued for %s\n", file_name); assert(BUFFER_SIZE > strlen(file_name) + strlen(mount->export->export_path) + 1); - sprintf(full_path, "%s/%s", mount->export->export_path, file_name); + snprintf(full_path, sizeof(full_path), "%s/%s", + mount->export->export_path, file_name); assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0); printf("Issuing fs space for %s\n", full_path); ret = statfs(full_path, &stat); diff -r 1201c7657832 -r 0034766b45c2 tools/fs-back/fs-xenbus.c --- a/tools/fs-back/fs-xenbus.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/fs-back/fs-xenbus.c Thu Jun 19 12:46:26 2008 +0900 @@ -22,8 +22,8 @@ static bool xenbus_printf(struct xs_hand va_list args; va_start(args, fmt); - sprintf(fullpath,"%s/%s", node, path); - vsprintf(val, fmt, args); + snprintf(fullpath, sizeof(fullpath), "%s/%s", node, path); + vsnprintf(val, sizeof(val), fmt, args); va_end(args); printf("xenbus_printf (%s) <= %s.\n", fullpath, val); @@ -72,7 +72,7 @@ int xenbus_register_export(struct fs_exp printf("XS transaction is %d\n", xst); /* Create node string */ - sprintf(node, "%s/%d", EXPORTS_NODE, export->export_id); + snprintf(node, sizeof(node), "%s/%d", EXPORTS_NODE, export->export_id); /* Remove old export (if exists) */ xs_rm(xsh, xst, node); @@ -116,20 +116,20 @@ void xenbus_read_mount_request(struct mo assert(xsh != NULL); #if 0 - sprintf(node, WATCH_NODE"/%d/%d/frontend", + snprintf(node, sizeof(node), WATCH_NODE"/%d/%d/frontend", mount->dom_id, mount->export->export_id); frontend = xs_read(xsh, XBT_NULL, node, NULL); #endif mount->frontend = frontend; - sprintf(node, "%s/state", frontend); + snprintf(node, sizeof(node), "%s/state", frontend); s = xs_read(xsh, XBT_NULL, node, NULL); assert(strcmp(s, STATE_READY) == 0); free(s); - sprintf(node, "%s/ring-ref", frontend); + snprintf(node, sizeof(node), "%s/ring-ref", frontend); s = xs_read(xsh, XBT_NULL, node, NULL); mount->gref = atoi(s); free(s); - sprintf(node, "%s/event-channel", frontend); + snprintf(node, sizeof(node), "%s/event-channel", frontend); s = xs_read(xsh, XBT_NULL, node, NULL); mount->remote_evtchn = atoi(s); free(s); @@ -158,12 +158,12 @@ void xenbus_write_backend_node(struct mo assert(xsh != NULL); self_id = get_self_id(); printf("Our own dom_id=%d\n", self_id); - sprintf(node, "%s/backend", mount->frontend); - sprintf(backend_node, "/local/domain/%d/"ROOT_NODE"/%d", + snprintf(node, sizeof(node), "%s/backend", mount->frontend); + snprintf(backend_node, sizeof(backend_node), "/local/domain/%d/"ROOT_NODE"/%d", self_id, mount->mount_id); xs_write(xsh, XBT_NULL, node, backend_node, strlen(backend_node)); - sprintf(node, ROOT_NODE"/%d/state", mount->mount_id); + snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id); xs_write(xsh, XBT_NULL, node, STATE_INITIALISED, strlen(STATE_INITIALISED)); } @@ -174,7 +174,7 @@ void xenbus_write_backend_ready(struct m assert(xsh != NULL); self_id = get_self_id(); - sprintf(node, ROOT_NODE"/%d/state", mount->mount_id); + snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id); xs_write(xsh, XBT_NULL, node, STATE_READY, strlen(STATE_READY)); } diff -r 1201c7657832 -r 0034766b45c2 tools/include/xen-sys/NetBSD/privcmd.h --- a/tools/include/xen-sys/NetBSD/privcmd.h Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/include/xen-sys/NetBSD/privcmd.h Thu Jun 19 12:46:26 2008 +0900 @@ -36,6 +36,7 @@ typedef struct privcmd_hypercall { unsigned long op; unsigned long arg[5]; + long retval; } privcmd_hypercall_t; typedef struct privcmd_mmap_entry { diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/Makefile.target --- a/tools/ioemu/Makefile.target Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/Makefile.target Thu Jun 19 12:46:26 2008 +0900 @@ -358,13 +358,6 @@ endif endif ifdef CONFIG_STUBDOM -VL_OBJS+=main-qemu.o -CFLAGS += -DCONFIG_QEMU -main-qemu.c: - ln -s $(XEN_ROOT)/extras/mini-os/main.c $@ -endif - -ifdef CONFIG_STUBDOM #CONFIG_PASSTHROUGH=1 else ifeq (,$(wildcard /usr/include/pci)) @@ -444,7 +437,11 @@ VL_OBJS+= xen_machine_fv.o VL_OBJS+= xen_machine_fv.o VL_OBJS+= xen_machine_pv.o VL_OBJS+= xenfb.o +ifdef CONFIG_STUBDOM +VL_OBJS+= xenfbfront.o +endif VL_OBJS+= xen_console.o +VL_OBJS+= pci_emulation.o ifndef CONFIG_STUBDOM VL_OBJS+= tpm_tis.o VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/cocoa.m --- a/tools/ioemu/cocoa.m Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/cocoa.m Thu Jun 19 12:46:26 2008 +0900 @@ -96,7 +96,7 @@ static void cocoa_update(DisplayState *d cocoa_resize ------------------------------------------------------ */ -static void cocoa_resize(DisplayState *ds, int w, int h, int linesize) +static void cocoa_resize(DisplayState *ds, int w, int h) { const int device_bpp = 32; static void *screen_pixels; diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/pc.c --- a/tools/ioemu/hw/pc.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/hw/pc.c Thu Jun 19 12:46:26 2008 +0900 @@ -1090,6 +1090,13 @@ static void pc_init1(uint64_t ram_size, } } #endif /* !CONFIG_DM */ + + if (pci_enabled) { + PCI_EMULATION_INFO *p; + for (p = PciEmulationInfoHead; p != NULL; p = p->next) { + pci_emulation_init(pci_bus, p); + } + } } static void pc_init_pci(uint64_t ram_size, int vga_ram_size, char *boot_device, diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/pci_emulation.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/hw/pci_emulation.c Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,118 @@ +/* + * Changes to PCI emulation made by Marathon Technologies, June 2008 + */ + +#include "vl.h" + +typedef struct { + PCIDevice dev; +} PCI_EMULATION_State; + +void parse_pci_emulation_info(char *config_text, PCI_EMULATION_INFO *pci_emulation_info) +{ + char *p; + int i; + int ret; + for (p = config_text, i = 0; *p != '\0'; p++) { + if (*p == ':') { + break; + } + if (i < sizeof(pci_emulation_info->name) - 1) { + pci_emulation_info->name[i] = *p; + i++; + } + } + pci_emulation_info->name[i] = '\0'; + if (*p == '\0') return; + p++; + ret = sscanf(p, "%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x", + &(pci_emulation_info->vendorid), + &(pci_emulation_info->deviceid), + &(pci_emulation_info->command), + &(pci_emulation_info->status), + &(pci_emulation_info->revision), + &(pci_emulation_info->classcode), + &(pci_emulation_info->headertype), + &(pci_emulation_info->subvendorid), + &(pci_emulation_info->subsystemid), + &(pci_emulation_info->interruputline), + &(pci_emulation_info->interruputpin)); +#ifdef DEBUG + fprintf(logfile, "qemu: pciemulation %s:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x\n", + pci_emulation_info->name, + pci_emulation_info->vendorid, + pci_emulation_info->deviceid, + pci_emulation_info->command, + pci_emulation_info->status, + pci_emulation_info->revision, + pci_emulation_info->classcode, + pci_emulation_info->headertype, + pci_emulation_info->subvendorid, + pci_emulation_info->subsystemid, + pci_emulation_info->interruputline, + pci_emulation_info->interruputpin); +#endif + return; +} + +static void pci_emulation_save(QEMUFile *f, void *opaque) +{ + PCIDevice *d = opaque; + + pci_device_save(d, f); +} + +static int pci_emulation_load(QEMUFile *f, void *opaque, int version_id) +{ + PCIDevice *d = opaque; + + if (version_id != 1) + return -EINVAL; + + return pci_device_load(d, f); +} + + +void pci_emulation_init(PCIBus *bus, PCI_EMULATION_INFO *pci_emulation_info) +{ + int instance_id; + PCI_EMULATION_State *d; + uint8_t *pci_conf; + +#ifdef DEBUG + fprintf(logfile, "qemu: pciinit\n"); +#endif + + d = (PCI_EMULATION_State *)pci_register_device(bus, + pci_emulation_info->name, + sizeof(PCI_EMULATION_State), + -1, + NULL, NULL); + pci_conf = d->dev.config; + pci_conf[0x00] = pci_emulation_info->vendorid & 0xff; + pci_conf[0x01] = (pci_emulation_info->vendorid & 0xff00) >> 8; + pci_conf[0x02] = pci_emulation_info->deviceid & 0xff; + pci_conf[0x03] = (pci_emulation_info->deviceid & 0xff00) >> 8; + pci_conf[0x04] = pci_emulation_info->command & 0xff; + pci_conf[0x05] = (pci_emulation_info->command & 0xff00) >> 8; + pci_conf[0x06] = pci_emulation_info->status & 0xff; + pci_conf[0x07] = (pci_emulation_info->status & 0xff00) >> 8; + pci_conf[0x08] = pci_emulation_info->revision & 0xff; + pci_conf[0x09] = pci_emulation_info->classcode & 0xff; + pci_conf[0x0a] = (pci_emulation_info->classcode & 0xff00) >> 8; + pci_conf[0x0b] = (pci_emulation_info->classcode & 0xff0000) >> 16; + pci_conf[0x0e] = pci_emulation_info->headertype & 0xff; + pci_conf[0x2c] = pci_emulation_info->subvendorid & 0xff; + pci_conf[0x2d] = (pci_emulation_info->subvendorid & 0xff00) >> 8; + pci_conf[0x2e] = pci_emulation_info->subsystemid & 0xff; + pci_conf[0x2f] = (pci_emulation_info->subsystemid & 0xff00) >> 8; + pci_conf[0x3c] = pci_emulation_info->interruputline & 0xff; + pci_conf[0x3d] = pci_emulation_info->interruputpin & 0xff; + + instance_id = pci_bus_num(bus) << 8 | d->dev.devfn; + register_savevm(pci_emulation_info->name, instance_id, + 1, pci_emulation_save, pci_emulation_load, d); + + + return; +} diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/pci_emulation.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/hw/pci_emulation.h Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,24 @@ +/* + * Changes to PCI emulation made by Marathon Technologies, June 2008 + */ + +typedef struct PCI_EMULATION_INFO_t { + struct PCI_EMULATION_INFO_t *next; + char name[32]; + unsigned int vendorid; + unsigned int deviceid; + unsigned int command; + unsigned int status; + unsigned int revision; + unsigned int classcode; + unsigned int headertype; + unsigned int subvendorid; + unsigned int subsystemid; + unsigned int interruputline; + unsigned int interruputpin; +} PCI_EMULATION_INFO; + +void parse_pci_emulation_info(char *config_text, PCI_EMULATION_INFO *pci_emulation_info); +void pci_emulation_init(PCIBus *bus, PCI_EMULATION_INFO *pci_emulation_info); + +extern PCI_EMULATION_INFO *PciEmulationInfoHead; diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/pl110.c --- a/tools/ioemu/hw/pl110.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/hw/pl110.c Thu Jun 19 12:46:26 2008 +0900 @@ -262,7 +262,7 @@ static void pl110_resize(pl110_state *s, { if (width != s->cols || height != s->rows) { if (pl110_enabled(s)) { - dpy_resize(s->ds, width, height, width * 4); + dpy_resize(s->ds, width, height); } } s->cols = width; @@ -375,7 +375,7 @@ static void pl110_write(void *opaque, ta s->cr = val; s->bpp = (val >> 1) & 7; if (pl110_enabled(s)) { - dpy_resize(s->ds, s->cols, s->rows, s->cols * 4); + dpy_resize(s->ds, s->cols, s->rows); } break; case 10: /* LCDICR */ diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/tcx.c --- a/tools/ioemu/hw/tcx.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/hw/tcx.c Thu Jun 19 12:46:26 2008 +0900 @@ -342,7 +342,7 @@ void tcx_init(DisplayState *ds, uint32_t register_savevm("tcx", addr, 1, tcx_save, tcx_load, s); qemu_register_reset(tcx_reset, s); tcx_reset(s); - dpy_resize(s->ds, width, height, width * 1); + dpy_resize(s->ds, width, height); } static void tcx_screen_dump(void *opaque, const char *filename) diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/usb-msd.c --- a/tools/ioemu/hw/usb-msd.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/hw/usb-msd.c Thu Jun 19 12:46:26 2008 +0900 @@ -510,7 +510,7 @@ static void usb_msd_handle_destroy(USBDe qemu_free(s); } -USBDevice *usb_msd_init(const char *filename) +USBDevice *usb_msd_init(const char *filename, BlockDriver *drv) { MSDState *s; BlockDriverState *bdrv; @@ -520,7 +520,7 @@ USBDevice *usb_msd_init(const char *file return NULL; bdrv = bdrv_new("usb"); - if (bdrv_open(bdrv, filename, 0) < 0) + if (bdrv_open2(bdrv, filename, 0, drv) < 0) goto fail; s->bs = bdrv; diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/usb.h --- a/tools/ioemu/hw/usb.h Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/hw/usb.h Thu Jun 19 12:46:26 2008 +0900 @@ -217,7 +217,7 @@ USBDevice *usb_tablet_init(void); USBDevice *usb_tablet_init(void); /* usb-msd.c */ -USBDevice *usb_msd_init(const char *filename); +USBDevice *usb_msd_init(const char *filename, BlockDriver *drv); /* usb.c */ void generic_usb_save(QEMUFile* f, void *opaque); diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/vga.c --- a/tools/ioemu/hw/vga.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/hw/vga.c Thu Jun 19 12:46:26 2008 +0900 @@ -1089,40 +1089,6 @@ static void vga_draw_text(VGAState *s, i /* Disable dirty bit tracking */ xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL); - if (s->ds->dpy_colourdepth != NULL && s->ds->depth != 0) - s->ds->dpy_colourdepth(s->ds, 0); - s->rgb_to_pixel = - rgb_to_pixel_dup_table[get_depth_index(s->ds)]; - - full_update |= update_palette16(s); - palette = s->last_palette; - - /* compute font data address (in plane 2) */ - v = s->sr[3]; - offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2; - if (offset != s->font_offsets[0]) { - s->font_offsets[0] = offset; - full_update = 1; - } - font_base[0] = s->vram_ptr + offset; - - offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2; - font_base[1] = s->vram_ptr + offset; - if (offset != s->font_offsets[1]) { - s->font_offsets[1] = offset; - full_update = 1; - } - if (s->plane_updated & (1 << 2)) { - /* if the plane 2 was modified since the last display, it - indicates the font may have been modified */ - s->plane_updated = 0; - full_update = 1; - } - full_update |= update_basic_params(s); - - line_offset = s->line_offset; - s1 = s->vram_ptr + (s->start_addr * 4); - /* total width & height */ cheight = (s->cr[9] & 0x1f) + 1; cw = 8; @@ -1130,7 +1096,6 @@ static void vga_draw_text(VGAState *s, i cw = 9; if (s->sr[1] & 0x08) cw = 16; /* NOTE: no 18 pixel wide */ - x_incr = cw * ((s->ds->depth + 7) >> 3); width = (s->cr[0x01] + 1); if (s->cr[0x06] == 100) { /* ugly hack for CGA 160x100x16 - explain me the logic */ @@ -1146,17 +1111,52 @@ static void vga_draw_text(VGAState *s, i return; } + s->last_scr_width = width * cw; + s->last_scr_height = height * cheight; if (width != s->last_width || height != s->last_height || - cw != s->last_cw || cheight != s->last_ch) { - s->last_scr_width = width * cw; - s->last_scr_height = height * cheight; - dpy_resize(s->ds, s->last_scr_width, s->last_scr_height, s->last_scr_width * (s->ds->depth / 8)); - s->last_width = width; - s->last_height = height; - s->last_ch = cheight; - s->last_cw = cw; + cw != s->last_cw || cheight != s->last_ch || s->last_depth) { + dpy_resize(s->ds, s->last_scr_width, s->last_scr_height); + s->last_depth = 0; full_update = 1; } + s->last_width = width; + s->last_height = height; + s->last_ch = cheight; + s->last_cw = cw; + + s->rgb_to_pixel = + rgb_to_pixel_dup_table[get_depth_index(s->ds)]; + + full_update |= update_palette16(s); + palette = s->last_palette; + + x_incr = cw * ((s->ds->depth + 7) >> 3); + /* compute font data address (in plane 2) */ + v = s->sr[3]; + offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2; + if (offset != s->font_offsets[0]) { + s->font_offsets[0] = offset; + full_update = 1; + } + font_base[0] = s->vram_ptr + offset; + + offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2; + font_base[1] = s->vram_ptr + offset; + if (offset != s->font_offsets[1]) { + s->font_offsets[1] = offset; + full_update = 1; + } + if (s->plane_updated & (1 << 2)) { + /* if the plane 2 was modified since the last display, it + indicates the font may have been modified */ + s->plane_updated = 0; + full_update = 1; + } + full_update |= update_basic_params(s); + + line_offset = s->line_offset; + s1 = s->vram_ptr + (s->start_addr * 4); + cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr; if (cursor_offset != s->cursor_offset || s->cr[0xa] != s->cursor_start || @@ -1501,16 +1501,6 @@ static void vga_draw_graphic(VGAState *s s->get_resolution(s, &width, &height); disp_width = width; - ds_depth = s->ds->depth; - depth = s->get_bpp(s); - if (s->ds->dpy_colourdepth != NULL && - (ds_depth != depth || !s->ds->shared_buf)) - s->ds->dpy_colourdepth(s->ds, depth); - if (ds_depth != s->ds->depth) full_update = 1; - - s->rgb_to_pixel = - rgb_to_pixel_dup_table[get_depth_index(s->ds)]; - shift_control = (s->gr[0x05] >> 5) & 3; double_scan = (s->cr[0x09] >> 7); if (shift_control != 1) { @@ -1527,12 +1517,44 @@ static void vga_draw_graphic(VGAState *s s->shift_control = shift_control; s->double_scan = double_scan; } - + if (shift_control == 1 && (s->sr[0x01] & 8)) { + disp_width <<= 1; + } + + ds_depth = s->ds->depth; + depth = s->get_bpp(s); + if (s->ds->dpy_resize_shared) { + if (s->line_offset != s->last_line_offset || + disp_width != s->last_width || + height != s->last_height || + s->last_depth != depth) { + dpy_resize_shared(s->ds, disp_width, height, depth, s->line_offset, s->vram_ptr + (s->start_addr * 4)); + s->last_scr_width = disp_width; + s->last_scr_height = height; + s->last_width = disp_width; + s->last_height = height; + s->last_line_offset = s->line_offset; + s->last_depth = depth; + full_update = 1; + } else if (s->ds->shared_buf && (full_update || s->ds->data != s->vram_ptr + (s->start_addr * 4))) + s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4)); + } else if (disp_width != s->last_width || + height != s->last_height) { + dpy_resize(s->ds, disp_width, height); + s->last_scr_width = disp_width; + s->last_scr_height = height; + s->last_width = disp_width; + s->last_height = height; + full_update = 1; + } + + s->rgb_to_pixel = + rgb_to_pixel_dup_table[get_depth_index(s->ds)]; + if (shift_control == 0) { full_update |= update_palette16(s); if (s->sr[0x01] & 8) { v = VGA_DRAW_LINE4D2; - disp_width <<= 1; } else { v = VGA_DRAW_LINE4; } @@ -1541,7 +1563,6 @@ static void vga_draw_graphic(VGAState *s full_update |= update_palette16(s); if (s->sr[0x01] & 8) { v = VGA_DRAW_LINE2D2; - disp_width <<= 1; } else { v = VGA_DRAW_LINE2; } @@ -1579,19 +1600,6 @@ static void vga_draw_graphic(VGAState *s } vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)]; - if (s->line_offset != s->last_line_offset || - disp_width != s->last_width || - height != s->last_height) { - dpy_resize(s->ds, disp_width, height, s->line_offset); - s->last_scr_width = disp_width; - s->last_scr_height = height; - s->last_width = disp_width; - s->last_height = height; - s->last_line_offset = s->line_offset; - full_update = 1; - } - if (s->ds->shared_buf && (full_update || s->ds->data != s->vram_ptr + (s->start_addr * 4))) - s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4)); if (!s->ds->shared_buf && s->cursor_invalidate) s->cursor_invalidate(s); @@ -2143,6 +2151,11 @@ void vga_common_init(VGAState *s, Displa /* Video RAM must be 128-bit aligned for SSE optimizations later */ /* and page-aligned for PVFB memory sharing */ s->vram_ptr = s->vram_alloc = qemu_memalign(TARGET_PAGE_SIZE, vga_ram_size); + +#ifdef CONFIG_STUBDOM + if (!cirrus_vga_enabled) + xenfb_pv_display_start(s->vram_ptr); +#endif s->vram_offset = vga_ram_offset; s->vram_size = vga_ram_size; @@ -2311,7 +2324,7 @@ static void vga_save_dpy_update(DisplayS { } -static void vga_save_dpy_resize(DisplayState *s, int w, int h, int linesize) +static void vga_save_dpy_resize(DisplayState *s, int w, int h) { s->linesize = w * 4; s->data = qemu_malloc(h * s->linesize); diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/vga_int.h --- a/tools/ioemu/hw/vga_int.h Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/hw/vga_int.h Thu Jun 19 12:46:26 2008 +0900 @@ -135,6 +135,7 @@ uint8_t last_cw, last_ch; \ uint32_t last_width, last_height; /* in chars or pixels */ \ uint32_t last_scr_width, last_scr_height; /* in pixels */ \ + uint32_t last_depth; /* in bits */ \ uint8_t cursor_start, cursor_end; \ uint32_t cursor_offset; \ unsigned int (*rgb_to_pixel)(unsigned int r, \ diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/xenfb.c --- a/tools/ioemu/hw/xenfb.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/hw/xenfb.c Thu Jun 19 12:46:26 2008 +0900 @@ -19,12 +19,6 @@ #include "xenfb.h" -#ifdef CONFIG_STUBDOM -#include <semaphore.h> -#include <sched.h> -#include <fbfront.h> -#endif - #ifndef BTN_LEFT #define BTN_LEFT 0x110 /* from <linux/input.h> */ #endif @@ -90,7 +84,7 @@ static int xenfb_register_console(struct * Scancodes are hardware-specific. These maps assumes a * standard AT or PS/2 keyboard which is what QEMU feeds us. */ -static const unsigned char atkbd_set2_keycode[512] = { +const unsigned char atkbd_set2_keycode[512] = { 0, 67, 65, 63, 61, 59, 60, 88, 0, 68, 66, 64, 62, 15, 41,117, 0, 56, 42, 93, 29, 16, 2, 0, 0, 0, 44, 31, 30, 17, 3, 0, @@ -112,7 +106,7 @@ static const unsigned char atkbd_set2_ke }; -static const unsigned char atkbd_unxlate_table[128] = { +const unsigned char atkbd_unxlate_table[128] = { 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13, 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27, @@ -587,10 +581,10 @@ static void xenfb_on_fb_event(struct xen event->resize.offset, event->resize.stride) < 0) break; - dpy_colourdepth(xenfb->ds, xenfb->depth); - dpy_resize(xenfb->ds, xenfb->width, xenfb->height, xenfb->row_stride); - if (xenfb->ds->shared_buf) - dpy_setdata(xenfb->ds, xenfb->pixels + xenfb->offset); + if (xenfb->ds->dpy_resize_shared) + dpy_resize_shared(xenfb->ds, xenfb->width, xenfb->height, xenfb->depth, xenfb->row_stride, xenfb->pixels + xenfb->offset); + else + dpy_resize(xenfb->ds, xenfb->width, xenfb->height); xenfb_invalidate(xenfb); break; } @@ -1324,10 +1318,10 @@ static int xenfb_register_console(struct xenfb_invalidate, xenfb_screen_dump, xenfb); - dpy_colourdepth(xenfb->ds, xenfb->depth); - dpy_resize(xenfb->ds, xenfb->width, xenfb->height, xenfb->row_stride); - if (xenfb->ds->shared_buf) - dpy_setdata(xenfb->ds, xenfb->pixels); + if (xenfb->ds->dpy_resize_shared) + dpy_resize_shared(xenfb->ds, xenfb->width, xenfb->height, xenfb->depth, xenfb->row_stride, xenfb->pixels + xenfb->offset); + else + dpy_resize(xenfb->ds, xenfb->width, xenfb->height); if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, xenfb_dispatch_channel, NULL, xenfb) < 0) return -1; @@ -1337,323 +1331,6 @@ static int xenfb_register_console(struct fprintf(stderr, "Xen Framebuffer registered\n"); return 0; } - -#ifdef CONFIG_STUBDOM -typedef struct XenFBState { - struct semaphore kbd_sem; - struct kbdfront_dev *kbd_dev; - struct fbfront_dev *fb_dev; - void *vga_vram, *nonshared_vram; - DisplayState *ds; -} XenFBState; - -XenFBState *xs; - -static char *kbd_path, *fb_path; - -static unsigned char linux2scancode[KEY_MAX + 1]; - -int xenfb_connect_vkbd(const char *path) -{ - kbd_path = strdup(path); - return 0; -} - -int xenfb_connect_vfb(const char *path) -{ - fb_path = strdup(path); - return 0; -} - -static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h) -{ - XenFBState *xs = ds->opaque; - struct fbfront_dev *fb_dev = xs->fb_dev; - if (!fb_dev) - return; - fbfront_update(fb_dev, x, y, w, h); -} - -static void xenfb_pv_resize(DisplayState *ds, int w, int h, int linesize) -{ - XenFBState *xs = ds->opaque; - struct fbfront_dev *fb_dev = xs->fb_dev; - fprintf(stderr,"resize to %dx%d, %d required\n", w, h, linesize); - ds->width = w; - ds->height = h; - if (!linesize) - ds->shared_buf = 0; - if (!ds->shared_buf) - linesize = w * 4; - ds->linesize = linesize; - if (!fb_dev) - return; - if (ds->shared_buf) { - ds->data = NULL; - } else { - ds->data = xs->nonshared_vram; - fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE); - } -} - -static void xenfb_pv_colourdepth(DisplayState *ds, int depth) -{ - XenFBState *xs = ds->opaque; - struct fbfront_dev *fb_dev = xs->fb_dev; - static int lastdepth = -1; - if (!depth) { - ds->shared_buf = 0; - ds->depth = 32; - } else { - ds->shared_buf = 1; - ds->depth = depth; - } - if (depth != lastdepth) { - fprintf(stderr,"redepth to %d required\n", depth); - lastdepth = depth; - } else return; - if (!fb_dev) - return; - if (ds->shared_buf) { - ds->data = NULL; - } else { - ds->data = xs->nonshared_vram; - fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, VGA_RAM_SIZE); - } -} - -static void xenfb_pv_setdata(DisplayState *ds, void *pixels) -{ - XenFBState *xs = ds->opaque; - struct fbfront_dev *fb_dev = xs->fb_dev; - int offset = pixels - xs->vga_vram; - ds->data = pixels; - if (!fb_dev) - return; - fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset); -} - -static void xenfb_pv_refresh(DisplayState *ds) -{ - vga_hw_update(); -} - -static void xenfb_fb_handler(void *opaque) -{ -#define FB_NUM_BATCH 4 - union xenfb_in_event buf[FB_NUM_BATCH]; - int n, i; - XenFBState *xs = opaque; - DisplayState *ds = xs->ds; - - n = fbfront_receive(xs->fb_dev, buf, FB_NUM_BATCH); - for (i = 0; i < n; i++) { - switch (buf[i].type) { - case XENFB_TYPE_REFRESH_PERIOD: - if (buf[i].refresh_period.period == XENFB_NO_REFRESH) { - /* Sleeping interval */ - ds->idle = 1; - ds->gui_timer_interval = 500; - } else { - /* Set interval */ - ds->idle = 0; - ds->gui_timer_interval = buf[i].refresh_period.period; - } - default: - /* ignore unknown events */ - break; - } - } -} - -static void xenfb_kbd_handler(void *opaque) -{ -#define KBD_NUM_BATCH 64 - union xenkbd_in_event buf[KBD_NUM_BATCH]; - int n, i; - XenFBState *xs = opaque; - DisplayState *s = xs->ds; - static int buttons; - static int x, y; - - n = kbdfront_receive(xs->kbd_dev, buf, KBD_NUM_BATCH); - for (i = 0; i < n; i++) { - switch (buf[i].type) { - - case XENKBD_TYPE_MOTION: - fprintf(stderr, "FB backend sent us relative mouse motion event!\n"); - break; - - case XENKBD_TYPE_POS: - { - int new_x = buf[i].pos.abs_x; - int new_y = buf[i].pos.abs_y; - if (new_x >= s->width) - new_x = s->width - 1; - if (new_y >= s->height) - new_y = s->height - 1; - if (kbd_mouse_is_absolute()) { - kbd_mouse_event( - new_x * 0x7FFF / (s->width - 1), - new_y * 0x7FFF / (s->height - 1), - buf[i].pos.rel_z, - buttons); - } else { - kbd_mouse_event( - new_x - x, - new_y - y, - buf[i].pos.rel_z, - buttons); - } - x = new_x; - y = new_y; - break; - } - - case XENKBD_TYPE_KEY: - { - int keycode = buf[i].key.keycode; - int button = 0; - - if (keycode == BTN_LEFT) - button = MOUSE_EVENT_LBUTTON; - else if (keycode == BTN_RIGHT) - button = MOUSE_EVENT_RBUTTON; - else if (keycode == BTN_MIDDLE) - button = MOUSE_EVENT_MBUTTON; - - if (button) { - if (buf[i].key.pressed) - buttons |= button; - else - buttons &= ~button; - if (kbd_mouse_is_absolute()) - kbd_mouse_event( - x * 0x7FFF / (s->width - 1), - y * 0x7FFF / (s->height - 1), - 0, - buttons); - else - kbd_mouse_event(0, 0, 0, buttons); - } else { - int scancode = linux2scancode[keycode]; - if (!scancode) { - fprintf(stderr, "Can't convert keycode %x to scancode\n", keycode); - break; - } - if (scancode & 0x80) { - kbd_put_keycode(0xe0); - scancode &= 0x7f; - } - if (!buf[i].key.pressed) - scancode |= 0x80; - kbd_put_keycode(scancode); - } - break; - } - } - } -} - -static void kbdfront_thread(void *p) -{ - int scancode, keycode; - XenFBState *xs = p; - xs->kbd_dev = init_kbdfront(kbd_path, 1); - if (!xs->kbd_dev) { - fprintf(stderr,"can't open keyboard\n"); - exit(1); - } - up(&xs->kbd_sem); - for (scancode = 0; scancode < 128; scancode++) { - keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode]]; - linux2scancode[keycode] = scancode; - keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode] | 0x80]; - linux2scancode[keycode] = scancode | 0x80; - } -} - -int xenfb_pv_display_init(DisplayState *ds) -{ - if (!fb_path || !kbd_path) - return -1; - - xs = qemu_mallocz(sizeof(XenFBState)); - if (!xs) - return -1; - - init_SEMAPHORE(&xs->kbd_sem, 0); - xs->ds = ds; - - create_thread("kbdfront", kbdfront_thread, (void*) xs); - - ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE); - memset(ds->data, 0, VGA_RAM_SIZE); - ds->opaque = xs; - ds->depth = 32; - ds->bgr = 0; - ds->width = 640; - ds->height = 400; - ds->linesize = 640 * 4; - ds->dpy_update = xenfb_pv_update; - ds->dpy_resize = xenfb_pv_resize; - ds->dpy_colourdepth = xenfb_pv_colourdepth; - ds->dpy_setdata = xenfb_pv_setdata; - ds->dpy_refresh = xenfb_pv_refresh; - return 0; -} - -int xenfb_pv_display_start(void *data) -{ - DisplayState *ds; - struct fbfront_dev *fb_dev; - int kbd_fd, fb_fd; - int offset = 0; - unsigned long *mfns; - int n = VGA_RAM_SIZE / PAGE_SIZE; - int i; - - if (!fb_path || !kbd_path) - return 0; - - ds = xs->ds; - xs->vga_vram = data; - mfns = malloc(2 * n * sizeof(*mfns)); - for (i = 0; i < n; i++) - mfns[i] = virtual_to_mfn(xs->vga_vram + i * PAGE_SIZE); - for (i = 0; i < n; i++) - mfns[n + i] = virtual_to_mfn(xs->nonshared_vram + i * PAGE_SIZE); - - fb_dev = init_fbfront(fb_path, mfns, ds->width, ds->height, ds->depth, ds->linesize, 2 * n); - free(mfns); - if (!fb_dev) { - fprintf(stderr,"can't open frame buffer\n"); - exit(1); - } - free(fb_path); - - if (ds->shared_buf) { - offset = (void*) ds->data - xs->vga_vram; - } else { - offset = VGA_RAM_SIZE; - ds->data = xs->nonshared_vram; - } - if (offset) - fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset); - - down(&xs->kbd_sem); - free(kbd_path); - - kbd_fd = kbdfront_open(xs->kbd_dev); - qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, xs); - - fb_fd = fbfront_open(fb_dev); - qemu_set_fd_handler(fb_fd, xenfb_fb_handler, NULL, xs); - - xs->fb_dev = fb_dev; - return 0; -} -#endif /* * Local variables: diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/xenfb.h --- a/tools/ioemu/hw/xenfb.h Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/hw/xenfb.h Thu Jun 19 12:46:26 2008 +0900 @@ -9,5 +9,7 @@ struct xenfb; struct xenfb *xenfb_new(int domid, DisplayState *ds); void xenfb_shutdown(struct xenfb *xenfb); +extern const unsigned char atkbd_set2_keycode[512]; +extern const unsigned char atkbd_unxlate_table[128]; #endif diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/monitor.c --- a/tools/ioemu/monitor.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/monitor.c Thu Jun 19 12:46:26 2008 +0900 @@ -387,7 +387,7 @@ static void do_change_block(const char * } if (eject_device(bs, 0) < 0) return; - bdrv_open(bs, filename, 0); + bdrv_open2(bs, filename, 0, &bdrv_raw); if (bdrv_is_encrypted(bs)) { term_printf("%s is encrypted.\n", device); for(i = 0; i < 3; i++) { diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/sdl.c --- a/tools/ioemu/sdl.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/sdl.c Thu Jun 19 12:46:26 2008 +0900 @@ -50,6 +50,8 @@ static int absolute_enabled = 0; static int absolute_enabled = 0; static int opengl_enabled; +static void sdl_colourdepth(DisplayState *ds, int depth); + #ifdef CONFIG_OPENGL static GLint tex_format; static GLint tex_type; @@ -211,11 +213,13 @@ static void sdl_setdata(DisplayState *ds ds->data = pixels; } -static void sdl_resize(DisplayState *ds, int w, int h, int linesize) +static void sdl_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels) { int flags; // printf("resizing to %d %d\n", w, h); + + sdl_colourdepth(ds, depth); #ifdef CONFIG_OPENGL if (ds->shared_buf && opengl_enabled) @@ -245,7 +249,8 @@ static void sdl_resize(DisplayState *ds, opengl_enabled = 0; ds->dpy_update = sdl_update; ds->dpy_setdata = sdl_setdata; - sdl_resize(ds, w, h, linesize); + ds->dpy_resize_shared = sdl_resize_shared; + sdl_resize_shared(ds, w, h, depth, linesize, pixels); return; } exit(1); @@ -272,6 +277,7 @@ static void sdl_resize(DisplayState *ds, } else { ds->bgr = 0; } + shared = NULL; ds->data = screen->pixels; ds->linesize = screen->pitch; } else { @@ -296,21 +302,26 @@ static void sdl_resize(DisplayState *ds, }; #endif } + if (ds->shared_buf) ds->dpy_setdata(ds, pixels); +} + +static void sdl_resize(DisplayState *ds, int w, int h) +{ + sdl_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL); } static void sdl_colourdepth(DisplayState *ds, int depth) { if (!depth || !ds->depth) { ds->shared_buf = 0; + ds->dpy_update = sdl_update; return; } ds->shared_buf = 1; ds->depth = depth; - ds->linesize = width * depth / 8; #ifdef CONFIG_OPENGL if (opengl_enabled) { ds->dpy_update = opengl_update; - ds->dpy_setdata = opengl_setdata; } #endif } @@ -517,8 +528,7 @@ static void toggle_full_screen(DisplaySt static void toggle_full_screen(DisplayState *ds) { gui_fullscreen = !gui_fullscreen; - sdl_resize(ds, ds->width, ds->height, ds->linesize); - ds->dpy_setdata(ds, ds->data); + sdl_resize_shared(ds, ds->width, ds->height, ds->depth, ds->linesize, ds->data); if (gui_fullscreen) { gui_saved_grab = gui_grab; sdl_grab_start(); @@ -760,11 +770,16 @@ void sdl_display_init(DisplayState *ds, ds->dpy_update = sdl_update; ds->dpy_resize = sdl_resize; + ds->dpy_resize_shared = sdl_resize_shared; ds->dpy_refresh = sdl_refresh; - ds->dpy_colourdepth = sdl_colourdepth; - ds->dpy_setdata = sdl_setdata; - - sdl_resize(ds, 640, 400, 640 * 4); +#ifdef CONFIG_OPENGL + if (opengl_enabled) + ds->dpy_setdata = opengl_setdata; + else + ds->dpy_setdata = sdl_setdata; +#endif + + sdl_resize(ds, 640, 400); sdl_update_caption(); SDL_EnableKeyRepeat(250, 50); SDL_EnableUNICODE(1); diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/vl.c Thu Jun 19 12:46:26 2008 +0900 @@ -136,6 +136,9 @@ /* XXX: use a two level table to limit memory usage */ #define MAX_IOPORTS 65536 + +/* Max number of PCI emulation */ +#define MAX_PCI_EMULATION 32 const char *bios_dir = CONFIG_QEMU_SHAREDIR; void *ioport_opaque[MAX_IOPORTS]; @@ -211,6 +214,8 @@ int xc_handle; char domain_name[64] = "Xen-no-name"; extern int domid; + +PCI_EMULATION_INFO *PciEmulationInfoHead = NULL; /***********************************************************/ /* x86 ISA bus support */ @@ -4260,7 +4265,9 @@ static int usb_device_add(const char *de } else if (!strcmp(devname, "tablet")) { dev = usb_tablet_init(); } else if (strstart(devname, "disk:", &p)) { - dev = usb_msd_init(p); + dev = usb_msd_init(p, &bdrv_raw); + } else if (strstart(devname, "disk-qcow:", &p)) { + dev = usb_msd_init(p, 0); } else { return -1; } @@ -4399,6 +4406,17 @@ void do_pci_add(char *devname) #endif } +static int pci_emulation_add(char *config_text) +{ + PCI_EMULATION_INFO *new; + if ((new = qemu_mallocz(sizeof(PCI_EMULATION_INFO))) == NULL) { + return -1; + } + parse_pci_emulation_info(config_text, new); + new->next = PciEmulationInfoHead; + PciEmulationInfoHead = new; + return 0; +} /***********************************************************/ /* pid file */ @@ -4463,7 +4481,6 @@ void dumb_display_init(DisplayState *ds) ds->depth = 0; ds->dpy_update = dumb_update; ds->dpy_resize = dumb_resize; - ds->dpy_colourdepth = NULL; ds->dpy_refresh = dumb_refresh; ds->gui_timer_interval = 500; ds->idle = 1; @@ -6591,6 +6608,7 @@ void help(void) #endif "-option-rom rom load a file, rom, into the option ROM space\n" "-acpi disable or enable ACPI of HVM domain \n" + "-pciemulation name:vendorid:deviceid:command:status:revision:classcode:headertype:subvendorid:subsystemid:interruputline:interruputpin\n" "\n" "During emulation, the following keys are useful:\n" "ctrl-alt-f toggle full screen\n" @@ -6689,6 +6707,7 @@ enum { QEMU_OPTION_vncviewer, QEMU_OPTION_vncunused, QEMU_OPTION_pci, + QEMU_OPTION_pci_emulation, }; typedef struct QEMUOption { @@ -6790,6 +6809,7 @@ const QEMUOption qemu_options[] = { { "vcpus", 1, QEMU_OPTION_vcpus }, { "acpi", 0, QEMU_OPTION_acpi }, { "pci", HAS_ARG, QEMU_OPTION_pci}, + { "pciemulation", HAS_ARG, QEMU_OPTION_pci_emulation }, { NULL }, }; @@ -7074,6 +7094,8 @@ int main(int argc, char **argv) sigset_t set; char qemu_dm_logfilename[128]; const char *direct_pci = direct_pci_str; + int nb_pci_emulation = 0; + char pci_emulation_config_text[MAX_PCI_EMULATION][256]; #if !defined(__sun__) && !defined(CONFIG_STUBDOM) /* Maximise rlimits. Needed where default constraints are tight (*BSD). */ @@ -7599,6 +7621,16 @@ int main(int argc, char **argv) case QEMU_OPTION_vncunused: vncunused++; break; + case QEMU_OPTION_pci_emulation: + if (nb_pci_emulation >= MAX_PCI_EMULATION) { + fprintf(stderr, "Too many PCI emulations\n"); + exit(1); + } + pstrcpy(pci_emulation_config_text[nb_pci_emulation], + sizeof(pci_emulation_config_text[0]), + optarg); + nb_pci_emulation++; + break; } } } @@ -7898,6 +7930,13 @@ int main(int argc, char **argv) } } + for (i = 0; i < nb_pci_emulation; i++) { + if(pci_emulation_add(pci_emulation_config_text[i]) < 0) { + fprintf(stderr, "Warning: could not add PCI device %s\n", + pci_emulation_config_text[i]); + } + } + qemu_set_fd_handler(xenstore_fd(), xenstore_process_event, NULL, NULL); machine->init(ram_size, vga_ram_size, boot_device, diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/vl.h Thu Jun 19 12:46:26 2008 +0900 @@ -945,9 +945,9 @@ struct DisplayState { int shared_buf; void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h); - void (*dpy_resize)(struct DisplayState *s, int w, int h, int linesize); - void (*dpy_colourdepth)(struct DisplayState *s, int depth); + void (*dpy_resize)(struct DisplayState *s, int w, int h); void (*dpy_setdata)(DisplayState *s, void *pixels); + void (*dpy_resize_shared)(DisplayState *s, int w, int h, int depth, int linesize, void *pixels); void (*dpy_refresh)(struct DisplayState *s); void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y, int dst_x, int dst_y, int w, int h); }; @@ -957,14 +957,14 @@ static inline void dpy_update(DisplaySta s->dpy_update(s, x, y, w, h); } -static inline void dpy_resize(DisplayState *s, int w, int h, int linesize) -{ - s->dpy_resize(s, w, h, linesize); -} - -static inline void dpy_colourdepth(struct DisplayState *s, int depth) -{ - s->dpy_colourdepth(s, depth); +static inline void dpy_resize(DisplayState *s, int w, int h) +{ + s->dpy_resize(s, w, h); +} + +static inline void dpy_resize_shared(DisplayState *s, int w, int h, int depth, int linesize, void *pixels) +{ + s->dpy_resize_shared(s, w, h, depth, linesize, pixels); } static inline void dpy_setdata(DisplayState *s, void *pixels) @@ -1560,6 +1560,10 @@ void pci_xen_platform_init(PCIBus *bus); void pci_xen_platform_init(PCIBus *bus); #endif +/* pci_emulation.c */ +#ifndef QEMU_TOOL +#include "hw/pci_emulation.h" +#endif void kqemu_record_dump(void); diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/vnc.c --- a/tools/ioemu/vnc.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/ioemu/vnc.c Thu Jun 19 12:46:26 2008 +0900 @@ -277,6 +277,7 @@ static void dequeue_framebuffer_update(V static void dequeue_framebuffer_update(VncState *vs); static int is_empty_queue(VncState *vs); static void free_queue(VncState *vs); +static void vnc_colourdepth(DisplayState *ds, int depth); #if 0 static inline void vnc_set_bit(uint32_t *d, int k) @@ -363,13 +364,14 @@ static void vnc_framebuffer_update(VncSt vnc_write_s32(vs, encoding); } -static void vnc_dpy_resize(DisplayState *ds, int w, int h, int linesize) +static void vnc_dpy_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels) { static int allocated; int size_changed; VncState *vs = ds->opaque; int o; + vnc_colourdepth(ds, depth); if (!ds->shared_buf) { ds->linesize = w * vs->depth; if (allocated) @@ -419,6 +421,12 @@ static void vnc_dpy_resize(DisplayState for (o = DIRTY_PIXEL_BITS; o < ds->width; o *= 2) vs->dirty_pixel_shift++; framebuffer_set_updated(vs, 0, 0, ds->width, ds->height); + if (ds->shared_buf) ds->data = pixels; +} + +static void vnc_dpy_resize(DisplayState *ds, int w, int h) +{ + vnc_dpy_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL); } /* fastest code */ @@ -1640,7 +1648,7 @@ static void vnc_dpy_setdata(DisplayState ds->data = pixels; } -static void vnc_dpy_colourdepth(DisplayState *ds, int depth) +static void vnc_colourdepth(DisplayState *ds, int depth) { int host_big_endian_flag; struct VncState *vs = ds->opaque; @@ -1742,8 +1750,6 @@ static void vnc_dpy_colourdepth(DisplayS vs->write_pixels = vnc_write_pixels_generic; } } - - vnc_dpy_resize(ds, ds->width, ds->height, ds->linesize); } static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len) @@ -2502,14 +2508,14 @@ void vnc_display_init(DisplayState *ds) vs->ds->data = NULL; vs->ds->dpy_update = vnc_dpy_update; vs->ds->dpy_resize = vnc_dpy_resize; - vs->ds->dpy_colourdepth = vnc_dpy_colourdepth; vs->ds->dpy_setdata = vnc_dpy_setdata; + vs->ds->dpy_resize_shared = vnc_dpy_resize_shared; vs->ds->dpy_refresh = vnc_dpy_refresh; vs->ds->width = 640; vs->ds->height = 400; vs->ds->linesize = 640 * 4; - vnc_dpy_colourdepth(vs->ds, 24); + vnc_dpy_resize_shared(ds, ds->width, ds->height, 24, ds->linesize, NULL); } #if CONFIG_VNC_TLS diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/xenfbfront.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/xenfbfront.c Thu Jun 19 12:46:26 2008 +0900 @@ -0,0 +1,315 @@ +#include <stdint.h> +#include <xen/io/fbif.h> +#include <xen/io/kbdif.h> +#include <semaphore.h> +#include <sched.h> +#include <fbfront.h> + +#include <hw/xenfb.h> + +#include "vl.h" + +typedef struct XenFBState { + struct semaphore kbd_sem; + struct kbdfront_dev *kbd_dev; + struct fbfront_dev *fb_dev; + void *vga_vram, *nonshared_vram; + DisplayState *ds; +} XenFBState; + +XenFBState *xs; + +static char *kbd_path, *fb_path; + +static unsigned char linux2scancode[KEY_MAX + 1]; + +int xenfb_connect_vkbd(const char *path) +{ + kbd_path = strdup(path); + return 0; +} + +int xenfb_connect_vfb(const char *path) +{ + fb_path = strdup(path); + return 0; +} + +static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h) +{ + XenFBState *xs = ds->opaque; + struct fbfront_dev *fb_dev = xs->fb_dev; + if (!fb_dev) + return; + fbfront_update(fb_dev, x, y, w, h); +} + +static void xenfb_pv_resize_shared(DisplayState *ds, int w, int h, int depth, int linesize, void *pixels) +{ + XenFBState *xs = ds->opaque; + struct fbfront_dev *fb_dev = xs->fb_dev; + int offset; + + fprintf(stderr,"resize to %dx%d@%d, %d required\n", w, h, depth, linesize); + ds->width = w; + ds->height = h; + if (!depth) { + ds->shared_buf = 0; + ds->depth = 32; + } else { + ds->shared_buf = 1; + ds->depth = depth; + } + if (!linesize) + ds->shared_buf = 0; + if (!ds->shared_buf) + linesize = w * 4; + ds->linesize = linesize; + if (!fb_dev) + return; + if (ds->shared_buf) { + offset = pixels - xs->vga_vram; + ds->data = pixels; + fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset); + } else { + ds->data = xs->nonshared_vram; + fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE); + } +} + +static void xenfb_pv_resize(DisplayState *ds, int w, int h) +{ + xenfb_pv_resize_shared(ds, w, h, 0, 0, NULL); +} + +static void xenfb_pv_setdata(DisplayState *ds, void *pixels) +{ + XenFBState *xs = ds->opaque; + struct fbfront_dev *fb_dev = xs->fb_dev; + int offset = pixels - xs->vga_vram; + ds->data = pixels; + if (!fb_dev) + return; + fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset); +} + +static void xenfb_pv_refresh(DisplayState *ds) +{ + vga_hw_update(); +} + +static void xenfb_fb_handler(void *opaque) +{ +#define FB_NUM_BATCH 4 + union xenfb_in_event buf[FB_NUM_BATCH]; + int n, i; + XenFBState *xs = opaque; + DisplayState *ds = xs->ds; + + n = fbfront_receive(xs->fb_dev, buf, FB_NUM_BATCH); + for (i = 0; i < n; i++) { + switch (buf[i].type) { + case XENFB_TYPE_REFRESH_PERIOD: + if (buf[i].refresh_period.period == XENFB_NO_REFRESH) { + /* Sleeping interval */ + ds->idle = 1; + ds->gui_timer_interval = 500; + } else { + /* Set interval */ + ds->idle = 0; + ds->gui_timer_interval = buf[i].refresh_period.period; + } + default: + /* ignore unknown events */ + break; + } + } +} + +static void xenfb_kbd_handler(void *opaque) +{ +#define KBD_NUM_BATCH 64 + union xenkbd_in_event buf[KBD_NUM_BATCH]; + int n, i; + XenFBState *xs = opaque; + DisplayState *s = xs->ds; + static int buttons; + static int x, y; + + n = kbdfront_receive(xs->kbd_dev, buf, KBD_NUM_BATCH); + for (i = 0; i < n; i++) { + switch (buf[i].type) { + + case XENKBD_TYPE_MOTION: + fprintf(stderr, "FB backend sent us relative mouse motion event!\n"); + break; + + case XENKBD_TYPE_POS: + { + int new_x = buf[i].pos.abs_x; + int new_y = buf[i].pos.abs_y; + if (new_x >= s->width) + new_x = s->width - 1; + if (new_y >= s->height) + new_y = s->height - 1; + if (kbd_mouse_is_absolute()) { + kbd_mouse_event( + new_x * 0x7FFF / (s->width - 1), + new_y * 0x7FFF / (s->height - 1), + buf[i].pos.rel_z, + buttons); + } else { + kbd_mouse_event( + new_x - x, + new_y - y, + buf[i].pos.rel_z, + buttons); + } + x = new_x; + y = new_y; + break; + } + + case XENKBD_TYPE_KEY: + { + int keycode = buf[i].key.keycode; + int button = 0; + + if (keycode == BTN_LEFT) + button = MOUSE_EVENT_LBUTTON; + else if (keycode == BTN_RIGHT) + button = MOUSE_EVENT_RBUTTON; + else if (keycode == BTN_MIDDLE) + button = MOUSE_EVENT_MBUTTON; + + if (button) { + if (buf[i].key.pressed) + buttons |= button; + else + buttons &= ~button; + if (kbd_mouse_is_absolute()) + kbd_mouse_event( + x * 0x7FFF / (s->width - 1), + y * 0x7FFF / (s->height - 1), + 0, + buttons); + else + kbd_mouse_event(0, 0, 0, buttons); + } else { + int scancode = linux2scancode[keycode]; + if (!scancode) { + fprintf(stderr, "Can't convert keycode %x to scancode\n", keycode); + break; + } + if (scancode & 0x80) { + kbd_put_keycode(0xe0); + scancode &= 0x7f; + } + if (!buf[i].key.pressed) + scancode |= 0x80; + kbd_put_keycode(scancode); + } + break; + } + } + } +} + +static void kbdfront_thread(void *p) +{ + int scancode, keycode; + XenFBState *xs = p; + xs->kbd_dev = init_kbdfront(kbd_path, 1); + if (!xs->kbd_dev) { + fprintf(stderr,"can't open keyboard\n"); + exit(1); + } + up(&xs->kbd_sem); + for (scancode = 0; scancode < 128; scancode++) { + keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode]]; + linux2scancode[keycode] = scancode; + keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode] | 0x80]; + linux2scancode[keycode] = scancode | 0x80; + } +} + +int xenfb_pv_display_init(DisplayState *ds) +{ + if (!fb_path || !kbd_path) + return -1; + + xs = qemu_mallocz(sizeof(XenFBState)); + if (!xs) + return -1; + + init_SEMAPHORE(&xs->kbd_sem, 0); + xs->ds = ds; + + create_thread("kbdfront", kbdfront_thread, (void*) xs); + + ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE); + memset(ds->data, 0, VGA_RAM_SIZE); + ds->opaque = xs; + ds->depth = 32; + ds->bgr = 0; + ds->width = 640; + ds->height = 400; + ds->linesize = 640 * 4; + ds->dpy_update = xenfb_pv_update; + ds->dpy_resize = xenfb_pv_resize; + ds->dpy_resize_shared = xenfb_pv_resize_shared; + ds->dpy_setdata = xenfb_pv_setdata; + ds->dpy_refresh = xenfb_pv_refresh; + return 0; +} + +int xenfb_pv_display_start(void *data) +{ + DisplayState *ds; + struct fbfront_dev *fb_dev; + int kbd_fd, fb_fd; + int offset = 0; + unsigned long *mfns; + int n = VGA_RAM_SIZE / PAGE_SIZE; + int i; + + if (!fb_path || !kbd_path) + return 0; + + ds = xs->ds; + xs->vga_vram = data; + mfns = malloc(2 * n * sizeof(*mfns)); + for (i = 0; i < n; i++) + mfns[i] = virtual_to_mfn(xs->vga_vram + i * PAGE_SIZE); + for (i = 0; i < n; i++) + mfns[n + i] = virtual_to_mfn(xs->nonshared_vram + i * PAGE_SIZE); + + fb_dev = init_fbfront(fb_path, mfns, ds->width, ds->height, ds->depth, ds->linesize, 2 * n); + free(mfns); + if (!fb_dev) { + fprintf(stderr,"can't open frame buffer\n"); + exit(1); + } + free(fb_path); + + if (ds->shared_buf) { + offset = (void*) ds->data - xs->vga_vram; + } else { + offset = VGA_RAM_SIZE; + ds->data = xs->nonshared_vram; + } + if (offset) + fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset); + + down(&xs->kbd_sem); + free(kbd_path); + + kbd_fd = kbdfront_open(xs->kbd_dev); + qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, xs); + + fb_fd = fbfront_open(fb_dev); + qemu_set_fd_handler(fb_fd, xenfb_fb_handler, NULL, xs); + + xs->fb_dev = fb_dev; + return 0; +} diff -r 1201c7657832 -r 0034766b45c2 tools/libfsimage/ufs/fsys_ufs.c --- a/tools/libfsimage/ufs/fsys_ufs.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/libfsimage/ufs/fsys_ufs.c Thu Jun 19 12:46:26 2008 +0900 @@ -32,8 +32,9 @@ #define SUPERBLOCK ((struct fs *)(FSYS_BUF + 0x2000)) #define INODE ((struct icommon *)(FSYS_BUF + 0x1000)) #define DIRENT (FSYS_BUF + 0x4000) +#define MAXBSIZE ((FSYS_BUFLEN - 0x4000) / 2) #define INDIRBLK1 ((grub_daddr32_t *)(FSYS_BUF + 0x4000)) /* 2+ indir blk */ -#define INDIRBLK0 ((grub_daddr32_t *)(FSYS_BUF+ 0x6000)) /* 1st indirect blk */ +#define INDIRBLK0 ((grub_daddr32_t *)(FSYS_BUF+ 0x4000 + MAXBSIZE)) /* 1st indirect blk */ #define indirblk0 (*fsig_int1(ffi)) #define indirblk1 (*fsig_int2(ffi)) @@ -48,7 +49,8 @@ ufs_mount(fsi_file_t *ffi, const char *o { if (/*! IS_PC_SLICE_TYPE_SOLARIS(current_slice) || */ !devread(ffi, UFS_SBLOCK, 0, UFS_SBSIZE, (char *)SUPERBLOCK) || - SUPERBLOCK->fs_magic != UFS_MAGIC) + SUPERBLOCK->fs_magic != UFS_MAGIC || + MAXBSIZE < SUPERBLOCK->fs_bsize) return 0; return 1; diff -r 1201c7657832 -r 0034766b45c2 tools/libfsimage/zfs/fsys_zfs.c --- a/tools/libfsimage/zfs/fsys_zfs.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/libfsimage/zfs/fsys_zfs.c Thu Jun 19 12:46:26 2008 +0900 @@ -776,11 +776,11 @@ dnode_get_path(fsi_file_t *ffi, dnode_ph while (*path == '/') path++; - while (*path && !isspace(*path)) { + while (*path && !isspace((uint8_t)*path)) { /* get the next component name */ cname = path; - while (*path && !isspace(*path) && *path != '/') + while (*path && !isspace((uint8_t)*path) && *path != '/') path++; ch = *path; *path = 0; /* ensure null termination */ @@ -890,17 +890,17 @@ get_objset_mdn(fsi_file_t *ffi, dnode_ph } /* take out the pool name */ - while (*fsname && !isspace(*fsname) && *fsname != '/') + while (*fsname && !isspace((uint8_t)*fsname) && *fsname != '/') fsname++; - while (*fsname && !isspace(*fsname)) { + while (*fsname && !isspace((uint8_t)*fsname)) { uint64_t childobj; while (*fsname == '/') fsname++; cname = fsname; - while (*fsname && !isspace(*fsname) && *fsname != '/') + while (*fsname && !isspace((uint8_t)*fsname) && *fsname != '/') fsname++; ch = *fsname; *fsname = 0; @@ -1336,7 +1336,7 @@ zfs_open(fsi_file_t *ffi, char *filename char zfs_bootstr[] = "zfs-bootfs="; char zfs_bootpath[] = ",bootpath='"; - sprintf(temp, "%llu", (unsigned long long) + snprintf(temp, sizeof(temp), "%llu", (unsigned long long) current_bootfs_obj); alloc_size = strlen(zfs_bootstr) + strlen(current_rootpool) + diff -r 1201c7657832 -r 0034766b45c2 tools/libxc/Makefile --- a/tools/libxc/Makefile Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/libxc/Makefile Thu Jun 19 12:46:26 2008 +0900 @@ -32,7 +32,7 @@ GUEST_SRCS-$(CONFIG_MIGRATE) += xc_domai GUEST_SRCS-$(CONFIG_MIGRATE) += xc_domain_restore.c xc_domain_save.c GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c -VPATH = ../../xen/common/libelf +vpath %.c ../../xen/common/libelf CFLAGS += -I../../xen/common/libelf GUEST_SRCS-y += libelf-tools.c libelf-loader.c diff -r 1201c7657832 -r 0034766b45c2 tools/libxc/ia64/dom_fw_acpi.c --- a/tools/libxc/ia64/dom_fw_acpi.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/libxc/ia64/dom_fw_acpi.c Thu Jun 19 12:46:26 2008 +0900 @@ -1,14 +1,31 @@ #include <inttypes.h> #include "xc_dom_ia64_util.h" #include <xen/acpi.h> +#include <acpi/actables.h> -uint8_t -generate_acpi_checksum(void *tbl, unsigned long len) +/* stolen from xen/drivers/acpi/tables/tbutils.c */ + +/******************************************************************************* + * + * FUNCTION: acpi_tb_checksum + * + * PARAMETERS: Buffer - Pointer to memory region to be checked + * Length - Length of this memory region + * + * RETURN: Checksum (u8) + * + * DESCRIPTION: Calculates circular checksum of memory region. + * + ******************************************************************************/ + +u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length) { - uint8_t *ptr, sum = 0; + u8 sum = 0; + u8 *end = buffer + length; - for ( ptr = tbl; len > 0 ; len--, ptr++ ) - sum += *ptr; + while (buffer < end) { + sum = (u8) (sum + *(buffer++)); + } - return 0 - sum; + return sum; } diff -r 1201c7657832 -r 0034766b45c2 tools/libxc/xc_cpuid_x86.c --- a/tools/libxc/xc_cpuid_x86.c Tue Jun 10 16:00:33 2008 +0900 +++ b/tools/libxc/xc_cpuid_x86.c Thu Jun 19 12:46:26 2008 +0900 @@ -25,81 +25,17 @@ #include <xen/hvm/params.h> #define bitmaskof(idx) (1u << ((idx) & 31)) -#define clear_bit(idx, dst) ((dst) &= ~(1u << (idx))) -#define set_bit(idx, dst) ((dst) |= (1u << (idx))) +#define clear_bit(idx, dst) ((dst) &= ~(1u << ((idx) & 31))) +#define set_bit(idx, dst) ((dst) |= (1u << ((idx) & 31))) #define DEF_MAX_BASE 0x00000004u #define DEF_MAX_EXT 0x80000008u -static void amd_xc_cpuid_policy( - int xc, domid_t domid, const unsigned int *input, unsigned int *regs) -{ - unsigned long pae = 0; - - xc_get_hvm_param(xc, domid, HVM_PARAM_PAE_ENABLED, &pae); - - switch ( input[0] ) - { - case 0x00000001: - /* Mask Intel-only features. */ - regs[2] &= ~(bitmaskof(X86_FEATURE_SSSE3) | - bitmaskof(X86_FEATURE_SSE4_1) | - bitmaskof(X86_FEATURE_SSE4_2)); - break; - - case 0x00000002: - case 0x00000004: - regs[0] = regs[1] = regs[2] = 0; - break; - - case 0x80000001: - if ( !pae ) - clear_bit(X86_FEATURE_PAE & 31, regs[3]); - clear_bit(X86_FEATURE_PSE36 & 31, regs[3]); - - /* Filter all other features according to a whitelist. */ - regs[2] &= (bitmaskof(X86_FEATURE_LAHF_LM) | - bitmaskof(X86_FEATURE_ALTMOVCR) | - bitmaskof(X86_FEATURE_ABM) | - bitmaskof(X86_FEATURE_SSE4A) | - bitmaskof(X86_FEATURE_MISALIGNSSE) | - bitmaskof(X86_FEATURE_3DNOWPF)); - regs[3] &= (0x0183f3ff | /* features shared with 0x00000001:EDX */ - bitmaskof(X86_FEATURE_NX) | - bitmaskof(X86_FEATURE_LM) | - bitmaskof(X86_FEATURE_SYSCALL) | - bitmaskof(X86_FEATURE_MP) | - bitmaskof(X86_FEATURE_MMXEXT) | - bitmaskof(X86_FEATURE_FFXSR) | - bitmaskof(X86_FEATURE_3DNOW) | - bitmaskof(X86_FEATURE_3DNOWEXT)); - break; - } -} - -static void intel_xc_cpuid_policy( - int xc, domid_t domid, const unsigned int *input, unsigned int *regs) -{ - switch ( input[0] ) - { - case 0x00000001: - /* Mask AMD-only features. */ - regs[2] &= ~(bitmaskof(X86_FEATURE_POPCNT)); - break; - - case 0x00000004: - regs[0] &= 0x3FF; - regs[3] &= 0x3FF; - break; - - case 0x80000001: - /* Only a few features are advertised in Intel's 0x80000001. */ - regs[2] &= (bitmaskof(X86_FEATURE_LAHF_LM)); - regs[3] &= (bitmaskof(X86_FEATURE_NX) | - bitmaskof(X86_FEATURE_LM) | - bitmaskof(X86_FEATURE_SYSCALL)); - break; - } +static int hypervisor_is_64bit(int xc) +{ + xen_capabilities_info_t xen_caps = ""; + return ((xc_version(xc, XENVER_capabilities, &xen_caps) == 0) && + (strstr(xen_caps, "x86_64") != NULL)); } static void cpuid(const unsigned int *input, unsigned int *regs) @@ -129,15 +65,92 @@ static void xc_cpuid_brand_get(char *str str[12] = '\0'; } -static void xc_cpuid_policy( +static void amd_xc_cpuid_policy( + int xc, domid_t domid, const unsigned int *input, unsigned int *regs, + int is_pae) +{ + switch ( input[0] ) + { + case 0x00000001: + /* Mask Intel-only features. */ + regs[2] &= ~(bitmaskof(X86_FEATURE_SSSE3) | + bitmaskof(X86_FEATURE_SSE4_1) | + bitmaskof(X86_FEATURE_SSE4_2)); + break; + + case 0x00000002: + case 0x00000004: + regs[0] = regs[1] = regs[2] = 0; + break; + + case 0x80000001: { + int is_64bit = hypervisor_is_64bit(xc) && is_pae; + + if ( !is_pae ) + clear_bit(X86_FEATURE_PAE, regs[3]); + clear_bit(X86_FEATURE_PSE36, regs[3]); + + /* Filter all other features according to a whitelist. */ + regs[2] &= ((is_64bit ? bitmaskof(X86_FEATURE_LAHF_LM) : 0) | + bitmaskof(X86_FEATURE_ALTMOVCR) | + bitmaskof(X86_FEATURE_ABM) | + bitmaskof(X86_FEATURE_SSE4A) | + bitmaskof(X86_FEATURE_MISALIGNSSE) | + bitmaskof(X86_FEATURE_3DNOWPF)); + regs[3] &= (0x0183f3ff | /* features shared with 0x00000001:EDX */ + (is_pae ? bitmaskof(X86_FEATURE_NX) : 0) | + (is_64bit ? bitmaskof(X86_FEATURE_LM) : 0) | + bitmaskof(X86_FEATURE_SYSCALL) | + bitmaskof(X86_FEATURE_MP) | + bitmaskof(X86_FEATURE_MMXEXT) | + bitmaskof(X86_FEATURE_FFXSR) | + bitmaskof(X86_FEATURE_3DNOW) | + bitmaskof(X86_FEATURE_3DNOWEXT)); + break; + } + } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |