[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 1210836236 -32400 # Node ID c96507e0c83d292f36bd48b1d4a59771e92c0907 # Parent ef290f39ae6b8e3c58c224ec469ab09522cc7e0b # Parent 86587698116d742ff257e64ddfd230157fcee42c merge with xen-unstable.hg --- config/powerpc64.mk | 6 tools/libxc/powerpc64/Makefile | 4 tools/libxc/powerpc64/flatdevtree.c | 662 ---------- tools/libxc/powerpc64/flatdevtree.h | 108 - tools/libxc/powerpc64/flatdevtree_env.h | 94 - tools/libxc/powerpc64/mk_flatdevtree.c | 648 --------- tools/libxc/powerpc64/mk_flatdevtree.h | 37 tools/libxc/powerpc64/xc_memory.c | 42 tools/libxc/xc_core_powerpc.c | 79 - tools/libxc/xc_core_powerpc.h | 58 tools/libxc/xc_dom_powerpc.c | 236 --- tools/xm-test/ramdisk/configs/buildroot-powerpc | 338 ----- xen/arch/powerpc/0opt.c | 34 xen/arch/powerpc/Makefile | 152 -- xen/arch/powerpc/Rules.mk | 52 xen/arch/powerpc/audit.c | 47 xen/arch/powerpc/backtrace.c | 217 --- xen/arch/powerpc/bitops.c | 94 - xen/arch/powerpc/boot_of.c | 1257 ------------------- xen/arch/powerpc/cmdline.c | 24 xen/arch/powerpc/crash.c | 20 xen/arch/powerpc/dart.c | 297 ---- xen/arch/powerpc/dart.h | 36 xen/arch/powerpc/dart_u3.c | 108 - xen/arch/powerpc/dart_u4.c | 184 -- xen/arch/powerpc/domain.c | 357 ----- xen/arch/powerpc/domain_build.c | 297 ---- xen/arch/powerpc/domctl.c | 120 - xen/arch/powerpc/exceptions.c | 91 - xen/arch/powerpc/exceptions.h | 54 xen/arch/powerpc/external.c | 202 --- xen/arch/powerpc/float.S | 243 --- xen/arch/powerpc/gdbstub.c | 216 --- xen/arch/powerpc/hcalls.c | 171 -- xen/arch/powerpc/iommu.c | 95 - xen/arch/powerpc/iommu.h | 28 xen/arch/powerpc/irq.c | 22 xen/arch/powerpc/machine_kexec.c | 41 xen/arch/powerpc/memory.c | 224 --- xen/arch/powerpc/mm.c | 617 --------- xen/arch/powerpc/mpic.c | 1100 ---------------- xen/arch/powerpc/mpic_init.c | 416 ------ xen/arch/powerpc/mpic_init.h | 27 xen/arch/powerpc/multiboot2.c | 67 - xen/arch/powerpc/numa.c | 1 xen/arch/powerpc/of-devtree.c | 1087 ---------------- xen/arch/powerpc/of-devtree.h | 157 -- xen/arch/powerpc/of-devwalk.c | 133 -- xen/arch/powerpc/of_handler/Makefile | 32 xen/arch/powerpc/of_handler/console.c | 233 --- xen/arch/powerpc/of_handler/control.c | 90 - xen/arch/powerpc/of_handler/cpu.c | 82 - xen/arch/powerpc/of_handler/devtree.c | 268 ---- xen/arch/powerpc/of_handler/head.S | 156 -- xen/arch/powerpc/of_handler/io.c | 160 -- xen/arch/powerpc/of_handler/leap.S | 38 xen/arch/powerpc/of_handler/memcmp.c | 39 xen/arch/powerpc/of_handler/memory.c | 129 - xen/arch/powerpc/of_handler/memset.c | 67 - xen/arch/powerpc/of_handler/ofh.c | 439 ------ xen/arch/powerpc/of_handler/ofh.h | 164 -- xen/arch/powerpc/of_handler/papr.S | 97 - xen/arch/powerpc/of_handler/papr.h | 69 - xen/arch/powerpc/of_handler/rtas.c | 82 - xen/arch/powerpc/of_handler/services.c | 96 - xen/arch/powerpc/of_handler/snprintf.c | 332 ----- xen/arch/powerpc/of_handler/strcmp.c | 36 xen/arch/powerpc/of_handler/strlcpy.c | 58 xen/arch/powerpc/of_handler/strlen.c | 30 xen/arch/powerpc/of_handler/strncmp.c | 39 xen/arch/powerpc/of_handler/strnlen.c | 30 xen/arch/powerpc/of_handler/vdevice.c | 74 - xen/arch/powerpc/of_handler/xen_hvcall.S | 44 xen/arch/powerpc/of_handler/xencomm.c | 84 - xen/arch/powerpc/ofd_fixup.c | 428 ------ xen/arch/powerpc/ofd_fixup_memory.c | 128 - xen/arch/powerpc/oftree.h | 38 xen/arch/powerpc/papr/Makefile | 11 xen/arch/powerpc/papr/debug.c | 84 - xen/arch/powerpc/papr/h_perfmon.c | 158 -- xen/arch/powerpc/papr/tce.c | 84 - xen/arch/powerpc/papr/vtce.c | 158 -- xen/arch/powerpc/papr/vterm.c | 70 - xen/arch/powerpc/papr/xlate.c | 619 --------- xen/arch/powerpc/physdev.c | 24 xen/arch/powerpc/platform.c | 43 xen/arch/powerpc/powerpc64/Makefile | 14 xen/arch/powerpc/powerpc64/asm-offsets.c | 67 - xen/arch/powerpc/powerpc64/domain.c | 222 --- xen/arch/powerpc/powerpc64/exceptions.S | 644 --------- xen/arch/powerpc/powerpc64/hypercall_table.S | 46 xen/arch/powerpc/powerpc64/io.S | 193 -- xen/arch/powerpc/powerpc64/memcpy.S | 171 -- xen/arch/powerpc/powerpc64/ppc970.c | 302 ---- xen/arch/powerpc/powerpc64/ppc970_machinecheck.c | 125 - xen/arch/powerpc/powerpc64/ppc970_scom.c | 184 -- xen/arch/powerpc/powerpc64/prom_call.S | 116 - xen/arch/powerpc/powerpc64/scom.h | 39 xen/arch/powerpc/powerpc64/string.S | 286 ---- xen/arch/powerpc/powerpc64/traps.c | 58 xen/arch/powerpc/ppc32/prom_call.c | 41 xen/arch/powerpc/rtas.c | 201 --- xen/arch/powerpc/rtas.h | 65 xen/arch/powerpc/rtas_flash.c | 182 -- xen/arch/powerpc/rtas_nvram.c | 129 - xen/arch/powerpc/setup.c | 509 ------- xen/arch/powerpc/shadow.c | 155 -- xen/arch/powerpc/smp-tbsync.c | 193 -- xen/arch/powerpc/smp.c | 214 --- xen/arch/powerpc/smpboot.c | 29 xen/arch/powerpc/start.S | 62 xen/arch/powerpc/sysctl.c | 65 xen/arch/powerpc/systemsim.S | 64 xen/arch/powerpc/tce.h | 71 - xen/arch/powerpc/time.c | 90 - xen/arch/powerpc/usercopy.c | 50 xen/arch/powerpc/xen.lds.S | 250 --- xen/include/asm-powerpc/acpi.h | 2 xen/include/asm-powerpc/asm_defns.h | 28 xen/include/asm-powerpc/atomic.h | 211 --- xen/include/asm-powerpc/bitops.h | 309 ---- xen/include/asm-powerpc/boot.h | 46 xen/include/asm-powerpc/bug.h | 7 xen/include/asm-powerpc/byteorder.h | 80 - xen/include/asm-powerpc/cache.h | 74 - xen/include/asm-powerpc/config.h | 85 - xen/include/asm-powerpc/current.h | 79 - xen/include/asm-powerpc/debugger.h | 97 - xen/include/asm-powerpc/delay.h | 40 xen/include/asm-powerpc/desc.h | 25 xen/include/asm-powerpc/div64.h | 33 xen/include/asm-powerpc/domain.h | 123 - xen/include/asm-powerpc/elf.h | 30 xen/include/asm-powerpc/event.h | 99 - xen/include/asm-powerpc/flushtlb.h | 105 - xen/include/asm-powerpc/grant_table.h | 92 - xen/include/asm-powerpc/guest_access.h | 26 xen/include/asm-powerpc/hardirq.h | 21 xen/include/asm-powerpc/hcalls.h | 34 xen/include/asm-powerpc/htab.h | 136 -- xen/include/asm-powerpc/hypercall.h | 26 xen/include/asm-powerpc/init.h | 40 xen/include/asm-powerpc/io.h | 69 - xen/include/asm-powerpc/iocap.h | 26 xen/include/asm-powerpc/irq.h | 31 xen/include/asm-powerpc/mach-default/irq_vectors.h | 89 - xen/include/asm-powerpc/memory.h | 39 xen/include/asm-powerpc/mm.h | 286 ---- xen/include/asm-powerpc/mpic.h | 294 ---- xen/include/asm-powerpc/msr.h | 66 xen/include/asm-powerpc/multicall.h | 27 xen/include/asm-powerpc/nmi.h | 9 xen/include/asm-powerpc/numa.h | 28 xen/include/asm-powerpc/page.h | 134 -- xen/include/asm-powerpc/papr.h | 219 --- xen/include/asm-powerpc/pci.h | 35 xen/include/asm-powerpc/percpu.h | 36 xen/include/asm-powerpc/perfc.h | 16 xen/include/asm-powerpc/platform.h | 28 xen/include/asm-powerpc/powerpc64/config.h | 39 xen/include/asm-powerpc/powerpc64/ppc970-hid.h | 144 -- xen/include/asm-powerpc/powerpc64/ppc970.h | 31 xen/include/asm-powerpc/powerpc64/procarea.h | 38 xen/include/asm-powerpc/powerpc64/processor.h | 228 --- xen/include/asm-powerpc/powerpc64/string.h | 42 xen/include/asm-powerpc/processor.h | 429 ------ xen/include/asm-powerpc/reg_defs.h | 210 --- xen/include/asm-powerpc/regs.h | 25 xen/include/asm-powerpc/shadow.h | 52 xen/include/asm-powerpc/shared.h | 4 xen/include/asm-powerpc/smp.h | 60 xen/include/asm-powerpc/softirq.h | 6 xen/include/asm-powerpc/spinlock.h | 218 --- xen/include/asm-powerpc/string.h | 26 xen/include/asm-powerpc/system.h | 247 --- xen/include/asm-powerpc/time.h | 86 - xen/include/asm-powerpc/trace.h | 4 xen/include/asm-powerpc/types.h | 79 - xen/include/asm-powerpc/xenoprof.h | 100 - xen/include/asm-x86/x86_32/page-2level.h | 60 xen/include/asm-x86/x86_32/page-3level.h | 90 - xen/include/public/arch-powerpc.h | 120 - Config.mk | 7 Makefile | 4 buildconfigs/mk.linux-2.6-common | 4 buildconfigs/mk.linux-2.6.5-SLES-xen | 2 buildconfigs/mk.linux-2.6.9-RHEL-xen | 2 extras/mini-os/Config.mk | 8 extras/mini-os/arch/x86/arch.mk | 5 extras/mini-os/arch/x86/mm.c | 17 extras/mini-os/arch/x86/setup.c | 2 extras/mini-os/arch/x86/time.c | 2 extras/mini-os/arch/x86/traps.c | 5 extras/mini-os/arch/x86/x86_32.S | 4 extras/mini-os/blkfront.c | 32 extras/mini-os/events.c | 8 extras/mini-os/fbfront.c | 112 + extras/mini-os/hypervisor.c | 11 extras/mini-os/include/arch/cc.h | 3 extras/mini-os/include/fbfront.h | 3 extras/mini-os/include/lib.h | 4 extras/mini-os/include/mm.h | 1 extras/mini-os/include/types.h | 6 extras/mini-os/include/x86/arch_limits.h | 2 extras/mini-os/include/x86/arch_mm.h | 30 extras/mini-os/include/x86/x86_32/hypercall-x86_32.h | 12 extras/mini-os/kernel.c | 74 - extras/mini-os/lib/sys.c | 20 extras/mini-os/lib/xmalloc.c | 2 extras/mini-os/netfront.c | 68 - tools/examples/xmexample.hvm | 46 tools/examples/xmexample.vti | 3 tools/examples/xmexample1 | 5 tools/examples/xmexample2 | 5 tools/examples/xmexample3 | 5 tools/ioemu/block.c | 2 tools/ioemu/hw/ide.c | 6 tools/ioemu/hw/pass-through.c | 11 tools/ioemu/hw/pass-through.h | 21 tools/ioemu/hw/pt-msi.c | 424 +++++- tools/ioemu/hw/pt-msi.h | 15 tools/ioemu/hw/xenfb.c | 282 +++- tools/ioemu/keymaps.c | 16 tools/ioemu/sdl.c | 2 tools/ioemu/vl.c | 4 tools/ioemu/vl.h | 4 tools/ioemu/vnc.c | 58 tools/ioemu/vnc_keysym.h | 1 tools/ioemu/xenstore.c | 36 tools/libxc/Makefile | 2 tools/libxc/xc_core.h | 2 tools/libxc/xc_dom_elfloader.c | 2 tools/libxc/xc_physdev.c | 2 tools/libxc/xenctrl.h | 10 tools/libxc/xenguest.h | 14 tools/python/xen/lowlevel/xc/xc.c | 32 tools/python/xen/util/xsm/acm/acm.py | 97 + tools/python/xen/web/connection.py | 167 ++ tools/python/xen/web/tcp.py | 12 tools/python/xen/xend/XendCheckpoint.py | 14 tools/python/xen/xend/XendConfig.py | 108 + tools/python/xen/xend/XendDomain.py | 92 - tools/python/xen/xend/XendDomainInfo.py | 36 tools/python/xen/xend/arch.py | 2 tools/python/xen/xend/image.py | 24 tools/python/xen/xend/server/blkif.py | 17 tools/python/xen/xend/server/relocate.py | 22 tools/python/xen/xm/create.py | 7 tools/python/xen/xm/xenapi_create.py | 9 tools/xm-test/lib/XmTestLib/arch.py | 40 tools/xm-test/lib/XmTestReport/arch.py | 6 tools/xm-test/ramdisk/Makefile.am | 2 tools/xm-test/ramdisk/make-release.sh | 3 tools/xm-test/runtest.sh | 2 unmodified_drivers/linux-2.6/overrides.mk | 14 xen/Rules.mk | 3 xen/arch/ia64/xen/dom0_ops.c | 10 xen/arch/x86/Rules.mk | 5 xen/arch/x86/acpi/Makefile | 2 xen/arch/x86/acpi/cpu_idle.c | 2 xen/arch/x86/acpi/cpufreq/Makefile | 3 xen/arch/x86/acpi/cpufreq/cpufreq.c | 603 +++++++++ xen/arch/x86/acpi/cpufreq/cpufreq_ondemand.c | 237 +++ xen/arch/x86/acpi/cpufreq/utility.c | 167 ++ xen/arch/x86/boot/head.S | 24 xen/arch/x86/boot/trampoline.S | 6 xen/arch/x86/boot/wakeup.S | 6 xen/arch/x86/boot/x86_32.S | 2 xen/arch/x86/domain.c | 34 xen/arch/x86/domain_build.c | 6 xen/arch/x86/hvm/hvm.c | 2 xen/arch/x86/hvm/vmx/vmcs.c | 34 xen/arch/x86/hvm/vmx/vmx.c | 4 xen/arch/x86/mm.c | 53 xen/arch/x86/mm/hap/hap.c | 44 xen/arch/x86/mm/p2m.c | 43 xen/arch/x86/mm/shadow/Makefile | 18 xen/arch/x86/mm/shadow/common.c | 318 +--- xen/arch/x86/mm/shadow/multi.c | 212 --- xen/arch/x86/mm/shadow/multi.h | 58 xen/arch/x86/mm/shadow/private.h | 56 xen/arch/x86/mm/shadow/types.h | 107 - xen/arch/x86/msi.c | 33 xen/arch/x86/platform_hypercall.c | 66 xen/arch/x86/setup.c | 33 xen/arch/x86/sysctl.c | 19 xen/arch/x86/traps.c | 4 xen/arch/x86/x86_32/mm.c | 11 xen/arch/x86/x86_32/traps.c | 10 xen/arch/x86/x86_64/domain.c | 19 xen/arch/x86/x86_64/platform_hypercall.c | 6 xen/common/compat/domain.c | 20 xen/common/domain.c | 10 xen/drivers/passthrough/vtd/iommu.c | 1 xen/include/acpi/cpufreq/cpufreq.h | 129 + xen/include/acpi/cpufreq/processor_perf.h | 30 xen/include/asm-x86/config.h | 49 xen/include/asm-x86/desc.h | 2 xen/include/asm-x86/domain.h | 4 xen/include/asm-x86/fixmap.h | 2 xen/include/asm-x86/mm.h | 4 xen/include/asm-x86/msi.h | 1 xen/include/asm-x86/msr-index.h | 4 xen/include/asm-x86/mtrr.h | 3 xen/include/asm-x86/page.h | 16 xen/include/asm-x86/types.h | 6 xen/include/asm-x86/x86_32/page.h | 91 + xen/include/public/arch-x86/xen-x86_32.h | 7 xen/include/public/hvm/hvm_op.h | 5 xen/include/public/io/fbif.h | 21 xen/include/public/io/pciif.h | 14 xen/include/public/io/protocols.h | 3 xen/include/public/libelf.h | 4 xen/include/public/platform.h | 51 xen/include/public/xen.h | 2 xen/include/xen/domain.h | 2 xen/include/xlat.lst | 5 xen/tools/get-fields.sh | 1 318 files changed, 3452 insertions(+), 27297 deletions(-) diff -r ef290f39ae6b -r c96507e0c83d Config.mk --- a/Config.mk Thu May 15 14:53:48 2008 +0900 +++ b/Config.mk Thu May 15 16:23:56 2008 +0900 @@ -4,14 +4,9 @@ debug ?= n debug ?= n XEN_COMPILE_ARCH ?= $(shell uname -m | sed -e s/i.86/x86_32/ \ - -e s/ppc/powerpc/ -e s/i86pc/x86_32/ \ - -e s/amd64/x86_64/) + -e s/i86pc/x86_32/ -e s/amd64/x86_64/) XEN_TARGET_ARCH ?= $(XEN_COMPILE_ARCH) XEN_OS ?= $(shell uname -s) - -ifeq ($(XEN_TARGET_ARCH),x86_32) -XEN_TARGET_X86_PAE ?= y -endif CONFIG_$(XEN_OS) := y diff -r ef290f39ae6b -r c96507e0c83d Makefile --- a/Makefile Thu May 15 14:53:48 2008 +0900 +++ b/Makefile Thu May 15 16:23:56 2008 +0900 @@ -12,10 +12,6 @@ SUBARCH := $(subst x86_32,i386,$(XEN_TAR SUBARCH := $(subst x86_32,i386,$(XEN_TARGET_ARCH)) export XEN_TARGET_ARCH SUBARCH XEN_SYSTYPE include buildconfigs/Rules.mk - -ifeq ($(XEN_TARGET_X86_PAE),y) -export pae=y -endif # build and install everything into the standard system directories .PHONY: install diff -r ef290f39ae6b -r c96507e0c83d buildconfigs/mk.linux-2.6-common --- a/buildconfigs/mk.linux-2.6-common Thu May 15 14:53:48 2008 +0900 +++ b/buildconfigs/mk.linux-2.6-common Thu May 15 16:23:56 2008 +0900 @@ -91,11 +91,7 @@ ifneq ($(XEN_LINUX_CONFIG_UPDATE),) sh $(XEN_LINUX_CONFIG_UPDATE) $(CONFIG_FILE) endif ifeq ($(XEN_TARGET_ARCH),x86_32) -ifeq ($(pae),y) sed -e 's!^CONFIG_HIGHMEM4G=y$$!\# CONFIG_HIGHMEM4G is not set!;s!^\# CONFIG_HIGHMEM64G is not set$$!CONFIG_HIGHMEM64G=y!' $(CONFIG_FILE) > $(CONFIG_FILE)- && mv $(CONFIG_FILE)- $(CONFIG_FILE) -else - grep '^CONFIG_HIGHMEM64G=y' $(CONFIG_FILE) >/dev/null && ( sed -e 's!^CONFIG_HIGHMEM64G=y$$!\# CONFIG_HIGHMEM64G is not set!;s!^\# CONFIG_HIGHMEM4G is not set$$!CONFIG_HIGHMEM4G=y!' $(CONFIG_FILE) > $(CONFIG_FILE)- && mv $(CONFIG_FILE)- $(CONFIG_FILE) ) || true -endif endif ifneq ($(EXTRAVERSION),) echo "$(EXTRAVERSION)" >$(LINUX_DIR)/localversion-xen diff -r ef290f39ae6b -r c96507e0c83d buildconfigs/mk.linux-2.6.5-SLES-xen --- a/buildconfigs/mk.linux-2.6.5-SLES-xen Thu May 15 14:53:48 2008 +0900 +++ b/buildconfigs/mk.linux-2.6.5-SLES-xen Thu May 15 16:23:56 2008 +0900 @@ -1,6 +1,4 @@ -# This tree only supports PAE XEN_TARGET_ARCH = x86_32 -XEN_TARGET_X86_PAE = y EXTRAVERSION = -xen LINUX_VER = 2.6.5-SLES diff -r ef290f39ae6b -r c96507e0c83d buildconfigs/mk.linux-2.6.9-RHEL-xen --- a/buildconfigs/mk.linux-2.6.9-RHEL-xen Thu May 15 14:53:48 2008 +0900 +++ b/buildconfigs/mk.linux-2.6.9-RHEL-xen Thu May 15 16:23:56 2008 +0900 @@ -1,6 +1,4 @@ -# This tree only supports PAE XEN_TARGET_ARCH = x86_32 -XEN_TARGET_X86_PAE = y EXTRAVERSION = -xen LINUX_VER = 2.6.9-RHEL diff -r ef290f39ae6b -r c96507e0c83d config/powerpc64.mk --- a/config/powerpc64.mk Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -CONFIG_POWERPC := y -CONFIG_POWERPC_$(XEN_OS) := y - -CONFIG_XENCOMM := y - -CFLAGS += -DELFSIZE=64 diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/Config.mk --- a/extras/mini-os/Config.mk Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/Config.mk Thu May 15 16:23:56 2008 +0900 @@ -2,9 +2,6 @@ MINI-OS_ROOT=$(XEN_ROOT)/extras/mini-os MINI-OS_ROOT=$(XEN_ROOT)/extras/mini-os export MINI-OS_ROOT -ifeq ($(XEN_TARGET_ARCH),x86_32) -export pae ?= y -endif libc = $(stubdom) XEN_INTERFACE_VERSION := 0x00030205 @@ -25,7 +22,6 @@ TARGET_ARCH_DIR := arch/$(TARGET_ARCH_FA # Export these variables for possible use in architecture dependent makefiles. export TARGET_ARCH_DIR export TARGET_ARCH_FAM -export XEN_TARGET_X86_PAE # This is used for architecture specific links. # This can be overwritten from arch specific rules. @@ -70,7 +66,3 @@ ifneq ($(CAMLDIR),) ifneq ($(CAMLDIR),) caml=y endif - -ifeq ($(pae),y) -DEF_CPPFLAGS += -DCONFIG_X86_PAE -endif diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/arch/x86/arch.mk --- a/extras/mini-os/arch/x86/arch.mk Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/arch/x86/arch.mk Thu May 15 16:23:56 2008 +0900 @@ -9,11 +9,6 @@ ARCH_ASFLAGS := -m32 ARCH_ASFLAGS := -m32 EXTRA_INC += $(TARGET_ARCH_FAM)/$(XEN_TARGET_ARCH) EXTRA_SRC += arch/$(EXTRA_INC) - -ifeq ($(XEN_TARGET_X86_PAE),y) -ARCH_CFLAGS += -DCONFIG_X86_PAE=1 -ARCH_ASFLAGS += -DCONFIG_X86_PAE=1 -endif endif ifeq ($(XEN_TARGET_ARCH),x86_64) diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/arch/x86/mm.c --- a/extras/mini-os/arch/x86/mm.c Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/arch/x86/mm.c Thu May 15 16:23:56 2008 +0900 @@ -79,13 +79,11 @@ void new_pt_frame(unsigned long *pt_pfn, prot_t = L2_PROT; pincmd = MMUEXT_PIN_L1_TABLE; break; -#if defined(__x86_64__) || defined(CONFIG_X86_PAE) case L2_FRAME: prot_e = L2_PROT; prot_t = L3_PROT; pincmd = MMUEXT_PIN_L2_TABLE; break; -#endif #if defined(__x86_64__) case L3_FRAME: prot_e = L3_PROT; @@ -102,11 +100,8 @@ void new_pt_frame(unsigned long *pt_pfn, /* Update the entry */ #if defined(__x86_64__) tab = pte_to_virt(tab[l4_table_offset(pt_page)]); +#endif tab = pte_to_virt(tab[l3_table_offset(pt_page)]); -#endif -#if defined(CONFIG_X86_PAE) - tab = pte_to_virt(tab[l3_table_offset(pt_page)]); -#endif mmu_updates[0].ptr = ((pgentry_t)tab[l2_table_offset(pt_page)] & PAGE_MASK) + sizeof(pgentry_t) * l1_table_offset(pt_page); @@ -164,7 +159,6 @@ static int need_pt_frame(unsigned long v } else #endif -#if defined(__x86_64__) || defined(CONFIG_X86_PAE) if(level == L2_FRAME) { #if defined(__x86_64__) @@ -181,7 +175,6 @@ static int need_pt_frame(unsigned long v return 1; } else -#endif /* defined(__x86_64__) || defined(CONFIG_X86_PAE) */ /* Always need l1 frames */ if(level == L1_FRAME) @@ -236,7 +229,6 @@ void build_pagetable(unsigned long *star mfn = pte_to_mfn(page); tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT); #endif -#if defined(__x86_64__) || defined(CONFIG_X86_PAE) offset = l3_table_offset(start_address); /* Need new L2 pt frame */ if(!(start_address & L2_MASK)) @@ -246,7 +238,6 @@ void build_pagetable(unsigned long *star page = tab[offset]; mfn = pte_to_mfn(page); tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT); -#endif offset = l2_table_offset(start_address); /* Need new L1 pt frame */ if(!(start_address & L1_MASK)) @@ -298,12 +289,10 @@ static void set_readonly(void *text, voi mfn = pte_to_mfn(page); tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT); #endif -#if defined(__x86_64__) || defined(CONFIG_X86_PAE) offset = l3_table_offset(start_address); page = tab[offset]; mfn = pte_to_mfn(page); tab = to_virt(mfn_to_pfn(mfn) << PAGE_SHIFT); -#endif offset = l2_table_offset(start_address); page = tab[offset]; mfn = pte_to_mfn(page); @@ -382,13 +371,11 @@ static pgentry_t *get_pgt(unsigned long mfn = pte_to_mfn(tab[offset]); tab = mfn_to_virt(mfn); #endif -#if defined(__x86_64__) || defined(CONFIG_X86_PAE) offset = l3_table_offset(addr); if (!(tab[offset] & _PAGE_PRESENT)) return NULL; mfn = pte_to_mfn(tab[offset]); tab = mfn_to_virt(mfn); -#endif offset = l2_table_offset(addr); if (!(tab[offset] & _PAGE_PRESENT)) return NULL; @@ -418,7 +405,6 @@ static pgentry_t *need_pgt(unsigned long mfn = pte_to_mfn(tab[offset]); tab = mfn_to_virt(mfn); #endif -#if defined(__x86_64__) || defined(CONFIG_X86_PAE) offset = l3_table_offset(addr); if (!(tab[offset] & _PAGE_PRESENT)) { pt_pfn = virt_to_pfn(alloc_page()); @@ -427,7 +413,6 @@ static pgentry_t *need_pgt(unsigned long ASSERT(tab[offset] & _PAGE_PRESENT); mfn = pte_to_mfn(tab[offset]); tab = mfn_to_virt(mfn); -#endif offset = l2_table_offset(addr); if (!(tab[offset] & _PAGE_PRESENT)) { pt_pfn = virt_to_pfn(alloc_page()); diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/arch/x86/setup.c --- a/extras/mini-os/arch/x86/setup.c Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/arch/x86/setup.c Thu May 15 16:23:56 2008 +0900 @@ -53,7 +53,7 @@ void hypervisor_callback(void); void hypervisor_callback(void); void failsafe_callback(void); -#if !defined(CONFIG_X86_PAE) +#if defined(__x86_64__) #define __pte(x) ((pte_t) { (x) } ) #else #define __pte(x) ({ unsigned long long _x = (x); \ diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/arch/x86/time.c --- a/extras/mini-os/arch/x86/time.c Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/arch/x86/time.c Thu May 15 16:23:56 2008 +0900 @@ -201,10 +201,12 @@ void block_domain(s_time_t until) { struct timeval tv; gettimeofday(&tv, NULL); + ASSERT(irqs_disabled()); if(monotonic_clock() < until) { HYPERVISOR_set_timer_op(until); HYPERVISOR_sched_op(SCHEDOP_block, 0); + local_irq_disable(); } } diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/arch/x86/traps.c --- a/extras/mini-os/arch/x86/traps.c Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/arch/x86/traps.c Thu May 15 16:23:56 2008 +0900 @@ -104,11 +104,9 @@ void page_walk(unsigned long virt_addres tab = pte_to_virt(page); printk(" L4 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l4_table_offset(addr)); #endif -#if defined(__x86_64__) || defined(CONFIG_X86_PAE) page = tab[l3_table_offset(addr)]; tab = pte_to_virt(page); printk(" L3 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l3_table_offset(addr)); -#endif page = tab[l2_table_offset(addr)]; tab = pte_to_virt(page); printk(" L2 = %"PRIpte" (%p) [offset = %lx]\n", page, tab, l2_table_offset(addr)); @@ -129,12 +127,11 @@ static int handle_cow(unsigned long addr return 0; tab = pte_to_virt(page); #endif -#if defined(__x86_64__) || defined(CONFIG_X86_PAE) page = tab[l3_table_offset(addr)]; if (!(page & _PAGE_PRESENT)) return 0; tab = pte_to_virt(page); -#endif + page = tab[l2_table_offset(addr)]; if (!(page & _PAGE_PRESENT)) return 0; diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/arch/x86/x86_32.S --- a/extras/mini-os/arch/x86/x86_32.S Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/arch/x86/x86_32.S Thu May 15 16:23:56 2008 +0900 @@ -8,11 +8,7 @@ .ascii ",VIRT_BASE=0x0" /* &_text from minios_x86_32.lds */ .ascii ",ELF_PADDR_OFFSET=0x0" .ascii ",HYPERCALL_PAGE=0x2" -#ifdef CONFIG_X86_PAE .ascii ",PAE=yes" -#else - .ascii ",PAE=no" -#endif .ascii ",LOADER=generic" .byte 0 .text diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/blkfront.c --- a/extras/mini-os/blkfront.c Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/blkfront.c Thu May 15 16:23:56 2008 +0900 @@ -68,6 +68,21 @@ void blkfront_handler(evtchn_port_t port wake_up(&blkfront_queue); } +static void free_blkfront(struct blkfront_dev *dev) +{ + mask_evtchn(dev->evtchn); + + free(dev->backend); + + gnttab_end_access(dev->ring_ref); + free_page(dev->ring.sring); + + unbind_evtchn(dev->evtchn); + + free(dev->nodename); + free(dev); +} + struct blkfront_dev *init_blkfront(char *nodename, struct blkfront_info *info) { xenbus_transaction_t xbt; @@ -88,6 +103,7 @@ struct blkfront_dev *init_blkfront(char printk("******************* BLKFRONT for %s **********\n\n\n", nodename); dev = malloc(sizeof(*dev)); + memset(dev, 0, sizeof(*dev)); dev->nodename = strdup(nodename); snprintf(path, sizeof(path), "%s/backend-id", nodename); @@ -139,7 +155,7 @@ again: abort_transaction: xenbus_transaction_end(xbt, 1, &retry); - return NULL; + goto error; done: @@ -147,7 +163,7 @@ done: msg = xenbus_read(XBT_NIL, path, &dev->backend); if (msg) { printk("Error %s when reading the backend path %s\n", msg, path); - return NULL; + goto error; } printk("backend at %s\n", dev->backend); @@ -160,7 +176,7 @@ done: msg = xenbus_read(XBT_NIL, path, &c); if (msg) { printk("Error %s when reading the mode\n", msg); - return NULL; + goto error; } if (*c == 'w') dev->info.mode = O_RDWR; @@ -198,6 +214,10 @@ done: printk("**************************\n"); return dev; + +error: + free_blkfront(dev); + return NULL; } void shutdown_blkfront(struct blkfront_dev *dev) @@ -220,11 +240,7 @@ void shutdown_blkfront(struct blkfront_d xenbus_unwatch_path(XBT_NIL, path); - unbind_evtchn(dev->evtchn); - - free(nodename); - free(dev->backend); - free(dev); + free_blkfront(dev); } static void blkfront_wait_slot(struct blkfront_dev *dev) diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/events.c --- a/extras/mini-os/events.c Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/events.c Thu May 15 16:23:56 2008 +0900 @@ -58,9 +58,12 @@ int do_event(evtchn_port_t port, struct int do_event(evtchn_port_t port, struct pt_regs *regs) { ev_action_t *action; + + clear_evtchn(port); + if (port >= NR_EVS) { printk("Port number too large: %d\n", port); - goto out; + return 1; } action = &ev_actions[port]; @@ -68,9 +71,6 @@ int do_event(evtchn_port_t port, struct /* call the handler */ action->handler(port, regs, action->data); - - out: - clear_evtchn(port); return 1; diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/fbfront.c --- a/extras/mini-os/fbfront.c Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/fbfront.c Thu May 15 16:23:56 2008 +0900 @@ -49,6 +49,20 @@ void kbdfront_handler(evtchn_port_t port wake_up(&kbdfront_queue); } +static void free_kbdfront(struct kbdfront_dev *dev) +{ + mask_evtchn(dev->evtchn); + + free(dev->backend); + + free_page(dev->page); + + unbind_evtchn(dev->evtchn); + + free(dev->nodename); + free(dev); +} + struct kbdfront_dev *init_kbdfront(char *nodename, int abs_pointer) { xenbus_transaction_t xbt; @@ -122,7 +136,7 @@ again: abort_transaction: xenbus_transaction_end(xbt, 1, &retry); - return NULL; + goto error; done: @@ -130,7 +144,7 @@ done: msg = xenbus_read(XBT_NIL, path, &dev->backend); if (msg) { printk("Error %s when reading the backend path %s\n", msg, path); - return NULL; + goto error; } printk("backend at %s\n", dev->backend); @@ -153,6 +167,9 @@ done: printk("************************** KBDFRONT\n"); return dev; +error: + free_kbdfront(dev); + return NULL; } int kbdfront_receive(struct kbdfront_dev *dev, union xenkbd_in_event *buf, int n) @@ -208,12 +225,7 @@ void shutdown_kbdfront(struct kbdfront_d xenbus_unwatch_path(XBT_NIL, path); - unbind_evtchn(dev->evtchn); - - free_pages(dev->page,0); - free(nodename); - free(dev->backend); - free(dev); + free_kbdfront(dev); } #ifdef HAVE_LIBC @@ -255,11 +267,69 @@ struct fbfront_dev { int offset; xenbus_event_queue events; + +#ifdef HAVE_LIBC + int fd; +#endif }; void fbfront_handler(evtchn_port_t port, struct pt_regs *regs, void *data) { +#ifdef HAVE_LIBC + struct fbfront_dev *dev = data; + int fd = dev->fd; + + files[fd].read = 1; +#endif wake_up(&fbfront_queue); +} + +static void free_fbfront(struct fbfront_dev *dev) +{ + mask_evtchn(dev->evtchn); + + free(dev->backend); + + free_page(dev->page); + + unbind_evtchn(dev->evtchn); + + free(dev->nodename); + free(dev); +} + +int fbfront_receive(struct fbfront_dev *dev, union xenfb_in_event *buf, int n) +{ + struct xenfb_page *page = dev->page; + uint32_t prod, cons; + 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 */ +#endif + + prod = page->in_prod; + + if (prod == page->in_cons) + return 0; + + rmb(); /* ensure we see ring contents up to prod */ + + for (i = 0, cons = page->in_cons; i < n && cons != prod; i++, cons++) + memcpy(buf + i, &XENFB_IN_RING_REF(page, cons), sizeof(*buf)); + + mb(); /* ensure we got ring contents */ + page->in_cons = cons; + notify_remote_via_evtchn(dev->evtchn); + +#ifdef HAVE_LIBC + if (cons != prod) + /* still some events to read */ + files[dev->fd].read = 1; +#endif + + return i; } struct fbfront_dev *init_fbfront(char *nodename, unsigned long *mfns, int width, int height, int depth, int stride, int n) @@ -357,7 +427,7 @@ again: abort_transaction: xenbus_transaction_end(xbt, 1, &retry); - return NULL; + goto error; done: @@ -365,7 +435,7 @@ done: msg = xenbus_read(XBT_NIL, path, &dev->backend); if (msg) { printk("Error %s when reading the backend path %s\n", msg, path); - return NULL; + goto error; } printk("backend at %s\n", dev->backend); @@ -391,6 +461,10 @@ done: printk("************************** FBFRONT\n"); return dev; + +error: + free_fbfront(dev); + return NULL; } static void fbfront_out_event(struct fbfront_dev *dev, union xenfb_out_event *event) @@ -477,8 +551,16 @@ void shutdown_fbfront(struct fbfront_dev unbind_evtchn(dev->evtchn); - free_pages(dev->page,0); - free(nodename); - free(dev->backend); - free(dev); -} + free_fbfront(dev); +} + +#ifdef HAVE_LIBC +int fbfront_open(struct fbfront_dev *dev) +{ + dev->fd = alloc_fd(FTYPE_FB); + printk("fb_open(%s) -> %d\n", dev->nodename, dev->fd); + files[dev->fd].fb.dev = dev; + return dev->fd; +} +#endif + diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/hypervisor.c --- a/extras/mini-os/hypervisor.c Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/hypervisor.c Thu May 15 16:23:56 2008 +0900 @@ -46,7 +46,11 @@ void do_hypervisor_callback(struct pt_re in_callback = 1; vcpu_info->evtchn_upcall_pending = 0; - /* NB. No need for a barrier here -- XCHG is a barrier on x86. */ + /* NB x86. No need for a barrier here -- XCHG is a barrier on x86. */ +#if !defined(__i386__) && !defined(__x86_64__) + /* Clear master flag /before/ clearing selector flag. */ + wmb(); +#endif l1 = xchg(&vcpu_info->evtchn_pending_sel, 0); while ( l1 != 0 ) { @@ -58,7 +62,7 @@ void do_hypervisor_callback(struct pt_re l2i = __ffs(l2); l2 &= ~(1 << l2i); - port = (l1i << 5) + l2i; + port = (l1i * (sizeof(unsigned long) * 8)) + l2i; do_event(port, regs); } } @@ -100,7 +104,8 @@ inline void unmask_evtchn(u32 port) * a real IO-APIC we 'lose the interrupt edge' if the channel is masked. */ if ( synch_test_bit (port, &s->evtchn_pending[0]) && - !synch_test_and_set_bit(port>>5, &vcpu_info->evtchn_pending_sel) ) + !synch_test_and_set_bit(port / (sizeof(unsigned long) * 8), + &vcpu_info->evtchn_pending_sel) ) { vcpu_info->evtchn_upcall_pending = 1; if ( !vcpu_info->evtchn_upcall_mask ) diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/include/arch/cc.h --- a/extras/mini-os/include/arch/cc.h Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/include/arch/cc.h Thu May 15 16:23:56 2008 +0900 @@ -84,7 +84,4 @@ extern void lwip_die(char *fmt, ...); #define DBG_TYPES_ON DBG_ON #endif -/* TODO: checksum doesn't work fine?! */ -#define CHECKSUM_CHECK_TCP 0 - #endif /* __LWIP_ARCH_CC_H__ */ diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/include/fbfront.h --- a/extras/mini-os/include/fbfront.h Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/include/fbfront.h Thu May 15 16:23:56 2008 +0900 @@ -1,4 +1,5 @@ #include <xen/io/kbdif.h> +#include <xen/io/fbif.h> #include <wait.h> /* from <linux/input.h> */ @@ -36,6 +37,8 @@ int fbfront_open(struct fbfront_dev *dev int fbfront_open(struct fbfront_dev *dev); #endif +int fbfront_receive(struct fbfront_dev *dev, union xenfb_in_event *buf, int n); +extern struct wait_queue_head fbfront_queue; void fbfront_update(struct fbfront_dev *dev, int x, int y, int width, int height); void fbfront_resize(struct fbfront_dev *dev, int width, int height, int stride, int depth, int offset); diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/include/lib.h --- a/extras/mini-os/include/lib.h Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/include/lib.h Thu May 15 16:23:56 2008 +0900 @@ -141,6 +141,7 @@ enum fd_type { FTYPE_TAP, FTYPE_BLK, FTYPE_KBD, + FTYPE_FB, }; #define MAX_EVTCHN_PORTS 16 @@ -175,6 +176,9 @@ extern struct file { struct { struct kbdfront_dev *dev; } kbd; + struct { + struct fbfront_dev *dev; + } fb; struct { /* To each xenbus FD is associated a queue of watch events for this * FD. */ diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/include/mm.h --- a/extras/mini-os/include/mm.h Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/include/mm.h Thu May 15 16:23:56 2008 +0900 @@ -48,6 +48,7 @@ unsigned long alloc_pages(int order); unsigned long alloc_pages(int order); #define alloc_page() alloc_pages(0) void free_pages(void *pointer, int order); +#define free_page(p) free_pages(p, 0) static __inline__ int get_order(unsigned long size) { diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/include/types.h --- a/extras/mini-os/include/types.h Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/include/types.h Thu May 15 16:23:56 2008 +0900 @@ -43,11 +43,7 @@ typedef long long quad_t; typedef long long quad_t; typedef unsigned long long u_quad_t; -#if !defined(CONFIG_X86_PAE) -typedef struct { unsigned long pte_low; } pte_t; -#else typedef struct { unsigned long pte_low, pte_high; } pte_t; -#endif /* CONFIG_X86_PAE */ #elif defined(__x86_64__) || defined(__ia64__) typedef long quad_t; @@ -56,7 +52,7 @@ typedef struct { unsigned long pte; } pt typedef struct { unsigned long pte; } pte_t; #endif /* __i386__ || __x86_64__ */ -#if !defined(CONFIG_X86_PAE) +#ifdef __x86_64__ #define __pte(x) ((pte_t) { (x) } ) #else #define __pte(x) ({ unsigned long long _x = (x); \ diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/include/x86/arch_limits.h --- a/extras/mini-os/include/x86/arch_limits.h Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/include/x86/arch_limits.h Thu May 15 16:23:56 2008 +0900 @@ -7,7 +7,7 @@ #ifdef __ASSEMBLY__ #define __PAGE_SIZE (1 << __PAGE_SHIFT) #else -#ifndef CONFIG_X86_PAE +#ifdef __x86_64__ #define __PAGE_SIZE (1UL << __PAGE_SHIFT) #else #define __PAGE_SIZE (1ULL << __PAGE_SHIFT) diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/include/x86/arch_mm.h --- a/extras/mini-os/include/x86/arch_mm.h Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/include/x86/arch_mm.h Thu May 15 16:23:56 2008 +0900 @@ -44,24 +44,6 @@ #if defined(__i386__) -#if !defined(CONFIG_X86_PAE) - -#define L2_PAGETABLE_SHIFT 22 - -#define L1_PAGETABLE_ENTRIES 1024 -#define L2_PAGETABLE_ENTRIES 1024 - -#define PADDR_BITS 32 -#define PADDR_MASK (~0UL) - -#define NOT_L1_FRAMES 1 -#define PRIpte "08lx" -#ifndef __ASSEMBLY__ -typedef unsigned long pgentry_t; -#endif - -#else /* defined(CONFIG_X86_PAE) */ - #define L2_PAGETABLE_SHIFT 21 #define L3_PAGETABLE_SHIFT 30 @@ -85,8 +67,6 @@ typedef uint64_t pgentry_t; typedef uint64_t pgentry_t; #endif -#endif /* !defined(CONFIG_X86_PAE) */ - #elif defined(__x86_64__) #define L2_PAGETABLE_SHIFT 21 @@ -122,10 +102,8 @@ typedef unsigned long pgentry_t; (((_a) >> L1_PAGETABLE_SHIFT) & (L1_PAGETABLE_ENTRIES - 1)) #define l2_table_offset(_a) \ (((_a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1)) -#if defined(__x86_64__) || defined(CONFIG_X86_PAE) #define l3_table_offset(_a) \ (((_a) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES - 1)) -#endif #if defined(__x86_64__) #define l4_table_offset(_a) \ (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1)) @@ -146,9 +124,7 @@ typedef unsigned long pgentry_t; #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) #define L1_PROT_RO (_PAGE_PRESENT|_PAGE_ACCESSED) #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY |_PAGE_USER) -#if defined(CONFIG_X86_PAE) #define L3_PROT (_PAGE_PRESENT) -#endif /* CONFIG_X86_PAE */ #elif defined(__x86_64__) #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER) #define L1_PROT_RO (_PAGE_PRESENT|_PAGE_ACCESSED|_PAGE_USER) @@ -172,7 +148,7 @@ typedef unsigned long pgentry_t; #ifndef __ASSEMBLY__ /* Definitions for machine and pseudophysical addresses. */ -#ifdef CONFIG_X86_PAE +#ifdef __i386__ typedef unsigned long long paddr_t; typedef unsigned long long maddr_t; #else @@ -225,14 +201,10 @@ static __inline__ paddr_t machine_to_phy #define virtual_to_l3(_virt) PT_BASE #endif -#if defined(__x86_64__) || defined(CONFIG_X86_PAE) #define virtual_to_l2(_virt) ({ \ unsigned long __virt2 = (_virt); \ (pgentry_t *) pte_to_virt(virtual_to_l3(__virt2)[l3_table_offset(__virt2)]); \ }) -#else -#define virtual_to_l2(_virt) PT_BASE -#endif #define virtual_to_l1(_virt) ({ \ unsigned long __virt1 = (_virt); \ diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/include/x86/x86_32/hypercall-x86_32.h --- a/extras/mini-os/include/x86/x86_32/hypercall-x86_32.h Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/include/x86/x86_32/hypercall-x86_32.h Thu May 15 16:23:56 2008 +0900 @@ -220,12 +220,8 @@ HYPERVISOR_update_va_mapping( HYPERVISOR_update_va_mapping( unsigned long va, pte_t new_val, unsigned long flags) { - unsigned long pte_hi = 0; -#ifdef CONFIG_X86_PAE - pte_hi = new_val.pte_high; -#endif return _hypercall4(int, update_va_mapping, va, - new_val.pte_low, pte_hi, flags); + new_val.pte_low, new_val.pte_high, flags); } static inline int @@ -267,12 +263,8 @@ HYPERVISOR_update_va_mapping_otherdomain HYPERVISOR_update_va_mapping_otherdomain( unsigned long va, pte_t new_val, unsigned long flags, domid_t domid) { - unsigned long pte_hi = 0; -#ifdef CONFIG_X86_PAE - pte_hi = new_val.pte_high; -#endif return _hypercall5(int, update_va_mapping_otherdomain, va, - new_val.pte_low, pte_hi, flags, domid); + new_val.pte_low, new_val.pte_high, flags, domid); } static inline int diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/kernel.c --- a/extras/mini-os/kernel.c Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/kernel.c Thu May 15 16:23:56 2008 +0900 @@ -260,6 +260,7 @@ static void blkfront_thread(void *p) #define DEPTH 32 static uint32_t *fb; +static int refresh_period = 50; static struct fbfront_dev *fb_dev; static struct semaphore fbfront_sem = __SEMAPHORE_INITIALIZER(fbfront_sem, 0); @@ -302,13 +303,10 @@ static void fbfront_thread(void *p) memsize = n * PAGE_SIZE; fb = _xmalloc(memsize, PAGE_SIZE); + memset(fb, 0, memsize); mfns = xmalloc_array(unsigned long, n); - for (i = 0; i < n; i++) { - /* trigger CoW */ - ((char *) fb) [i * PAGE_SIZE] = 0; - barrier(); + for (i = 0; i < n; i++) mfns[i] = virtual_to_mfn((char *) fb + i * PAGE_SIZE); - } fb_dev = init_fbfront(NULL, mfns, WIDTH, HEIGHT, DEPTH, line_length, n); xfree(mfns); if (!fb_dev) { @@ -333,6 +331,10 @@ static void refresh_cursor(int new_x, in static void refresh_cursor(int new_x, int new_y) { static int old_x = -1, old_y = -1; + + if (!refresh_period) + return; + if (old_x != -1 && old_y != -1) { fbfront_drawvert(old_x, old_y + 1, old_y + 8, 0xffffffff); fbfront_drawhoriz(old_x + 1, old_x + 8, old_y, 0xffffffff); @@ -358,43 +360,46 @@ static void kbdfront_thread(void *p) down(&fbfront_sem); refresh_cursor(x, y); while (1) { - union xenkbd_in_event event; + union xenkbd_in_event kbdevent; + union xenfb_in_event fbevent; + int sleep = 1; add_waiter(w, kbdfront_queue); - - if (kbdfront_receive(kbd_dev, &event, 1) == 0) - schedule(); - else switch(event.type) { + add_waiter(w, fbfront_queue); + + while (kbdfront_receive(kbd_dev, &kbdevent, 1) != 0) { + sleep = 0; + switch(kbdevent.type) { case XENKBD_TYPE_MOTION: printk("motion x:%d y:%d z:%d\n", - event.motion.rel_x, - event.motion.rel_y, - event.motion.rel_z); - x += event.motion.rel_x; - y += event.motion.rel_y; - z += event.motion.rel_z; + kbdevent.motion.rel_x, + kbdevent.motion.rel_y, + kbdevent.motion.rel_z); + x += kbdevent.motion.rel_x; + y += kbdevent.motion.rel_y; + z += kbdevent.motion.rel_z; clip_cursor(&x, &y); refresh_cursor(x, y); break; case XENKBD_TYPE_POS: printk("pos x:%d y:%d dz:%d\n", - event.pos.abs_x, - event.pos.abs_y, - event.pos.rel_z); - x = event.pos.abs_x; - y = event.pos.abs_y; - z = event.pos.rel_z; + kbdevent.pos.abs_x, + kbdevent.pos.abs_y, + kbdevent.pos.rel_z); + x = kbdevent.pos.abs_x; + y = kbdevent.pos.abs_y; + z = kbdevent.pos.rel_z; clip_cursor(&x, &y); refresh_cursor(x, y); break; case XENKBD_TYPE_KEY: printk("key %d %s\n", - event.key.keycode, - event.key.pressed ? "pressed" : "released"); - if (event.key.keycode == BTN_LEFT) { + kbdevent.key.keycode, + kbdevent.key.pressed ? "pressed" : "released"); + if (kbdevent.key.keycode == BTN_LEFT) { printk("mouse %s at (%d,%d,%d)\n", - event.key.pressed ? "clic" : "release", x, y, z); - if (event.key.pressed) { + kbdevent.key.pressed ? "clic" : "release", x, y, z); + if (kbdevent.key.pressed) { uint32_t color = rand(); fbfront_drawvert(x - 16, y - 16, y + 15, color); fbfront_drawhoriz(x - 16, x + 15, y + 16, color); @@ -402,13 +407,26 @@ static void kbdfront_thread(void *p) fbfront_drawhoriz(x - 15, x + 16, y - 16, color); fbfront_update(fb_dev, x - 16, y - 16, 33, 33); } - } else if (event.key.keycode == KEY_Q) { + } else if (kbdevent.key.keycode == KEY_Q) { struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff }; HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown); do_exit(); } break; + } } + while (fbfront_receive(fb_dev, &fbevent, 1) != 0) { + sleep = 0; + switch(fbevent.type) { + case XENFB_TYPE_REFRESH_PERIOD: + refresh_period = fbevent.refresh_period.period; + printk("refresh period %d\n", refresh_period); + refresh_cursor(x, y); + break; + } + } + if (sleep) + schedule(); } } diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/lib/sys.c --- a/extras/mini-os/lib/sys.c Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/lib/sys.c Thu May 15 16:23:56 2008 +0900 @@ -249,6 +249,16 @@ int read(int fd, void *buf, size_t nbyte } return ret * sizeof(union xenkbd_in_event); } + case FTYPE_FB: { + int ret, n; + n = nbytes / sizeof(union xenfb_in_event); + ret = fbfront_receive(files[fd].fb.dev, buf, n); + if (ret <= 0) { + errno = EAGAIN; + return -1; + } + return ret * sizeof(union xenfb_in_event); + } case FTYPE_NONE: case FTYPE_XENBUS: case FTYPE_EVTCHN: @@ -290,6 +300,7 @@ int write(int fd, const void *buf, size_ case FTYPE_EVTCHN: case FTYPE_BLK: case FTYPE_KBD: + case FTYPE_FB: break; } printk("write(%d): Bad descriptor\n", fd); @@ -348,6 +359,7 @@ int fsync(int fd) { case FTYPE_TAP: case FTYPE_BLK: case FTYPE_KBD: + case FTYPE_FB: break; } printk("fsync(%d): Bad descriptor\n", fd); @@ -394,6 +406,10 @@ int close(int fd) shutdown_kbdfront(files[fd].kbd.dev); files[fd].type = FTYPE_NONE; return 0; + case FTYPE_FB: + shutdown_fbfront(files[fd].fb.dev); + files[fd].type = FTYPE_NONE; + return 0; case FTYPE_NONE: break; } @@ -485,6 +501,7 @@ int fstat(int fd, struct stat *buf) case FTYPE_TAP: case FTYPE_BLK: case FTYPE_KBD: + case FTYPE_FB: break; } @@ -513,6 +530,7 @@ int ftruncate(int fd, off_t length) case FTYPE_TAP: case FTYPE_BLK: case FTYPE_KBD: + case FTYPE_FB: break; } @@ -624,6 +642,7 @@ static const char file_types[] = { [FTYPE_TAP] = 'T', [FTYPE_BLK] = 'B', [FTYPE_KBD] = 'K', + [FTYPE_FB] = 'G', }; #ifdef LIBC_DEBUG static void dump_set(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout) @@ -732,6 +751,7 @@ static int select_poll(int nfds, fd_set case FTYPE_TAP: case FTYPE_BLK: case FTYPE_KBD: + case FTYPE_FB: if (FD_ISSET(i, readfds)) { if (files[i].read) n++; diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/lib/xmalloc.c --- a/extras/mini-os/lib/xmalloc.c Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/lib/xmalloc.c Thu May 15 16:23:56 2008 +0900 @@ -264,7 +264,7 @@ void xfree(const void *p) printk("Bug\n"); *(int*)0=0; } - free_pages(hdr, 0); + free_page(hdr); } else { diff -r ef290f39ae6b -r c96507e0c83d extras/mini-os/netfront.c --- a/extras/mini-os/netfront.c Thu May 15 14:53:48 2008 +0900 +++ b/extras/mini-os/netfront.c Thu May 15 16:23:56 2008 +0900 @@ -52,6 +52,7 @@ struct netfront_dev { char *nodename; char *backend; + char *mac; xenbus_event_queue events; @@ -263,6 +264,39 @@ void netfront_select_handler(evtchn_port } #endif +static void free_netfront(struct netfront_dev *dev) +{ + int i; + + for(i=0;i<NET_TX_RING_SIZE;i++) + down(&dev->tx_sem); + + mask_evtchn(dev->evtchn); + + free(dev->mac); + free(dev->backend); + + gnttab_end_access(dev->rx_ring_ref); + gnttab_end_access(dev->tx_ring_ref); + + free_page(dev->rx.sring); + free_page(dev->tx.sring); + + unbind_evtchn(dev->evtchn); + + for(i=0;i<NET_RX_RING_SIZE;i++) { + gnttab_end_access(dev->rx_buffers[i].gref); + free_page(dev->rx_buffers[i].page); + } + + for(i=0;i<NET_TX_RING_SIZE;i++) + if (dev->tx_buffers[i].page) + free_page(dev->tx_buffers[i].page); + + free(dev->nodename); + free(dev); +} + struct netfront_dev *init_netfront(char *nodename, void (*thenetif_rx)(unsigned char* data, int len), unsigned char rawmac[6], char **ip) { xenbus_transaction_t xbt; @@ -272,7 +306,6 @@ struct netfront_dev *init_netfront(char struct netif_rx_sring *rxs; int retry=0; int i; - char* mac; char* msg; struct netfront_dev *dev; @@ -288,6 +321,7 @@ struct netfront_dev *init_netfront(char printk("************************ NETFRONT for %s **********\n\n\n", nodename); dev = malloc(sizeof(*dev)); + memset(dev, 0, sizeof(*dev)); dev->nodename = strdup(nodename); printk("net TX ring size %d\n", NET_TX_RING_SIZE); @@ -314,7 +348,7 @@ struct netfront_dev *init_netfront(char #endif evtchn_alloc_unbound(dev->dom, netfront_handler, dev, &dev->evtchn); - txs = (struct netif_tx_sring*) alloc_page(); + txs = (struct netif_tx_sring *) alloc_page(); rxs = (struct netif_rx_sring *) alloc_page(); memset(txs,0,PAGE_SIZE); memset(rxs,0,PAGE_SIZE); @@ -328,11 +362,12 @@ struct netfront_dev *init_netfront(char dev->tx_ring_ref = gnttab_grant_access(dev->dom,virt_to_mfn(txs),0); dev->rx_ring_ref = gnttab_grant_access(dev->dom,virt_to_mfn(rxs),0); + init_rx_buffers(dev); + dev->netif_rx = thenetif_rx; dev->events = NULL; - // FIXME: proper frees on failures again: err = xenbus_transaction_start(&xbt); if (err) { @@ -379,25 +414,22 @@ again: abort_transaction: xenbus_transaction_end(xbt, 1, &retry); - return NULL; + goto error; done: snprintf(path, sizeof(path), "%s/backend", nodename); msg = xenbus_read(XBT_NIL, path, &dev->backend); snprintf(path, sizeof(path), "%s/mac", nodename); - msg = xenbus_read(XBT_NIL, path, &mac); - - if ((dev->backend == NULL) || (mac == NULL)) { - struct evtchn_close op = { dev->evtchn }; + msg = xenbus_read(XBT_NIL, path, &dev->mac); + + if ((dev->backend == NULL) || (dev->mac == NULL)) { printk("%s: backend/mac failed\n", __func__); - unbind_evtchn(dev->evtchn); - HYPERVISOR_event_channel_op(EVTCHNOP_close, &op); - return NULL; + goto error; } printk("backend at %s\n",dev->backend); - printk("mac is %s\n",mac); + printk("mac is %s\n",dev->mac); { char path[strlen(dev->backend) + 1 + 5 + 1]; @@ -415,13 +447,12 @@ done: printk("**************************\n"); - init_rx_buffers(dev); unmask_evtchn(dev->evtchn); /* Special conversion specifier 'hh' needed for __ia64__. Without this mini-os panics with 'Unaligned reference'. */ if (rawmac) - sscanf(mac,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + sscanf(dev->mac,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &rawmac[0], &rawmac[1], &rawmac[2], @@ -430,6 +461,9 @@ done: &rawmac[5]); return dev; +error: + free_netfront(dev); + return NULL; } #ifdef HAVE_LIBC @@ -467,11 +501,7 @@ void shutdown_netfront(struct netfront_d xenbus_unwatch_path(XBT_NIL, path); - unbind_evtchn(dev->evtchn); - - free(nodename); - free(dev->backend); - free(dev); + free_netfront(dev); } diff -r ef290f39ae6b -r c96507e0c83d tools/examples/xmexample.hvm --- a/tools/examples/xmexample.hvm Thu May 15 14:53:48 2008 +0900 +++ b/tools/examples/xmexample.hvm Thu May 15 16:23:56 2008 +0900 @@ -56,7 +56,8 @@ name = "ExampleHVMDomain" # List of which CPUS this domain is allowed to use, default Xen picks #cpus = "" # leave to Xen to pick #cpus = "0" # all vcpus run on CPU0 -#cpus = "0-3,5,^1" # run on cpus 0,2,3,5 +#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5 +#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3 # Optionally define mac and/or bridge for the network interfaces. # Random MACs are assigned if not given. @@ -222,17 +223,54 @@ serial='pty' #----------------------------------------------------------------------------- # Configure guest CPUID responses: -#cpuid=[ '1:ecx=xxxxxxxxxxxxxxxxxxxxxxxxxx1xxxxx, +# +#cpuid=[ '1:ecx=xxxxxxxxxxx00xxxxxxxxxxxxxxxxxxx, # eax=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' ] -# - Set the VMX feature flag in the guest (CPUID_1:ECX:5) +# - Unset the SSE4 features (CPUID.1[ECX][20-19]) # - Default behaviour for all other bits in ECX And EAX registers. # # Each successive character represent a lesser-significant bit: # '1' -> force the corresponding bit to 1 # '0' -> force to 0 -# 'x' -> we don't care (default behaviour) +# 'x' -> Get a safe value (pass through and mask with the default policy) # 'k' -> pass through the host bit value # 's' -> as 'k' but preserve across save/restore and migration +# +# Expose to the guest multi-core cpu instead of multiple processors +# Example for intel, expose a 8-core processor : +#cpuid=['1:edx=xxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx, +# ebx=xxxxxxxx00010000xxxxxxxxxxxxxxxx', +# '4,0:eax=001111xxxxxxxxxxxxxxxxxxxxxxxxxx'] +# - CPUID.1[EDX][HT] : Enable HT +# - CPUID.1[EBX] : Number of vcpus * 2 +# - CPUID.4,0[EAX] : Number of vcpus * 2 - 1 +#vcpus=8 +# +# Example for amd, expose a 5-core processor : +# cpuid = ['1:ebx=xxxxxxxx00000001xxxxxxxxxxxxxxxx, +# edx=xxx1xxxxxxxxxxxxxxxxxxxxxxxxxxxx', +# '0x80000008:ecx=xxxxxxxxxxxxxxxx0000xxxx00001010'] +# - CPUID.1[EBX] : (Thread * Cores ) per processors +# - CPUID.1[EDX][HT] : Enable HT +# - CPUID.0x80000008[ECX] : Number of vcpus * 2 +#vcpus=5 +# +# Downgrade the cpuid to make a better compatibility for migration : +# Look like a PIII : +# cpuid = [ '0:eax=0x3', +# '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'] +# with the highest leaf +# - CPUID.0[EAX] : Set the highest leaf +# - CPUID.1[EAX] : Pentium III +# - CPUID.1[ECX] : Mask some features +# - CPUID.1[EDX] : Mask some features +# - CPUID.4 : Reply like the highest leaf, in our case CPUID.3 +# - CPUID.0x80000000 : No extension we are on a Pentium III, reply like the +# highest leaf (CPUID.3). # # Configure host CPUID consistency checks, which must be satisfied for this # VM to be allowed to run on this host's processor type: diff -r ef290f39ae6b -r c96507e0c83d tools/examples/xmexample.vti --- a/tools/examples/xmexample.vti Thu May 15 14:53:48 2008 +0900 +++ b/tools/examples/xmexample.vti Thu May 15 16:23:56 2008 +0900 @@ -33,7 +33,8 @@ name = "ExampleVTIDomain" # List of which CPUS this domain is allowed to use, default Xen picks #cpus = "" # leave to Xen to pick #cpus = "0" # all vcpus run on CPU0 -#cpus = "0-3,5,^1" # run on cpus 0,2,3,5 +#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5 +#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3 # Log2 of VHPT size, default=23 (8MB), minimum=15 (32KB). # In Windows OS, smaller size shows better performance. diff -r ef290f39ae6b -r c96507e0c83d tools/examples/xmexample1 --- a/tools/examples/xmexample1 Thu May 15 14:53:48 2008 +0900 +++ b/tools/examples/xmexample1 Thu May 15 16:23:56 2008 +0900 @@ -33,7 +33,8 @@ name = "ExampleDomain" # List of which CPUS this domain is allowed to use, default Xen picks #cpus = "" # leave to Xen to pick #cpus = "0" # all vcpus run on CPU0 -#cpus = "0-3,5,^1" # run on cpus 0,2,3,5 +#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5 +#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3 # Number of Virtual CPUS to use, default is 1 #vcpus = 1 @@ -90,7 +91,7 @@ disk = [ 'phy:hda1,hda1,w' ] # # Or you can bind the first unused port above 5900: # -# vfb = [ 'type=vnc,vnclisten=0.0.0.0,vnunused=1' ] +# vfb = [ 'type=vnc,vnclisten=0.0.0.0,vncunused=1' ] # # You can override the password: # diff -r ef290f39ae6b -r c96507e0c83d tools/examples/xmexample2 --- a/tools/examples/xmexample2 Thu May 15 14:53:48 2008 +0900 +++ b/tools/examples/xmexample2 Thu May 15 16:23:56 2008 +0900 @@ -62,7 +62,8 @@ name = "VM%d" % vmid # List of which CPUS this domain is allowed to use, default Xen picks #cpus = "" # leave to Xen to pick #cpus = "0" # all vcpus run on CPU0 -#cpus = "0-3,5,^1" # run on cpus 0,2,3,5 +#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5 +#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3 #cpus = "%s" % vmid # set based on vmid (mod number of CPUs) # Number of Virtual CPUS to use, default is 1 @@ -126,7 +127,7 @@ disk = [ 'phy:sda%d,sda1,w' % (7+vmid), # # Or you can bind the first unused port above 5900: # -# vfb = [ 'type=vnc,vnclisten=0.0.0.0,vnunused=1' ] +# vfb = [ 'type=vnc,vnclisten=0.0.0.0,vncunused=1' ] # # You can override the password: # diff -r ef290f39ae6b -r c96507e0c83d tools/examples/xmexample3 --- a/tools/examples/xmexample3 Thu May 15 14:53:48 2008 +0900 +++ b/tools/examples/xmexample3 Thu May 15 16:23:56 2008 +0900 @@ -62,7 +62,8 @@ name = "VM%d" % vmid # List of which CPUS this domain is allowed to use, default Xen picks #cpus = "" # leave to Xen to pick #cpus = "0" # all vcpus run on CPU0 -#cpus = "0-3,5,^1" # run on cpus 0,2,3,5 +#cpus = "0-3,5,^1" # all vcpus run on cpus 0,2,3,5 +#cpus = ["2", "3"] # VCPU0 runs on CPU2, VCPU1 runs on CPU3 cpus = "%s" % vmid # set based on vmid (mod number of CPUs) #---------------------------------------------------------------------------- @@ -111,7 +112,7 @@ disk = [ 'phy:hda%d,hda1,w' % (vmid)] # # Or you can bind the first unused port above 5900: # -# vfb = [ 'type=vnc,vnclisten=0.0.0.0,vnunused=1' ] +# vfb = [ 'type=vnc,vnclisten=0.0.0.0,vncunused=1' ] # # You can override the password: # diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/block.c --- a/tools/ioemu/block.c Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/block.c Thu May 15 16:23:56 2008 +0900 @@ -254,7 +254,7 @@ static BlockDriver *find_protocol(const #endif p = strchr(filename, ':'); if (!p) - return &bdrv_raw; + return NULL; /* do not ever guess raw, it is a security problem! */ len = p - filename; if (len > sizeof(protocol) - 1) len = sizeof(protocol) - 1; diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/hw/ide.c --- a/tools/ioemu/hw/ide.c Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/hw/ide.c Thu May 15 16:23:56 2008 +0900 @@ -289,6 +289,7 @@ #define ASC_ILLEGAL_OPCODE 0x20 #define ASC_LOGICAL_BLOCK_OOR 0x21 #define ASC_INV_FIELD_IN_CMD_PACKET 0x24 +#define ASC_MEDIUM_MAY_HAVE_CHANGED 0x28 #define ASC_MEDIUM_NOT_PRESENT 0x3a #define ASC_SAVING_PARAMETERS_NOT_SUPPORTED 0x39 @@ -1456,6 +1457,11 @@ static void ide_atapi_cmd(IDEState *s) switch(s->io_buffer[0]) { case GPCMD_TEST_UNIT_READY: if (bdrv_is_inserted(s->bs)) { + if (s->is_cdrom && s->sense_key == SENSE_NOT_READY) { + ide_atapi_cmd_error(s, SENSE_UNIT_ATTENTION, + ASC_MEDIUM_MAY_HAVE_CHANGED); + break; + } ide_atapi_cmd_ok(s); } else { ide_atapi_cmd_error(s, SENSE_NOT_READY, diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/hw/pass-through.c --- a/tools/ioemu/hw/pass-through.c Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/hw/pass-through.c Thu May 15 16:23:56 2008 +0900 @@ -205,6 +205,7 @@ void pt_iomem_map(PCIDevice *d, int i, u if ( !first_map ) { + add_msix_mapping(assigned_device, i); /* Remove old mapping */ ret = xc_domain_memory_mapping(xc_handle, domid, old_ebase >> XC_PAGE_SHIFT, @@ -227,6 +228,9 @@ void pt_iomem_map(PCIDevice *d, int i, u if ( ret != 0 ) PT_LOG("Error: create new mapping failed!\n"); + ret = remove_msix_mapping(assigned_device, i); + if ( ret != 0 ) + PT_LOG("Error: remove MSX-X mmio mapping failed!\n"); } /* Being called each time a pio region has been updated */ @@ -289,6 +293,9 @@ static void pt_pci_write_config(PCIDevic } if ( pt_msi_write(assigned_device, address, val, len) ) + return; + + if ( pt_msix_write(assigned_device, address, val, len) ) return; /* PCI config pass-through */ @@ -338,6 +345,7 @@ static uint32_t pt_pci_read_config(PCIDe } pt_msi_read(assigned_device, address, len, &val); + pt_msix_read(assigned_device, address, len, &val); exit: #ifdef PT_DEBUG_PCI_CONFIG_ACCESS @@ -549,6 +557,9 @@ struct pt_dev * register_real_device(PCI if ( (pos = find_cap_offset(pci_dev, PCI_CAP_ID_MSI)) ) pt_msi_init(assigned_device, pos); + if ( (pos = find_cap_offset(pci_dev, PCI_CAP_ID_MSIX)) ) + pt_msix_init(assigned_device, pos); + /* Handle real device's MMIO/PIO BARs */ pt_register_regions(assigned_device); diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/hw/pass-through.h --- a/tools/ioemu/hw/pass-through.h Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/hw/pass-through.h Thu May 15 16:23:56 2008 +0900 @@ -61,8 +61,26 @@ struct pt_msi_info { uint32_t flags; int offset; int size; - int pvec; /* physical vector used */ int pirq; /* guest pirq corresponding */ +}; + +struct msix_entry_info { + int pirq; /* -1 means unmapped */ + int flags; /* flags indicting whether MSI ADDR or DATA is updated */ + uint32_t io_mem[4]; +}; + +struct pt_msix_info { + int enabled; + int offset; + int total_entries; + int bar_index; + uint32_t table_off; + uint64_t mmio_base_addr; + int mmio_index; + int fd; + void *phys_iomem_base; + struct msix_entry_info msix_entry[0]; }; /* @@ -74,6 +92,7 @@ struct pt_dev { struct pci_dev *pci_dev; /* libpci struct */ struct pt_region bases[PCI_NUM_REGIONS]; /* Access regions */ struct pt_msi_info *msi; /* MSI virtualization */ + struct pt_msix_info *msix; /* MSI-X virtualization */ }; /* Used for formatting PCI BDF into cf8 format */ diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/hw/pt-msi.c --- a/tools/ioemu/hw/pt-msi.c Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/hw/pt-msi.c Thu May 15 16:23:56 2008 +0900 @@ -20,7 +20,9 @@ */ #include "pt-msi.h" - +#include <sys/mman.h> + +/* MSI virtuailization functions */ #define PT_MSI_CTRL_WR_MASK_HI (0x1) #define PT_MSI_CTRL_WR_MASK_LO (0x8E) #define PT_MSI_DATA_WR_MASK (0x38) @@ -76,7 +78,7 @@ int pt_msi_init(struct pt_dev *dev, int */ static int pt_msi_setup(struct pt_dev *dev) { - int vector = -1, pirq = -1; + int pirq = -1; if ( !(dev->msi->flags & MSI_FLAG_UNINIT) ) { @@ -85,15 +87,15 @@ static int pt_msi_setup(struct pt_dev *d } if ( xc_physdev_map_pirq_msi(xc_handle, domid, MAP_PIRQ_TYPE_MSI, - vector, &pirq, + AUTO_ASSIGN, &pirq, dev->pci_dev->dev << 3 | dev->pci_dev->func, - dev->pci_dev->bus, 1) ) - { - PT_LOG("error map vector %x\n", vector); + dev->pci_dev->bus, 0, 1) ) + { + PT_LOG("error map msi\n"); return -1; } dev->msi->pirq = pirq; - PT_LOG("vector %x pirq %x\n", vector, pirq); + PT_LOG("msi mapped with pirq %x\n", pirq); return 0; } @@ -147,15 +149,10 @@ static uint8_t get_msi_gctrl(struct pt_d return *(uint8_t *)(pd->config + d->msi->offset + PCI_MSI_FLAGS); } -static uint32_t get_msi_gflags(struct pt_dev *d) +static uint32_t __get_msi_gflags(uint32_t data, uint64_t addr) { uint32_t result = 0; int rh, dm, dest_id, deliv_mode, trig_mode; - uint16_t data; - uint64_t addr; - - data = get_msi_gdata(d); - addr = get_msi_gaddr(d); rh = (addr >> MSI_ADDR_REDIRECTION_SHIFT) & 0x1; dm = (addr >> MSI_ADDR_DESTMODE_SHIFT) & 0x1; @@ -170,25 +167,20 @@ static uint32_t get_msi_gflags(struct pt return result; } +static uint32_t get_msi_gflags(struct pt_dev *d) +{ + uint16_t data = get_msi_gdata(d); + uint64_t addr = get_msi_gaddr(d); + + return __get_msi_gflags(data, addr); +} + /* * This may be arch different */ static inline uint8_t get_msi_gvec(struct pt_dev *d) { return get_msi_gdata(d) & 0xff; -} - -static inline uint8_t get_msi_hvec(struct pt_dev *d) -{ - struct pci_dev *pd = d->pci_dev; - uint16_t data; - - if ( d->msi->flags & PCI_MSI_FLAGS_64BIT ) - data = pci_read_word(pd, PCI_MSI_DATA_64); - else - data = pci_read_word(pd, PCI_MSI_DATA_32); - - return data & 0xff; } /* @@ -198,7 +190,7 @@ static int pt_msi_update(struct pt_dev * static int pt_msi_update(struct pt_dev *d) { PT_LOG("now update msi with pirq %x gvec %x\n", - get_msi_gvec(d), d->msi->pirq); + d->msi->pirq, get_msi_gvec(d)); return xc_domain_update_msi_irq(xc_handle, domid, get_msi_gvec(d), d->msi->pirq, get_msi_gflags(d)); } @@ -266,7 +258,6 @@ static int static int pt_msi_map_update(struct pt_dev *d, uint32_t old_data, uint64_t old_addr) { - uint16_t pctrl; uint32_t data; uint64_t addr; @@ -301,6 +292,8 @@ static int pt_msi_mask_update(struct pt_ if ( old_mask != mask ) pci_write_long(pd, offset, mask); + + return 0; } #define ACCESSED_DATA 0x2 @@ -486,3 +479,378 @@ int pt_msi_read(struct pt_dev *d, int ad return e_len; } +/* MSI-X virtulization functions */ +#define PT_MSIX_CTRL_WR_MASK_HI (0xC0) +static void mask_physical_msix_entry(struct pt_dev *dev, int entry_nr, int mask) +{ + void *phys_off; + + phys_off = dev->msix->phys_iomem_base + 16 * entry_nr + 12; + *(uint32_t *)phys_off = mask; +} + +static int pt_msix_update_one(struct pt_dev *dev, int entry_nr) +{ + struct msix_entry_info *entry = &dev->msix->msix_entry[entry_nr]; + int pirq = entry->pirq; + int gvec = entry->io_mem[2] & 0xff; + uint64_t gaddr = *(uint64_t *)&entry->io_mem[0]; + uint32_t gflags = __get_msi_gflags(entry->io_mem[2], gaddr); + int ret; + + if ( !entry->flags ) + return 0; + + /* Check if this entry is already mapped */ + if ( entry->pirq == -1 ) + { + ret = xc_physdev_map_pirq_msi(xc_handle, domid, MAP_PIRQ_TYPE_MSI, + AUTO_ASSIGN, &pirq, + dev->pci_dev->dev << 3 | dev->pci_dev->func, + dev->pci_dev->bus, entry_nr, 0); + if ( ret ) + { + PT_LOG("error map msix entry %x\n", entry_nr); + return ret; + } + entry->pirq = pirq; + } + + PT_LOG("now update msix entry %x with pirq %x gvec %x\n", + entry_nr, pirq, gvec); + + ret = xc_domain_update_msi_irq(xc_handle, domid, gvec, pirq, gflags); + if ( ret ) + { + PT_LOG("error update msix irq info for entry %d\n", entry_nr); + return ret; + } + + entry->flags = 0; + + return 0; +} + +static int pt_msix_update(struct pt_dev *dev) +{ + struct pt_msix_info *msix = dev->msix; + int i; + + for ( i = 0; i < msix->total_entries; i++ ) + { + pt_msix_update_one(dev, i); + } + + return 0; +} + +static void pci_msix_invalid_write(void *opaque, target_phys_addr_t addr, + uint32_t val) +{ + PT_LOG("invalid write to MSI-X table, \ + only dword access is allowed.\n"); +} + +static void pci_msix_writel(void *opaque, target_phys_addr_t addr, uint32_t val) +{ + struct pt_dev *dev = (struct pt_dev *)opaque; + struct pt_msix_info *msix = dev->msix; + struct msix_entry_info *entry; + int entry_nr, offset; + + if ( addr % 4 ) + { + PT_LOG("unaligned dword access to MSI-X table, addr %016lx\n", + addr); + return; + } + + entry_nr = (addr - msix->mmio_base_addr) / 16; + entry = &msix->msix_entry[entry_nr]; + offset = ((addr - msix->mmio_base_addr) % 16) / 4; + + if ( offset != 3 && msix->enabled && entry->io_mem[3] & 0x1 ) + { + PT_LOG("can not update msix entry %d since MSI-X is already \ + function now.\n", entry_nr); + return; + } + + if ( offset != 3 && entry->io_mem[offset] != val ) + entry->flags = 1; + entry->io_mem[offset] = val; + + if ( offset == 3 ) + { + if ( !(val & 0x1) ) + pt_msix_update_one(dev, entry_nr); + mask_physical_msix_entry(dev, entry_nr, entry->io_mem[3] & 0x1); + } +} + +static CPUWriteMemoryFunc *pci_msix_write[] = { + pci_msix_invalid_write, + pci_msix_invalid_write, + pci_msix_writel +}; + +static uint32_t pci_msix_invalid_read(void *opaque, target_phys_addr_t addr) +{ + PT_LOG("invalid read to MSI-X table, \ + only dword access is allowed.\n"); + return 0; +} + +static uint32_t pci_msix_readl(void *opaque, target_phys_addr_t addr) +{ + struct pt_dev *dev = (struct pt_dev *)opaque; + struct pt_msix_info *msix = dev->msix; + int entry_nr, offset; + + if ( addr % 4 ) + { + PT_LOG("unaligned dword access to MSI-X table, addr %016lx\n", + addr); + return 0; + } + + entry_nr = (addr - msix->mmio_base_addr) / 16; + offset = ((addr - msix->mmio_base_addr) % 16) / 4; + + return msix->msix_entry[entry_nr].io_mem[offset]; +} + +static CPUReadMemoryFunc *pci_msix_read[] = { + pci_msix_invalid_read, + pci_msix_invalid_read, + pci_msix_readl +}; + +int add_msix_mapping(struct pt_dev *dev, int bar_index) +{ + if ( !(dev->msix && dev->msix->bar_index == bar_index) ) + return 0; + + return xc_domain_memory_mapping(xc_handle, domid, + dev->msix->mmio_base_addr >> XC_PAGE_SHIFT, + (dev->bases[bar_index].access.maddr + + dev->msix->table_off) >> XC_PAGE_SHIFT, + (dev->msix->total_entries * 16 + + XC_PAGE_SIZE -1) >> XC_PAGE_SHIFT, + DPCI_ADD_MAPPING); +} + +int remove_msix_mapping(struct pt_dev *dev, int bar_index) +{ + if ( !(dev->msix && dev->msix->bar_index == bar_index) ) + return 0; + + dev->msix->mmio_base_addr = dev->bases[bar_index].e_physbase + + dev->msix->table_off; + + cpu_register_physical_memory(dev->msix->mmio_base_addr, + dev->msix->total_entries * 16, + dev->msix->mmio_index); + + return xc_domain_memory_mapping(xc_handle, domid, + dev->msix->mmio_base_addr >> XC_PAGE_SHIFT, + (dev->bases[bar_index].access.maddr + + dev->msix->table_off) >> XC_PAGE_SHIFT, + (dev->msix->total_entries * 16 + + XC_PAGE_SIZE -1) >> XC_PAGE_SHIFT, + DPCI_REMOVE_MAPPING); +} + +int pt_msix_init(struct pt_dev *dev, int pos) +{ + uint8_t id; + uint16_t flags, control; + int i, total_entries, table_off, bar_index; + uint64_t bar_base; + struct pci_dev *pd = dev->pci_dev; + + id = pci_read_byte(pd, pos + PCI_CAP_LIST_ID); + + if ( id != PCI_CAP_ID_MSIX ) + { + PT_LOG("error id %x pos %x\n", id, pos); + return -1; + } + + control = pci_read_word(pd, pos + 2); + total_entries = control & 0x7ff; + total_entries += 1; + + dev->msix = malloc(sizeof(struct pt_msix_info) + + total_entries*sizeof(struct msix_entry_info)); + if ( !dev->msix ) + { + PT_LOG("error allocation pt_msix_info\n"); + return -1; + } + memset(dev->msix, 0, sizeof(struct pt_msix_info) + + total_entries*sizeof(struct msix_entry_info)); + dev->msix->total_entries = total_entries; + dev->msix->offset = pos; + for ( i = 0; i < total_entries; i++ ) + dev->msix->msix_entry[i].pirq = -1; + + dev->msix->mmio_index = + cpu_register_io_memory(0, pci_msix_read, pci_msix_write, dev); + + flags = pci_read_word(pd, pos + PCI_MSI_FLAGS); + if ( flags & PCI_MSIX_ENABLE ) + { + PT_LOG("MSIX enabled already, disable first\n"); + pci_write_word(pd, pos + PCI_MSI_FLAGS, flags & ~PCI_MSIX_ENABLE); + *(uint16_t *)&dev->dev.config[pos + PCI_MSI_FLAGS] + = flags & ~(PCI_MSIX_ENABLE | PCI_MSIX_MASK); + } + + table_off = pci_read_long(pd, pos + PCI_MSIX_TABLE); + bar_index = dev->msix->bar_index = table_off & PCI_MSIX_BIR; + table_off &= table_off & ~PCI_MSIX_BIR; + bar_base = pci_read_long(pd, 0x10 + 4 * bar_index); + if ( (bar_base & 0x6) == 0x4 ) + { + bar_base &= ~0xf; + bar_base += (uint64_t)pci_read_long(pd, 0x10 + 4 * (bar_index + 1)) << 32; + } + PT_LOG("get MSI-X table bar base %lx\n", bar_base); + + dev->msix->fd = open("/dev/mem", O_RDWR); + dev->msix->phys_iomem_base = mmap(0, total_entries * 16, + PROT_WRITE | PROT_READ, MAP_SHARED | MAP_LOCKED, + dev->msix->fd, bar_base + table_off); + PT_LOG("mapping physical MSI-X table to %lx\n", + (unsigned long)dev->msix->phys_iomem_base); + return 0; +} + +static int pt_msix_enable(struct pt_dev *d, int enable) +{ + uint16_t ctrl; + struct pci_dev *pd = d->pci_dev; + + if ( !pd ) + return -1; + + ctrl = pci_read_word(pd, d->msix->offset + PCI_MSI_FLAGS); + if ( enable ) + ctrl |= PCI_MSIX_ENABLE; + else + ctrl &= ~PCI_MSIX_ENABLE; + pci_write_word(pd, d->msix->offset + PCI_MSI_FLAGS, ctrl); + d->msix->enabled = !!enable; + + return 0; +} + +static int pt_msix_func_mask(struct pt_dev *d, int mask) +{ + uint16_t ctrl; + struct pci_dev *pd = d->pci_dev; + + if ( !pd ) + return -1; + + ctrl = pci_read_word(pd, d->msix->offset + PCI_MSI_FLAGS); + + if ( mask ) + ctrl |= PCI_MSIX_MASK; + else + ctrl &= ~PCI_MSIX_MASK; + + pci_write_word(pd, d->msix->offset + PCI_MSI_FLAGS, ctrl); + return 0; +} + +static int pt_msix_control_update(struct pt_dev *d) +{ + PCIDevice *pd = (PCIDevice *)d; + uint16_t ctrl = *(uint16_t *)(&pd->config[d->msix->offset + 2]); + + if ( ctrl & PCI_MSIX_ENABLE && !(ctrl & PCI_MSIX_MASK ) ) + pt_msix_update(d); + + pt_msix_func_mask(d, ctrl & PCI_MSIX_MASK); + pt_msix_enable(d, ctrl & PCI_MSIX_ENABLE); + + return 0; +} + +int pt_msix_write(struct pt_dev *d, uint32_t addr, uint32_t val, uint32_t len) +{ + struct pci_dev *pd; + int i, cur = addr; + uint8_t value; + PCIDevice *dev = (PCIDevice *)d; + + if ( !d || !d->msix ) + return 0; + + if ( (addr >= (d->msix->offset + 4) ) || + (addr + len) < d->msix->offset) + return 0; + + PT_LOG("addr %x val %x len %x offset %x\n", + addr, val, len, d->msix->offset); + + pd = d->pci_dev; + + for ( i = 0; i < len; i++, cur++ ) + { + uint8_t orig_value; + + if ( cur != d->msix->offset + 3 ) + continue; + + value = (val >> (i * 8)) & 0xff; + + orig_value = pci_read_byte(pd, cur); + value = (orig_value & ~PT_MSIX_CTRL_WR_MASK_HI) | + (value & PT_MSIX_CTRL_WR_MASK_HI); + dev->config[cur] = value; + pt_msix_control_update(d); + return 1; + } + + return 0; +} + +int pt_msix_read(struct pt_dev *d, int addr, int len, uint32_t *val) +{ + int e_addr = addr, e_len = len, offset = 0, i; + uint8_t e_val = 0; + PCIDevice *pd = (PCIDevice *)d; + + if ( !d || !d->msix ) + return 0; + + if ( (addr > (d->msix->offset + 3) ) || + (addr + len) <= d->msix->offset ) + return 0; + + if ( (addr + len ) > (d->msix->offset + 3) ) + e_len -= addr + len - d->msix->offset - 3; + + if ( addr < d->msix->offset ) + { + e_addr = d->msix->offset; + offset = d->msix->offset - addr; + e_len -= offset; + } + + for ( i = 0; i < e_len; i++ ) + { + e_val = *(uint8_t *)(&pd->config[e_addr] + i); + *val &= ~(0xff << ( (offset + i) * 8)); + *val |= (e_val << ( (offset + i) * 8)); + } + + PT_LOG("addr %x len %x val %x offset %x\n", + addr, len, *val, d->msix->offset); + + return e_len; +} + diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/hw/pt-msi.h --- a/tools/ioemu/hw/pt-msi.h Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/hw/pt-msi.h Thu May 15 16:23:56 2008 +0900 @@ -62,4 +62,19 @@ int int pt_msi_read(struct pt_dev *d, int addr, int len, uint32_t *val); +int +remove_msix_mapping(struct pt_dev *dev, int bar_index); + +int +add_msix_mapping(struct pt_dev *dev, int bar_index); + +int +pt_msix_init(struct pt_dev *dev, int pos); + +int +pt_msix_write(struct pt_dev *d, uint32_t addr, uint32_t val, uint32_t len); + +int +pt_msix_read(struct pt_dev *d, int addr, int len, uint32_t *val); + #endif diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/hw/xenfb.c --- a/tools/ioemu/hw/xenfb.c Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/hw/xenfb.c Thu May 15 16:23:56 2008 +0900 @@ -29,8 +29,6 @@ #define BTN_LEFT 0x110 /* from <linux/input.h> */ #endif -// FIXME defend against malicious frontend? - struct xenfb; struct xenfb_device { @@ -59,6 +57,7 @@ struct xenfb { int offset; /* offset of the framebuffer */ int abs_pointer_wanted; /* Whether guest supports absolute pointer */ int button_state; /* Last seen pointer button state */ + int refresh_period; /* The refresh period we have advised */ char protocol[64]; /* frontend protocol */ }; @@ -483,6 +482,68 @@ void xenfb_shutdown(struct xenfb *xenfb) free(xenfb); } +static int xenfb_configure_fb(struct xenfb *xenfb, size_t fb_len_lim, + int width, int height, int depth, + size_t fb_len, int offset, int row_stride) +{ + size_t mfn_sz = sizeof(*((struct xenfb_page *)0)->pd); + size_t pd_len = sizeof(((struct xenfb_page *)0)->pd) / mfn_sz; + size_t fb_pages = pd_len * XC_PAGE_SIZE / mfn_sz; + size_t fb_len_max = fb_pages * XC_PAGE_SIZE; + int max_width, max_height; + + if (fb_len_lim > fb_len_max) { + fprintf(stderr, + "FB: fb size limit %zu exceeds %zu, corrected\n", + fb_len_lim, fb_len_max); + fb_len_lim = fb_len_max; + } + if (fb_len > fb_len_lim) { + fprintf(stderr, + "FB: frontend fb size %zu limited to %zu\n", + fb_len, fb_len_lim); + } + if (depth != 8 && depth != 16 && depth != 24 && depth != 32) { + fprintf(stderr, + "FB: can't handle frontend fb depth %d\n", + depth); + return -1; + } + if (row_stride < 0 || row_stride > fb_len) { + fprintf(stderr, + "FB: invalid frontend stride %d\n", row_stride); + return -1; + } + max_width = row_stride / (depth / 8); + if (width < 0 || width > max_width) { + fprintf(stderr, + "FB: invalid frontend width %d limited to %d\n", + width, max_width); + width = max_width; + } + if (offset < 0 || offset >= fb_len) { + fprintf(stderr, + "FB: invalid frontend offset %d (max %zu)\n", + offset, fb_len - 1); + return -1; + } + max_height = (fb_len - offset) / row_stride; + if (height < 0 || height > max_height) { + fprintf(stderr, + "FB: invalid frontend height %d limited to %d\n", + height, max_height); + height = max_height; + } + xenfb->fb_len = fb_len; + xenfb->row_stride = row_stride; + xenfb->depth = depth; + xenfb->width = width; + xenfb->height = height; + xenfb->offset = offset; + fprintf(stderr, "Framebuffer %dx%dx%d offset %d stride %d\n", + width, height, depth, offset, row_stride); + return 0; +} static void xenfb_on_fb_event(struct xenfb *xenfb) { @@ -513,16 +574,18 @@ static void xenfb_on_fb_event(struct xen || h != event->update.height) { fprintf(stderr, "%s bogus update clipped\n", xenfb->fb.nodename); - break; } xenfb_guest_copy(xenfb, x, y, w, h); break; case XENFB_TYPE_RESIZE: - xenfb->width = event->resize.width; - xenfb->height = event->resize.height; - xenfb->depth = event->resize.depth; - xenfb->row_stride = event->resize.stride; - xenfb->offset = event->resize.offset; + if (xenfb_configure_fb(xenfb, xenfb->fb_len, + event->resize.width, + event->resize.height, + event->resize.depth, + xenfb->fb_len, + 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) @@ -534,6 +597,41 @@ static void xenfb_on_fb_event(struct xen xen_mb(); /* ensure we're done with ring contents */ page->out_cons = cons; xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port); +} + +static int xenfb_queue_full(struct xenfb *xenfb) +{ + struct xenfb_page *page = xenfb->fb.page; + uint32_t cons, prod; + + prod = page->in_prod; + cons = page->in_cons; + return prod - cons == XENFB_IN_RING_LEN; +} + +static void xenfb_send_event(struct xenfb *xenfb, union xenfb_in_event *event) +{ + uint32_t prod; + struct xenfb_page *page = xenfb->fb.page; + + prod = page->in_prod; + /* caller ensures !xenfb_queue_full() */ + xen_mb(); /* ensure ring space available */ + XENFB_IN_RING_REF(page, prod) = *event; + xen_wmb(); /* ensure ring contents visible */ + page->in_prod = prod + 1; + + xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port); +} + +static void xenfb_send_refresh_period(struct xenfb *xenfb, int period) +{ + union xenfb_in_event event; + + memset(&event, 0, sizeof(event)); + event.type = XENFB_TYPE_REFRESH_PERIOD; + event.refresh_period.period = period; + xenfb_send_event(xenfb, &event); } static void xenfb_on_kbd_event(struct xenfb *xenfb) @@ -707,30 +805,20 @@ static int xenfb_read_frontend_fb_config xenfb->protocol) < 0) xenfb->protocol[0] = '\0'; xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "request-update", "1"); - - /* TODO check for permitted ranges */ - fb_page = xenfb->fb.page; - xenfb->depth = fb_page->depth; - xenfb->width = fb_page->width; - xenfb->height = fb_page->height; - /* TODO check for consistency with the above */ - xenfb->fb_len = fb_page->mem_length; - xenfb->row_stride = fb_page->line_length; - - /* Protect against hostile frontend, limit fb_len to max allowed */ + xenfb->refresh_period = -1; + if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.nodename, "videoram", "%d", &videoram) < 0) videoram = 0; - videoram = videoram * 1024 * 1024; - if (videoram && xenfb->fb_len > videoram) { - fprintf(stderr, "Framebuffer requested length of %zd exceeded allowed %d\n", - xenfb->fb_len, videoram); - xenfb->fb_len = videoram; - if (xenfb->row_stride * xenfb->height > xenfb->fb_len) - xenfb->height = xenfb->fb_len / xenfb->row_stride; - } - fprintf(stderr, "Framebuffer depth %d width %d height %d line %d\n", - fb_page->depth, fb_page->width, fb_page->height, fb_page->line_length); + fb_page = xenfb->fb.page; + if (xenfb_configure_fb(xenfb, videoram * 1024 * 1024U, + fb_page->width, fb_page->height, fb_page->depth, + fb_page->mem_length, 0, fb_page->line_length) + < 0) { + errno = EINVAL; + return -1; + } + if (xenfb_map_fb(xenfb, xenfb->fb.otherend_id) < 0) return -1; @@ -1185,10 +1273,28 @@ static void xenfb_guest_copy(struct xenf dpy_update(xenfb->ds, x, y, w, h); } -/* Periodic update of display, no need for any in our case */ +/* Periodic update of display, transmit the refresh interval to the frontend */ static void xenfb_update(void *opaque) { struct xenfb *xenfb = opaque; + int period; + + if (xenfb_queue_full(xenfb)) + return; + + if (xenfb->ds->idle) + period = XENFB_NO_REFRESH; + else { + period = xenfb->ds->gui_timer_interval; + if (!period) + period = GUI_REFRESH_INTERVAL; + } + + /* Will have to be disabled for frontends without feature-update */ + if (xenfb->refresh_period != period) { + xenfb_send_refresh_period(xenfb, period); + xenfb->refresh_period = period; + } } /* QEMU display state changed, so refresh the framebuffer copy */ @@ -1232,11 +1338,17 @@ static int xenfb_register_console(struct } #ifdef CONFIG_STUBDOM -static struct semaphore kbd_sem = __SEMAPHORE_INITIALIZER(kbd_sem, 0); -static struct kbdfront_dev *kbd_dev; +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 void *vga_vram, *nonshared_vram; -static DisplayState *xenfb_ds; static unsigned char linux2scancode[KEY_MAX + 1]; @@ -1254,7 +1366,8 @@ int xenfb_connect_vfb(const char *path) static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h) { - struct fbfront_dev *fb_dev = ds->opaque; + XenFBState *xs = ds->opaque; + struct fbfront_dev *fb_dev = xs->fb_dev; if (!fb_dev) return; fbfront_update(fb_dev, x, y, w, h); @@ -1262,7 +1375,8 @@ static void xenfb_pv_update(DisplayState static void xenfb_pv_resize(DisplayState *ds, int w, int h, int linesize) { - struct fbfront_dev *fb_dev = ds->opaque; + 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; @@ -1276,14 +1390,15 @@ static void xenfb_pv_resize(DisplayState if (ds->shared_buf) { ds->data = NULL; } else { - ds->data = nonshared_vram; + 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) { - struct fbfront_dev *fb_dev = ds->opaque; + XenFBState *xs = ds->opaque; + struct fbfront_dev *fb_dev = xs->fb_dev; static int lastdepth = -1; if (!depth) { ds->shared_buf = 0; @@ -1301,15 +1416,16 @@ static void xenfb_pv_colourdepth(Display if (ds->shared_buf) { ds->data = NULL; } else { - ds->data = nonshared_vram; + 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) { - struct fbfront_dev *fb_dev = ds->opaque; - int offset = pixels - vga_vram; + 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; @@ -1321,16 +1437,45 @@ static void xenfb_pv_refresh(DisplayStat 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; - DisplayState *s = opaque; + XenFBState *xs = opaque; + DisplayState *s = xs->ds; static int buttons; static int x, y; - n = kbdfront_receive(kbd_dev, buf, KBD_NUM_BATCH); + n = kbdfront_receive(xs->kbd_dev, buf, KBD_NUM_BATCH); for (i = 0; i < n; i++) { switch (buf[i].type) { @@ -1412,12 +1557,13 @@ static void kbdfront_thread(void *p) static void kbdfront_thread(void *p) { int scancode, keycode; - kbd_dev = init_kbdfront(p, 1); - if (!kbd_dev) { + 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(&kbd_sem); + up(&xs->kbd_sem); for (scancode = 0; scancode < 128; scancode++) { keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode]]; linux2scancode[keycode] = scancode; @@ -1431,12 +1577,18 @@ int xenfb_pv_display_init(DisplayState * if (!fb_path || !kbd_path) return -1; - create_thread("kbdfront", kbdfront_thread, (void*) kbd_path); - - xenfb_ds = ds; - - ds->data = nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE); + 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; @@ -1452,9 +1604,9 @@ int xenfb_pv_display_init(DisplayState * int xenfb_pv_display_start(void *data) { - DisplayState *ds = xenfb_ds; + DisplayState *ds; struct fbfront_dev *fb_dev; - int kbd_fd; + int kbd_fd, fb_fd; int offset = 0; unsigned long *mfns; int n = VGA_RAM_SIZE / PAGE_SIZE; @@ -1463,12 +1615,13 @@ int xenfb_pv_display_start(void *data) if (!fb_path || !kbd_path) return 0; - vga_vram = data; + ds = xs->ds; + xs->vga_vram = data; mfns = malloc(2 * n * sizeof(*mfns)); for (i = 0; i < n; i++) - mfns[i] = virtual_to_mfn(vga_vram + i * PAGE_SIZE); + mfns[i] = virtual_to_mfn(xs->vga_vram + i * PAGE_SIZE); for (i = 0; i < n; i++) - mfns[n + i] = virtual_to_mfn(nonshared_vram + i * PAGE_SIZE); + 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); @@ -1479,21 +1632,24 @@ int xenfb_pv_display_start(void *data) free(fb_path); if (ds->shared_buf) { - offset = (void*) ds->data - vga_vram; + offset = (void*) ds->data - xs->vga_vram; } else { offset = VGA_RAM_SIZE; - ds->data = nonshared_vram; + ds->data = xs->nonshared_vram; } if (offset) fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, offset); - down(&kbd_sem); + down(&xs->kbd_sem); free(kbd_path); - kbd_fd = kbdfront_open(kbd_dev); - qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, ds); - - xenfb_ds->opaque = fb_dev; + 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 diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/keymaps.c --- a/tools/ioemu/keymaps.c Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/keymaps.c Thu May 15 16:23:56 2008 +0900 @@ -50,6 +50,7 @@ typedef struct { struct key_range *keypad_range; struct key_range *numlock_range; struct key_range *shift_range; + struct key_range *localstate_range; } kbd_layout_t; static void add_to_key_range(struct key_range **krp, int code) { @@ -132,6 +133,10 @@ static kbd_layout_t *parse_keyboard_layo add_to_key_range(&k->shift_range, keysym); //fprintf(stderr, "shift keysym %04x keycode %d\n", keysym, keycode); } + if (rest && strstr(rest, "localstate")) { + add_to_key_range(&k->localstate_range, keycode); + //fprintf(stderr, "localstate keysym %04x keycode %d\n", keysym, keycode); + } /* if(keycode&0x80) keycode=(keycode<<8)^0x80e0; */ @@ -221,3 +226,14 @@ static int keysymIsShift(void *kbd_layou return 1; return 0; } + +static int keycodeIsShiftable(void *kbd_layout, int keycode) +{ + kbd_layout_t *k = kbd_layout; + struct key_range *kr; + + for (kr = k->localstate_range; kr; kr = kr->next) + if (keycode >= kr->start && keycode <= kr->end) + return 0; + return 1; +} diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/sdl.c --- a/tools/ioemu/sdl.c Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/sdl.c Thu May 15 16:23:56 2008 +0900 @@ -696,9 +696,11 @@ static void sdl_refresh(DisplayState *ds if (ev->active.gain) { /* Back to default interval */ ds->gui_timer_interval = 0; + ds->idle = 0; } else { /* Sleeping interval */ ds->gui_timer_interval = 500; + ds->idle = 1; } } break; diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/vl.c --- a/tools/ioemu/vl.c Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/vl.c Thu May 15 16:23:56 2008 +0900 @@ -130,8 +130,6 @@ #else #define DEFAULT_RAM_SIZE 128 #endif -/* in ms */ -#define GUI_REFRESH_INTERVAL 30 /* Max number of USB devices that can be specified on the commandline. */ #define MAX_USB_CMDLINE 8 @@ -4467,6 +4465,8 @@ void dumb_display_init(DisplayState *ds) ds->dpy_resize = dumb_resize; ds->dpy_colourdepth = NULL; ds->dpy_refresh = dumb_refresh; + ds->gui_timer_interval = 500; + ds->idle = 1; } /***********************************************************/ diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/vl.h --- a/tools/ioemu/vl.h Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/vl.h Thu May 15 16:23:56 2008 +0900 @@ -929,6 +929,9 @@ extern struct soundhw soundhw[]; #define VGA_RAM_SIZE (8192 * 1024) +/* in ms */ +#define GUI_REFRESH_INTERVAL 30 + struct DisplayState { uint8_t *data; int linesize; @@ -939,6 +942,7 @@ struct DisplayState { void *opaque; uint32_t *palette; uint64_t gui_timer_interval; + int idle; int shared_buf; diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/vnc.c --- a/tools/ioemu/vnc.c Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/vnc.c Thu May 15 16:23:56 2008 +0900 @@ -778,6 +778,7 @@ static void _vnc_update_client(void *opa vs->has_update = 0; vnc_flush(vs); vs->last_update_time = now; + vs->ds->idle = 0; vs->timer_interval /= 2; if (vs->timer_interval < VNC_REFRESH_INTERVAL_BASE) @@ -790,26 +791,29 @@ static void _vnc_update_client(void *opa vs->timer_interval += VNC_REFRESH_INTERVAL_INC; if (vs->timer_interval > VNC_REFRESH_INTERVAL_MAX) { vs->timer_interval = VNC_REFRESH_INTERVAL_MAX; - if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL && - vs->update_requested) { - /* Send a null update. If the client is no longer - interested (e.g. minimised) it'll ignore this, and we - can stop scanning the buffer until it sends another - update request. */ - /* It turns out that there's a bug in realvncviewer 4.1.2 - which means that if you send a proper null update (with - no update rectangles), it gets a bit out of sync and - never sends any further requests, regardless of whether - it needs one or not. Fix this by sending a single 1x1 - update rectangle instead. */ - vnc_write_u8(vs, 0); - vnc_write_u8(vs, 0); - vnc_write_u16(vs, 1); - send_framebuffer_update(vs, 0, 0, 1, 1); - vnc_flush(vs); - vs->last_update_time = now; - vs->update_requested--; - return; + if (now - vs->last_update_time >= VNC_MAX_UPDATE_INTERVAL) { + if (!vs->update_requested) { + vs->ds->idle = 1; + } else { + /* Send a null update. If the client is no longer + interested (e.g. minimised) it'll ignore this, and we + can stop scanning the buffer until it sends another + update request. */ + /* It turns out that there's a bug in realvncviewer 4.1.2 + which means that if you send a proper null update (with + no update rectangles), it gets a bit out of sync and + never sends any further requests, regardless of whether + it needs one or not. Fix this by sending a single 1x1 + update rectangle instead. */ + vnc_write_u8(vs, 0); + vnc_write_u8(vs, 0); + vnc_write_u16(vs, 1); + send_framebuffer_update(vs, 0, 0, 1, 1); + vnc_flush(vs); + vs->last_update_time = now; + vs->update_requested--; + return; + } } } qemu_mod_timer(vs->timer, now + vs->timer_interval); @@ -970,6 +974,7 @@ static int vnc_client_io_error(VncState qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL); closesocket(vs->csock); vs->csock = -1; + vs->ds->idle = 1; buffer_reset(&vs->input); buffer_reset(&vs->output); free_queue(vs); @@ -1302,6 +1307,7 @@ static void do_key_event(VncState *vs, i int keycode; int shift_keys = 0; int shift = 0; + int keypad = 0; if (is_graphic_console()) { if (sym >= 'A' && sym <= 'Z') { @@ -1328,6 +1334,8 @@ static void do_key_event(VncState *vs, i case 0x9d: /* Right CTRL */ case 0x38: /* Left ALT */ case 0xb8: /* Right ALT */ + if (keycode & 0x80) + kbd_put_keycode(0xe0); if (down) { vs->modifiers_state[keycode] = 1; kbd_put_keycode(keycode & 0x7f); @@ -1356,7 +1364,8 @@ static void do_key_event(VncState *vs, i return; } - if (keycodeIsKeypad(vs->kbd_layout, keycode)) { + keypad = keycodeIsKeypad(vs->kbd_layout, keycode); + if (keypad) { /* If the numlock state needs to change then simulate an additional keypress before sending this one. This will happen if the user toggles numlock away from the VNC window. @@ -1376,13 +1385,14 @@ static void do_key_event(VncState *vs, i if (is_graphic_console()) { /* If the shift state needs to change then simulate an additional - keypress before sending this one. + keypress before sending this one. Ignore for non shiftable keys. */ if (shift && !shift_keys) { press_key_shift_down(vs, down, keycode); return; } - else if (!shift && shift_keys) { + else if (!shift && shift_keys && !keypad && + keycodeIsShiftable(vs->kbd_layout, keycode)) { press_key_shift_up(vs, down, keycode); return; } @@ -2443,6 +2453,7 @@ static void vnc_listen_read(void *opaque vs->csock = accept(vs->lsock, (struct sockaddr *)&addr, &addrlen); if (vs->csock != -1) { VNC_DEBUG("New client on socket %d\n", vs->csock); + vs->ds->idle = 0; socket_set_nonblock(vs->csock); qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, opaque); vnc_write(vs, "RFB 003.008\n", 12); @@ -2468,6 +2479,7 @@ void vnc_display_init(DisplayState *ds) exit(1); ds->opaque = vs; + ds->idle = 1; vnc_state = vs; vs->display = NULL; vs->password = NULL; diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/vnc_keysym.h --- a/tools/ioemu/vnc_keysym.h Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/vnc_keysym.h Thu May 15 16:23:56 2008 +0900 @@ -345,6 +345,7 @@ static name2keysym_t name2keysym[]={ {"Num_Lock", 0xff7f}, /* XK_Num_Lock */ {"Pause", 0xff13}, /* XK_Pause */ {"Escape", 0xff1b}, /* XK_Escape */ +{"ISO_Left_Tab", 0xfe20},/* XK_ISO_Left_Tab */ /* localized keys */ {"BackApostrophe", 0xff21}, diff -r ef290f39ae6b -r c96507e0c83d tools/ioemu/xenstore.c --- a/tools/ioemu/xenstore.c Thu May 15 14:53:48 2008 +0900 +++ b/tools/ioemu/xenstore.c Thu May 15 16:23:56 2008 +0900 @@ -90,6 +90,7 @@ void xenstore_parse_domain_config(int hv int i, is_scsi, is_hdN = 0; unsigned int len, num, hd_index, pci_devid = 0; BlockDriverState *bs; + BlockDriver *format; for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) media_filename[i] = NULL; @@ -135,6 +136,8 @@ void xenstore_parse_domain_config(int hv } for (i = 0; i < num; i++) { + format = NULL; /* don't know what the format is yet */ + /* read the backend path */ if (pasprintf(&buf, "%s/device/vbd/%s/backend", path, e[i]) == -1) continue; @@ -181,13 +184,20 @@ void xenstore_parse_domain_config(int hv drv = xs_read(xsh, XBT_NULL, buf, &len); if (drv == NULL) continue; - /* Strip off blktap sub-type prefix aio: - QEMU can autodetect this */ + /* Obtain blktap sub-type prefix */ if (!strcmp(drv, "tap") && params[0]) { char *offset = strchr(params, ':'); if (!offset) continue ; + free(drv); + drv = malloc(offset - params + 1); + memcpy(drv, params, offset - params); + drv[offset - params] = '\0'; + if (!strcmp(drv, "aio")) + /* qemu does aio anyway if it can */ + format = &bdrv_raw; memmove(params, offset+1, strlen(offset+1)+1 ); - fprintf(logfile, "Strip off blktap sub-type prefix to %s\n", params); + fprintf(logfile, "Strip off blktap sub-type prefix to %s (drv '%s')\n", params, drv); } /* Prefix with /dev/ if needed */ if (!strcmp(drv, "phy") && params[0] != '/') { @@ -195,6 +205,7 @@ void xenstore_parse_domain_config(int hv sprintf(newparams, "/dev/%s", params); free(params); params = newparams; + format = &bdrv_raw; } /* @@ -240,8 +251,25 @@ void xenstore_parse_domain_config(int hv #endif if (params[0]) { - if (bdrv_open(bs, params, 0 /* snapshot */) < 0) - fprintf(stderr, "qemu: could not open vbd '%s' or hard disk image '%s'\n", buf, params); + if (!format) { + if (!drv) { + fprintf(stderr, "qemu: type (image format) not specified for vbd '%s' or image '%s'\n", buf, params); + continue; + } + if (!strcmp(drv,"qcow")) { + /* autoguess qcow vs qcow2 */ + } else if (!strcmp(drv,"file") || !strcmp(drv,"phy")) { + format = &bdrv_raw; + } else { + format = bdrv_find_format(drv); + if (!format) { + fprintf(stderr, "qemu: type (image format) '%s' unknown for vbd '%s' or image '%s'\n", drv, buf, params); + continue; + } + } + } + if (bdrv_open2(bs, params, 0 /* snapshot */, format) < 0) + fprintf(stderr, "qemu: could not open vbd '%s' or hard disk image '%s' (drv '%s')\n", buf, params, drv ? drv : "?"); } } diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/Makefile --- a/tools/libxc/Makefile Thu May 15 14:53:48 2008 +0900 +++ b/tools/libxc/Makefile Thu May 15 16:23:56 2008 +0900 @@ -9,7 +9,6 @@ CTRL_SRCS-y += xc_core.c CTRL_SRCS-y += xc_core.c CTRL_SRCS-$(CONFIG_X86) += xc_core_x86.c CTRL_SRCS-$(CONFIG_IA64) += xc_core_ia64.c -CTRL_SRCS-$(CONFIG_POWERPC) += xc_core_powerpc.c endif CTRL_SRCS-y += xc_domain.c CTRL_SRCS-y += xc_evtchn.c @@ -55,7 +54,6 @@ GUEST_SRCS-$(CONFIG_X86) += xc_dom_x GUEST_SRCS-$(CONFIG_X86) += xc_dom_x86.c GUEST_SRCS-$(CONFIG_X86) += xc_cpuid_x86.c GUEST_SRCS-$(CONFIG_IA64) += xc_dom_ia64.c -GUEST_SRCS-$(CONFIG_POWERPC) += xc_dom_powerpc.c endif -include $(XEN_TARGET_ARCH)/Makefile diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/powerpc64/Makefile --- a/tools/libxc/powerpc64/Makefile Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,4 +0,0 @@ -GUEST_SRCS-y += powerpc64/flatdevtree.c -GUEST_SRCS-y += powerpc64/mk_flatdevtree.c - -CTRL_SRCS-y += powerpc64/xc_memory.c diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/powerpc64/flatdevtree.c --- a/tools/libxc/powerpc64/flatdevtree.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,662 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright Pantelis Antoniou 2006 - * Copyright IBM Corporation 2006, 2007 - * 2006 (c) MontaVista, Software, Inc. - * - * Authors: Pantelis Antoniou <pantelis@xxxxxxxxxxxxxxxxx> - * Hollis Blanchard <hollisb@xxxxxxxxxx> - * Mark A. Greer <mgreer@xxxxxxxxxx> - */ - -#include "flatdevtree.h" - -/* Set ptrs to current one's info; return addr of next one */ -static u32 *ft_next(u32 *p, const u32 *p_strings, const u32 version, - u32 **tagpp, char **namepp, char **datapp, u32 **sizepp) -{ - u32 sz; - - *namepp = NULL; - *datapp = NULL; - *sizepp = NULL; - *tagpp = p; - - switch (be32_to_cpu(*p++)) { /* Tag */ - case OF_DT_BEGIN_NODE: - *namepp = (char *)p; - p = (u32 *)_ALIGN((unsigned long)p + strlen((char *)p) + 1, 4); - break; - case OF_DT_PROP: - sz = be32_to_cpu(*p); - *sizepp = p++; - *namepp = (char *)p_strings + be32_to_cpu(*p++); - if ((version < 0x10) && (sz >= 8)) - p = (u32 *)_ALIGN((unsigned long)p, 8); - *datapp = (char *)p; - p = (u32 *)_ALIGN((unsigned long)p + sz, 4); - break; - case OF_DT_END_NODE: - case OF_DT_NOP: - break; - case OF_DT_END: - default: - p = NULL; - break; - } - - return p; -} - -static void ft_put_word(struct ft_cxt *cxt, u32 v) -{ - if (cxt->overflow) /* do nothing */ - return; - - /* check for overflow */ - if (cxt->p + 4 > cxt->pstr) { - cxt->overflow = 1; - return; - } - - *(u32 *) cxt->p = cpu_to_be32(v); - cxt->p += 4; -} - -static inline void ft_put_bin(struct ft_cxt *cxt, const void *data, int sz) -{ - char *p; - - if (cxt->overflow) /* do nothing */ - return; - - /* next pointer pos */ - p = (char *) _ALIGN((unsigned long)cxt->p + sz, 4); - - /* check for overflow */ - if (p > cxt->pstr) { - cxt->overflow = 1; - return; - } - - memcpy(cxt->p, data, sz); - if ((sz & 3) != 0) - memset(cxt->p + sz, 0, 4 - (sz & 3)); - cxt->p = p; -} - -void ft_begin_node(struct ft_cxt *cxt, const char *name) -{ - ft_put_word(cxt, OF_DT_BEGIN_NODE); - ft_put_bin(cxt, name, strlen(name) + 1); -} - -void ft_end_node(struct ft_cxt *cxt) -{ - ft_put_word(cxt, OF_DT_END_NODE); -} - -void ft_nop(struct ft_cxt *cxt) -{ - ft_put_word(cxt, OF_DT_NOP); -} - -static int lookup_string(struct ft_cxt *cxt, const char *name) -{ - char *p; - - p = cxt->pstr; - while (p < cxt->pstr_begin) { - if (strcmp(p, (char *)name) == 0) - return p - cxt->p_begin; - p += strlen(p) + 1; - } - - return -1; -} - -void ft_prop(struct ft_cxt *cxt, const char *name, - const void *data, unsigned int sz) -{ - int len, off; - - if (cxt->overflow) - return; - - len = strlen(name) + 1; - - off = lookup_string(cxt, name); - if (off == -1) { - /* check if we have space */ - if (cxt->p + 12 + sz + len > cxt->pstr) { - cxt->overflow = 1; - return; - } - - cxt->pstr -= len; - memcpy(cxt->pstr, name, len); - off = cxt->pstr - cxt->p_begin; - } - - /* now put offset from beginning of *STRUCTURE* */ - /* will be fixed up at the end */ - ft_put_word(cxt, OF_DT_PROP); - ft_put_word(cxt, sz); - ft_put_word(cxt, off); - ft_put_bin(cxt, data, sz); -} - -void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str) -{ - ft_prop(cxt, name, str, strlen(str) + 1); -} - -void ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val) -{ - u32 v = cpu_to_be32((u32) val); - - ft_prop(cxt, name, &v, 4); -} - -/* start construction of the flat OF tree */ -void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size) -{ - struct boot_param_header *bph = blob; - u32 off; - - /* clear the cxt */ - memset(cxt, 0, sizeof(*cxt)); - - cxt->bph = bph; - cxt->max_size = max_size; - - /* zero everything in the header area */ - memset(bph, 0, sizeof(*bph)); - - bph->magic = cpu_to_be32(OF_DT_HEADER); - bph->version = cpu_to_be32(0x10); - bph->last_comp_version = cpu_to_be32(0x10); - - /* start pointers */ - cxt->pres_begin = (char *) _ALIGN((unsigned long)(bph + 1), 8); - cxt->pres = cxt->pres_begin; - - off = (unsigned long)cxt->pres_begin - (unsigned long)bph; - bph->off_mem_rsvmap = cpu_to_be32(off); - - ((u64 *) cxt->pres)[0] = 0; /* phys = 0, size = 0, terminate */ - ((u64 *) cxt->pres)[1] = 0; - - cxt->p_anchor = cxt->pres + 16; /* over the terminator */ -} - -/* add a reserver physical area to the rsvmap */ -void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size) -{ - ((u64 *) cxt->pres)[0] = cpu_to_be64(physaddr); /* phys = 0, size = 0, terminate */ - ((u64 *) cxt->pres)[1] = cpu_to_be64(size); - - cxt->pres += 16; /* advance two u64s worth */ - - ((u64 *) cxt->pres)[0] = 0; /* phys = 0, size = 0, terminate */ - ((u64 *) cxt->pres)[1] = 0; - - /* keep track of size */ - cxt->res_size = cxt->pres + 16 - cxt->pres_begin; - - cxt->p_anchor = cxt->pres + 16; /* over the terminator */ -} - -int ft_set_rsvmap(void *bphp, int m, u64 physaddr, u64 size) -{ - const struct boot_param_header *bph = bphp; - u64 *p_rsvmap = (u64 *) - ((char *)bph + be32_to_cpu(bph->off_mem_rsvmap)); - u32 i; - - for (i = 0;; i++) { - u64 addr, sz; - - addr = be64_to_cpu(p_rsvmap[i * 2]); - sz = be64_to_cpu(p_rsvmap[i * 2 + 1]); - if (addr == 0 && size == 0) - break; - if (m == i) { - p_rsvmap[i * 2] = cpu_to_be64(physaddr); - p_rsvmap[i * 2 + 1] = cpu_to_be64(size); - return 0; - } - } - return -1; -} - -void ft_begin_tree(struct ft_cxt *cxt) -{ - cxt->p_begin = cxt->p_anchor; - cxt->pstr_begin = (char *)cxt->bph + cxt->max_size; /* point at the end */ - - cxt->p = cxt->p_begin; - cxt->pstr = cxt->pstr_begin; -} - -int ft_end_tree(struct ft_cxt *cxt) -{ - struct boot_param_header *bph = cxt->bph; - int off, sz, sz1; - u32 tag, v; - char *p; - - ft_put_word(cxt, OF_DT_END); - - if (cxt->overflow) - return -ENOMEM; - - /* size of the areas */ - cxt->struct_size = cxt->p - cxt->p_begin; - cxt->strings_size = cxt->pstr_begin - cxt->pstr; - - /* the offset we must move */ - off = (cxt->pstr_begin - cxt->p_begin) - cxt->strings_size; - - /* the new strings start */ - cxt->pstr_begin = cxt->p_begin + cxt->struct_size; - - /* move the whole string area */ - memmove(cxt->pstr_begin, cxt->pstr, cxt->strings_size); - - /* now perform the fixup of the strings */ - p = cxt->p_begin; - while ((tag = be32_to_cpu(*(u32 *) p)) != OF_DT_END) { - p += 4; - - if (tag == OF_DT_BEGIN_NODE) { - p = (char *) _ALIGN((unsigned long)p + strlen(p) + 1, 4); - continue; - } - - if (tag == OF_DT_END_NODE || tag == OF_DT_NOP) - continue; - - if (tag != OF_DT_PROP) - return -EINVAL; - - sz = be32_to_cpu(*(u32 *) p); - p += 4; - - v = be32_to_cpu(*(u32 *) p); - v -= off; - *(u32 *) p = cpu_to_be32(v); /* move down */ - p += 4; - - p = (char *) _ALIGN((unsigned long)p + sz, 4); - } - - /* fix sizes */ - p = (char *)cxt->bph; - sz = (cxt->pstr_begin + cxt->strings_size) - p; - sz1 = _ALIGN(sz, 16); /* align at 16 bytes */ - if (sz != sz1) - memset(p + sz, 0, sz1 - sz); - bph->totalsize = cpu_to_be32(sz1); - bph->off_dt_struct = cpu_to_be32(cxt->p_begin - p); - bph->off_dt_strings = cpu_to_be32(cxt->pstr_begin - p); - - /* the new strings start */ - cxt->pstr_begin = cxt->p_begin + cxt->struct_size; - cxt->pstr = cxt->pstr_begin + cxt->strings_size; - - /* mark the size of string structure in bph */ - bph->size_dt_strings = cxt->strings_size; - - return 0; -} - -/**********************************************************************/ - -static inline int isprint(int c) -{ - return c >= 0x20 && c <= 0x7e; -} - -static int is_printable_string(const void *data, int len) -{ - const char *s = data; - const char *ss; - - /* zero length is not */ - if (len == 0) - return 0; - - /* must terminate with zero */ - if (s[len - 1] != '\0') - return 0; - - ss = s; - while (*s && isprint(*s)) - s++; - - /* not zero, or not done yet */ - if (*s != '\0' || (s + 1 - ss) < len) - return 0; - - return 1; -} - -static void print_data(const void *data, int len) -{ - int i; - const char *s; - - /* no data, don't print */ - if (len == 0) - return; - - if (is_printable_string(data, len)) { - printf(" = \"%s\"", (char *)data); - return; - } - - switch (len) { - case 1: /* byte */ - printf(" = <0x%02x>", (*(char *) data) & 0xff); - break; - case 2: /* half-word */ - printf(" = <0x%04x>", be16_to_cpu(*(u16 *) data) & 0xffff); - break; - case 4: /* word */ - printf(" = <0x%08x>", be32_to_cpu(*(u32 *) data) & 0xffffffffU); - break; - case 8: /* double-word */ - printf(" = <0x%16llx>", be64_to_cpu(*(u64 *) data)); - break; - default: /* anything else... hexdump */ - printf(" = ["); - for (i = 0, s = data; i < len; i++) - printf("%02x%s", s[i], i < len - 1 ? " " : ""); - printf("]"); - - break; - } -} - -void ft_dump_blob(const void *bphp) -{ - const struct boot_param_header *bph = bphp; - const u64 *p_rsvmap = (const u64 *) - ((const char *)bph + be32_to_cpu(bph->off_mem_rsvmap)); - const u32 *p_struct = (const u32 *) - ((const char *)bph + be32_to_cpu(bph->off_dt_struct)); - const u32 *p_strings = (const u32 *) - ((const char *)bph + be32_to_cpu(bph->off_dt_strings)); - const u32 version = be32_to_cpu(bph->version); - u32 i, *p, *tagp, *sizep; - char *namep, *datap; - int depth, shift; - u64 addr, size; - - - if (be32_to_cpu(bph->magic) != OF_DT_HEADER) { - /* not valid tree */ - return; - } - - depth = 0; - shift = 4; - - for (i = 0;; i++) { - addr = be64_to_cpu(p_rsvmap[i * 2]); - size = be64_to_cpu(p_rsvmap[i * 2 + 1]); - if (addr == 0 && size == 0) - break; - - printf("/memreserve/ 0x%llx 0x%llx;\n", addr, size); - } - - p = (u32 *)p_struct; - while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap, - &sizep)) != NULL) - switch (be32_to_cpu(*tagp)) { - case OF_DT_BEGIN_NODE: - printf("%*s%s {\n", depth * shift, "", namep); - depth++; - break; - case OF_DT_END_NODE: - depth--; - printf("%*s};\n", depth * shift, ""); - break; - case OF_DT_NOP: - printf("%*s[NOP]\n", depth * shift, ""); - break; - case OF_DT_END: - break; - case OF_DT_PROP: - printf("%*s%s", depth * shift, "", namep); - print_data(datap, *sizep); - printf(";\n"); - break; - default: - fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", - depth * shift, "", *tagp); - return; - } -} - -void ft_backtrack_node(struct ft_cxt *cxt) -{ - if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE) - return; /* XXX only for node */ - - cxt->p -= 4; -} - -/* note that the root node of the blob is "peeled" off */ -void ft_merge_blob(struct ft_cxt *cxt, void *blob) -{ - struct boot_param_header *bph = (struct boot_param_header *)blob; - u32 *p_struct = (u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_struct)); - u32 *p_strings = - (u32 *) ((char *)bph + be32_to_cpu(bph->off_dt_strings)); - const u32 version = be32_to_cpu(bph->version); - u32 *p, *tagp, *sizep; - char *namep, *datap; - int depth; - - if (be32_to_cpu(*(u32 *) (cxt->p - 4)) != OF_DT_END_NODE) - return; /* XXX only for node */ - - cxt->p -= 4; - - depth = 0; - p = p_struct; - while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap, - &sizep)) != NULL) - switch (be32_to_cpu(*tagp)) { - case OF_DT_BEGIN_NODE: - if (depth++ > 0) - ft_begin_node(cxt, namep); - break; - case OF_DT_END_NODE: - ft_end_node(cxt); - if (--depth == 0) - return; - break; - case OF_DT_PROP: - ft_prop(cxt, namep, datap, *sizep); - break; - } -} - -/**********************************************************************/ - -void *ft_find_node(const void *bphp, const char *srch_path) -{ - const struct boot_param_header *bph = bphp; - u32 *p_struct = (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_struct)); - u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings)); - u32 version = be32_to_cpu(bph->version); - u32 *p, *tagp, *sizep; - char *namep, *datap; - static char path[MAX_PATH_LEN]; - - path[0] = '\0'; - p = p_struct; - - while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap, - &sizep)) != NULL) - switch (be32_to_cpu(*tagp)) { - case OF_DT_BEGIN_NODE: - strcat(path, namep); - if (!strcmp(path, srch_path)) - return tagp; - strcat(path, "/"); - break; - case OF_DT_END_NODE: - ft_parentize(path, 1); - break; - } - return NULL; -} - -int ft_get_prop(const void *bphp, const void *node, const char *propname, - void *buf, const unsigned int buflen) -{ - const struct boot_param_header *bph = bphp; - u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings)); - u32 version = be32_to_cpu(bph->version); - u32 *p, *tagp, *sizep, size; - char *namep, *datap; - int depth; - - depth = 0; - p = (u32 *)node; - - while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap, - &sizep)) != NULL) - switch (be32_to_cpu(*tagp)) { - case OF_DT_BEGIN_NODE: - depth++; - break; - case OF_DT_PROP: - if ((depth == 1) && !strcmp(namep, propname)) { - size = min(be32_to_cpu(*sizep), (u32)buflen); - memcpy(buf, datap, size); - return size; - } - break; - case OF_DT_END_NODE: - if (--depth <= 0) - return -1; - break; - } - return -1; -} - -static void ft_modify_prop(void **bphpp, char *datap, u32 *old_prop_sizep, - const char *buf, const unsigned int buflen) -{ - u32 old_prop_data_len, new_prop_data_len; - - old_prop_data_len = _ALIGN(be32_to_cpu(*old_prop_sizep), 4); - new_prop_data_len = _ALIGN(buflen, 4); - - /* Check if new prop data fits in old prop data area */ - if (new_prop_data_len == old_prop_data_len) { - memcpy(datap, buf, buflen); - *old_prop_sizep = cpu_to_be32(buflen); - } else { - /* Need to alloc new area to put larger or smaller ft */ - struct boot_param_header *old_bph = *bphpp, *new_bph; - u32 *old_tailp, *new_tailp, *new_datap; - u32 old_total_size, new_total_size, head_len, tail_len, diff, v; - - old_total_size = be32_to_cpu(old_bph->totalsize); - head_len = (u32)(datap - (char *)old_bph); - tail_len = old_total_size - (head_len + old_prop_data_len); - old_tailp = (u32 *)(datap + old_prop_data_len); - new_total_size = head_len + new_prop_data_len + tail_len; - - if (!(new_bph = malloc(new_total_size))) { - printf("Can't alloc space for new ft\n"); - ft_exit(-ENOSPC); - } - - new_datap = (u32 *)((char *)new_bph + head_len); - new_tailp = (u32 *)((char *)new_datap + new_prop_data_len); - - memcpy(new_bph, *bphpp, head_len); - memcpy(new_datap, buf, buflen); - memcpy(new_tailp, old_tailp, tail_len); - - *(new_datap - 2) = cpu_to_be32(buflen); /* Set prop size */ - - new_bph->totalsize = cpu_to_be32(new_total_size); - diff = new_prop_data_len - old_prop_data_len; - - if (be32_to_cpu(old_bph->off_dt_strings) - > be32_to_cpu(old_bph->off_dt_struct)) { - v = be32_to_cpu(new_bph->off_dt_strings); - new_bph->off_dt_strings = cpu_to_be32(v + diff); - } - - if (be32_to_cpu(old_bph->off_mem_rsvmap) - > be32_to_cpu(old_bph->off_dt_struct)) { - v = be32_to_cpu(new_bph->off_mem_rsvmap); - new_bph->off_mem_rsvmap = cpu_to_be32(v + diff); - } - - ft_free(*bphpp, old_total_size); - *bphpp = new_bph; - } -} - -/* - * - Only modifies existing properties. - * - The dev tree passed in may be freed and a new one allocated - * (and *bphpp set to location of new dev tree). - */ -int ft_set_prop(void **bphpp, const void *node, const char *propname, - const void *buf, const unsigned int buflen) -{ - struct boot_param_header *bph = *bphpp; - u32 *p_strings= (u32 *)((char *)bph + be32_to_cpu(bph->off_dt_strings)); - u32 version = be32_to_cpu(bph->version); - u32 *p, *tagp, *sizep; - char *namep, *datap; - int depth; - - depth = 0; - p = (u32 *)node; - - while ((p = ft_next(p, p_strings, version, &tagp, &namep, &datap, - &sizep)) != NULL) - switch (be32_to_cpu(*tagp)) { - case OF_DT_BEGIN_NODE: - depth++; - break; - case OF_DT_PROP: - if ((depth == 1) && !strcmp(namep, propname)) { - ft_modify_prop(bphpp, datap, sizep, buf, - buflen); - return be32_to_cpu(*sizep); - } - break; - case OF_DT_END_NODE: - if (--depth <= 0) - return -1; - break; - } - return -1; -} diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/powerpc64/flatdevtree.h --- a/tools/libxc/powerpc64/flatdevtree.h Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef _FLATDEVTREE_H_ -#define _FLATDEVTREE_H_ - -#include "flatdevtree_env.h" - -/* Definitions used by the flattened device tree */ -#define OF_DT_HEADER 0xd00dfeed /* marker */ -#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */ -#define OF_DT_END_NODE 0x2 /* End node */ -#define OF_DT_PROP 0x3 /* Property: name off, size, content */ -#define OF_DT_NOP 0x4 /* nop */ -#define OF_DT_END 0x9 - -#define OF_DT_VERSION 0x10 - -struct boot_param_header { - u32 magic; /* magic word OF_DT_HEADER */ - u32 totalsize; /* total size of DT block */ - u32 off_dt_struct; /* offset to structure */ - u32 off_dt_strings; /* offset to strings */ - u32 off_mem_rsvmap; /* offset to memory reserve map */ - u32 version; /* format version */ - u32 last_comp_version; /* last compatible version */ - /* version 2 fields below */ - u32 boot_cpuid_phys; /* Physical CPU id we're booting on */ - /* version 3 fields below */ - u32 size_dt_strings; /* size of the DT strings block */ -}; - -struct ft_cxt { - struct boot_param_header *bph; - int max_size; /* maximum size of tree */ - int overflow; /* set when this happens */ - char *p, *pstr, *pres; /* running pointers */ - char *p_begin, *pstr_begin, *pres_begin; /* starting pointers */ - char *p_anchor; /* start of constructed area */ - int struct_size, strings_size, res_size; -}; - -void ft_begin_node(struct ft_cxt *cxt, const char *name); -void ft_end_node(struct ft_cxt *cxt); - -void ft_begin_tree(struct ft_cxt *cxt); -int ft_end_tree(struct ft_cxt *cxt); - -void ft_nop(struct ft_cxt *cxt); -void ft_prop(struct ft_cxt *cxt, const char *name, - const void *data, unsigned int sz); -void ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str); -void ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val); -void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size); -void ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size); -int ft_set_rsvmap(void *bphp, int m, u64 physaddr, u64 size); - -void ft_dump_blob(const void *bphp); -void ft_backtrack_node(struct ft_cxt *cxt); -void ft_merge_blob(struct ft_cxt *cxt, void *blob); - -void *ft_find_node(const void *bphp, const char *srch_path); -int ft_get_prop(const void *bphp, const void *node, const char *propname, - void *buf, const unsigned int buflen); -int ft_set_prop(void **bphp, const void *node, const char *propname, - const void *buf, const unsigned int buflen); - -static inline char *ft_strrchr(const char *s, int c) -{ - const char *p = s + strlen(s); - - do { - if (*p == (char)c) - return (char *)p; - } while (--p >= s); - return NULL; -} - -/* 'path' is modified */ -static inline void ft_parentize(char *path, int leave_slash) -{ - char *s = &path[strlen(path) - 1]; - - if (*s == '/') - *s = '\0'; - s = ft_strrchr(path, '/'); - if (s != NULL) { - if (leave_slash) - s[1] = '\0'; - else if (s[0] == '/') - s[0] = '\0'; - } -} - -#endif /* FLATDEVTREE_H */ diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/powerpc64/flatdevtree_env.h --- a/tools/libxc/powerpc64/flatdevtree_env.h Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef _FLATDEVTREE_ENV_H_ -#define _FLATDEVTREE_ENV_H_ - -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <endian.h> -#include <errno.h> - -#define MAX_PATH_LEN 1024 - -#define _ALIGN(addr,size) (((addr)+(size)-1)&(~((size)-1))) - -typedef unsigned short u16; -typedef unsigned int u32; -typedef unsigned long long u64; - -static inline u16 swab16(u16 x) -{ - return (((u16)(x) & (u16)0x00ffU) << 8) | - (((u16)(x) & (u16)0xff00U) >> 8); -} - -static inline u32 swab32(u32 x) -{ - return (((u32)(x) & (u32)0x000000ffUL) << 24) | - (((u32)(x) & (u32)0x0000ff00UL) << 8) | - (((u32)(x) & (u32)0x00ff0000UL) >> 8) | - (((u32)(x) & (u32)0xff000000UL) >> 24); -} - -static inline u64 swab64(u64 x) -{ - return (u64)(((u64)(x) & (u64)0x00000000000000ffULL) << 56) | - (u64)(((u64)(x) & (u64)0x000000000000ff00ULL) << 40) | - (u64)(((u64)(x) & (u64)0x0000000000ff0000ULL) << 24) | - (u64)(((u64)(x) & (u64)0x00000000ff000000ULL) << 8) | - (u64)(((u64)(x) & (u64)0x000000ff00000000ULL) >> 8) | - (u64)(((u64)(x) & (u64)0x0000ff0000000000ULL) >> 24) | - (u64)(((u64)(x) & (u64)0x00ff000000000000ULL) >> 40) | - (u64)(((u64)(x) & (u64)0xff00000000000000ULL) >> 56); -} - -#if __BYTE_ORDER == __LITTLE_ENDIAN -#define cpu_to_be16(x) swab16(x) -#define be16_to_cpu(x) swab16(x) -#define cpu_to_be32(x) swab32(x) -#define be32_to_cpu(x) swab32(x) -#define cpu_to_be64(x) swab64(x) -#define be64_to_cpu(x) swab64(x) -#else -#define cpu_to_be16(x) (x) -#define be16_to_cpu(x) (x) -#define cpu_to_be32(x) (x) -#define be32_to_cpu(x) (x) -#define cpu_to_be64(x) (x) -#define be64_to_cpu(x) (x) -#endif - -static inline void ft_exit(int code) -{ - exit(code); -} - -static inline void ft_free(void *ptr, int len) -{ - free(ptr); -} - -static inline u32 min(u32 a, u32 b) -{ - if (a < b) - return a; - return b; -} - -#endif /* _FLATDEVTREE_ENV_H_ */ diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/powerpc64/mk_flatdevtree.c --- a/tools/libxc/powerpc64/mk_flatdevtree.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,648 +0,0 @@ -/* - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright IBM Corporation 2007 - * - * Authors: Ryan Harper <ryanh@xxxxxxxxxx> - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <dirent.h> -#include <unistd.h> -#include <libgen.h> -#include <inttypes.h> -#include <math.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/dir.h> -#include <sys/stat.h> -#include <sys/param.h> - -#include <xc_private.h> /* for PERROR() */ -#include <xc_dom.h> - -#include "mk_flatdevtree.h" - -static uint32_t current_phandle = 0; - -static uint32_t get_phandle(void) -{ - return current_phandle++; -} - -static int readfile(const char *fullpath, void *data, int len) -{ - struct stat st; - int saved_errno; - int rc = -1; - int fd; - - if ((fd = open(fullpath, O_RDONLY)) == -1) { - PERROR("%s: failed to open file %s", __func__, fullpath); - return -1; - } - - if ((rc = fstat(fd, &st)) == -1) { - PERROR("%s: failed to stat fd %d", __func__, fd); - goto error; - } - - if (S_ISREG(st.st_mode)) - rc = read(fd, data, len); - - close(fd); - return rc; - -error: - saved_errno = errno; - close(fd); - errno = saved_errno; - return -1; -} - -/* - * @property - string to check against the filter list - * @filter - NULL terminated list of strings - * - * compare @property string to each string in @filter - * - * return 1 if @property matches any filter, otherwise 0 - * - */ -static int match(const char *property, const char **filter) -{ - int i; - - for (i=0; filter[i] != NULL; i++) { - /* compare the filter to property */ - if (strncmp(property, filter[i], strlen(filter[i])) == 0) - return 1; - } - - return 0; -} - -/* - * copy the node at @dirpath filtering out any properties that match in @propfilter - */ -static int copynode(struct ft_cxt *cxt, const char *dirpath, const char **propfilter) -{ - struct dirent *tree; - struct stat st; - DIR *dir; - char fullpath[MAX_PATH]; - char *bname = NULL; - char *basec = NULL; - int saved_errno; - - if ((dir = opendir(dirpath)) == NULL) { - PERROR("%s: failed to open dir %s", __func__, dirpath); - return -1; - } - - while (1) { - if ((tree = readdir(dir)) == NULL) - break; /* reached end of directory entries */ - - /* ignore . and .. */ - if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree->d_name,"..") == 0) - continue; - - /* build full path name of the file, for stat() */ - if (snprintf(fullpath, sizeof(fullpath), "%s/%s", dirpath, - tree->d_name) >= sizeof(fullpath)) { - PERROR("%s: failed to build full path", __func__); - goto error; - } - - /* stat the entry */ - if (stat(fullpath, &st) < 0) { - PERROR("%s: failed to stat file %s", __func__, fullpath); - goto error; - } - - if (S_ISDIR(st.st_mode)) { - /* start a new node for a dir */ - ft_begin_node(cxt, tree->d_name); - - /* copy everything in this dir */ - if (copynode(cxt, fullpath, propfilter) < 0) { - PERROR("%s: failed to copy node @ %s", __func__, fullpath); - goto error; - } - - /* end the node */ - ft_end_node(cxt); - } - /* add files in dir as properties */ - else if (S_ISREG(st.st_mode)) { - - if ((basec = strdup(fullpath)) == NULL) { - PERROR("%s: failed to dupe string", __func__); - goto error; - } - - if ((bname = basename(basec)) == NULL) { - PERROR("%s: basename() failed", __func__); - goto error; - } - - /* only add files that don't match the property filter string */ - if (!match(bname, propfilter)) { - char data[BUFSIZE]; - int len; - - /* snarf the data and push into the property */ - if ((len = readfile(fullpath, data, sizeof(data))) < 0) { - PERROR("%s: failed to read data from file %s", __func__, - fullpath); - goto error; - } - ft_prop(cxt, tree->d_name, data, len); - - } - - /* strdup mallocs memory */ - if (basec != NULL ) { - free(basec); - basec = NULL; - } - - } - } - - closedir(dir); - return 0; - -error: - saved_errno = errno; - - /* strdup mallocs memory */ - if (basec != NULL ) { - free(basec); - basec = NULL; - } - - closedir(dir); - - errno = saved_errno; - return -1; -} - -static int find_cpu0(char *cpupath, int len) -{ - const char path[] = "/proc/device-tree/cpus"; - const char device[] = "device_type"; - const char dev_cpu[] = "cpu"; - const char reg[] = "reg"; - char data[sizeof(dev_cpu)]; - char prop[MAX_PATH]; - char node[MAX_PATH]; - struct dirent *tree; - struct stat st; - DIR* dir; - int saved_errno; - int found = 0; - - if ((dir = opendir(path)) == NULL) { - PERROR("%s: failed to open directory %s", __func__, path); - return -1; - } - - while (!found) { - - if ((tree = readdir(dir)) == NULL) - break; /* reached end of directory entries */ - - /* ignore ., .. */ - if (strcmp(tree->d_name,"." ) == 0 || strcmp(tree->d_name,"..") == 0) - continue; - - /* build full path name of the file, for stat() */ - if (snprintf(node, sizeof(node), "%s/%s", path, - tree->d_name) >= sizeof(node)) { - PERROR("%s: failed to concat strings", __func__); - goto error; - } - - /* stat the entry */ - if (stat(node, &st) < 0) { - PERROR("%s: failed to stat file %s", __func__, node); - /* something funny happen in /proc/device-tree, but march onward */ - continue; - } - - /* for each dir, check the device_type property until we find 'cpu'*/ - if (S_ISDIR(st.st_mode)) { - - /* construct path to device_type */ - if (snprintf(prop, sizeof(prop), "%s/%s", node, - device) >= sizeof(prop)) { - PERROR("%s: failed to concat strings", __func__); - goto error; - } - - /* read device_type into buffer */ - if ((readfile(prop, data, sizeof(data))) < 0) { - PERROR("%s: failed to read data from file %s", __func__, prop); - goto error; - } - - /* if the device_type is 'cpu', and reg is 0 - * return the path where we found it */ - if (strcmp(data, "cpu") == 0) { - - /* construct path to reg */ - if (snprintf(prop, sizeof(prop), "%s/%s", node, - reg) >= sizeof(prop)) { - PERROR("%s: failed to concat strings", __func__); - goto error; - } - - /* using data buffer since reg and device_type values have same size */ - if ((readfile(prop, data, sizeof(data))) < 0) { - PERROR("%s: failed to read data from file %s", __func__, prop); - goto error; - } - - /* now check property "reg" for value 0 */ - if ((u32)*data == 0) { - if (snprintf(cpupath, len, "%s", node) >= len) { - PERROR("%s: failed to copy cpupath", __func__); - goto error; - } - found = 1; - } - } - } - } - - closedir(dir); - return found; - -error: - saved_errno = errno; - closedir(dir); - errno = saved_errno; - return -1; -} - -void free_devtree(struct ft_cxt *root) -{ - if ((root != NULL) && root->bph != NULL) { - free(root->bph); - root->bph = NULL; - } -} - -int make_devtree(struct ft_cxt *root, - struct xc_dom_image *dom, - unsigned long shadow_mb) -{ - struct boot_param_header *bph = NULL; - uint64_t val[2]; - uint32_t val32[2]; - uint64_t shared_info_paddr = dom->shared_info_pfn << PAGE_SHIFT; - uint64_t xenstore_paddr = dom->xenstore_pfn << PAGE_SHIFT; - uint64_t console_paddr = dom->console_pfn << PAGE_SHIFT; - long remaining; - unsigned long ramdisk_start; - unsigned long ramdisk_size; - unsigned long rma_bytes = 1 << dom->realmodearea_log; - int64_t shadow_mb_log; - uint64_t pft_size; - char cpupath[MAX_PATH]; - const char *propfilter[] = { "ibm", "linux,", NULL }; - char *cpupath_copy = NULL; - char *cpuname = NULL; - int saved_errno; - int dtb_fd = -1; - uint32_t cpu0_phandle = get_phandle(); - uint32_t xen_phandle = get_phandle(); - uint32_t rma_phandle = get_phandle(); - - /* initialize bph to prevent double free on error path */ - root->bph = NULL; - - /* carve out space for bph */ - if ((bph = (struct boot_param_header *)malloc(BPH_SIZE)) == NULL) { - PERROR("%s: Failed to malloc bph buffer size", __func__); - goto error; - } - - /* NB: struct ft_cxt root defined at top of file */ - /* root = Tree() */ - ft_begin(root, bph, BPH_SIZE); - - /* you MUST set reservations BEFORE _starting_the_tree_ */ - - /* reserve shared_info_t page */ - if (shared_info_paddr) { - val[0] = cpu_to_be64((u64) shared_info_paddr); - val[1] = cpu_to_be64((u64) PAGE_SIZE); - ft_add_rsvmap(root, val[0], val[1]); - } - - /* reserve console page for domU */ - if (console_paddr) { - val[0] = cpu_to_be64((u64) console_paddr); - val[1] = cpu_to_be64((u64) PAGE_SIZE); - ft_add_rsvmap(root, val[0], val[1]); - } - - /* reserve xen store page for domU */ - if (xenstore_paddr) { - val[0] = cpu_to_be64((u64) xenstore_paddr); - val[1] = cpu_to_be64((u64) PAGE_SIZE); - ft_add_rsvmap(root, val[0], val[1]); - } - - /* reserve space for initrd if needed */ - ramdisk_start = dom->ramdisk_seg.pfn << PAGE_SHIFT; - ramdisk_size = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart; - if (ramdisk_size > 0) { - val[0] = cpu_to_be64((u64) ramdisk_start); - val[1] = cpu_to_be64((u64) ramdisk_size); - ft_add_rsvmap(root, val[0], val[1]); - } - - /* NB: ft_add_rsvmap() already terminates with a NULL reservation for us */ - - /* done with reservations, _starting_the_tree_ */ - ft_begin_tree(root); - - /* make root node */ - ft_begin_node(root, ""); - - /* root.addprop('device_type', 'chrp-but-not-really\0') */ - ft_prop_str(root, "device_type", "chrp-but-not-really"); - - /* root.addprop('#size-cells', 2) */ - ft_prop_int(root, "#size-cells", 2); - - /* root.addprop('#address-cells', 2) */ - ft_prop_int(root, "#address-cells", 2); - - /* root.addprop('model', 'Momentum,Maple-D\0') */ - ft_prop_str(root, "model", "Momentum,Maple-D"); - - /* root.addprop('compatible', 'Momentum,Maple\0') */ - ft_prop_str(root, "compatible", "Momentum,Maple"); - - /* start chosen node */ - ft_begin_node(root, "chosen"); - - /* chosen.addprop('cpu', cpu0.get_phandle()) */ - ft_prop_int(root, "cpu", cpu0_phandle); - - /* chosen.addprop('rma', rma.get_phandle()) */ - ft_prop_int(root, "memory", rma_phandle); - - /* chosen.addprop('linux,stdout-path', '/xen/console\0') */ - ft_prop_str(root, "linux,stdout-path", "/xen/console"); - - /* chosen.addprop('interrupt-controller, xen.get_phandle()) */ - ft_prop_int(root, "interrupt-controller", xen_phandle); - - /* chosen.addprop('bootargs', imghandler.cmdline + '\0') */ - if (dom->cmdline != NULL) - ft_prop_str(root, "bootargs", dom->cmdline); - - /* mark where the initrd is, if present */ - if (ramdisk_size > 0) { - val[0] = cpu_to_be64((u64) ramdisk_start); - val[1] = cpu_to_be64((u64) ramdisk_start + ramdisk_size); - ft_prop(root, "linux,initrd-start", &(val[0]), sizeof(val[0])); - ft_prop(root, "linux,initrd-end", &(val[1]), sizeof(val[1])); - } - - /* end chosen node */ - ft_end_node(root); - - /* xen = root.addnode('xen') */ - ft_begin_node(root, "xen"); - - /* xen.addprop('version', 'Xen-3.0-unstable\0') */ - ft_prop_str(root, "compatible", "Xen-3.0-unstable"); - - /* xen.addprop('reg', long(imghandler.vm.domid), long(0)) */ - val[0] = cpu_to_be64((u64) dom->guest_domid); - val[1] = cpu_to_be64((u64) 0); - ft_prop(root, "reg", val, sizeof(val)); - - /* point to shared_info_t page base addr */ - val[0] = cpu_to_be64((u64) shared_info_paddr); - val[1] = cpu_to_be64((u64) PAGE_SIZE); - ft_prop(root, "shared-info", val, sizeof(val)); - - /* xen.addprop('domain-name', imghandler.vm.getName() + '\0') */ - /* libxc doesn't know the domain name, that is purely a xend thing */ - /* ft_prop_str(root, "domain-name", domain_name); */ - - /* add xen/linux,phandle for chosen/interrupt-controller */ - ft_prop_int(root, "linux,phandle", xen_phandle); - - if (console_paddr != 0) { - /* xencons = xen.addnode('console') */ - ft_begin_node(root, "console"); - - /* console_paddr */ - val[0] = cpu_to_be64((u64) console_paddr); - val[1] = cpu_to_be64((u64) PAGE_SIZE); - ft_prop(root, "reg", val, sizeof(val)); - - /* xencons.addprop('interrupts', console_evtchn, 0) */ - val32[0] = cpu_to_be32((u32) dom->console_evtchn); - val32[1] = cpu_to_be32((u32) 0); - ft_prop(root, "interrupts", val32, sizeof(val32)); - - /* end of console */ - ft_end_node(root); - } - - if (xenstore_paddr != 0) { - /* start store node */ - ft_begin_node(root, "store"); - - /* store paddr */ - val[0] = cpu_to_be64((u64) xenstore_paddr); - val[1] = cpu_to_be64((u64) PAGE_SIZE); - ft_prop(root, "reg", val, sizeof(val)); - - /* store event channel */ - val32[0] = cpu_to_be32((u32) dom->xenstore_evtchn); - val32[1] = cpu_to_be32((u32) 0); - ft_prop(root, "interrupts", val32, sizeof(val32)); - - /* end of store */ - ft_end_node(root); - } - - /* end of xen node */ - ft_end_node(root); - - /* rma = root.addnode('memory@0') */ - ft_begin_node(root, "memory@0"); - - /* rma.addprop('reg', long(0), long(rma_bytes)) */ - val[0] = cpu_to_be64((u64) 0); - val[1] = cpu_to_be64((u64) rma_bytes); - ft_prop(root, "reg", val, sizeof(val)); - - /* rma.addprop('device_type', 'memory\0') */ - ft_prop_str(root, "device_type", "memory"); - - /* add linux,phandle for chosen/rma node */ - ft_prop_int(root, "linux,phandle", rma_phandle); - - /* end of memory@0 */ - ft_end_node(root); - - /* calculate remaining bytes from total - rma size */ - remaining = (dom->total_pages << PAGE_SHIFT) - rma_bytes; - - /* memory@<rma_bytes> is all remaining memory after RMA */ - if (remaining > 0) - { - char mem[MAX_PATH]; - - if (snprintf(mem, sizeof(mem), "memory@%lx", - rma_bytes) >= sizeof(mem)) { - PERROR("%s: failed to build memory string", __func__); - goto error; - } - - /* memory@<rma_bytes> is all remaining memory after RMA */ - ft_begin_node(root, mem); - - /* mem.addprop('reg', long(rma_bytes), long(remaining)) */ - val[0] = cpu_to_be64((u64) rma_bytes); - val[1] = cpu_to_be64((u64) remaining); - ft_prop(root, "reg", val, sizeof(val)); - - /* mem.addprop('device_type', 'memory\0') */ - ft_prop_str(root, "device_type", "memory"); - - /* end memory@<rma_bytes> node */ - ft_end_node(root); - } - - /* add CPU nodes */ - /* cpus = root.addnode('cpus') */ - ft_begin_node(root, "cpus"); - - /* cpus.addprop('smp-enabled') */ - ft_prop(root, "smp-enabled", NULL, 0); - - /* cpus.addprop('#size-cells', 0) */ - ft_prop_int(root, "#size-cells", 0); - - /* cpus.addprop('#address-cells', 1) */ - ft_prop_int(root, "#address-cells", 1); - - /* - * Copy all properties the system firmware gave us from a - * CPU node in the device tree. - */ - if (find_cpu0(cpupath, sizeof(cpupath)) <= 0) { - PERROR("%s: failed find cpu0 node in host devtree", __func__); - goto error; - } - - /* get the basename from path to cpu device */ - if ((cpupath_copy = strdup(cpupath)) == NULL) { - PERROR("%s: failed to dupe string", __func__); - goto error; - } - if ((cpuname = basename(cpupath_copy)) == NULL) { - PERROR("%s: basename() failed", __func__); - goto error; - } - - /* start node for the cpu */ - ft_begin_node(root, cpuname); - - /* strdup() mallocs memory */ - if ( cpupath_copy != NULL ) { - free(cpupath_copy); - cpupath_copy = NULL; - } - - /* copy over most properties from host tree for cpu */ - if (copynode(root, cpupath, propfilter) < 0) { - PERROR("%s: failed to copy node", __func__); - goto error; - } - - /* calculate the pft-size */ - shadow_mb_log = (int)log2((double)shadow_mb); - pft_size = shadow_mb_log + 20; - - val32[0] = cpu_to_be32((u32) 0); - val32[1] = cpu_to_be32((u32) pft_size); - ft_prop(root, "ibm,pft-size", val32, sizeof(val32)); - - /* make phandle for cpu0 */ - ft_prop_int(root, "linux,phandle", cpu0_phandle); - - /* end <cpuname> node */ - ft_end_node(root); - - /* end cpus node */ - ft_end_node(root); - - /* end root node */ - ft_end_node(root); - - /* end of the tree */ - if (ft_end_tree(root) != 0) { - PERROR("%s: failed to end tree", __func__); - goto error; - } - - /* write a copy of the tree to a file */ - if ((dtb_fd = creat(DTB_FILE, S_IRUSR | S_IWUSR)) == -1) { - PERROR("%s: failed to open file %s", __func__, DTB_FILE); - goto error; - } - - if (write(dtb_fd, (const void *)bph, bph->totalsize) != bph->totalsize) { - PERROR("%s: failed to write blob to file", __func__); - goto error; - } - - return 0; - -error: - saved_errno = errno; - - /* strdup() mallocs memory */ - if ( cpupath_copy != NULL ) { - free(cpupath_copy); - cpupath_copy = NULL; - } - - /* free bph buffer */ - free_devtree(root); - - if (dtb_fd) - close(dtb_fd); - - errno = saved_errno; - return -1; -} diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/powerpc64/mk_flatdevtree.h --- a/tools/libxc/powerpc64/mk_flatdevtree.h Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright IBM Corporation 2007 - * - * Authors: Ryan Harper <ryanh@xxxxxxxxxx> - */ - -#ifndef MK_FLATDEVTREE_H -#define MK_FLATDEVTREE_H - -#include "flatdevtree_env.h" -#include "flatdevtree.h" - -extern void free_devtree(struct ft_cxt *root); -extern int make_devtree(struct ft_cxt *root, - struct xc_dom_image *dom, - unsigned long shadow_mb); - -#define MAX_PATH 200 -#define BUFSIZE 1024 -#define BPH_SIZE 16*1024 -#define DTB_FILE "/tmp/domU.dtb" - -#endif /* MK_FLATDEVTREE_H */ diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/powerpc64/xc_memory.c --- a/tools/libxc/powerpc64/xc_memory.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright (C) IBM Corporation 2006 - * - * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx> - */ - -#include "xc_private.h" -#include <xen/domctl.h> - -int xc_alloc_real_mode_area(int xc_handle, - uint32_t domain, - unsigned int log) -{ - DECLARE_DOMCTL; - int err; - - domctl.cmd = XEN_DOMCTL_real_mode_area; - domctl.domain = (domid_t)domain; - domctl.u.real_mode_area.log = log; - - err = do_domctl(xc_handle, &domctl); - - if (err) - DPRINTF("Failed real mode area allocation for dom %u (log %u)\n", - domain, log); - - return err; -} diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/xc_core.h --- a/tools/libxc/xc_core.h Thu May 15 14:53:48 2008 +0900 +++ b/tools/libxc/xc_core.h Thu May 15 16:23:56 2008 +0900 @@ -148,8 +148,6 @@ int xc_core_arch_map_p2m(int xc_handle, # include "xc_core_x86.h" #elif defined (__ia64__) # include "xc_core_ia64.h" -#elif defined (__powerpc__) -# include "xc_core_powerpc.h" #else # error "unsupported architecture" #endif diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/xc_core_powerpc.c --- a/tools/libxc/xc_core_powerpc.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp> - * VA Linux Systems Japan K.K. - * Copyright IBM Corp. 2007 - * - * Authors: Isaku Yamahata <yamahata at valinux co jp> - * Hollis Blanchard <hollisb@xxxxxxxxxx> - * - */ - -#include "xg_private.h" -#include "xc_core.h" - -int -xc_core_arch_auto_translated_physmap(const xc_dominfo_t *info) -{ - /* All PowerPC domU are autotranslated. */ - return 1; -} - -int -xc_core_arch_map_p2m(int xc_handle, xc_dominfo_t *info, - shared_info_t *live_shinfo, xen_pfn_t **live_p2m, - unsigned long *pfnp) -{ - /* All PowerPC domU are autotranslated. */ - errno = ENOSYS; - return -1; -} - -int -xc_core_arch_memory_map_get(int xc_handle, struct xc_core_arch_context *unused, - xc_dominfo_t *info, shared_info_t *live_shinfo, - xc_core_memory_map_t **mapp, - unsigned int *nr_entries) -{ - xc_core_memory_map_t *map = NULL; - - map = malloc(sizeof(*map)); - if (!map) { - PERROR("Could not allocate memory"); - goto out; - } - - map->addr = 0; - map->size = info->max_memkb * 1024; - - *mapp = map; - *nr_entries = 1; - return 0; - -out: - free(map); - return -1; -} - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/xc_core_powerpc.h --- a/tools/libxc/xc_core_powerpc.h Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp> - * VA Linux Systems Japan K.K. - * - */ - -#ifndef XC_CORE_POWERPC_H -#define XC_CORE_POWERPC_H - -#define ELF_ARCH_DATA ELFDATA2MSB -#define ELF_ARCH_MACHINE EM_PPC64 - -struct xc_core_arch_context { - /* nothing */ -}; - -#define xc_core_arch_context_init(arch_ctxt) do {} while (0) -#define xc_core_arch_context_free(arch_ctxt) do {} while (0) -#define xc_core_arch_context_get(arch_ctxt, ctxt, xc_handle, domid) \ - (0) -#define xc_core_arch_context_dump(arch_ctxt, args, dump_rtn) (0) -#define xc_core_arch_gpfn_may_present(arch_ctxt, i) (1) - -static inline int -xc_core_arch_context_get_shdr(struct xc_core_arch_context *arch_ctxt, - struct xc_core_section_headers *sheaders, - struct xc_core_strtab *strtab, - uint64_t *filesz, uint64_t offset) -{ - *filesz = 0; - return 0; -} - -#endif /* XC_CORE_POWERPC_H */ - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/xc_dom_elfloader.c --- a/tools/libxc/xc_dom_elfloader.c Thu May 15 14:53:48 2008 +0900 +++ b/tools/libxc/xc_dom_elfloader.c Thu May 15 16:23:56 2008 +0900 @@ -43,8 +43,6 @@ static char *xc_dom_guest_type(struct xc return "xen-3.0-x86_64"; case EM_IA_64: return elf_msb(elf) ? "xen-3.0-ia64be" : "xen-3.0-ia64"; - case EM_PPC64: - return "xen-3.0-powerpc64"; default: return "xen-3.0-unknown"; } diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/xc_dom_powerpc.c --- a/tools/libxc/xc_dom_powerpc.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +0,0 @@ -/* - * Xen domain builder -- powerpc bits. - * - * Most architecture-specific code for powerpc goes here. - * - * This code is licenced under the GPL. - * written 2006 by Gerd Hoffmann <kraxel@xxxxxxx>. - * - * Copyright IBM Corp. 2007 - * - * Authors: Gerd Hoffmann <kraxel@xxxxxxx> - * Hollis Blanchard <hollisb@xxxxxxxxxx> - * - */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <inttypes.h> - -#include <xen/xen.h> - -#include "xg_private.h" -#include "xc_dom.h" -#include "powerpc64/flatdevtree.h" -#include "powerpc64/mk_flatdevtree.h" - -#define RMA_LOG 26 /* 64 MB */ -#define EXTENT_LOG 24 /* 16 MB */ -#define EXTENT_ORDER (EXTENT_LOG - PAGE_SHIFT) - -/* ------------------------------------------------------------------------ */ - -static int alloc_magic_pages(struct xc_dom_image *dom) -{ - struct ft_cxt devtree; - void *guest_devtree; - unsigned long shadow_mb; - int rma_pages; - int rc; - - /* Allocate special pages from the end of the RMA. */ - rma_pages = 1 << (dom->realmodearea_log - PAGE_SHIFT); - dom->shared_info_pfn = --rma_pages; - dom->console_pfn = --rma_pages; - dom->xenstore_pfn = --rma_pages; - - /* Gather shadow allocation info for the device tree. */ - rc = xc_shadow_control(dom->guest_xc, dom->guest_domid, - XEN_DOMCTL_SHADOW_OP_GET_ALLOCATION, NULL, 0, - &shadow_mb, 0, NULL); - if (rc < 0 || shadow_mb == 0) { - xc_dom_printf("Couldn't get shadow allocation size or it was 0.\n"); - return rc; - } - - /* Build device tree. */ - rc = make_devtree(&devtree, dom, shadow_mb); - if (rc < 0) { - xc_dom_printf("Failed to create flattened device tree.\n"); - return rc; - } - - /* Find a spot for it. */ - rc = xc_dom_alloc_segment(dom, &dom->devicetree_seg, "devtree", 0, - devtree.bph->totalsize); - if (rc) - goto out; - - /* Copy the device tree into place. */ - guest_devtree = xc_dom_seg_to_ptr(dom, &dom->devicetree_seg); - if (!guest_devtree) { - xc_dom_printf("Couldn't map guest memory for device tree.\n"); - rc = -1; - goto out; - } - memcpy(guest_devtree, devtree.bph, devtree.bph->totalsize); - -out: - free_devtree(&devtree); - return rc; -} - -static int shared_info(struct xc_dom_image *dom, void *ptr) -{ - shared_info_t *shared_info = ptr; - - xc_dom_printf("%s: called\n", __FUNCTION__); - - memset(shared_info, 0, sizeof(*shared_info)); - return 0; -} - -static int vcpu(struct xc_dom_image *dom, void *ptr) -{ - vcpu_guest_context_t *ctxt = ptr; - - memset(ctxt, 0x55, sizeof(*ctxt)); - ctxt->user_regs.pc = dom->parms.virt_entry; - ctxt->user_regs.msr = 0; - ctxt->user_regs.gprs[1] = 0; /* Linux uses its own stack */ - ctxt->user_regs.gprs[3] = dom->devicetree_seg.pfn << PAGE_SHIFT; - ctxt->user_regs.gprs[4] = dom->kernel_seg.pfn << PAGE_SHIFT; - ctxt->user_regs.gprs[5] = 0; - - /* There is a buggy kernel that does not zero the "local_paca", so - * we must make sure this register is 0 */ - ctxt->user_regs.gprs[13] = 0; - - xc_dom_printf("%s: initial vcpu:\n", __FUNCTION__); - xc_dom_printf(" pc 0x%016"PRIx64", msr 0x%016"PRIx64"\n" - " r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64 - " %016"PRIx64"\n", - ctxt->user_regs.pc, ctxt->user_regs.msr, - ctxt->user_regs.gprs[1], - ctxt->user_regs.gprs[2], - ctxt->user_regs.gprs[3], - ctxt->user_regs.gprs[4], - ctxt->user_regs.gprs[5]); - - return 0; -} - -/* ------------------------------------------------------------------------ */ - -static struct xc_dom_arch xc_dom_arch = { - .guest_type = "xen-3.0-powerpc64", - .page_shift = PAGE_SHIFT, - .alloc_magic_pages = alloc_magic_pages, - .shared_info = shared_info, - .vcpu = vcpu, -}; - -static void __init register_arch_hooks(void) -{ - xc_dom_register_arch_hooks(&xc_dom_arch); -} - -int arch_setup_meminit(struct xc_dom_image *dom) -{ - xen_pfn_t *extent_list; - unsigned long total_mem = dom->total_pages << PAGE_SHIFT; - unsigned long rma_bytes; - unsigned long rma_nr_pages; - unsigned long nr_extents; - int rc = 0; - int i; - - /* XXX RMA size is processor-dependent. */ - dom->realmodearea_log = RMA_LOG; - rma_bytes = 1 << dom->realmodearea_log; - rma_nr_pages = rma_bytes >> PAGE_SHIFT; - - xc_dom_printf("dom%u memory: %lu MB RMA, %lu MB additional.\n", - dom->guest_domid, rma_bytes >> 20, (total_mem - rma_bytes) >> 20); - - if (total_mem < rma_bytes) { - xc_dom_printf("Domain must have at least %lu MB\n", rma_bytes >> 20); - return -EINVAL; - } - - /* Allocate the first chunk of memory. */ - rc = xc_alloc_real_mode_area(dom->guest_xc, dom->guest_domid, - dom->realmodearea_log); - if (rc) { - xc_dom_printf("Failed to allocate real mode area.\n"); - return rc; - } - - /* Allocate p2m map. */ - dom->p2m_host = xc_dom_malloc(dom, sizeof(xen_pfn_t) * dom->total_pages); - if (dom->p2m_host == NULL) { - xc_dom_printf("Couldn't allocate p2m map.\n"); - return -ENOMEM; - } - - nr_extents = (dom->total_pages - rma_nr_pages) >> EXTENT_ORDER; - if (nr_extents) { - /* Allocate extent list for populate_physmap() call. */ - extent_list = xc_dom_malloc(dom, sizeof(xen_pfn_t) * nr_extents); - if (extent_list == NULL) { - xc_dom_printf("Couldn't allocate extent list.\n"); - return -ENOMEM; - } - - /* Allocate the remaining (non-RMA) memory. */ - for (i = 0; i < nr_extents; i++) { - /* Use PFNs above the RMA memory we already allocated. */ - extent_list[i] = rma_nr_pages + i * (1<<EXTENT_ORDER); - } - rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid, - nr_extents, EXTENT_ORDER, 0, - extent_list); - if (rc < 0) { - xc_dom_printf("populate_physmap(0x%lx extents order %u) -> 0x%x\n", - nr_extents, EXTENT_ORDER, rc); - return rc; - } - } - - /* Populate the p2m map. */ - rc = xc_get_pfn_list(dom->guest_xc, dom->guest_domid, dom->p2m_host, - dom->total_pages); - if (rc < 0) { - xc_dom_printf("Couldn't get p2m translation.\n"); - return rc; - } - - xc_dom_printf("%s: success\n", __func__); - - return 0; -} - -int arch_setup_bootearly(struct xc_dom_image *dom) -{ - xc_dom_printf("%s: doing nothing\n", __FUNCTION__); - return 0; -} - -int arch_setup_bootlate(struct xc_dom_image *dom) -{ - unsigned int page_size = XC_DOM_PAGE_SIZE(dom); - shared_info_t *shared_info; - - /* setup shared_info page */ - xc_dom_printf("%s: shared_info: mfn 0x%" PRIpfn "\n", - __FUNCTION__, dom->shared_info_mfn); - shared_info = xc_map_foreign_range(dom->guest_xc, dom->guest_domid, - page_size, - PROT_READ | PROT_WRITE, - dom->shared_info_mfn); - if ( shared_info == NULL ) - return -1; - dom->arch_hooks->shared_info(dom, shared_info); - munmap(shared_info, page_size); - return 0; -} diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/xc_physdev.c --- a/tools/libxc/xc_physdev.c Thu May 15 14:53:48 2008 +0900 +++ b/tools/libxc/xc_physdev.c Thu May 15 16:23:56 2008 +0900 @@ -52,6 +52,7 @@ int xc_physdev_map_pirq_msi(int xc_handl int *pirq, int devfn, int bus, + int entry_nr, int msi_type) { int rc; @@ -66,6 +67,7 @@ int xc_physdev_map_pirq_msi(int xc_handl map.pirq = *pirq; map.msi_info.devfn = devfn; map.msi_info.bus = bus; + map.msi_info.entry_nr = entry_nr; map.msi_info.msi = msi_type; rc = do_physdev_op(xc_handle, PHYSDEVOP_map_pirq, &map); diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Thu May 15 14:53:48 2008 +0900 +++ b/tools/libxc/xenctrl.h Thu May 15 16:23:56 2008 +0900 @@ -55,10 +55,6 @@ #define xen_mb() asm volatile ("mf" ::: "memory") #define xen_rmb() asm volatile ("mf" ::: "memory") #define xen_wmb() asm volatile ("mf" ::: "memory") -#elif defined(__powerpc__) -#define xen_mb() asm volatile ("sync" : : : "memory") -#define xen_rmb() asm volatile ("sync" : : : "memory") /* lwsync? */ -#define xen_wmb() asm volatile ("sync" : : : "memory") /* eieio? */ #else #error "Define barriers" #endif @@ -863,6 +859,7 @@ int xc_physdev_map_pirq_msi(int xc_handl int *pirq, int devfn, int bus, + int entry_nr, int msi_type); int xc_physdev_unmap_pirq(int xc_handle, @@ -943,11 +940,6 @@ xc_error_handler xc_set_error_handler(xc int xc_set_hvm_param(int handle, domid_t dom, int param, unsigned long value); int xc_get_hvm_param(int handle, domid_t dom, int param, unsigned long *value); - -/* PowerPC specific. */ -int xc_alloc_real_mode_area(int xc_handle, - uint32_t domid, - unsigned int log); /* IA64 specific, nvram save */ int xc_ia64_save_to_nvram(int xc_handle, uint32_t dom); diff -r ef290f39ae6b -r c96507e0c83d tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Thu May 15 14:53:48 2008 +0900 +++ b/tools/libxc/xenguest.h Thu May 15 16:23:56 2008 +0900 @@ -136,18 +136,4 @@ int xc_hvm_build_mem(int xc_handle, const char *image_buffer, unsigned long image_size); -/* PowerPC specific. */ -int xc_prose_build(int xc_handle, - uint32_t domid, - unsigned int mem_mb, - const char *image_name, - const char *ramdisk_name, - const char *cmdline, - const char *features, - unsigned long flags, - unsigned int store_evtchn, - unsigned long *store_mfn, - unsigned int console_evtchn, - unsigned long *console_mfn); - #endif /* XENGUEST_H */ diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/lowlevel/xc/xc.c Thu May 15 16:23:56 2008 +0900 @@ -1350,28 +1350,6 @@ static PyObject *dom_op(XcObject *self, return zero; } -#ifdef __powerpc__ -static PyObject *pyxc_alloc_real_mode_area(XcObject *self, - PyObject *args, - PyObject *kwds) -{ - uint32_t dom; - unsigned int log; - - static char *kwd_list[] = { "dom", "log", NULL }; - - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, - &dom, &log) ) - return NULL; - - if ( xc_alloc_real_mode_area(self->xc_handle, dom, log) ) - return pyxc_error_to_exception(); - - Py_INCREF(zero); - return zero; -} -#endif /* powerpc */ - static PyMethodDef pyxc_methods[] = { { "handle", (PyCFunction)pyxc_handle, @@ -1759,16 +1737,6 @@ static PyMethodDef pyxc_methods[] = { "Inject debug keys into Xen.\n" " keys [str]: String of keys to inject.\n" }, -#ifdef __powerpc__ - { "arch_alloc_real_mode_area", - (PyCFunction)pyxc_alloc_real_mode_area, - METH_VARARGS | METH_KEYWORDS, "\n" - "Allocate a domain's real mode area.\n" - " dom [int]: Identifier of domain.\n" - " log [int]: Specifies the area's size.\n" - "Returns: [int] 0 on success; -1 on error.\n" }, -#endif /* __powerpc */ - #if defined(__i386__) || defined(__x86_64__) { "domain_check_cpuid", (PyCFunction)pyxc_dom_check_cpuid, diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/util/xsm/acm/acm.py --- a/tools/python/xen/util/xsm/acm/acm.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/util/xsm/acm/acm.py Thu May 15 16:23:56 2008 +0900 @@ -1363,6 +1363,45 @@ def relabel_domains(relabel_list): return rc, errors +def __update_label_policy_change(sec_lab, + cur_poltype, + cur_polname, + new_poltype, + new_polname, + polnew_labels, + label_map): + """ + Determine a new resource label given the new policy's type + and name and the new policy's (resource/VM) labels and the + (resource/VM) label map that indicates renaming rules for + labels. + """ + is_deleted = False + policytype, policy, label = sec_lab + + if cur_poltype != policytype or \ + cur_polname != policy: + return sec_lab, is_deleted + + if policytype != xsconstants.ACM_POLICY_ID: + return sec_lab, is_deleted + elif label_map.has_key(label) and policy == cur_polname: + # renaming of an active label; policy may have been renamed + label = label_map[label] + polname = new_polname + elif label not in polnew_labels: + # label been removed + policytype = xsconstants.INVALID_POLICY_PREFIX + policytype + polname = policy + is_deleted = True + else: + # no change to label + policytype = xsconstants.ACM_POLICY_ID + polname = new_polname + + return tuple( [ policytype, polname, label ] ), is_deleted + + def change_acm_policy(bin_pol, del_array, chg_array, vmlabel_map, reslabel_map, cur_acmpol, new_acmpol, is_reset): @@ -1430,30 +1469,21 @@ def change_acm_policy(bin_pol, del_array else: return -xsconstants.XSERR_BAD_LABEL_FORMAT, "" - if policytype != cur_policytype or \ - policy != cur_policyname: - continue - - # label been renamed or deleted? - if policytype != xsconstants.ACM_POLICY_ID: - continue - elif reslabel_map.has_key(label) and cur_policyname == policy: - # renaming of an active label; policy may have been renamed - label = reslabel_map[label] - polname = new_policyname - elif label not in polnew_reslabels: - # label been removed - policytype = xsconstants.INVALID_POLICY_PREFIX + policytype + new_sec_lab, is_deleted = \ + __update_label_policy_change( tuple([policytype, + policy, + label]), + cur_policytype, + cur_policyname, + new_policytype, + new_policyname, + polnew_reslabels, + reslabel_map) + + if is_deleted: label_changes.append(key) - polname = policy - else: - # no change to label - policytype = xsconstants.ACM_POLICY_ID - polname = new_policyname - # Update entry - access_control[key] = \ - tuple([ policytype, polname, label ]) + access_control[key] = new_sec_lab # All resources have new labels in the access_control map # There may still be labels in there that are invalid now. @@ -1509,6 +1539,29 @@ def change_acm_policy(bin_pol, del_array new_acmpol.policy_get_virtualmachinelabel_names()) if not compatible: return (-xsconstants.XSERR_RESOURCE_ACCESS, "") + + for dominfo in dominfos: + # relabel the VIF interfaces + changed = False + for vif_uuid in dominfo.get_vifs(): + sec_lab = dominfo.info['devices'][vif_uuid][1]\ + .get('security_label') + if sec_lab: + result, _ = \ + __update_label_policy_change(tuple(sec_lab.split(':')), + cur_policytype, + cur_policyname, + new_policytype, + new_policyname, + polnew_reslabels, + reslabel_map) + new_sec_lab = ':'.join(list(result)) + if new_sec_lab != sec_lab: + changed = True + dominfo.info['devices'][vif_uuid][1]\ + ['security_label'] = new_sec_lab + if changed: + XendDomain.instance().managed_config_save(dominfo) rc, errors = hv_chg_policy(bin_pol, del_array, chg_array) if rc == 0: diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/web/connection.py --- a/tools/python/xen/web/connection.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/web/connection.py Thu May 15 16:23:56 2008 +0900 @@ -18,11 +18,17 @@ #============================================================================ import sys +import os import threading import socket import fcntl from errno import EAGAIN, EINTR, EWOULDBLOCK + +try: + from OpenSSL import SSL +except ImportError: + pass from xen.xend.XendLogging import log @@ -113,6 +119,167 @@ class SocketListener: break finally: self.close() + + +class SSLSocketServerConnection(SocketServerConnection): + """An SSL aware accepted connection to a server. + + As pyOpenSSL SSL.Connection fileno() method just retrieve the file + descriptor number for the underlying socket, direct read/write to the file + descriptor will result no data encrypted. + + recv2fd() and fd2send() are simple wrappers for functions who need direct + read/write to a file descriptor rather than a socket like object. + + To use recv2fd(), you can create a pipe and start a thread to transfer all + received data to one end of the pipe, then read from the other end: + + p2cread, p2cwrite = os.pipe() + threading.Thread(target=connection.SSLSocketServerConnection.recv2fd, + args=(sock, p2cwrite)).start() + os.read(p2cread, 1024) + + To use fd2send(): + + p2cread, p2cwrite = os.pipe() + threading.Thread(target=connection.SSLSocketServerConnection.fd2send, + args=(sock, p2cread)).start() + os.write(p2cwrite, "data") + """ + + def __init__(self, sock, protocol_class): + SocketServerConnection.__init__(self, sock, protocol_class) + + + def main(self): + try: + while True: + try: + data = self.sock.recv(BUFFER_SIZE) + if data == "": + break + if self.protocol.dataReceived(data): + break + except socket.error, ex: + if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR): + break + except (SSL.WantReadError, SSL.WantWriteError, \ + SSL.WantX509LookupError): + # The operation did not complete; the same I/O method + # should be called again. + continue + except SSL.ZeroReturnError: + # The SSL Connection has been closed. + break + except SSL.SysCallError, (retval, desc): + if ((retval == -1 and desc == "Unexpected EOF") + or retval > 0): + # The SSL Connection is lost. + break + log.debug("SSL SysCallError:%d:%s" % (retval, desc)) + break + except SSL.Error, e: + # other SSL errors + log.debug("SSL Error:%s" % e) + break + finally: + try: + self.sock.close() + except: + pass + + + def recv2fd(sock, fd): + try: + while True: + try: + data = sock.recv(BUFFER_SIZE) + if data == "": + break + count = 0 + while count < len(data): + try: + nbytes = os.write(fd, data[count:]) + count += nbytes + except os.error, ex: + if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR): + raise + except socket.error, ex: + if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR): + break + except (SSL.WantReadError, SSL.WantWriteError, \ + SSL.WantX509LookupError): + # The operation did not complete; the same I/O method + # should be called again. + continue + except SSL.ZeroReturnError: + # The SSL Connection has been closed. + break + except SSL.SysCallError, (retval, desc): + if ((retval == -1 and desc == "Unexpected EOF") + or retval > 0): + # The SSL Connection is lost. + break + log.debug("SSL SysCallError:%d:%s" % (retval, desc)) + break + except SSL.Error, e: + # other SSL errors + log.debug("SSL Error:%s" % e) + break + finally: + try: + sock.close() + os.close(fd) + except: + pass + + recv2fd = staticmethod(recv2fd) + + + def fd2send(sock, fd): + try: + while True: + try: + data = os.read(fd, BUFFER_SIZE) + if data == "": + break + count = 0 + while count < len(data): + try: + nbytes = sock.send(data[count:]) + count += nbytes + except socket.error, ex: + if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR): + raise + except (SSL.WantReadError, SSL.WantWriteError, \ + SSL.WantX509LookupError): + # The operation did not complete; the same I/O method + # should be called again. + continue + except SSL.ZeroReturnError: + # The SSL Connection has been closed. + raise + except SSL.SysCallError, (retval, desc): + if not (retval == -1 and data == ""): + # errors when writing empty strings are expected + # and can be ignored + log.debug("SSL SysCallError:%d:%s" % (retval, desc)) + raise + except SSL.Error, e: + # other SSL errors + log.debug("SSL Error:%s" % e) + raise + except os.error, ex: + if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR): + break + finally: + try: + sock.close() + os.close(fd) + except: + pass + + fd2send = staticmethod(fd2send) def hostAllowed(addrport, hosts_allowed): diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/web/tcp.py --- a/tools/python/xen/web/tcp.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/web/tcp.py Thu May 15 16:23:56 2008 +0900 @@ -88,6 +88,7 @@ class SSLTCPListener(TCPListener): ctx.use_certificate_file(self.ssl_cert_file) sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) + sock.set_accept_state() sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # SO_REUSEADDR does not always ensure that we do not get an address @@ -104,3 +105,14 @@ class SSLTCPListener(TCPListener): else: raise + + def acceptConnection(self, sock, addrport): + addr = addrport[0] + if connection.hostAllowed(addrport, self.hosts_allow): + connection.SSLSocketServerConnection(sock, self.protocol_class) + else: + try: + sock.close() + except: + pass + diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/xend/XendCheckpoint.py --- a/tools/python/xen/xend/XendCheckpoint.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/xend/XendCheckpoint.py Thu May 15 16:23:56 2008 +0900 @@ -81,8 +81,6 @@ def save(fd, dominfo, network, live, dst # thing is useful for debugging. dominfo.setName('migrating-' + domain_name) - done_suspend = 0 - try: dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP1, domain_name) @@ -110,7 +108,6 @@ def save(fd, dominfo, network, live, dst log.debug("Suspending %d ...", dominfo.getDomid()) dominfo.shutdown('suspend') dominfo.waitForShutdown() - done_suspend = 1 dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP2, domain_name) log.info("Domain %d suspended.", dominfo.getDomid()) @@ -154,16 +151,9 @@ def save(fd, dominfo, network, live, dst pass except Exception, exn: - log.exception("Save failed on domain %s (%s).", domain_name, + log.exception("Save failed on domain %s (%s) - resuming.", domain_name, dominfo.getDomid()) - - # If we didn't get as far as suspending the domain (for - # example, we couldn't balloon enough memory for the new - # domain), then we don't want to re-plumb the devices, as the - # domU will not be expecting it. - if done_suspend: - log.debug("XendCheckpoint.save: resumeDomain") - dominfo.resumeDomain() + dominfo.resumeDomain() try: dominfo.setName(domain_name) diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/xend/XendConfig.py Thu May 15 16:23:56 2008 +0900 @@ -640,46 +640,84 @@ class XendConfig(dict): else: cfg['cpus'] = str(cfg['cpu']) - # Convert 'cpus' to list of ints + # Convert 'cpus' to list of list of ints + cpus_list = [] if 'cpus' in cfg: - cpus = [] + # Convert the following string to list of ints. + # The string supports a list of ranges (0-3), + # seperated by commas, and negation (^1). + # Precedence is settled by order of the string: + # "0-3,^1" -> [0,2,3] + # "0-3,^1,1" -> [0,1,2,3] + def cnv(s): + l = [] + for c in s.split(','): + if c.find('-') != -1: + (x, y) = c.split('-') + for i in range(int(x), int(y)+1): + l.append(int(i)) + else: + # remove this element from the list + if c[0] == '^': + l = [x for x in l if x != int(c[1:])] + else: + l.append(int(c)) + return l + if type(cfg['cpus']) == list: - # If sxp_cfg was created from config.sxp, - # the form of 'cpus' is list of string. - # Convert 'cpus' to list of ints. - # ['1'] -> [1] - # ['0','2','3'] -> [0,2,3] + if len(cfg['cpus']) > 0 and type(cfg['cpus'][0]) == list: + # If sxp_cfg was created from config.sxp, + # the form of 'cpus' is list of list of string. + # Convert 'cpus' to list of list of ints. + # Conversion examples: + # [['1']] -> [[1]] + # [['0','2'],['1','3']] -> [[0,2],[1,3]] + try: + for c1 in cfg['cpus']: + cpus = [] + for c2 in c1: + cpus.append(int(c2)) + cpus_list.append(cpus) + except ValueError, e: + raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e)) + else: + # Conversion examples: + # ["1"] -> [[1]] + # ["0,2","1,3"] -> [[0,2],[1,3]] + # ["0-3,^1","1-4,^2"] -> [[0,2,3],[1,3,4]] + try: + for c in cfg['cpus']: + cpus = cnv(c) + cpus_list.append(cpus) + except ValueError, e: + raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e)) + + if len(cpus_list) != cfg['vcpus']: + raise XendConfigError('vcpus and the item number of cpus are not same') + else: + # Conversion examples: + # vcpus=1: + # "1" -> [[1]] + # "0-3,^1" -> [[0,2,3]] + # vcpus=2: + # "1" -> [[1],[1]] + # "0-3,^1" -> [[0,2,3],[0,2,3]] try: - for c in cfg['cpus']: - cpus.append(int(c)) - - cfg['cpus'] = cpus + cpus = cnv(cfg['cpus']) + for v in range(0, cfg['vcpus']): + cpus_list.append(cpus) except ValueError, e: raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e)) - else: - # Convert 'cpus' string to list of ints - # 'cpus' supports a list of ranges (0-3), - # seperated by commas, and negation, (^1). - # Precedence is settled by order of the - # string: - # "0-3,^1" -> [0,2,3] - # "0-3,^1,1" -> [0,1,2,3] - try: - for c in cfg['cpus'].split(','): - if c.find('-') != -1: - (x, y) = c.split('-') - for i in range(int(x), int(y)+1): - cpus.append(int(i)) - else: - # remove this element from the list - if c[0] == '^': - cpus = [x for x in cpus if x != int(c[1:])] - else: - cpus.append(int(c)) - - cfg['cpus'] = cpus - except ValueError, e: - raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e)) + else: + # Generation examples: + # vcpus=1: + # -> [[]] + # vcpus=2: + # -> [[],[]] + for v in range(0, cfg['vcpus']): + cpus_list.append(list()) + + cfg['cpus'] = cpus_list # Parse cpuid if 'cpuid' in cfg: diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/xend/XendDomain.py --- a/tools/python/xen/xend/XendDomain.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/xend/XendDomain.py Thu May 15 16:23:56 2008 +0900 @@ -1293,23 +1293,56 @@ class XendDomain: if port == 0: port = xoptions.get_xend_relocation_port() - try: - tls = xoptions.get_xend_relocation_tls() - if tls: - from OpenSSL import SSL + tls = xoptions.get_xend_relocation_tls() + if tls: + from OpenSSL import SSL + from xen.web import connection + try: ctx = SSL.Context(SSL.SSLv23_METHOD) - sock = SSL.Connection(ctx, socket.socket(socket.AF_INET, socket.SOCK_STREAM)) + sock = SSL.Connection(ctx, + socket.socket(socket.AF_INET, socket.SOCK_STREAM)) sock.set_connect_state() - else: + sock.connect((dst, port)) + sock.send("sslreceive\n") + sock.recv(80) + except SSL.Error, err: + raise XendError("SSL error: %s" % err) + except socket.error, err: + raise XendError("can't connect: %s" % err) + + p2cread, p2cwrite = os.pipe() + threading.Thread(target=connection.SSLSocketServerConnection.fd2send, + args=(sock, p2cread)).start() + + try: + XendCheckpoint.save(p2cwrite, dominfo, True, live, dst, + node=node) + finally: + sock.shutdown() + sock.close() + + os.close(p2cread) + os.close(p2cwrite) + else: + try: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.connect((dst, port)) - except socket.error, err: - raise XendError("can't connect: %s" % err[1]) - - sock.send("receive\n") - sock.recv(80) - XendCheckpoint.save(sock.fileno(), dominfo, True, live, dst, node=node) - sock.close() + # When connecting to our ssl enabled relocation server using a + # plain socket, send will success but recv will block. Add a + # 30 seconds timeout to raise a socket.timeout exception to + # inform the client. + sock.settimeout(30.0) + sock.connect((dst, port)) + sock.send("receive\n") + sock.recv(80) + sock.settimeout(None) + except socket.error, err: + raise XendError("can't connect: %s" % err) + + try: + XendCheckpoint.save(sock.fileno(), dominfo, True, live, + dst, node=node) + finally: + sock.close() def domain_save(self, domid, dst, checkpoint=False): """Start saving a domain to file. @@ -1365,28 +1398,25 @@ class XendDomain: raise XendInvalidDomain(str(domid)) # if vcpu is keyword 'all', apply the cpumap to all vcpus - vcpus = [ vcpu ] if str(vcpu).lower() == "all": vcpus = range(0, int(dominfo.getVCpuCount())) + else: + vcpus = [ int(vcpu) ] # set the same cpumask for all vcpus rc = 0 - if dominfo._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED): - for v in vcpus: - try: - rc = xc.vcpu_setaffinity(dominfo.getDomid(), int(v), cpumap) - except Exception, ex: - log.exception(ex) - raise XendError("Cannot pin vcpu: %s to cpu: %s - %s" % \ - (v, cpumap, str(ex))) - else: - # FIXME: if we could define cpu affinity definitions to - # each vcpu, reprogram the following processing. - if str(vcpu).lower() != "all": - raise XendError("Must specify 'all' to VCPU " - "for inactive managed domains") - dominfo.setCpus(cpumap) - self.managed_config_save(dominfo) + cpus = dominfo.getCpus() + for v in vcpus: + try: + if dominfo._stateGet() in (DOM_STATE_RUNNING, DOM_STATE_PAUSED): + rc = xc.vcpu_setaffinity(dominfo.getDomid(), v, cpumap) + cpus[v] = cpumap + except Exception, ex: + log.exception(ex) + raise XendError("Cannot pin vcpu: %d to cpu: %s - %s" % \ + (v, cpumap, str(ex))) + dominfo.setCpus(cpus) + self.managed_config_save(dominfo) return rc diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/xend/XendDomainInfo.py Thu May 15 16:23:56 2008 +0900 @@ -1051,8 +1051,8 @@ class XendDomainInfo: ['running', 0], ['cpu_time', 0.0], ['cpu', -1], - ['cpumap', self.info['cpus'] and \ - self.info['cpus'] or range(64)]]) + ['cpumap', self.info['cpus'][i] and \ + self.info['cpus'][i] or range(64)]]) return sxpr @@ -1477,6 +1477,13 @@ class XendDomainInfo: self.info['VCPUs_live'] = vcpus self._writeDom(self._vcpuDomDetails()) else: + if self.info['VCPUs_max'] > vcpus: + # decreasing + del self.info['cpus'][vcpus:] + elif self.info['VCPUs_max'] < vcpus: + # increasing + for c in range(self.info['VCPUs_max'], vcpus): + self.info['cpus'].append(list()) self.info['VCPUs_max'] = vcpus xen.xend.XendDomain.instance().managed_config_save(self) log.info("Set VCPU count on domain %s to %d", self.info['name_label'], @@ -2071,9 +2078,17 @@ class XendDomainInfo: # repin domain vcpus if a restricted cpus list is provided # this is done prior to memory allocation to aide in memory # distribution for NUMA systems. - if self.info['cpus'] is not None and len(self.info['cpus']) > 0: + def has_cpus(): + if self.info['cpus'] is not None: + for c in self.info['cpus']: + if c: + return True + return False + + if has_cpus(): for v in range(0, self.info['VCPUs_max']): - xc.vcpu_setaffinity(self.domid, v, self.info['cpus']) + if self.info['cpus'][v]: + xc.vcpu_setaffinity(self.domid, v, self.info['cpus'][v]) else: def find_relaxed_node(node_list): import sys @@ -2363,8 +2378,19 @@ class XendDomainInfo: def resumeDomain(self): log.debug("XendDomainInfo.resumeDomain(%s)", str(self.domid)) - if self.domid is None: + # resume a suspended domain (e.g. after live checkpoint, or after + # a later error during save or migate); checks that the domain + # is currently suspended first so safe to call from anywhere + + xeninfo = dom_get(self.domid) + if xeninfo is None: return + if not xeninfo['shutdown']: + return + reason = shutdown_reason(xeninfo['shutdown_reason']) + if reason != 'suspend': + return + try: # could also fetch a parsed note from xenstore fast = self.info.get_notes().get('SUSPEND_CANCEL') and 1 or 0 diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/xend/arch.py --- a/tools/python/xen/xend/arch.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/xend/arch.py Thu May 15 16:23:56 2008 +0900 @@ -28,7 +28,5 @@ _types = { "amd64": "x86", "i86pc": "x86", "ia64": "ia64", - "ppc": "powerpc", - "ppc64": "powerpc", } type = _types.get(os.uname()[4], "unknown") diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/xend/image.py Thu May 15 16:23:56 2008 +0900 @@ -294,11 +294,11 @@ class ImageHandler: vnclisten = vnc_config.get('vnclisten', XendOptions.instance().get_vnclisten_address()) - vncdisplay = vnc_config.get('vncdisplay', 0) + vncdisplay = int(vnc_config.get('vncdisplay', 0)) ret.append('-vnc') ret.append("%s:%s%s" % (vnclisten, vncdisplay, vncopts)) - if vnc_config.get('vncunused', 0): + if int(vnc_config.get('vncunused', 1)) != 0: ret.append('-vncunused') elif has_sdl: @@ -506,20 +506,6 @@ class LinuxImageHandler(ImageHandler): return args -class PPC_LinuxImageHandler(LinuxImageHandler): - - ostype = "linux" - - def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb): - """@param shadow_mem_kb The configured shadow memory, in KiB. - @param maxmem_kb The configured maxmem, in KiB. - @return The corresponding required amount of shadow memory, also in - KiB. - PowerPC currently uses "shadow memory" to refer to the hash table.""" - return max(maxmem_kb / 64, shadow_mem_kb) - - - class HVMImageHandler(ImageHandler): ostype = "hvm" @@ -734,6 +720,9 @@ class IA64_HVM_ImageHandler(HVMImageHand (self.getRequiredInitialReservation() / 1024) ]) return args + def setCpuid(self): + # Guest CPUID configuration is not implemented yet. + return class IA64_Linux_ImageHandler(LinuxImageHandler): @@ -783,9 +772,6 @@ class X86_Linux_ImageHandler(LinuxImageH return LinuxImageHandler.buildDomain(self) _handlers = { - "powerpc": { - "linux": PPC_LinuxImageHandler, - }, "ia64": { "linux": IA64_Linux_ImageHandler, "hvm": IA64_HVM_ImageHandler, diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/xend/server/blkif.py --- a/tools/python/xen/xend/server/blkif.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/xend/server/blkif.py Thu May 15 16:23:56 2008 +0900 @@ -47,7 +47,7 @@ class BlkifController(DevController): except ValueError: dev_type = "disk" - if uname is None: + if uname == '': if dev_type == 'cdrom': (typ, params) = ("", "") else: @@ -56,8 +56,13 @@ class BlkifController(DevController): else: try: (typ, params) = string.split(uname, ':', 1) + if typ not in ('phy', 'file', 'tap'): + raise VmError( + 'Block device must have "phy", "file" or "tap" ' + 'specified to type') except ValueError: - (typ, params) = ("", "") + raise VmError( + 'Block device must have physical details specified') mode = config.get('mode', 'r') if mode not in ('r', 'w', 'w!'): @@ -83,6 +88,10 @@ class BlkifController(DevController): front = { 'virtual-device' : "%i" % devid, 'device-type' : dev_type } + + protocol = config.get('protocol') + if protocol: + front['protocol'] = protocol return (devid, back, front) @@ -157,6 +166,10 @@ class BlkifController(DevController): if uuid: config['uuid'] = uuid + proto = self.readFrontend(devid, 'protocol') + if proto: + config['protocol'] = proto + return config def destroyDevice(self, devid, force): diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/xend/server/relocate.py --- a/tools/python/xen/xend/server/relocate.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/xend/server/relocate.py Thu May 15 16:23:56 2008 +0900 @@ -17,10 +17,12 @@ #============================================================================ import re +import os import sys import StringIO +import threading -from xen.web import protocol, tcp, unix +from xen.web import protocol, tcp, unix, connection from xen.xend import sxp from xen.xend import XendDomain @@ -116,6 +118,24 @@ class RelocationProtocol(protocol.Protoc log.error(name + ": no transport") raise XendError(name + ": no transport") + def op_sslreceive(self, name, _): + if self.transport: + self.send_reply(["ready", name]) + p2cread, p2cwrite = os.pipe() + threading.Thread(target=connection.SSLSocketServerConnection.recv2fd, + args=(self.transport.sock, p2cwrite)).start() + try: + XendDomain.instance().domain_restore_fd(p2cread, + relocating=True) + except: + os.close(p2cread) + os.close(p2cwrite) + self.send_error() + self.close() + else: + log.error(name + ": no transport") + raise XendError(name + ": no transport") + def listenRelocation(): xoptions = XendOptions.instance() diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/xm/create.py Thu May 15 16:23:56 2008 +0900 @@ -610,7 +610,7 @@ def configure_disks(config_devs, vals): def configure_disks(config_devs, vals): """Create the config for disks (virtual block devices). """ - for (uname, dev, mode, backend) in vals.disk: + for (uname, dev, mode, backend, protocol) in vals.disk: if uname.startswith('tap:'): cls = 'tap' else: @@ -622,6 +622,8 @@ def configure_disks(config_devs, vals): ['mode', mode ] ] if backend: config_vbd.append(['backend', backend]) + if protocol: + config_vbd.append(['protocol', protocol]) config_devs.append(['device', config_vbd]) def configure_pci(config_devs, vals): @@ -845,7 +847,10 @@ def preprocess_disk(vals): n = len(d) if n == 3: d.append(None) + d.append(None) elif n == 4: + d.append(None) + elif n == 5: pass else: err('Invalid disk specifier: ' + v) diff -r ef290f39ae6b -r c96507e0c83d tools/python/xen/xm/xenapi_create.py --- a/tools/python/xen/xm/xenapi_create.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/python/xen/xm/xenapi_create.py Thu May 15 16:23:56 2008 +0900 @@ -31,6 +31,7 @@ import sys import sys import os import traceback +import re def log(_, msg): #print "> " + msg @@ -509,7 +510,7 @@ class sxp2xml: if len(child) > 0 and child[0] == "device"] vbds_sxp = map(lambda x: x[1], [device for device in devices - if device[1][0] == "vbd"]) + if device[1][0] in ("vbd", "tap")]) vifs_sxp = map(lambda x: x[1], [device for device in devices if device[1][0] == "vif"]) @@ -707,9 +708,11 @@ class sxp2xml: = get_child_by_name(vbd_sxp, "mode") != "w" \ and "RO" or "RW" vbd.attributes["device"] \ - = get_child_by_name(vbd_sxp, "dev") + = re.sub(":cdrom$", "", get_child_by_name(vbd_sxp, "dev")) vbd.attributes["bootable"] = "1" - vbd.attributes["type"] = "disk" + vbd.attributes["type"] \ + = re.search(":cdrom$", get_child_by_name(vbd_sxp, "dev")) \ + and "CD" or "disk" vbd.attributes["qos_algorithm_type"] = "" return vbd diff -r ef290f39ae6b -r c96507e0c83d tools/xm-test/lib/XmTestLib/arch.py --- a/tools/xm-test/lib/XmTestLib/arch.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/xm-test/lib/XmTestLib/arch.py Thu May 15 16:23:56 2008 +0900 @@ -88,39 +88,6 @@ ia_HVMDefaults = {"memory" : } # End : Intel ia32 and ia64 as well as AMD 32-bit and 64-bit processors -# Begin: PowerPC -def ppc_checkBuffer(buffer): - checks = [ - {"pattern" : re.compile("^\d+:mon>\s*$", re.MULTILINE), - "message" : "domain trapped into XMON"}, - ] - - for i in range(0, len(checks)): - check=checks[i] - if check.get('pattern').search(buffer): - FAIL(check.get('message')) - - return - -def ppc_minSafeMem(): - return 64 - -def ppc_getDefaultKernel(): - """Get the path to the default DomU kernel""" - dom0Ver = commands.getoutput("uname -r"); - domUVer = dom0Ver.replace("xen0", "xenU"); - - return "/boot/vmlinux-" + domUVer; - -ppc_ParavirtDefaults = {"memory" : 64, - "vcpus" : 1, - "kernel" : ppc_getDefaultKernel(), - "root" : "/dev/ram0", - "ramdisk" : getRdPath() + "/initrd.img", - "extra" : "xencons=tty128 console=tty128", -} -# End : PowerPC - """Convert from uname specification to a more general platform.""" _uname_to_arch_map = { "i386" : "x86", @@ -129,8 +96,6 @@ _uname_to_arch_map = { "i686" : "x86", "x86_64": "x86_64", "ia64" : "ia64", - "ppc" : "powerpc", - "ppc64" : "powerpc", } # Lookup current platform. @@ -158,10 +123,5 @@ if _arch == "x86" or _arch == "x86_64" o minSafeMem = ia64_minSafeMem configDefaults['memory'] = ia64_minSafeMem() -elif _arch == "powerpc": - minSafeMem = ppc_minSafeMem - getDefaultKernel = ppc_getDefaultKernel - checkBuffer = ppc_checkBuffer - configDefaults = ppc_ParavirtDefaults else: raise ValueError, "Unknown architecture!" diff -r ef290f39ae6b -r c96507e0c83d tools/xm-test/lib/XmTestReport/arch.py --- a/tools/xm-test/lib/XmTestReport/arch.py Thu May 15 14:53:48 2008 +0900 +++ b/tools/xm-test/lib/XmTestReport/arch.py Thu May 15 16:23:56 2008 +0900 @@ -30,8 +30,6 @@ _uname_to_arch_map = { "i686" : "x86", "x86_64": "x86_64", "ia64" : "ia64", - "ppc" : "powerpc", - "ppc64" : "powerpc", } _arch = _uname_to_arch_map.get(os.uname()[4], "Unknown") @@ -44,9 +42,5 @@ elif _arch == "ia64": elif _arch == "ia64": cpuValues = {"arch" : "Unknown", "features" : "Unknown"} -elif _arch == "powerpc": - cpuValues = {"cpu" : "Unknown", - "platform" : "Unknown", - "revision" : "Unknown"} else: raise ValueError, "Unknown architecture!" diff -r ef290f39ae6b -r c96507e0c83d tools/xm-test/ramdisk/Makefile.am --- a/tools/xm-test/ramdisk/Makefile.am Thu May 15 14:53:48 2008 +0900 +++ b/tools/xm-test/ramdisk/Makefile.am Thu May 15 16:23:56 2008 +0900 @@ -14,7 +14,7 @@ INITRD ?= http://xm-test.xensource.com/ramdisks -BR_ARCH ?= $(shell uname -m | sed -e 's/i.86/i386/' -e 's/ppc\(64\)*/powerpc/' -e 's/x86_64/i386/') +BR_ARCH ?= $(shell uname -m | sed -e 's/i.86/i386/' -e 's/x86_64/i386/') @MK@ifdef BR_SNAPSHOT @MK@ BR_URL = http://buildroot.uclibc.org/downloads/snapshots/buildroot-snapshot.tar.bz2 diff -r ef290f39ae6b -r c96507e0c83d tools/xm-test/ramdisk/configs/buildroot-powerpc --- a/tools/xm-test/ramdisk/configs/buildroot-powerpc Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,338 +0,0 @@ -# -# Automatically generated make config: don't edit -# -BR2_HAVE_DOT_CONFIG=y -# BR2_alpha is not set -# BR2_arm is not set -# BR2_armeb is not set -# BR2_cris is not set -# BR2_i386 is not set -# BR2_m68k is not set -# BR2_mips is not set -# BR2_mipsel is not set -# BR2_nios2 is not set -BR2_powerpc=y -# BR2_sh is not set -# BR2_sh64 is not set -# BR2_sparc is not set -# BR2_x86_64 is not set -BR2_ARCH="powerpc" -BR2_ENDIAN="BIG" - -# -# Build options -# -BR2_WGET="wget --passive-ftp" -BR2_SVN="svn co" -BR2_ZCAT="zcat" -BR2_TAR_OPTIONS="" -BR2_DL_DIR="$(BASE_DIR)/dl" -BR2_SOURCEFORGE_MIRROR="easynews" -BR2_STAGING_DIR="$(BUILD_DIR)/staging_dir" -BR2_TOPDIR_PREFIX="" -BR2_TOPDIR_SUFFIX="" -BR2_GNU_BUILD_SUFFIX="pc-linux-gnu" -BR2_GNU_TARGET_SUFFIX="linux-uclibc" -BR2_JLEVEL=1 - -# -# Toolchain Options -# - -# -# Kernel Header Options -# -# BR2_KERNEL_HEADERS_2_4_25 is not set -# BR2_KERNEL_HEADERS_2_4_27 is not set -# BR2_KERNEL_HEADERS_2_4_29 is not set -# BR2_KERNEL_HEADERS_2_4_31 is not set -# BR2_KERNEL_HEADERS_2_6_9 is not set -# BR2_KERNEL_HEADERS_2_6_11 is not set -BR2_KERNEL_HEADERS_2_6_12=y -# BR2_KERNEL_HEADERS_2_6_18 is not set -BR2_DEFAULT_KERNEL_HEADERS="2.6.12" - -# -# uClibc Options -# -# BR2_UCLIBC_VERSION_SNAPSHOT is not set -# BR2_ENABLE_LOCALE is not set -# BR2_PTHREADS_NONE is not set -# BR2_PTHREADS is not set -BR2_PTHREADS_OLD=y -# BR2_PTHREADS_NATIVE is not set - -# -# Binutils Options -# -# BR2_BINUTILS_VERSION_2_14_90_0_8 is not set -# BR2_BINUTILS_VERSION_2_15 is not set -# BR2_BINUTILS_VERSION_2_15_94_0_2_2 is not set -# BR2_BINUTILS_VERSION_2_16_1 is not set -# BR2_BINUTILS_VERSION_2_16_90_0_3 is not set -# BR2_BINUTILS_VERSION_2_16_91_0_5 is not set -# BR2_BINUTILS_VERSION_2_16_91_0_6 is not set -# BR2_BINUTILS_VERSION_2_16_91_0_7 is not set -BR2_BINUTILS_VERSION_2_17=y -# BR2_BINUTILS_VERSION_2_17_50_0_2 is not set -# BR2_BINUTILS_VERSION_2_17_50_0_3 is not set -# BR2_BINUTILS_VERSION_2_17_50_0_4 is not set -# BR2_BINUTILS_VERSION_2_17_50_0_5 is not set -# BR2_BINUTILS_VERSION_2_17_50_0_6 is not set -BR2_BINUTILS_VERSION="2.17" -BR2_EXTRA_BINUTILS_CONFIG_OPTIONS="" - -# -# Gcc Options -# -# BR2_GCC_VERSION_3_3_5 is not set -# BR2_GCC_VERSION_3_3_6 is not set -BR2_GCC_VERSION_3_4_2=y -# BR2_GCC_VERSION_3_4_3 is not set -# BR2_GCC_VERSION_3_4_4 is not set -# BR2_GCC_VERSION_3_4_5 is not set -# BR2_GCC_VERSION_3_4_6 is not set -# BR2_GCC_VERSION_4_0_0 is not set -# BR2_GCC_VERSION_4_0_1 is not set -# BR2_GCC_VERSION_4_0_2 is not set -# BR2_GCC_VERSION_4_0_3 is not set -# BR2_GCC_VERSION_4_1_0 is not set -# BR2_GCC_VERSION_4_1_1 is not set -# BR2_GCC_VERSION_4_2 is not set -# BR2_GCC_IS_SNAP is not set -BR2_GCC_VERSION="3.4.2" -# BR2_GCC_USE_SJLJ_EXCEPTIONS is not set -BR2_EXTRA_GCC_CONFIG_OPTIONS="" -# BR2_INSTALL_LIBSTDCPP is not set -# BR2_INSTALL_OBJC is not set -# BR2_GCC_SHARED_LIBGCC is not set - -# -# Ccache Options -# -BR2_CCACHE=y - -# -# Gdb Options -# -# BR2_PACKAGE_GDB is not set -# BR2_PACKAGE_GDB_SERVER is not set -# BR2_PACKAGE_GDB_HOST is not set - -# -# elf2flt -# -# BR2_ELF2FLT is not set -# BR2_MKLIBS is not set - -# -# Common Toolchain Options -# -# BR2_PACKAGE_SSTRIP_TARGET is not set -# BR2_PACKAGE_SSTRIP_HOST is not set -BR2_ENABLE_MULTILIB=y -BR2_LARGEFILE=y -# BR2_SOFT_FLOAT is not set -BR2_TARGET_OPTIMIZATION="-Os -pipe" -BR2_CROSS_TOOLCHAIN_TARGET_UTILS=y - -# -# Package Selection for the target -# - -# -# The default minimal system -# -BR2_PACKAGE_BUSYBOX=y -# BR2_PACKAGE_BUSYBOX_SNAPSHOT is not set -BR2_PACKAGE_BUSYBOX_INSTALL_SYMLINKS=y -BR2_PACKAGE_BUSYBOX_CONFIG="package/busybox/busybox.config" - -# -# The minimum needed to build a uClibc development system -# -# BR2_PACKAGE_BASH is not set -# BR2_PACKAGE_BZIP2 is not set -# BR2_PACKAGE_COREUTILS is not set -# BR2_PACKAGE_DIFFUTILS is not set -# BR2_PACKAGE_ED is not set -# BR2_PACKAGE_FINDUTILS is not set -# BR2_PACKAGE_FLEX is not set -# BR2_PACKAGE_GAWK is not set -# BR2_PACKAGE_GCC_TARGET is not set -# BR2_PACKAGE_CCACHE_TARGET is not set -# BR2_PACKAGE_GREP is not set -# BR2_PACKAGE_MAKE is not set -# BR2_PACKAGE_PATCH is not set -# BR2_PACKAGE_SED is not set -# BR2_PACKAGE_TAR is not set - -# -# Other stuff -# -# BR2_PACKAGE_ACPID is not set -# BR2_PACKAGE_ASTERISK is not set -# BR2_PACKAGE_AT is not set -# BR2_PACKAGE_AUTOCONF is not set -# BR2_PACKAGE_AUTOMAKE is not set -# BR2_PACKAGE_BERKELEYDB is not set -# BR2_PACKAGE_BIND is not set -# BR2_PACKAGE_BISON is not set -# BR2_PACKAGE_BOA is not set -# BR2_PACKAGE_BRIDGE is not set -# BR2_PACKAGE_CUSTOMIZE is not set -# BR2_PACKAGE_ISC_DHCP is not set -# BR2_PACKAGE_DIALOG is not set -# BR2_PACKAGE_DIRECTFB is not set -# BR2_PACKAGE_DISTCC is not set -# BR2_PACKAGE_DM is not set -# BR2_PACKAGE_DMRAID is not set -# BR2_PACKAGE_DNSMASQ is not set -# BR2_PACKAGE_DROPBEAR is not set -# BR2_PACKAGE_ETHTOOL is not set -# BR2_PACKAGE_EXPAT is not set -# BR2_PACKAGE_E2FSPROGS is not set -# BR2_PACKAGE_FAKEROOT is not set -# BR2_PACKAGE_FILE is not set -# BR2_PACKAGE_FREETYPE is not set -# BR2_PACKAGE_GETTEXT is not set -# BR2_PACKAGE_LIBINTL is not set -# BR2_PACKAGE_GZIP is not set -# BR2_PACKAGE_HASERL is not set -# BR2_PACKAGE_HDPARM is not set -# BR2_PACKAGE_HOSTAP is not set -# BR2_PACKAGE_HOTPLUG is not set -# BR2_PACKAGE_IOSTAT is not set -# BR2_PACKAGE_IPROUTE2 is not set -# BR2_PACKAGE_IPSEC_TOOLS is not set -# BR2_PACKAGE_IPTABLES is not set -# BR2_PACKAGE_JPEG is not set -# BR2_PACKAGE_LESS is not set -# BR2_PACKAGE_LIBCGI is not set -# BR2_PACKAGE_LIBCGICC is not set -# BR2_PACKAGE_LIBELF is not set -# BR2_PACKAGE_LIBFLOAT is not set -# BR2_PACKAGE_LIBGLIB12 is not set -# BR2_PACKAGE_LIBMAD is not set -# BR2_PACKAGE_LIBPCAP is not set -# BR2_PACKAGE_LIBPNG is not set -# BR2_PACKAGE_LIBSYSFS is not set -# BR2_PACKAGE_LIBTOOL is not set -# BR2_PACKAGE_LIBUSB is not set -# BR2_PACKAGE_LIGHTTPD is not set -# BR2_PACKAGE_LINKS is not set -# BR2_PACKAGE_LRZSZ is not set -# BR2_PACKAGE_LSOF is not set -# BR2_PACKAGE_LTP-TESTSUITE is not set -# BR2_PACKAGE_LTT is not set -# BR2_PACKAGE_LVM2 is not set -# BR2_PACKAGE_LZO is not set -# BR2_PACKAGE_LZMA is not set -# BR2_PACKAGE_M4 is not set -# BR2_PACKAGE_MDADM is not set -# BR2_PACKAGE_MEMTESTER is not set -# BR2_PACKAGE_MICROCOM is not set -# BR2_PACKAGE_MICROPERL is not set -# BR2_PACKAGE_MICROWIN is not set -# BR2_PACKAGE_MKDOSFS is not set -# BR2_PACKAGE_MODULE_INIT_TOOLS is not set -# BR2_PACKAGE_MODUTILS is not set -# BR2_PACKAGE_MPG123 is not set -# BR2_PACKAGE_MROUTED is not set -# BR2_PACKAGE_MTD is not set -# BR2_PACKAGE_NANO is not set -# BR2_PACKAGE_NBD is not set -# BR2_PACKAGE_NCURSES is not set -# BR2_PACKAGE_NETKITBASE is not set -# BR2_PACKAGE_NETKITTELNET is not set -# BR2_PACKAGE_NETSNMP is not set -# BR2_PACKAGE_NEWT is not set -# BR2_PACKAGE_NTP is not set -# BR2_PACKAGE_OPENNTPD is not set -# BR2_PACKAGE_OPENSSH is not set -# BR2_PACKAGE_OPENSSL is not set -# BR2_PACKAGE_OPENVPN is not set -# BR2_PACKAGE_PCIUTILS is not set -# BR2_PACKAGE_PKGCONFIG is not set -# BR2_PACKAGE_PORTAGE is not set -# BR2_PACKAGE_PORTMAP is not set -# BR2_PACKAGE_PPPD is not set -# BR2_PACKAGE_PROCPS is not set -# BR2_PACKAGE_PSMISC is not set -# BR2_PACKAGE_PYTHON is not set -# BR2_PACKAGE_QTE is not set -BR2_QTE_TMAKE_VERSION="1.13" -# BR2_PACKAGE_RAIDTOOLS is not set -# BR2_READLINE is not set -# BR2_PACKAGE_RSYNC is not set -# BR2_PACKAGE_RUBY is not set -# BR2_PACKAGE_RXVT is not set -# BR2_PACKAGE_SDL is not set -# BR2_PACKAGE_SFDISK is not set -# BR2_PACKAGE_SLANG is not set -# BR2_PACKAGE_SMARTMONTOOLS is not set -# BR2_PACKAGE_SOCAT is not set -# BR2_PACKAGE_SQLITE is not set -# BR2_PACKAGE_STRACE is not set -# BR2_PACKAGE_SUDO is not set -# BR2_PACKAGE_SYSKLOGD is not set -# BR2_PACKAGE_SYSVINIT is not set -# BR2_PACKAGE_TCL is not set -# BR2_PACKAGE_TCPDUMP is not set -# BR2_PACKAGE_TFTPD is not set -# BR2_PACKAGE_THTTPD is not set -# BR2_PACKAGE_TINYLOGIN is not set -# BR2_PACKAGE_TINYX is not set -# BR2_PACKAGE_TN5250 is not set -# BR2_PACKAGE_TTCP is not set -# BR2_PACKAGE_UDEV is not set -# BR2_PACKAGE_UDHCP is not set -# BR2_PACKAGE_UEMACS is not set -# BR2_PACKAGE_USBUTILS is not set -# BR2_PACKAGE_UTIL-LINUX is not set -# BR2_PACKAGE_VALGRIND is not set -# BR2_PACKAGE_VTUN is not set -# BR2_PACKAGE_WGET is not set -# BR2_PACKAGE_WHICH is not set -# BR2_PACKAGE_WIPE is not set -# BR2_PACKAGE_WIRELESS_TOOLS is not set -# BR2_PACKAGE_XFSPROGS is not set -# BR2_PACKAGE_ZLIB is not set -BR2_PACKAGE_HPING=y - -# -# Target Options -# - -# -# filesystem for target device -# -# BR2_TARGET_ROOTFS_CRAMFS is not set -# BR2_TARGET_ROOTFS_CLOOP is not set -BR2_TARGET_ROOTFS_EXT2=y -BR2_TARGET_ROOTFS_EXT2_BLOCKS=0 -BR2_TARGET_ROOTFS_EXT2_INODES=0 -BR2_TARGET_ROOTFS_EXT2_RESBLKS=0 -BR2_TARGET_ROOTFS_EXT2_SQUASH=y -BR2_TARGET_ROOTFS_EXT2_OUTPUT="$(IMAGE).ext2" -# BR2_TARGET_ROOTFS_EXT2_GZ is not set -BR2_TARGET_ROOTFS_EXT2_COPYTO="" -# BR2_TARGET_ROOTFS_JFFS2 is not set -# BR2_TARGET_ROOTFS_SQUASHFS is not set -# BR2_TARGET_ROOTFS_TAR is not set - -# -# bootloader for target device -# -# BR2_TARGET_YABOOT is not set - -# -# Board Support Options -# - -# -# Generic System Support -# -# BR2_TARGET_GENERIC_ACCESS_POINT is not set -# BR2_TARGET_GENERIC_FIREWALL is not set -# BR2_TARGET_GENERIC_DEV_SYSTEM is not set diff -r ef290f39ae6b -r c96507e0c83d tools/xm-test/ramdisk/make-release.sh --- a/tools/xm-test/ramdisk/make-release.sh Thu May 15 14:53:48 2008 +0900 +++ b/tools/xm-test/ramdisk/make-release.sh Thu May 15 16:23:56 2008 +0900 @@ -3,9 +3,6 @@ if [ "$1" == "" ] if [ "$1" == "" ] then arch="" -elif [ "$1" == "powerpc" ] -then - arch="BR_ARCH=powerpc" else echo "Invalid architecture specified." >&2 exit 1 diff -r ef290f39ae6b -r c96507e0c83d tools/xm-test/runtest.sh --- a/tools/xm-test/runtest.sh Thu May 15 14:53:48 2008 +0900 +++ b/tools/xm-test/runtest.sh Thu May 15 16:23:56 2008 +0900 @@ -77,7 +77,7 @@ runnable_tests() { # using the right version realrd=$(readlink ramdisk/initrd.img) eval $(./lib/XmTestReport/xmtest.py) - ARCH=$(uname -m | sed -e s/i.86/i386/ -e 's/ppc\(64\)*/powerpc/') + ARCH=$(uname -m | sed -e s/i.86/i386/) rrdver="initrd-${XM_TEST_MAJ}.${XM_TEST_MIN}-${ARCH}.img" exp_flag=0 realarch=`echo $realrd | awk -F- '{print $3}' | awk -F. '{print $1}'` diff -r ef290f39ae6b -r c96507e0c83d unmodified_drivers/linux-2.6/overrides.mk --- a/unmodified_drivers/linux-2.6/overrides.mk Thu May 15 14:53:48 2008 +0900 +++ b/unmodified_drivers/linux-2.6/overrides.mk Thu May 15 16:23:56 2008 +0900 @@ -4,12 +4,14 @@ # # (i.e. we need the native config for things like -mregparm, but # a Xen kernel to find the right headers) -EXTRA_CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030205 -EXTRA_CFLAGS += -DCONFIG_XEN_COMPAT=0xffffff -EXTRA_CFLAGS += -I$(M)/include -I$(M)/compat-include -DHAVE_XEN_PLATFORM_COMPAT_H +_XEN_CPPFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030205 +_XEN_CPPFLAGS += -DCONFIG_XEN_COMPAT=0xffffff +_XEN_CPPFLAGS += -I$(M)/include -I$(M)/compat-include -DHAVE_XEN_PLATFORM_COMPAT_H ifeq ($(ARCH),ia64) - EXTRA_CFLAGS += -DCONFIG_VMX_GUEST + _XEN_CPPFLAGS += -DCONFIG_VMX_GUEST endif -EXTRA_CFLAGS += -include $(objtree)/include/linux/autoconf.h -EXTRA_AFLAGS += -I$(M)/include -I$(M)/compat-include -DHAVE_XEN_PLATFORM_COMPAT_H +_XEN_CPPFLAGS += -include $(objtree)/include/linux/autoconf.h + +EXTRA_CFLAGS += $(_XEN_CPPFLAGS) +EXTRA_AFLAGS += $(_XEN_CPPFLAGS) diff -r ef290f39ae6b -r c96507e0c83d xen/Rules.mk --- a/xen/Rules.mk Thu May 15 14:53:48 2008 +0900 +++ b/xen/Rules.mk Thu May 15 16:23:56 2008 +0900 @@ -30,8 +30,7 @@ endif # Set ARCH/SUBARCH appropriately. override TARGET_SUBARCH := $(XEN_TARGET_ARCH) override TARGET_ARCH := $(shell echo $(XEN_TARGET_ARCH) | \ - sed -e 's/x86.*/x86/' \ - -e 's/powerpc.*/powerpc/') + sed -e 's/x86.*/x86/') TARGET := $(BASEDIR)/xen diff -r ef290f39ae6b -r c96507e0c83d xen/arch/ia64/xen/dom0_ops.c --- a/xen/arch/ia64/xen/dom0_ops.c Thu May 15 14:53:48 2008 +0900 +++ b/xen/arch/ia64/xen/dom0_ops.c Thu May 15 16:23:56 2008 +0900 @@ -407,10 +407,15 @@ long arch_do_sysctl(xen_sysctl_t *op, XE { int i; uint32_t max_array_ent; + XEN_GUEST_HANDLE_64(uint32) cpu_to_node_arr; xen_sysctl_physinfo_t *pi = &op->u.physinfo; + max_array_ent = pi->max_cpu_id; + cpu_to_node_arr = pi->cpu_to_node; + memset(pi, 0, sizeof(*pi)); + pi->cpu_to_node = cpu_to_node_arr; pi->threads_per_core = cpus_weight(cpu_sibling_map[0]); pi->cores_per_socket = cpus_weight(cpu_core_map[0]) / pi->threads_per_core; @@ -421,16 +426,15 @@ long arch_do_sysctl(xen_sysctl_t *op, XE pi->scrub_pages = avail_scrub_pages(); pi->cpu_khz = local_cpu_data->proc_freq / 1000; - max_array_ent = pi->max_cpu_id; pi->max_cpu_id = last_cpu(cpu_online_map); max_array_ent = min_t(uint32_t, max_array_ent, pi->max_cpu_id); ret = 0; - if (!guest_handle_is_null(pi->cpu_to_node)) { + if (!guest_handle_is_null(cpu_to_node_arr)) { for (i = 0; i <= max_array_ent; i++) { uint32_t node = cpu_online(i) ? cpu_to_node(i) : ~0u; - if (copy_to_guest_offset(pi->cpu_to_node, i, &node, 1)) { + if (copy_to_guest_offset(cpu_to_node_arr, i, &node, 1)) { ret = -EFAULT; break; } diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/0opt.c --- a/xen/arch/powerpc/0opt.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (C) IBM Corp. 2005 - * - * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> - */ - -#include <xen/config.h> -#include <xen/lib.h> - -extern void __xchg_called_with_bad_pointer(void); -void __xchg_called_with_bad_pointer(void) -{ - BUG(); -} - -extern void __cmpxchg_called_with_bad_pointer(void); -void __cmpxchg_called_with_bad_pointer(void) -{ - BUG(); -} diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/Makefile --- a/xen/arch/powerpc/Makefile Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,152 +0,0 @@ -ifneq ($(DOM0_IMAGE),) -builtin_dom0 := y -endif - -subdir-$(HAS_PPC64) += powerpc64 -subdir-y += papr - -obj-y += audit.o -obj-y += backtrace.o -obj-y += bitops.o -obj-y += boot_of.o -obj-y += cmdline.o -obj-y += dart.o -obj-y += dart_u3.o -obj-y += dart_u4.o -obj-y += domctl.o -obj-y += domain_build.o -obj-y += domain.o -obj-y += exceptions.o -obj-y += external.o -obj-y += float.o -obj-y += hcalls.o -obj-y += iommu.o -obj-y += irq.o -obj-y += systemsim.o -obj-y += memory.o -obj-y += mm.o -obj-y += mpic.o -obj-y += mpic_init.o -obj-y += multiboot2.o -obj-y += numa.o -obj-y += of-devtree.o -obj-y += of-devwalk.o -obj-y += ofd_fixup.o -obj-y += ofd_fixup_memory.o -obj-y += physdev.o -obj-y += platform.o -obj-y += rtas.o -obj-y += rtas_nvram.o -obj-y += rtas_flash.o -obj-y += setup.o -obj-y += shadow.o -obj-y += smp.o -obj-y += smpboot.o -obj-y += smp-tbsync.o -obj-y += sysctl.o -obj-y += time.o -obj-y += usercopy.o -obj-y += machine_kexec.o -obj-y += crash.o - -obj-$(debug) += 0opt.o -obj-$(crash_debug) += gdbstub.o -obj-$(builtin_dom0) += dom0.o - -obj-y += firmware_image.o - -# These are extra warnings like for the arch/ppc directory but may not -# allow the rest of the tree to build. -PPC_C_WARNINGS += -Wundef -Wmissing-prototypes -Wmissing-declarations -PPC_C_WARNINGS += -Wshadow -CFLAGS += $(PPC_C_WARNINGS) - -# -# The following flags are fed to gcc in order to link several -# objects into a single ELF segment and to not link in any additional -# objects that gcc would normally like to -# -OMAGIC = -nodefaultlibs -nostartfiles -Wl,--omagic - -firmware: of_handler/built_in.o $(TARGET_SUBARCH)/memcpy.o of-devtree.o - $(CC) $(CFLAGS) $(OMAGIC) -e __ofh_start -Wl,-Ttext,0x0 $^ -o $@ - -# -# Link firmware again but this time at the place we expect to load it. -# This makes debugging _way_ easier. -# -firmware.dbg: of_handler/built_in.o $(TARGET_SUBARCH)/memcpy.o of-devtree.o - $(CC) $(CFLAGS) $(OMAGIC) -e __ofh_start -Wl,-Ttext,0x2000000 $^ -o $@ - -firmware_image.bin: firmware firmware.dbg - $(CROSS_COMPILE)objcopy --output-target=binary $< $@ - -# -# Hacks for included C files -# -irq.o: ../x86/irq.c -physdev.o: ../x86/physdev.c -numa.o: ../x86/numa.c - -ifneq ($(CMDLINE),) -# The first token in the arguments will be silently dropped. -FULL_CMDLINE := xen $(CMDLINE) -endif - -ifeq ($(wildcard cmdline.dep),) -cmdline.dep: - echo $(FULL_CMDLINE) > cmdline.dep -else -ifneq ($(FULL_CMDLINE),$(shell cat cmdline.dep)) -cmdline.dep:: - echo $(FULL_CMDLINE) > cmdline.dep -else -cmdline.dep: -endif -endif - -cmdline.o: cmdline.dep -cmdline.o: CFLAGS += -DCMDLINE="\"$(FULL_CMDLINE)\"" - -TARGET_OPTS = $(OMAGIC) -Wl,-T,xen.lds -TARGET_OPTS += start.o $(ALL_OBJS) - -.xen-syms: start.o $(ALL_OBJS) xen.lds - $(MAKE) -f $(BASEDIR)/Rules.mk $(BASEDIR)/common/symbols-dummy.o - $(CC) $(CFLAGS) $(TARGET_OPTS) $(BASEDIR)/common/symbols-dummy.o -o $@ - -NM=$(CROSS_COMPILE)nm -new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi) - -ifeq ($(new_nm),y) -NM := $(NM) --synthetic -endif - -xen-syms.S: .xen-syms - $(NM) -n $^ | $(BASEDIR)/tools/symbols > $@ - -xen-syms.o: xen-syms.S - $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $@ - -$(TARGET)-syms: start.o $(ALL_OBJS) xen-syms.o xen.lds - $(CC) $(CFLAGS) $(TARGET_OPTS) xen-syms.o -o $@ - -# our firmware only loads 32-bit ELF files -OCPYFLAGS := --input-target=elf64-powerpc --output-target=elf32-powerpc -$(TARGET): $(TARGET)-syms - $(CROSS_COMPILE)objcopy $(OCPYFLAGS) $^ $@ - -asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c $(HDRS) - $(CC) $(CFLAGS) -S -o $@ $< - -xen.lds: xen.lds.S $(HDRS) - $(CC) -P -E $(AFLAGS) -o $@ $< - -dom0.bin: $(DOM0_IMAGE) - cp $< $@ - -clean:: - $(MAKE) -f $(BASEDIR)/Rules.mk -C of_handler clean - rm -f firmware firmware.dbg firmware_image.bin \ - dom0.bin .xen-syms xen-syms.S \ - xen.lds asm-offsets.s cmdline.dep diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/Rules.mk --- a/xen/arch/powerpc/Rules.mk Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -HAS_PPC64 := y - -CC := $(CROSS_COMPILE)gcc -LD := $(CROSS_COMPILE)ld - -# These are goodess that applies to all source. -C_WARNINGS := -Wredundant-decls - -# _no_ common code can have packed data structures or we are in touble. -C_WARNINGS += -Wpacked - -CFLAGS += -m64 -ffreestanding -fno-builtin -fno-common -CFLAGS += -iwithprefix include -Werror -pipe -CFLAGS += -I$(BASEDIR)/include -CFLAGS += -I$(BASEDIR)/include/asm-powerpc/mach-default -CFLAGS += $(C_WARNINGS) -CFLAGS += -msoft-float -O2 -CFLAGS-$(debug) += -O0 # last one wins -CFLAGS-$(papr_vterm) += -DPAPR_VDEVICE -DPAPR_VTERM - -LDFLAGS += -m elf64ppc - -# -# command to embed a binary inside a .o -# -%.o: %.bin - $(CROSS_COMPILE)objcopy --input-target=binary \ - --output-target=elf64-powerpc \ - --binary-architecture=powerpc \ - --redefine-sym _binary_$*_bin_start=$*_start \ - --redefine-sym _binary_$*_bin_end=$*_end \ - --redefine-sym _binary_$*_bin_size=$*_size \ - $< $@ - -HDRS += $(wildcard $(BASEDIR)/include/asm-powerpc/mach-*/*.h) - -# Test for at least GCC v3.2.x. -gcc-ver = $(shell $(CC) -dumpversion | sed -e 's/^\(.\)\.\(.\)\.\(.\)/\$(1)/') -ifeq ($(call gcc-ver,1),1) -$(error gcc-1.x.x unsupported - upgrade to at least gcc-3.2.x) -endif -ifeq ($(call gcc-ver,1),2) -$(error gcc-2.x.x unsupported - upgrade to at least gcc-3.2.x) -endif -ifeq ($(call gcc-ver,1),3) -ifeq ($(call gcc-ver,2),0) -$(error gcc-3.0.x unsupported - upgrade to at least gcc-3.2.x) -endif -ifeq ($(call gcc-ver,2),1) -$(error gcc-3.1.x unsupported - upgrade to at least gcc-3.2.x) -endif -endif diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/audit.c --- a/xen/arch/powerpc/audit.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (C) IBM Corp. 2005 - * - * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx> - */ - -#ifndef NDEBUG -#include <xen/lib.h> -#include <xen/sched.h> - -extern void audit_domain(struct domain *d); -extern void audit_domains(void); -extern void audit_domains_key(unsigned char key); - -void audit_domain(struct domain *d) -{ - panic("%s unimplemented\n", __func__); -} - -void audit_domains(void) -{ - struct domain *d; - rcu_read_lock(&domlist_read_lock); - for_each_domain ( d ) - audit_domain(d); - rcu_read_unlock(&domlist_read_lock); -} - -void audit_domains_key(unsigned char key) -{ - audit_domains(); -} -#endif diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/backtrace.c --- a/xen/arch/powerpc/backtrace.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,217 +0,0 @@ -/* - * Routines providing a simple monitor for use on the PowerMac. - * - * Copyright (C) 1996-2005 Paul Mackerras. - * - * 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. - */ - -#include <xen/config.h> -#include <xen/lib.h> -#include <xen/console.h> -#include <xen/sched.h> -#include <xen/symbols.h> -#include <asm/debugger.h> - -static char namebuf[KSYM_NAME_LEN+1]; - -/* Shamelessly lifted from Linux Xmon try to keep pristene */ -#ifdef __powerpc64__ -#define LRSAVE_OFFSET 0x10 -#define REG_FRAME_MARKER 0x7265677368657265ul /* "regshere" */ -#define MARKER_OFFSET 0x60 -#define REGS_OFFSET 0x70 -#define REG "%016lX" -#else -#define LRSAVE_OFFSET 4 -#define REG_FRAME_MARKER 0x72656773 -#define MARKER_OFFSET 8 -#define REGS_OFFSET 16 -#define REG "%08lX" -#endif - -#define TRAP(regs) ((regs)->entry_vector & ~0xF) -static int xmon_depth_to_print = 64; - -/* Very cheap human name for vector lookup. */ -static -const char *getvecname(unsigned long vec) -{ - char *ret; - - switch (vec) { - case 0x100: ret = "(System Reset)"; break; - case 0x200: ret = "(Machine Check)"; break; - case 0x300: ret = "(Data Access)"; break; - case 0x380: ret = "(Data SLB Access)"; break; - case 0x400: ret = "(Instruction Access)"; break; - case 0x480: ret = "(Instruction SLB Access)"; break; - case 0x500: ret = "(Hardware Interrupt)"; break; - case 0x600: ret = "(Alignment)"; break; - case 0x700: ret = "(Program Check)"; break; - case 0x800: ret = "(FPU Unavailable)"; break; - case 0x900: ret = "(Decrementer)"; break; - case 0xc00: ret = "(System Call)"; break; - case 0xd00: ret = "(Single Step)"; break; - case 0xf00: ret = "(Performance Monitor)"; break; - case 0xf20: ret = "(Altivec Unavailable)"; break; - case 0x1300: ret = "(Instruction Breakpoint)"; break; - default: ret = ""; - } - return ret; -} - -static int mread(unsigned long adrs, void *buf, int size) -{ - memcpy(buf, (void *)adrs, size); - return size; -} - -static void get_function_bounds(unsigned long pc, unsigned long *startp, - unsigned long *endp) -{ - unsigned long size, offset; - const char *name; - - *startp = *endp = 0; - if (pc == 0) - return; - - name = symbols_lookup(pc, &size, &offset, namebuf); - if (name != NULL) { - *startp = pc - offset; - *endp = pc - offset + size; - } -} - -/* Print an address in numeric and symbolic form (if possible) */ -static void xmon_print_symbol(unsigned long address, const char *mid, - const char *after) -{ - const char *name = NULL; - unsigned long offset, size; - - printk(REG, address); - - name = symbols_lookup(address, &size, &offset, namebuf); - if (name) { - printk("%s%s+%#lx/%#lx", mid, name, offset, size); - } - printk("%s", after); -} - -static void backtrace( - unsigned long sp, unsigned long lr, unsigned long pc) -{ - unsigned long ip; - unsigned long newsp; - unsigned long marker; - int count = 0; - struct cpu_user_regs regs; - - do { - if (sp > xenheap_phys_end) { - if (sp != 0) - printk("SP (%lx) is not in xen space\n", sp); - break; - } - - if (!mread(sp + LRSAVE_OFFSET, &ip, sizeof(unsigned long)) - || !mread(sp, &newsp, sizeof(unsigned long))) { - printk("Couldn't read stack frame at %lx\n", sp); - break; - } - - /* - * For the first stack frame, try to work out if - * LR and/or the saved LR value in the bottommost - * stack frame are valid. - */ - if ((pc | lr) != 0) { - unsigned long fnstart, fnend; - unsigned long nextip; - int printip = 1; - - get_function_bounds(pc, &fnstart, &fnend); - nextip = 0; - if (newsp > sp) - mread(newsp + LRSAVE_OFFSET, &nextip, - sizeof(unsigned long)); - if (lr == ip) { - if (lr >= xenheap_phys_end - || (fnstart <= lr && lr < fnend)) - printip = 0; - } else if (lr == nextip) { - printip = 0; - } else if (lr < xenheap_phys_end - && !(fnstart <= lr && lr < fnend)) { - printk("[link register ] "); - xmon_print_symbol(lr, " ", "\n"); - } - if (printip) { - printk("["REG"] ", sp); - xmon_print_symbol(ip, " ", " (unreliable)\n"); - } - pc = lr = 0; - - } else { - printk("["REG"] ", sp); - xmon_print_symbol(ip, " ", "\n"); - } - - /* Look for "regshere" marker to see if this is - an exception frame. */ - if (mread(sp + MARKER_OFFSET, &marker, sizeof(unsigned long)) - && marker == REG_FRAME_MARKER) { - if (mread(sp + REGS_OFFSET, ®s, sizeof(regs)) - != sizeof(regs)) { - printk("Couldn't read registers at %lx\n", - sp + REGS_OFFSET); - break; - } - printk("--- Exception: %x %s at ", regs.entry_vector, - getvecname(TRAP(®s))); - pc = regs.pc; - lr = regs.lr; - xmon_print_symbol(pc, " ", "\n"); - } - - if (newsp == 0) - break; - - sp = newsp; - } while (count++ < xmon_depth_to_print); -} - -void show_backtrace(ulong sp, ulong lr, ulong pc) -{ - console_start_sync(); - backtrace(sp, lr, pc); - console_end_sync(); -} - -void show_backtrace_regs(struct cpu_user_regs *regs) -{ - console_start_sync(); - - show_registers(regs); - printk("hid4 0x%016lx\n", regs->hid4); - printk("---[ backtrace ]---\n"); - show_backtrace(regs->gprs[1], regs->lr, regs->pc); - - console_end_sync(); -} - -void dump_execution_state(void) -{ - struct cpu_user_regs *regs = guest_cpu_user_regs(); - - show_registers(regs); - if (regs->msr & MSR_HV) { - printk("In Xen:\n"); - show_backtrace(regs->gprs[1], regs->pc, regs->lr); - } -} diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/bitops.c --- a/xen/arch/powerpc/bitops.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,94 +0,0 @@ -/* from linux/arch/powerpc/lib/bitops.c */ - -#include <asm/types.h> -#include <asm/bitops.h> - -#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG) - -/** - * find_next_bit - find the next set bit in a memory region - * @addr: The address to base the search on - * @offset: The bitnumber to start searching at - * @size: The maximum size to search - */ -unsigned long find_next_bit(const unsigned long *addr, unsigned long size, - unsigned long offset) -{ - const unsigned long *p = addr + BITOP_WORD(offset); - unsigned long result = offset & ~(BITS_PER_LONG-1); - unsigned long tmp; - - if (offset >= size) - return size; - size -= result; - offset %= BITS_PER_LONG; - if (offset) { - tmp = *(p++); - tmp &= (~0UL << offset); - if (size < BITS_PER_LONG) - goto found_first; - if (tmp) - goto found_middle; - size -= BITS_PER_LONG; - result += BITS_PER_LONG; - } - while (size & ~(BITS_PER_LONG-1)) { - if ((tmp = *(p++))) - goto found_middle; - result += BITS_PER_LONG; - size -= BITS_PER_LONG; - } - if (!size) - return result; - tmp = *p; - -found_first: - tmp &= (~0UL >> (BITS_PER_LONG - size)); - if (tmp == 0UL) /* Are any bits set? */ - return result + size; /* Nope. */ -found_middle: - return result + __ffs(tmp); -} - -/* - * This implementation of find_{first,next}_zero_bit was stolen from - * Linus' asm-alpha/bitops.h. - */ -unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, - unsigned long offset) -{ - const unsigned long *p = addr + BITOP_WORD(offset); - unsigned long result = offset & ~(BITS_PER_LONG-1); - unsigned long tmp; - - if (offset >= size) - return size; - size -= result; - offset %= BITS_PER_LONG; - if (offset) { - tmp = *(p++); - tmp |= ~0UL >> (BITS_PER_LONG - offset); - if (size < BITS_PER_LONG) - goto found_first; - if (~tmp) - goto found_middle; - size -= BITS_PER_LONG; - result += BITS_PER_LONG; - } - while (size & ~(BITS_PER_LONG-1)) { - if (~(tmp = *(p++))) - goto found_middle; - result += BITS_PER_LONG; - size -= BITS_PER_LONG; - } - if (!size) - return result; - tmp = *p; - -found_first: - tmp |= ~0UL << size; - if (tmp == ~0UL) /* Are any bits zero? */ - return result + size; /* Nope. */ -found_middle: - return result + ffz(tmp); -} diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/boot_of.c --- a/xen/arch/powerpc/boot_of.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1257 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright IBM Corp. 2005, 2006, 2007 - * - * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> - * Hollis Blanchard <hollisb@xxxxxxxxxx> - */ - -#include <xen/config.h> -#include <xen/init.h> -#include <xen/lib.h> -#include <xen/version.h> -#include <xen/spinlock.h> -#include <xen/serial.h> -#include <xen/time.h> -#include <xen/sched.h> -#include <asm/page.h> -#include <asm/io.h> -#include <asm/boot.h> -#include "exceptions.h" -#include "of-devtree.h" -#include "oftree.h" -#include "rtas.h" - -/* Secondary processors use this for handshaking with main processor. */ -volatile unsigned int __spin_ack; - -static ulong of_vec; -static ulong of_msr; -static int of_out; -static ulong eomem; - -/* Track memory during early boot with a limited per-page bitmap. We need an - * allocator to tell us where we can place RTAS, our copy of the device tree. - * We could examine the "available" properties in memory nodes, but we - * apparently can't depend on firmware to update those when we call "claim". So - * we need to track it ourselves. - * We can't dynamically allocate the bitmap, because we would need something - * to tell us where it's safe to allocate... - */ -#define MEM_AVAILABLE_PAGES ((32 << 20) >> PAGE_SHIFT) -static DECLARE_BITMAP(mem_available_pages, MEM_AVAILABLE_PAGES); - -extern struct ns16550_defaults ns16550; - -#undef OF_DEBUG -#undef OF_DEBUG_LOW - -#ifdef OF_DEBUG -#define DBG(args...) of_printf(args) -#else -#define DBG(args...) -#endif - -#ifdef OF_DEBUG_LOW -#define DBG_LOW(args...) of_printf(args) -#else -#define DBG_LOW(args...) -#endif - -#define of_panic(MSG...) \ - do { of_printf(MSG); of_printf("\nHANG\n"); for (;;); } while (0) - -struct of_service { - u32 ofs_service; - u32 ofs_nargs; - u32 ofs_nrets; - u32 ofs_args[10]; -}; - -static int bof_chosen; - -static struct of_service s; - -static int __init of_call( - const char *service, u32 nargs, u32 nrets, s32 rets[], ...) -{ - int rc; - - if (of_vec != 0) { - va_list args; - int i; - memset(&s, 0, sizeof (s)); - s.ofs_service = (ulong)service; - s.ofs_nargs = nargs; - s.ofs_nrets = nrets; - s.ofs_nargs = nargs; - - /* copy all the params into the args array */ - va_start(args, rets); - - for (i = 0; i < nargs; i++) { - s.ofs_args[i] = va_arg(args, u32); - } - - va_end(args); - - rc = prom_call(&s, 0, of_vec, of_msr); - - /* yes always to the copy, just in case */ - for (i = 0; i < nrets; i++) { - rets[i] = s.ofs_args[i + nargs]; - } - } else { - rc = OF_FAILURE; - } - return rc; -} - -/* popular OF methods */ -static int __init _of_write(int ih, const char *addr, u32 len) -{ - int rets[1] = { OF_FAILURE }; - if (of_call("write", 3, 1, rets, ih, addr, len) == OF_FAILURE) { - return OF_FAILURE; - } - return rets[0]; -} - -/* popular OF methods */ -static int __init of_write(int ih, const char *addr, u32 len) -{ - int rc; - int i = 0; - int sum = 0; - - while (i < len) { - if (addr[i] == '\n') { - if (i > 0) { - rc = _of_write(ih, addr, i); - if (rc == OF_FAILURE) - return rc; - sum += rc; - } - rc = _of_write(ih, "\r\n", 2); - if (rc == OF_FAILURE) - return rc; - sum += rc; - i++; - addr += i; - len -= i; - i = 0; - continue; - } - i++; - } - if (len > 0) { - rc = _of_write(ih, addr, len); - if (rc == OF_FAILURE) - return rc; - sum += rc; - } - - return sum; -} - -static int of_printf(const char *fmt, ...) - __attribute__ ((format (printf, 1, 2))); -static int __init of_printf(const char *fmt, ...) -{ - static char buf[1024]; - va_list args; - int sz; - - if (of_out == 0) { - return OF_FAILURE; - } - - va_start(args, fmt); - - sz = vsnprintf(buf, sizeof (buf), fmt, args); - if (sz <= sizeof (buf)) { - of_write(of_out, buf, sz); - } else { - static const char trunc[] = "\n(TRUNCATED)\n"; - - sz = sizeof (buf); - of_write(of_out, buf, sz); - of_write(of_out, trunc, sizeof (trunc)); - } - return sz; -} - -static int __init of_finddevice(const char *devspec) -{ - int rets[1] = { OF_FAILURE }; - - of_call("finddevice", 1, 1, rets, devspec); - if (rets[0] == OF_FAILURE) { - DBG("finddevice %s -> FAILURE %d\n",devspec,rets[0]); - return OF_FAILURE; - } - DBG_LOW("finddevice %s -> %d\n",devspec, rets[0]); - return rets[0]; -} - -static int __init of_getprop(int ph, const char *name, void *buf, u32 buflen) -{ - int rets[1] = { OF_FAILURE }; - - of_call("getprop", 4, 1, rets, ph, name, buf, buflen); - - if (rets[0] == OF_FAILURE) { - DBG_LOW("getprop 0x%x %s -> FAILURE\n", ph, name); - return OF_FAILURE; - } - - DBG_LOW("getprop 0x%x %s -> 0x%x (%s)\n", ph, name, rets[0], (char *)buf); - return rets[0]; -} - -static int __init of_setprop( - int ph, const char *name, const void *buf, u32 buflen) -{ - int rets[1] = { OF_FAILURE }; - - of_call("setprop", 4, 1, rets, ph, name, buf, buflen); - - if (rets[0] == OF_FAILURE) { - DBG("setprop 0x%x %s -> FAILURE\n", ph, name); - return OF_FAILURE; - } - - DBG_LOW("setprop 0x%x %s -> %s\n", ph, name, (char *)buf); - return rets[0]; -} - -/* - * returns 0 if there are no children (of spec) - */ -static int __init of_getchild(int ph) -{ - int rets[1] = { OF_FAILURE }; - - of_call("child", 1, 1, rets, ph); - DBG_LOW("getchild 0x%x -> 0x%x\n", ph, rets[0]); - - return rets[0]; -} - -/* - * returns 0 is there are no peers - */ -static int __init of_getpeer(int ph) -{ - int rets[1] = { OF_FAILURE }; - - of_call("peer", 1, 1, rets, ph); - DBG_LOW("getpeer 0x%x -> 0x%x\n", ph, rets[0]); - - return rets[0]; -} - -static int __init of_getproplen(int ph, const char *name) -{ - int rets[1] = { OF_FAILURE }; - - of_call("getproplen", 2, 1, rets, ph, name); - if (rets[0] == OF_FAILURE) { - DBG("getproplen 0x%x %s -> FAILURE\n", ph, name); - return OF_FAILURE; - } - DBG_LOW("getproplen 0x%x %s -> 0x%x\n", ph, name, rets[0]); - return rets[0]; -} - -static int __init of_package_to_path(int ph, char *buffer, u32 buflen) -{ - int rets[1] = { OF_FAILURE }; - - of_call("package-to-path", 3, 1, rets, ph, buffer, buflen); - if (rets[0] == OF_FAILURE) { - DBG("%s 0x%x -> FAILURE\n", __func__, ph); - return OF_FAILURE; - } - DBG_LOW("%s 0x%x %s -> 0x%x\n", __func__, ph, buffer, rets[0]); - if (rets[0] <= buflen) - buffer[rets[0]] = '\0'; - return rets[0]; -} - -static int __init of_nextprop(int ph, const char *name, void *buf) -{ - int rets[1] = { OF_FAILURE }; - - of_call("nextprop", 3, 1, rets, ph, name, buf); - - if (rets[0] == OF_FAILURE) { - DBG("nextprop 0x%x %s -> FAILURE\n", ph, name); - return OF_FAILURE; - } - - DBG_LOW("nextprop 0x%x %s -> %s\n", ph, name, (char *)buf); - return rets[0]; -} - -static int __init of_instance_to_path(int ih, char *buffer, u32 buflen) -{ - int rets[1] = { OF_FAILURE }; - - if (of_call("instance-to-path", 3, 1, rets, ih, buffer, buflen) - == OF_FAILURE) - return OF_FAILURE; - - if (rets[0] <= buflen) - buffer[rets[0]] = '\0'; - return rets[0]; -} - -static int __init of_start_cpu(int cpu, u32 pc, u32 reg) -{ - int ret; - - ret = of_call("start-cpu", 3, 0, NULL, cpu, pc, reg); - - return ret; -} - -static void __init of_test(const char *of_method_name) -{ - int rets[1] = { OF_FAILURE }; - - of_call("test", 1, 1, rets, of_method_name); - if (rets[0] == OF_FAILURE ) { - of_printf("Warning: possibly no OF method %s.\n" - "(Ignore this warning on PIBS.)\n", of_method_name); - } -} - -static int __init of_claim(u32 virt, u32 size, u32 align) -{ - int rets[1] = { OF_FAILURE }; - - of_call("claim", 3, 1, rets, virt, size, align); - if (rets[0] == OF_FAILURE) { - DBG("%s 0x%08x 0x%08x 0x%08x -> FAIL\n", __func__, virt, size, align); - return OF_FAILURE; - } - - DBG_LOW("%s 0x%08x 0x%08x 0x%08x -> 0x%08x\n", __func__, virt, size, align, - rets[0]); - return rets[0]; -} - -static int __init of_instance_to_package(int ih) -{ - int rets[1] = { OF_FAILURE }; - - of_call("instance-to-package", 1, 1, rets, ih); - if (rets[0] == OF_FAILURE) - return OF_FAILURE; - - return rets[0]; -} - -static int __init of_getparent(int ph) -{ - int rets[1] = { OF_FAILURE }; - - of_call("parent", 1, 1, rets, ph); - - DBG_LOW("getparent 0x%x -> 0x%x\n", ph, rets[0]); - return rets[0]; -} - -static int __init of_open(const char *devspec) -{ - int rets[1] = { OF_FAILURE }; - - of_call("open", 1, 1, rets, devspec); - return rets[0]; -} - -static void boot_of_alloc_init(int m, uint addr_cells, uint size_cells) -{ - int rc; - uint pg; - uint a[64]; - int tst; - u64 start; - u64 size; - - rc = of_getprop(m, "available", a, sizeof (a)); - if (rc > 0) { - int l = rc / sizeof(a[0]); - int r = 0; - -#ifdef OF_DEBUG - { - int i; - of_printf("avail:\n"); - for (i = 0; i < l; i += 4) - of_printf(" 0x%x%x, 0x%x%x\n", - a[i], a[i + 1], - a[i + 2] ,a[i + 3]); - } -#endif - - pg = 0; - while (pg < MEM_AVAILABLE_PAGES && r < l) { - ulong end; - - start = a[r++]; - if (addr_cells == 2 && (r < l) ) - start = (start << 32) | a[r++]; - - size = a[r++]; - if (size_cells == 2 && (r < l) ) - size = (size << 32) | a[r++]; - - end = ALIGN_DOWN(start + size, PAGE_SIZE); - - start = ALIGN_UP(start, PAGE_SIZE); - - DBG("%s: marking 0x%x - 0x%lx\n", __func__, - pg << PAGE_SHIFT, start); - - start >>= PAGE_SHIFT; - while (pg < MEM_AVAILABLE_PAGES && pg < start) { - set_bit(pg, mem_available_pages); - pg++; - } - - pg = end >> PAGE_SHIFT; - } - } - - /* Now make sure we mark our own memory */ - pg = (ulong)_start >> PAGE_SHIFT; - start = (ulong)_end >> PAGE_SHIFT; - - DBG("%s: marking 0x%x - 0x%lx\n", __func__, - pg << PAGE_SHIFT, start << PAGE_SHIFT); - - /* Lets try and detect if our image has stepped on something. It - * is possible that FW has already subtracted our image from - * available memory so we must make sure that the previous bits - * are the same for the whole image */ - tst = test_and_set_bit(pg, mem_available_pages); - ++pg; - while (pg <= start) { - if (test_and_set_bit(pg, mem_available_pages) != tst) - of_panic("%s: pg :0x%x of our image is different\n", - __func__, pg); - ++pg; - } - - DBG("%s: marking 0x%x - 0x%x\n", __func__, - 0 << PAGE_SHIFT, 3 << PAGE_SHIFT); - /* First for pages (where the vectors are) should be left alone as well */ - set_bit(0, mem_available_pages); - set_bit(1, mem_available_pages); - set_bit(2, mem_available_pages); - set_bit(3, mem_available_pages); -} - -#ifdef BOOT_OF_FREE -/* this is here in case we ever need a free call at a later date */ -static void boot_of_free(ulong addr, ulong size) -{ - ulong bits; - ulong pos; - ulong i; - - size = ALIGN_UP(size, PAGE_SIZE); - bits = size >> PAGE_SHIFT; - pos = addr >> PAGE_SHIFT; - - for (i = 0; i < bits; i++) { - if (!test_and_clear_bit(pos + i, mem_available_pages)) - of_panic("%s: pg :0x%lx was never allocated\n", - __func__, pos + i); - } -} -#endif - -static ulong boot_of_alloc(ulong size) -{ - ulong bits; - ulong pos; - - if (size == 0) - return 0; - - DBG("%s(0x%lx)\n", __func__, size); - - size = ALIGN_UP(size, PAGE_SIZE); - bits = size >> PAGE_SHIFT; - pos = 0; - for (;;) { - ulong i; - - pos = find_next_zero_bit(mem_available_pages, - MEM_AVAILABLE_PAGES, pos); - DBG("%s: found start bit at: 0x%lx\n", __func__, pos); - - /* found nothing */ - if ((pos + bits) > MEM_AVAILABLE_PAGES) { - of_printf("%s: allocation of size: 0x%lx failed\n", - __func__, size); - return 0; - } - - /* find a set that fits */ - DBG("%s: checking for 0x%lx bits: 0x%lx\n", __func__, bits, pos); - - i = find_next_bit(mem_available_pages, MEM_AVAILABLE_PAGES, pos); - if (i - pos >= bits) { - uint addr = pos << PAGE_SHIFT; - - /* make sure OF is happy with our choice */ - if (of_claim(addr, size, 0) != OF_FAILURE) { - for (i = 0; i < bits; i++) - set_bit(pos + i, mem_available_pages); - - DBG("%s: 0x%lx is good returning 0x%x\n", - __func__, pos, addr); - return addr; - } - /* if OF did not like the address then simply start from - * the next bit */ - i = 1; - } - - pos = pos + i; - } -} - -int boot_of_mem_avail(int pos, ulong *startpage, ulong *endpage) -{ - ulong freebit; - ulong usedbit; - - if (pos >= MEM_AVAILABLE_PAGES) - /* Stop iterating. */ - return -1; - - /* Find first free page. */ - freebit = find_next_zero_bit(mem_available_pages, MEM_AVAILABLE_PAGES, pos); - if (freebit >= MEM_AVAILABLE_PAGES) { - /* We know everything after MEM_AVAILABLE_PAGES is still free. */ - *startpage = MEM_AVAILABLE_PAGES << PAGE_SHIFT; - *endpage = ~0UL; - return freebit; - } - *startpage = freebit << PAGE_SHIFT; - - /* Now find first used page after that. */ - usedbit = find_next_bit(mem_available_pages, MEM_AVAILABLE_PAGES, freebit); - if (usedbit >= MEM_AVAILABLE_PAGES) { - /* We know everything after MEM_AVAILABLE_PAGES is still free. */ - *endpage = ~0UL; - return usedbit; - } - - *endpage = usedbit << PAGE_SHIFT; - return usedbit; -} - -static ulong boot_of_mem_init(void) -{ - int root; - int p; - int rc; - uint addr_cells; - uint size_cells; - - root = of_finddevice("/"); - p = of_getchild(root); - - /* code is writen to assume sizes of 1 */ - of_getprop(root, "#address-cells", &addr_cells, - sizeof (addr_cells)); - of_getprop(root, "#size-cells", &size_cells, - sizeof (size_cells)); - DBG("%s: address_cells=%d size_cells=%d\n", - __func__, addr_cells, size_cells); - - /* We do ream memory discovery later, for now we only want to find - * the first LMB */ - do { - const char memory[] = "memory"; - char type[32]; - - type[0] = '\0'; - - of_getprop(p, "device_type", type, sizeof (type)); - if (strncmp(type, memory, sizeof (memory)) == 0) { - uint reg[48]; - u64 start; - u64 size; - int r; - int l; - - rc = of_getprop(p, "reg", reg, sizeof (reg)); - if (rc == OF_FAILURE) { - of_panic("no reg property for memory node: 0x%x.\n", p); - } - - l = rc / sizeof(reg[0]); /* number reg element */ - DBG("%s: number of bytes in property 'reg' %d\n", - __func__, rc); - - r = 0; - while (r < l) { - start = reg[r++]; - if (addr_cells == 2 && (r < l) ) - start = (start << 32) | reg[r++]; - - if (r >= l) - break; /* partial line. Skip */ - - if (start > 0) { - /* this is not the first LMB so we skip it */ - break; - } - - size = reg[r++]; - if (size_cells == 2 && (r < l) ) - size = (size << 32) | reg[r++]; - - if (r > l) - break; /* partial line. Skip */ - - boot_of_alloc_init(p, addr_cells, size_cells); - - eomem = size; - return size; - } - } - p = of_getpeer(p); - } while (p != OF_FAILURE && p != 0); - - return 0; -} - -static int save_props(void *m, ofdn_t n, int pkg) -{ - int ret; - char name[128]; - int result = 1; - int found_name = 0; - int found_device_type = 0; - const char name_str[] = "name"; - const char devtype_str[] = "device_type"; - - /* get first */ - result = of_nextprop(pkg, 0, name); - - while (result > 0) { - int sz; - u64 obj[1024]; - - sz = of_getproplen(pkg, name); - if (sz >= 0) { - ret = OF_SUCCESS; - } else { - ret = OF_FAILURE; - } - - if (ret == OF_SUCCESS) { - int actual = 0; - ofdn_t pos; - - if (sz > 0) { - if (sz > sizeof (obj)) { - of_panic("obj array not big enough for 0x%x\n", sz); - } - actual = of_getprop(pkg, name, obj, sz); - if (actual > sz) - of_panic("obj too small"); - } - - if (strncmp(name, name_str, sizeof(name_str)) == 0) { - found_name = 1; - } - - if (strncmp(name, devtype_str, sizeof(devtype_str)) == 0) { - found_device_type = 1; - } - - pos = ofd_prop_add(m, n, name, obj, actual); - if (pos == 0) - of_panic("prop_create"); - } - - result = of_nextprop(pkg, name, name); - } - - return 1; -} - - -static void do_pkg(void *m, ofdn_t n, int p, char *path, size_t psz) -{ - int pnext; - ofdn_t nnext; - int sz; - -retry: - save_props(m, n, p); - - /* do children first */ - pnext = of_getchild(p); - - if (pnext != 0) { - sz = of_package_to_path(pnext, path, psz); - if (sz == OF_FAILURE) - of_panic("bad path\n"); - - nnext = ofd_node_child_create(m, n, path, sz); - if (nnext == 0) - of_panic("out of mem\n"); - - do_pkg(m, nnext, pnext, path, psz); - } - - /* do peer */ - pnext = of_getpeer(p); - - if (pnext != 0) { - sz = of_package_to_path(pnext, path, psz); - - nnext = ofd_node_peer_create(m, n, path, sz); - if (nnext <= 0) - of_panic("out of space in OFD tree.\n"); - - n = nnext; - p = pnext; - goto retry; - } -} - -static long pkg_save(void *mem) -{ - int root; - char path[256]; - int r; - - path[0]='/'; - path[1]='\0'; - - /* get root */ - root = of_getpeer(0); - if (root == OF_FAILURE) - of_panic("no root package\n"); - - do_pkg(mem, OFD_ROOT, root, path, sizeof(path)); - - r = ofd_size(mem); - - of_printf("%s: saved device tree in 0x%x bytes\n", __func__, r); - - return r; -} - -static int boot_of_fixup_refs(void *mem) -{ - static const char *fixup_props[] = { - "interrupt-parent", - }; - int i; - int count = 0; - - for (i = 0; i < ARRAY_SIZE(fixup_props); i++) { - ofdn_t c; - const char *name = fixup_props[i]; - - c = ofd_node_find_by_prop(mem, OFD_ROOT, name, NULL, 0); - while (c > 0) { - const char *path; - int rp; - int ref; - ofdn_t dp; - int rc; - ofdn_t upd; - char ofpath[256]; - - path = ofd_node_path(mem, c); - if (path == NULL) - of_panic("no path to found prop: %s\n", name); - - rp = of_finddevice(path); - if (rp == OF_FAILURE) - of_panic("no real device for: name %s, path %s\n", - name, path); - /* Note: In theory 0 is a valid node handle but it is highly - * unlikely. - */ - if (rp == 0) { - of_panic("%s: of_finddevice returns 0 for path %s\n", - __func__, path); - } - - rc = of_getprop(rp, name, &ref, sizeof(ref)); - if ((rc == OF_FAILURE) || (rc == 0)) - of_panic("no prop: name %s, path %s, device 0x%x\n", - name, path, rp); - - rc = of_package_to_path(ref, ofpath, sizeof (ofpath)); - if (rc == OF_FAILURE) - of_panic("no package: name %s, path %s, device 0x%x,\n" - "ref 0x%x\n", name, path, rp, ref); - - dp = ofd_node_find(mem, ofpath); - if (dp <= 0) - of_panic("no ofd node for OF node[0x%x]: %s\n", - ref, ofpath); - - ref = dp; - - upd = ofd_prop_add(mem, c, name, &ref, sizeof(ref)); - if (upd <= 0) - of_panic("update failed: %s\n", name); - -#ifdef DEBUG - of_printf("%s: %s/%s -> %s\n", __func__, - path, name, ofpath); -#endif - ++count; - c = ofd_node_find_next(mem, c); - } - } - return count; -} - -static int boot_of_fixup_chosen(void *mem) -{ - int ch; - ofdn_t dn; - ofdn_t dc; - int val; - int rc; - char ofpath[256]; - - ch = of_finddevice("/chosen"); - if (ch == OF_FAILURE) - of_panic("/chosen not found\n"); - - rc = of_getprop(ch, "cpu", &val, sizeof (val)); - - if (rc != OF_FAILURE) { - rc = of_instance_to_path(val, ofpath, sizeof (ofpath)); - - if (rc > 0) { - dn = ofd_node_find(mem, ofpath); - if (dn <= 0) - of_panic("no node for: %s\n", ofpath); - - ofd_boot_cpu = dn; - val = dn; - - dn = ofd_node_find(mem, "/chosen"); - if (dn <= 0) - of_panic("no /chosen node\n"); - - dc = ofd_prop_add(mem, dn, "cpu", &val, sizeof (val)); - if (dc <= 0) - of_panic("could not fix /chosen/cpu\n"); - rc = 1; - } else { - of_printf("*** can't find path to booting cpu, " - "SMP is disabled\n"); - ofd_boot_cpu = -1; - } - } - return rc; -} - -/* PIBS Version 1.05.0000 04/26/2005 has an incorrect /ht/isa/ranges - * property. The values are bad, and it doesn't even have the - * right number of cells. */ - -static void __init boot_of_fix_maple(void) -{ - int isa; - const char *ranges = "ranges"; - u32 isa_ranges[3]; - const u32 isa_test[] = { 0x00000001, 0xf4000000, 0x00010000 }; - const u32 isa_fixed[] = { - 0x00000001, - 0x00000000, - 0x00000000, /* 0xf4000000, matt says this */ - 0x00000000, - 0x00000000, - 0x00010000 - }; - - isa = of_finddevice("/ht@0/isa@4"); - if (isa != OF_FAILURE) { - if (of_getproplen(isa, ranges) == sizeof (isa_test)) { - of_getprop(isa, ranges, isa_ranges, sizeof (isa_ranges)); - if (memcmp(isa_ranges, isa_test, sizeof (isa_test)) == 0) { - int rc; - - of_printf("OF: fixing bogus ISA range on maple\n"); - rc = of_setprop(isa, ranges, isa_fixed, sizeof (isa_fixed)); - if (rc == OF_FAILURE) { - of_panic("of_setprop() failed\n"); - } - } - } - } -} - -void __init boot_of_serial(void *oft) -{ - int n; - int p; - int rc; - u32 val[3]; - char buf[128]; - - n = of_instance_to_package(of_out); - if (n == OF_FAILURE) { - of_panic("instance-to-package of /chosen/stdout: failed\n"); - } - - /* Prune all serial devices from the device tree, including the - * one pointed to by /chosen/stdout, because a guest domain can - * initialize them and in so doing corrupt our console output. - */ - for (p = n; p > 0; p = of_getpeer(p)) { - char type[32]; - - rc = of_package_to_path(p, buf, sizeof(buf)); - if (rc == OF_FAILURE) - of_panic("package-to-path failed\n"); - - rc = of_getprop(p, "device_type", type, sizeof (type)); - if (rc == OF_FAILURE) { - of_printf("%s: fetching type of `%s' failed\n", __func__, buf); - continue; - } - - if (strcmp(type, "serial") != 0) - continue; - - of_printf("pruning `%s' from devtree\n", buf); - rc = ofd_prune_path(oft, buf); - if (rc < 0) - of_panic("prune of `%s' failed\n", buf); - } - - p = of_getparent(n); - if (p == OF_FAILURE) { - of_panic("no parent for: 0x%x\n", n); - } - - buf[0] = '\0'; - of_getprop(p, "device_type", buf, sizeof (buf)); - if (strstr(buf, "isa") == NULL) { - of_panic("only ISA UARTS supported\n"); - } - - /* should get this from devtree */ - isa_io_base = 0xf4000000; - of_printf("%s: ISA base: 0x%lx\n", __func__, isa_io_base); - - buf[0] = '\0'; - of_getprop(n, "device_type", buf, sizeof (buf)); - if (strstr(buf, "serial") == NULL) { - of_panic("only UARTS supported\n"); - } - - rc = of_getprop(n, "reg", val, sizeof (val)); - if (rc == OF_FAILURE) { - of_panic("%s: no location for serial port\n", __func__); - } - - ns16550.baud = BAUD_AUTO; - ns16550.data_bits = 8; - ns16550.parity = 'n'; - ns16550.stop_bits = 1; - - rc = of_getprop(n, "interrupts", val, sizeof (val)); - if (rc == OF_FAILURE) { - of_printf("%s: no ISRC, forcing poll mode\n", __func__); - ns16550.irq = 0; - } else { - ns16550.irq = val[0]; - of_printf("%s: ISRC=0x%x, but forcing poll mode\n", - __func__, ns16550.irq); - ns16550.irq = 0; - } -} - -static int __init boot_of_rtas(void) -{ - int rtas_node; - int rtas_instance; - uint size = 0; - int res[2]; - int mem; - int ret; - - rtas_node = of_finddevice("/rtas"); - - if (rtas_node <= 0) { - of_printf("No RTAS, Xen has no power control\n"); - return 0; - } - of_getprop(rtas_node, "rtas-size", &size, sizeof (size)); - if (size == 0) { - of_printf("RTAS, has no size\n"); - return 0; - } - - rtas_instance = of_open("/rtas"); - if (rtas_instance == OF_FAILURE) { - of_printf("RTAS, could not open\n"); - return 0; - } - - size = ALIGN_UP(size, PAGE_SIZE); - - mem = boot_of_alloc(size); - if (mem == 0) - of_panic("Could not allocate RTAS tree\n"); - - of_printf("instantiating RTAS at: 0x%x\n", mem); - - ret = of_call("call-method", 3, 2, res, - "instantiate-rtas", rtas_instance, mem); - if (ret == OF_FAILURE) { - of_printf("RTAS, could not open\n"); - return 0; - } - - rtas_entry = res[1]; - rtas_base = mem; - rtas_end = mem + size; - rtas_msr = of_msr; - - return 1; -} - -void __init *boot_of_devtree(void) -{ - void *oft; - ulong oft_sz = 48 * PAGE_SIZE; - ulong alloc_sz = 32 << 10; /* 32KiB should be plenty */ - ulong sz; - - /* snapshot the tree */ - oft = (void *)boot_of_alloc(alloc_sz); - if (oft == NULL) - of_panic("Could not allocate OFD tree\n"); - - of_printf("creating oftree at: 0x%p\n", oft); - of_test("package-to-path"); - oft = ofd_create(oft, alloc_sz); - pkg_save(oft); - sz = ofd_size(oft); - - if (sz > alloc_sz) - of_panic("Could not fit all of native devtree in 0x%lx of memory\n", - alloc_sz); - - boot_of_fixup_refs(oft); - boot_of_fixup_chosen(oft); - - if (sz > alloc_sz) - of_panic("Could not fit all devtree fixupsin 0x%lx of memory\n", - alloc_sz); - - ofd_walk(oft, __func__, OFD_ROOT, /* add_hype_props */ NULL, 2); - - oftree = (ulong)oft; - oftree = (ulong)oft + oft_sz; - oftree_len = oft_sz; - - return oft; -} - -static int __init boot_of_cpus(void) -{ - int cpus_node, cpu_node; - int bootcpu_instance, bootcpu_node; - int logical; - int result; - s32 cpuid; - u32 cpu_clock[2]; - extern uint cpu_hard_id[NR_CPUS]; - u32 tbf; - - /* Look up which CPU we are running on right now and get all info - * from there */ - result = of_getprop(bof_chosen, "cpu", - &bootcpu_instance, sizeof (bootcpu_instance)); - if (result == OF_FAILURE) - of_panic("Failed to look up boot cpu instance\n"); - - bootcpu_node = of_instance_to_package(bootcpu_instance); - if (result == OF_FAILURE) - of_panic("Failed to look up boot cpu package\n"); - - cpu_node = bootcpu_node; - - result = of_getprop(cpu_node, "timebase-frequency", &tbf, sizeof(tbf)); - timebase_freq = tbf; - if (result == OF_FAILURE) { - of_panic("Couldn't get timebase frequency!\n"); - } - of_printf("OF: timebase-frequency = %ld Hz\n", timebase_freq); - - result = of_getprop(cpu_node, "clock-frequency", - &cpu_clock, sizeof(cpu_clock)); - if (result == OF_FAILURE || (result !=4 && result != 8)) { - of_panic("Couldn't get clock frequency!\n"); - } - cpu_khz = cpu_clock[0]; - if (result == 8) { - cpu_khz <<= 32; - cpu_khz |= cpu_clock[1]; - } - cpu_khz /= 1000; - of_printf("OF: clock-frequency = %ld KHz\n", cpu_khz); - - /* We want a continuous logical cpu number space and we'll make - * the booting CPU logical 0. */ - cpu_set(0, cpu_present_map); - cpu_set(0, cpu_online_map); - cpu_set(0, cpu_possible_map); - - result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid)); - cpu_hard_id[0] = cpuid; - - /* Spin up all CPUS, even if there are more than NR_CPUS or we are - * runnign nosmp, because Open Firmware has them spinning on cache - * lines which will eventually be scrubbed, which could lead to - * random CPU activation. - */ - - /* Find the base of the multi-CPU package node */ - cpus_node = of_finddevice("/cpus"); - if (cpus_node <= 0) { - of_printf("Single Processor System\n"); - return 1; - } - /* Start with the first child */ - cpu_node = of_getchild(cpus_node); - - for (logical = 1; cpu_node > 0; logical++) { - unsigned int ping, pong; - unsigned long now, then, timeout; - - if (cpu_node == bootcpu_node) { - /* same CPU as boot CPU shich we have already made 0 so - * reduce the logical count */ - --logical; - } else { - result = of_getprop(cpu_node, "reg", &cpuid, sizeof(cpuid)); - if (result == OF_FAILURE) - of_panic("cpuid lookup failed\n"); - - cpu_hard_id[logical] = cpuid; - - of_printf("spinning up secondary processor #%d: ", logical); - - __spin_ack = ~0x0; - ping = __spin_ack; - pong = __spin_ack; - of_printf("ping = 0x%x: ", ping); - - mb(); - result = of_start_cpu(cpu_node, (ulong)spin_start, logical); - if (result == OF_FAILURE) - of_panic("start cpu failed\n"); - - /* We will give the secondary processor five seconds to reply. */ - then = mftb(); - timeout = then + (5 * timebase_freq); - - do { - now = mftb(); - if (now >= timeout) { - of_printf("BROKEN: "); - break; - } - - mb(); - pong = __spin_ack; - } while (pong == ping); - of_printf("pong = 0x%x\n", pong); - - if (pong != ping) { - cpu_set(logical, cpu_present_map); - cpu_set(logical, cpu_possible_map); - } - } - cpu_node = of_getpeer(cpu_node); - } - return 1; -} - -void __init boot_of_init(ulong vec, ulong orig_msr) -{ - int r; - - of_vec = vec; - of_msr = orig_msr; - - if (is_kernel(vec)) { - of_panic("Hmm.. OF[0x%lx] seems to have stepped on our image " - "that ranges: %p .. %p.\n", - vec, _start, _end); - } - of_printf("%s: _start %p _end %p\n", __func__, _start, _end); - - bof_chosen = of_finddevice("/chosen"); - of_getprop(bof_chosen, "stdout", &of_out, sizeof (of_out)); - - of_printf("%s\n", "---------------------------------------------------"); - of_printf("OF: Xen/PPC version %d.%d%s (%s@%s) (%s) %s\n", - xen_major_version(), xen_minor_version(), xen_extra_version(), - xen_compile_by(), xen_compile_domain(), - xen_compiler(), xen_compile_date()); - - boot_of_fix_maple(); - r = boot_of_mem_init(); - if (r == 0) - of_panic("failure to initialize memory allocator"); - - boot_of_rtas(); - boot_of_cpus(); -} - -void __init boot_of_finish(void) -{ - /* end of OF */ - of_printf("Quiescing Open Firmware ...\n"); - of_call("quiesce", 0, 0, NULL); -} - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/cmdline.c --- a/xen/arch/powerpc/cmdline.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (C) IBM Corp. 2006 - * - * Authors: Hollis Blanchard <hollisb@xxxxxxxxxx> - */ - -#include <asm/config.h> - -char builtin_cmdline[CONFIG_CMDLINE_SIZE] - __attribute__((section("__builtin_cmdline"))) = CMDLINE; diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/crash.c --- a/xen/arch/powerpc/crash.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -#include <xen/lib.h> /* for printk() used in stub */ -#include <xen/types.h> -#include <xen/kexec.h> -#include <public/kexec.h> - -void machine_crash_shutdown(void) -{ - printk("STUB: " __FILE__ ": %s: not implemented\n", __FUNCTION__); -} - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ - diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/dart.c --- a/xen/arch/powerpc/dart.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,297 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (C) IBM Corp. 2005 - * - * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> - */ - -#include <xen/config.h> -#include <xen/types.h> -#include <xen/mm.h> -#include <asm/cache.h> -#include <xen/init.h> -#include "tce.h" -#include "iommu.h" -#include "dart.h" -#include "oftree.h" -#include "of-devtree.h" - -#undef DEBUG -#ifdef DEBUG -#define DBG(fmt...) printk(fmt) -static int dbg_after; -#define DBG_SET_AFTER dbg_after = 1; -#define DBG_AFTER(fmt...) if (dbg_after) DBG(fmt) -#else -#define DBG(fmt...) -#define DBG_SET_AFTER -#define DBG_AFTER(fmt...) -#endif - -/* Max size of 512 pages */ -#define U3_LOG_MAX_PAGES 9 - -#define DART_DEF_BASE 0xf8033000UL -#define DART_NONE 0 -#define DART_U3 3 -#define DART_U4 4 -#define DART_WRITE 0x1 -#define DART_READ 0x2 - -static ulong dummy_page; -static ulong dart_entries; -static struct dart_ops *dops; -static u32 *dart_table; - -union dart_entry { - u32 de_word; - struct { - u32 de_v:1; /* valid */ - u32 de_rp:1; /* read protected */ - u32 de_wp:1; /* write protected */ - u32 _de_res:5; - u32 de_ppn:24; /* 24 bit Physical Page Number - * representing address [28:51] */ - } de_bits; -}; - -struct dma_window { - u32 dw_liobn; - u32 dw_base_hi; - u64 dw_base; - u64 dw_size; -}; - -struct dart_info { - struct dma_window di_window; - ulong di_base; - int di_model; -}; - -static u32 dart_encode(int perm, ulong rpn) -{ - union dart_entry e; - - e.de_word = 0; - e.de_bits.de_v = 1; - e.de_bits.de_ppn = rpn; - - /* protect the page */ - e.de_bits.de_rp = 1; - e.de_bits.de_wp = 1; - if (perm & DART_READ) { - e.de_bits.de_rp = 0; - } - if (perm & DART_WRITE) { - e.de_bits.de_wp = 0; - } - return e.de_word; -} - -static void dart_fill(ulong index, int perm, ulong rpg, ulong num_pg) -{ - u32 volatile *entry = dart_table + index; - ulong i = 0; - ulong last_flush = 0; - - while (1) { - entry[i] = dart_encode(perm, rpg); - ++i; - ++rpg; - if (i == num_pg) break; - - if ((((ulong)&entry[i]) % cpu_caches.dline_size) == 0) { - last_flush = (ulong)&entry[i - 1]; - dcbst(last_flush); - } - } - dcbst((ulong) &entry[i - 1]); -} - -static void dart_clear(ulong index, ulong num_pg) -{ - u32 *entry = dart_table + index; - ulong i = 0; - ulong rpg = dummy_page; - ulong last_flush = 0; - - while (1) { - entry[i] = dart_encode(DART_READ | DART_WRITE, rpg); - ++i; - if (i == num_pg) break; - - if ((((ulong)&entry[i]) % cpu_caches.dline_size) == 0) { - last_flush = (ulong)&entry[i - 1]; - dcbst(last_flush); - } - } - dcbst((ulong)&entry[i - 1]); -} - -static int dart_put(ulong ioba, union tce tce) -{ - ulong index = ioba >> PAGE_SHIFT; - - if (index > dart_entries) { - return -1; - } - - if (tce.tce_bits.tce_vlps != 0 || tce.tce_bits.tce_lpx != 0) { - panic("no support for large TCEs\n"); - } - - if (tce.tce_bits.tce_read == 0 && - tce.tce_bits.tce_write == 0) { - /* the TCE table is inited by the domain by a bunch of 0 - * perminssion puts. We are only interesting in debugging the - * ones after the first put */ - DBG_AFTER(">DART[0x%lx] clear\n", index); - dart_clear(index, 1); - } else { - unsigned perm = 0; - - if (tce.tce_bits.tce_read) - perm |= DART_READ; - if (tce.tce_bits.tce_write) - perm |= DART_WRITE; - - DBG("<DART[0x%lx]: ioba: 0x%lx perm:%x[%c%c] rpn:0x%lx\n", - index, ioba, perm, - (perm & DART_READ) ? 'R' : '-', - (perm & DART_WRITE) ? 'W' : '-', - (ulong)tce.tce_bits.tce_rpn); - DBG_SET_AFTER; - - dart_fill(index, perm, tce.tce_bits.tce_rpn, 1); - } - dops->do_inv_entry(tce.tce_bits.tce_rpn); - - return 0; -} - -static int find_dart(struct dart_info *di) -{ - int rc; - void *ofd_p; - ofdn_t n; - char compat[128]; - - if (on_systemsim()) { - DBG("%s: systemsim does not support a dart\n", __func__); - return -1; - } - - ofd_p = (void *)oftree; - n = ofd_node_find(ofd_p, "/ht"); - if (n <= 0) - return -1; - - /* get the defaults from the HT node model */ - rc = ofd_getprop(ofd_p, n, "compatible", compat, sizeof (compat)); - if (rc <= 0) - return -1; - - if (ofd_strstr(compat, rc, "u4")) - di->di_model = DART_U4; - else if (ofd_strstr(compat, rc, "u3")) - di->di_model = DART_U3; - else { - DBG("%s: not a U3 or U4\n", __func__); - return -1; - } - - di->di_base = DART_DEF_BASE; - - /* FIXME: this should actually be the HT reg value */ - di->di_window.dw_liobn = 0; - di->di_window.dw_base_hi = 0; - di->di_window.dw_base = 0; - - /* lets see if the devtree has more info */ - n = ofd_node_find(ofd_p, "/dart"); - if (n > 0) { - ulong base; - - rc = ofd_getprop(ofd_p, n, "compatible", compat, sizeof (compat)); - if (rc > 0) { - if (strstr(compat, "u4")) { - di->di_model = DART_U4; - } - } - - rc = ofd_getprop(ofd_p, n, "reg", &base, sizeof (base)); - if (rc > 0) { - di->di_base = base; - } - } - return 0; -} - -static int init_dart(void) -{ - ulong log_pgs; - void *ofd_p; - ofdn_t n; - struct dart_info di; - - if (find_dart(&di)) - return 0; - - /* Max size of 512 pages == 2MB == 1<<21. That siz is good enough for U4 */ - log_pgs = U3_LOG_MAX_PAGES; - dart_table = alloc_xenheap_pages(log_pgs); - BUG_ON(dart_table == NULL); - - dart_entries = (1UL << (log_pgs + PAGE_SHIFT)) / sizeof (union dart_entry); - di.di_window.dw_size = dart_entries << PAGE_SHIFT; - - /* Linux uses a dummy page, filling "empty" DART entries with a - reference to this page to capture stray DMA's */ - dummy_page = (ulong)alloc_xenheap_pages(0); - clear_page((void *)dummy_page); - dummy_page >>= PAGE_SHIFT; - - printk("Initializing DART 0x%lx: tbl: %p[0x%lx] entries: 0x%lx\n", - di.di_base, dart_table, 1UL << log_pgs, dart_entries); - - /* register this iommu */ - iommu_register(di.di_window.dw_liobn, dart_put); - - switch (di.di_model) { - case DART_U3: - dops = u3_init(di.di_base, (ulong)dart_table, 1UL << log_pgs); - break; - case DART_U4: - dops = u4_init(di.di_base, (ulong)dart_table, 1UL << log_pgs); - break; - } - - dart_clear(0, dart_entries); - dops->do_inv_all(); - - /* fix up the devtree */ - ofd_p = (void *)oftree; - n = ofd_node_find(ofd_p, "/ht"); - if (n > 0) { - di.di_window.dw_size = dart_entries << PAGE_SHIFT; - ofd_prop_add(ofd_p, n, "ibm,dma-window", &di.di_window, - sizeof (di.di_window)); - } else { - panic("%s: no /ht node\n", __func__); - } - return 0; -} -__initcall(init_dart); diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/dart.h --- a/xen/arch/powerpc/dart.h Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (C) IBM Corp. 2005 - * - * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> - */ - -#ifndef _DART_H -#define _DART_H - -#include <xen/config.h> -#include <xen/types.h> - -struct dart_ops { - void (*do_inv_all)(void); - void (*do_inv_entry)(ulong pg); -}; - -extern struct dart_ops *u3_init(ulong base, ulong table, ulong dart_pages); -extern struct dart_ops *u4_init(ulong base, ulong table, ulong dart_pages); - -#endif /* _DART_H */ - diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/dart_u3.c --- a/xen/arch/powerpc/dart_u3.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,108 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (C) IBM Corp. 2005 - * - * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> - */ - -#undef DEBUG - -#include <xen/config.h> -#include <xen/types.h> -#include <xen/sched.h> -#include <xen/mm.h> -#include <public/xen.h> -#include <asm/io.h> -#include <asm/current.h> -#include "tce.h" -#include "iommu.h" -#include "dart.h" - -union dart_ctl { - u32 dc_word; - struct { - u32 dc_base:20; - u32 dc_stop_access:1; - u32 dc_invtlb:1; - u32 dc_enable:1; - u32 dc_size:9; - } reg; -}; - -static u32 volatile *dart_ctl_reg; - -static void u3_inv_all(void) -{ - union dart_ctl dc; - ulong r = 0; - int l = 0; - - for (;;) { - dc.dc_word = in_32(dart_ctl_reg); - dc.reg.dc_invtlb = 1; - out_32(dart_ctl_reg, dc.dc_word); - - do { - dc.dc_word = in_32(dart_ctl_reg); - r++; - } while ((dc.reg.dc_invtlb == 1) && (r < (1 << l))); - - if (r == (1 << l)) { - if (l < 4) { - l++; - dc.dc_word = in_32(dart_ctl_reg); - dc.reg.dc_invtlb = 0; - out_32(dart_ctl_reg, dc.dc_word); - continue; - } else { - panic(" broken U3???\n"); - } - } - return; - } -} - -static void u3_inv_entry(ulong pg) -{ - /* sadly single entry invalidation has been reported not to work */ - u3_inv_all(); -} - -static struct dart_ops u3_ops = { - .do_inv_all = u3_inv_all, - .do_inv_entry = u3_inv_entry, -}; - -struct dart_ops *u3_init(ulong base, ulong table, ulong dart_pages) -{ - union dart_ctl dc; - - dart_ctl_reg = (u32 *)base; - - dc.dc_word = 0; - - dc.reg.dc_base = table >> PAGE_SHIFT; - dc.reg.dc_size = dart_pages; - dc.reg.dc_enable = 1; - - - printk("Initializing DART Model U3: reg: %p word: %x\n", - dart_ctl_reg, dc.dc_word); - - out_32(dart_ctl_reg, dc.dc_word); - - return &u3_ops; -} diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/dart_u4.c --- a/xen/arch/powerpc/dart_u4.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,184 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright (C) IBM Corp. 2005 - * - * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> - */ - -#undef DEBUG -#define INVALIDATE_ALL - -#include <xen/config.h> -#include <xen/types.h> -#include <xen/sched.h> -#include <xen/init.h> -#include <xen/mm.h> -#include <public/xen.h> -#include <asm/io.h> -#include <asm/current.h> -#include "tce.h" -#include "iommu.h" -#include "dart.h" - -#define TOO_MANY_RETRIES ~0 - -union dart_ctl { - u32 dc_word; - struct { - u32 dc_darten:1; /* DART Enable (0:disabled) */ - u32 dc_ione:1; /* Invalidate one DART TLB entry (using ILPN) */ - u32 dc_iall:1; /* Invalidate all DART TLB entries */ - u32 dc_idle:1; /* DART is idle */ - u32 dc_peen:1; /* Parity Checking is enabled */ - u32 dc_ilpn:27; /* 27-bit Logical Page Address for - * invalidating one TLB entry */ - } dc_bits; -}; - -union dart_base { - u32 db_word; - struct { - u32 _db_resv:8; - u32 db_dartbase:24; /* Base Address of DART (4K byte Alignment) */ - } db_bits; -}; - -union dart_size { - u32 ds_word; - struct { - u32 _ds_resv:15; - u32 ds_dartsize:17; /* Size of Dart in 4K-Byte Pages */ - } ds_bits; -}; - -union dart_excp { - u32 de_word; - struct { - u32 de_rqsrc:1; /* Request Source. [0:PCIE, 1:HT] */ - u32 de_lpn:27; /* 27Ðbit Logical Address of Exception [25:51] */ - u32 de_rqop:1; /* Request operation. [0:Read, 1:Write] */ - u32 de_xcd:3; /* Exception code */ - } de_bits; -}; - -struct dart { - /* 0x00 */ - union dart_ctl d_dartcntl; - u32 _pad0x04_0x10[3]; - /* 0x10 */ - union dart_base d_dartbase; - u32 _pad0x14_0x20[3]; - /* 0x20 */ - union dart_size d_dartsize; - u32 _pad0x24_0x30[3]; - /* 0x30 */ - union dart_excp d_dartexcp; - u32 _pad0x34_0x40[3]; -}; - -static volatile struct dart *dart; - -static void u4_inv_all(void) -{ - union dart_ctl dc; - ulong r = 0; - int l = 0; - - for (;;) { - dc.dc_word = in_32(&dart->d_dartcntl.dc_word); - dc.dc_bits.dc_iall = 1; - out_32(&dart->d_dartcntl.dc_word, dc.dc_word); - - do { - dc.dc_word = in_32(&dart->d_dartcntl.dc_word); - r++; - } while ((dc.dc_bits.dc_iall == 1) && (r < (1 << l))); - - if (r == (1 << l)) { - if (l < 4) { - l++; - dc.dc_word = in_32(&dart->d_dartcntl.dc_word); - dc.dc_bits.dc_iall = 0; - out_32(&dart->d_dartcntl.dc_word, dc.dc_word); - continue; - } else { - panic(" broken U4???\n"); - } - } - return; - } -} - -static void u4_inv_entry(ulong pgn) -{ -#ifdef INVALIDATE_ALL - return u4_inv_all(); -#else - union dart_ctl dc; - ulong retries = 0; - - return u4_inv_all(); - - dc.dc_word = in_32(&dart->d_dartcntl.dc_word); - dc.dc_bits.dc_ilpn = pgn; - dc.dc_bits.dc_ione = 1; - out_32(&dart->d_dartcntl.dc_word, dc.dc_word); - - /* wait for completion */ - /* FIXME: since we do this from the HV do we need to wait?! */ - do { - dc.dc_word = in_32(&dart->d_dartcntl.dc_word); - retries++; - if (retries > 1000000) - panic("WAY! too long\n"); - } while (dc.dc_bits.dc_ione != 0); -#endif -} - -static struct dart_ops u4_ops = { - .do_inv_all = u4_inv_all, - .do_inv_entry = u4_inv_entry, -}; - -struct dart_ops *u4_init(ulong base, ulong table, ulong dart_pages) -{ - union dart_base db; - union dart_size ds; - union dart_ctl dc; - - dart = (struct dart *)base; - - db.db_word = 0; - db.db_bits.db_dartbase = table >> PAGE_SHIFT; - - ds.ds_word = 0; - ds.ds_bits.ds_dartsize = dart_pages; - - dc.dc_word = in_32(&dart->d_dartcntl.dc_word); - if (dc.dc_bits.dc_darten == 1) { - panic("%s: dart is already enabled: 0x%x\n", __func__, dc.dc_word); - } - dc.dc_bits.dc_darten = 1; /* enable it */ - - printk("Initializing DART Model U4: ctl: 0x%x base: 0x%x size: 0x%x\n", - dc.dc_word, db.db_word, ds.ds_word); - - out_32(&dart->d_dartbase.db_word, db.db_word); - out_32(&dart->d_dartsize.ds_word, ds.ds_word); - out_32(&dart->d_dartcntl.dc_word, dc.dc_word); - - return &u4_ops; -} diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/domain.c --- a/xen/arch/powerpc/domain.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,357 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright IBM Corp. 2005, 2006, 2007 - * - * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> - * Ryan Harper <ryanh@xxxxxxxxxx> - * Hollis Blanchard <hollisb@xxxxxxxxxx> - */ - -#include <stdarg.h> -#include <xen/config.h> -#include <xen/lib.h> -#include <xen/sched.h> -#include <xen/mm.h> -#include <xen/serial.h> -#include <xen/domain.h> -#include <xen/console.h> -#include <xen/shutdown.h> -#include <xen/paging.h> -#include <xen/mm.h> -#include <xen/softirq.h> -#include <asm/htab.h> -#include <asm/current.h> -#include <asm/hcalls.h> -#include "rtas.h" -#include "exceptions.h" - -#define next_arg(fmt, args) ({ \ - unsigned long __arg; \ - switch ( *(fmt)++ ) \ - { \ - case 'i': __arg = (unsigned long)va_arg(args, unsigned int); break; \ - case 'l': __arg = (unsigned long)va_arg(args, unsigned long); break; \ - case 'p': __arg = (unsigned long)va_arg(args, void *); break; \ - case 'h': __arg = (unsigned long)va_arg(args, void *); break; \ - default: __arg = 0; BUG(); \ - } \ - __arg; \ -}) - -unsigned long hypercall_create_continuation(unsigned int op, - const char *format, ...) -{ - struct cpu_user_regs *regs = guest_cpu_user_regs(); - const char *p = format; - va_list args; - int gprnum = 4; - int i; - - va_start(args, format); - - regs->pc -= 4; /* re-execute 'sc' */ - - for (i = 0; *p != '\0'; i++) { - regs->gprs[gprnum++] = next_arg(p, args); - } - - va_end(args); - - /* As luck would have it, we use the same register for hcall opcodes and - * for hcall return values. The return value from this function is placed - * in r3 on return, so modifying regs->gprs[3] would have no effect. */ - return XEN_MARK(op); -} - -int arch_domain_create(struct domain *d, unsigned int domcr_flags) -{ - if (d->domain_id == IDLE_DOMAIN_ID) { - d->shared_info = (void *)alloc_xenheap_page(); - clear_page(d->shared_info); - - return 0; - } - - d->arch.large_page_sizes = cpu_large_page_orders( - d->arch.large_page_order, ARRAY_SIZE(d->arch.large_page_order)); - - d->arch.foreign_mfn_count = 2048; - d->arch.foreign_mfns = xmalloc_array(uint, d->arch.foreign_mfn_count); - BUG_ON(d->arch.foreign_mfns == NULL); - - memset(d->arch.foreign_mfns, -1, d->arch.foreign_mfn_count * sizeof(uint)); - - return 0; -} - -void arch_domain_destroy(struct domain *d) -{ - shadow_teardown(d); - /* shared_info is part of the RMA so no need to release it */ -} - -static void machine_fail(const char *s) -{ - printk("%s failed, manual powercycle required!\n" - " spinning....\n", s); - for (;;) - sleep(); -} -void machine_halt(void) -{ - console_start_sync(); - printk("%s called\n", __func__); - rtas_halt(); - - machine_fail(__func__); -} - -void machine_restart(void) -{ - console_start_sync(); - printk("%s called\n", __func__); - rtas_reboot(); - machine_fail(__func__); -} - -struct vcpu *alloc_vcpu_struct(void) -{ - struct vcpu *v; - if ( (v = xmalloc(struct vcpu)) != NULL ) - memset(v, 0, sizeof(*v)); - return v; -} - -void free_vcpu_struct(struct vcpu *v) -{ - xfree(v); -} - -int vcpu_initialise(struct vcpu *v) -{ - /* Guests by default have a 100Hz ticker. */ - v->periodic_period = MILLISECS(10); - return 0; -} - -void vcpu_destroy(struct vcpu *v) -{ -} - -int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c) -{ - struct domain *d = v->domain; - - memcpy(&v->arch.ctxt, &c.nat->user_regs, sizeof(c.nat->user_regs)); - - printk("Domain[%d].%d: initializing\n", d->domain_id, v->vcpu_id); - - if (d->arch.htab.order == 0) - panic("Page table never allocated for Domain: %d\n", d->domain_id); - if (d->arch.rma_order == 0) - panic("RMA never allocated for Domain: %d\n", d->domain_id); - - d->shared_info->wc_sec = dom0->shared_info->wc_sec; - d->shared_info->wc_nsec = dom0->shared_info->wc_nsec; - d->shared_info->arch.boot_timebase = dom0->shared_info->arch.boot_timebase; - - if ( !v->is_initialised ) - { - v->is_initialised = 1; - /* Auto-online VCPU0 when it is initialised. */ - if ( v->vcpu_id == 0 ) - clear_bit(_VPF_down, &v->pause_flags); - } - - cpu_init_vcpu(v); - - return 0; -} - -int arch_vcpu_reset(struct vcpu *v) -{ - panic("%s: called for Dom%d[%d]\n", - __func__, v->domain->domain_id, v->vcpu_id); - return 0; -} - -void dump_pageframe_info(struct domain *d) -{ - struct page_info *page; - - printk("Memory pages belonging to domain %u:\n", d->domain_id); - - if ( d->tot_pages >= 10 ) - { - printk(" DomPage list too long to display\n"); - } - else - { - list_for_each_entry ( page, &d->page_list, list ) - { - printk(" DomPage %p: mfn=%p, caf=%016lx, taf=%" PRtype_info "\n", - _p(page_to_maddr(page)), _p(page_to_mfn(page)), - page->count_info, page->u.inuse.type_info); - } - } - - list_for_each_entry ( page, &d->xenpage_list, list ) - { - printk(" XenPage %p: mfn=%p, caf=%016lx, taf=%" PRtype_info "\n", - _p(page_to_maddr(page)), _p(page_to_mfn(page)), - page->count_info, page->u.inuse.type_info); - } -} - -void context_switch(struct vcpu *prev, struct vcpu *next) -{ - struct cpu_user_regs *stack_regs = guest_cpu_user_regs(); - cpumask_t dirty_mask = next->vcpu_dirty_cpumask; - unsigned int cpu = smp_processor_id(); - -#if 0 - printk("%s: dom %x to dom %x\n", __func__, prev->domain->domain_id, - next->domain->domain_id); -#endif - - /* Allow at most one CPU at a time to be dirty. */ - ASSERT(cpus_weight(dirty_mask) <= 1); - if (unlikely(!cpu_isset(cpu, dirty_mask) && !cpus_empty(dirty_mask))) - { - /* Other cpus call __sync_lazy_execstate from flush ipi handler. */ - if (!cpus_empty(next->vcpu_dirty_cpumask)) - flush_tlb_mask(next->vcpu_dirty_cpumask); - } - - /* copy prev guest state off the stack into its vcpu */ - memcpy(&prev->arch.ctxt, stack_regs, sizeof(struct cpu_user_regs)); - - set_current(next); - - /* copy next guest state onto the stack */ - memcpy(stack_regs, &next->arch.ctxt, sizeof(struct cpu_user_regs)); - - /* save old domain state */ - save_sprs(prev); - save_float(prev); - save_segments(prev); - - context_saved(prev); - - /* load up new domain */ - load_sprs(next); - load_float(next); - load_segments(next); - - mtsdr1(next->domain->arch.htab.sdr1); - local_flush_tlb(); /* XXX maybe flush_tlb_mask? */ - cpu_flush_icache(); - - if (is_idle_vcpu(next)) { - reset_stack_and_jump(idle_loop); - } - - reset_stack_and_jump(full_resume); - /* not reached */ -} - -void continue_running(struct vcpu *same) -{ - /* nothing to do */ - return; -} - -void sync_vcpu_execstate(struct vcpu *v) -{ - /* do nothing */ - return; -} - -static void relinquish_memory(struct domain *d, struct list_head *list) -{ - struct list_head *ent; - struct page_info *page; - - /* Use a recursive lock, as we may enter 'free_domheap_page'. */ - spin_lock_recursive(&d->page_alloc_lock); - - ent = list->next; - while ( ent != list ) - { - page = list_entry(ent, struct page_info, list); - - /* Grab a reference to the page so it won't disappear from under us. */ - if ( unlikely(!get_page(page, d)) ) - { - /* Couldn't get a reference -- someone is freeing this page. */ - ent = ent->next; - continue; - } - if ( test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) ) - put_page_and_type(page); - - if ( test_and_clear_bit(_PGC_allocated, &page->count_info) ) - put_page(page); - - /* Follow the list chain and /then/ potentially free the page. */ - ent = ent->next; - put_page(page); - } - spin_unlock_recursive(&d->page_alloc_lock); -} - -int domain_relinquish_resources(struct domain *d) -{ - relinquish_memory(d, &d->xenpage_list); - relinquish_memory(d, &d->page_list); - xfree(d->arch.foreign_mfns); - xfree(d->arch.p2m); - return 0; -} - -void arch_dump_domain_info(struct domain *d) -{ -} - -void arch_dump_vcpu_info(struct vcpu *v) -{ -} - -static void safe_halt(void) -{ - int cpu = smp_processor_id(); - - while (!softirq_pending(cpu)) - sleep(); -} - -static void default_idle(void) -{ - local_irq_disable(); - if ( !softirq_pending(smp_processor_id()) ) - safe_halt(); - else - local_irq_enable(); -} - -void idle_loop(void) -{ - for ( ; ; ) { - page_scrub_schedule_work(); - default_idle(); - do_softirq(); - } -} diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/domain_build.c --- a/xen/arch/powerpc/domain_build.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,297 +0,0 @@ -/* - * 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Copyright IBM Corp. 2005, 2007 - * - * Authors: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> - * Ryan Harper <ryanh@xxxxxxxxxx> - * Hollis Blanchard <hollisb@xxxxxxxxxx> - */ - -#include <xen/config.h> -#include <xen/lib.h> -#include <xen/sched.h> -#include <xen/init.h> -#include <xen/ctype.h> -#include <xen/iocap.h> -#include <xen/domain.h> -#include <xen/version.h> -#include <xen/paging.h> -#include <asm/processor.h> -#include <asm/platform.h> -#include <asm/papr.h> -#include <public/arch-powerpc.h> -#include <public/libelf.h> -#include "oftree.h" - -/* opt_dom0_mem: memory allocated to domain 0. */ -static unsigned int dom0_nrpages; -static void parse_dom0_mem(char *s) -{ - unsigned long long bytes; - - bytes = parse_size_and_unit(s, NULL); - dom0_nrpages = bytes >> PAGE_SHIFT; -} -custom_param("dom0_mem", parse_dom0_mem); - -static unsigned int opt_dom0_max_vcpus; -integer_param("dom0_max_vcpus", opt_dom0_max_vcpus); - -static unsigned int opt_dom0_shadow; -boolean_param("dom0_shadow", opt_dom0_shadow); - -/* adapted from common/elf.c */ -#define RM_MASK(a,l) ((a) & ((1UL << (l)) - 1)) - -int construct_dom0(struct domain *d, - unsigned long image_start, unsigned long image_len, - unsigned long initrd_start, unsigned long initrd_len, - char *cmdline) -{ - struct elf_binary elf; - struct elf_dom_parms parms; - int rc; - struct vcpu *v; - ulong dst; - u64 *ofh_tree; - ulong firmware_base; - uint rma_nrpages = 1 << cpu_default_rma_order_pages(); - ulong rma_sz; - ulong rma; - ulong eomem; - int preempt = 0; - int vcpu; - ulong mod_start = 0; - ulong mod_len = 0; - ulong shared_info_addr; - uint extent_size = 1 << cpu_extent_order(); - ulong sz; - - /* Sanity! */ - BUG_ON(d->domain_id != 0); - - if (image_len == 0) - panic("No Dom0 image supplied\n"); - - printk("*** LOADING DOMAIN 0 ***\n"); - - /* default is the max(1/16th of memory, CONFIG_MIN_DOM0_PAGES) */ - if (dom0_nrpages == 0) { - dom0_nrpages = total_pages >> 4; - - if (dom0_nrpages < CONFIG_MIN_DOM0_PAGES) - dom0_nrpages = CONFIG_MIN_DOM0_PAGES; - } - - /* Dom0 has to be at least RMA size. */ - if (dom0_nrpages < rma_nrpages) { - dom0_nrpages = rma_nrpages; - printk("Increasing DOM0 memory size to %u MiB for RMA.\n", - ((rma_nrpages << PAGE_SHIFT) >> 20)); - } - - /* Ensure Dom0 is cpu_extent_order aligned. Round up if - not and let user know we did so. */ - if (dom0_nrpages != ALIGN_UP(dom0_nrpages, extent_size)) { - dom0_nrpages = ALIGN_UP(dom0_nrpages, extent_size); - printk("Increasing DOM0 memory size to %u MiB for large pages.\n", - ((dom0_nrpages << PAGE_SHIFT) >> 20)); - } - - /* XXX Dom0 currently can't extend past the IO hole. */ - if (dom0_nrpages > (platform_iohole_base() >> PAGE_SHIFT)) { - dom0_nrpages = (platform_iohole_base() >> PAGE_SHIFT); - printk("Limiting DOM0 memory size to %u MiB to avoid IO hole.\n", - ((dom0_nrpages << PAGE_SHIFT) >> 20)); - } - - /* Set Dom0 max mem, triggering p2m table creation. */ - if ((guest_physmap_max_mem_pages(d, dom0_nrpages)) != 0) - panic("Failed to set DOM0 max mem pages value\n"); - - d->max_pages = dom0_nrpages; - if (0 > allocate_rma(d, cpu_default_rma_order_pages())) - panic("Error allocating domain 0 RMA\n"); - - rma_sz = rma_size(d->arch.rma_order); - rma = page_to_maddr(d->arch.rma_page); - - /* If we are bigger than RMA, allocate extents. */ - if (dom0_nrpages > rma_nrpages) - dom0_nrpages = allocate_extents(d, dom0_nrpages, rma_nrpages); - - ASSERT(d->tot_pages == dom0_nrpages); - ASSERT(d->tot_pages >= rma_nrpages); - - if (opt_dom0_shadow == 0) { - /* 1/64 of memory */ - opt_dom0_shadow = (d->tot_pages >> 6) >> (20 - PAGE_SHIFT); - } - - do { - shadow_set_allocation(d, opt_dom0_shadow, &preempt); - } while (preempt); - if (shadow_get_allocation(d) == 0) - panic("shadow allocation failed: %dMib\n", opt_dom0_shadow); - - ASSERT( image_len < rma_sz ); - - eomem = ((ulong)d->shared_info) - rma; - printk("shared_info: 0x%lx,%p\n", eomem, d->shared_info); - - /* startup secondary processors */ - if ( opt_dom0_max_vcpus == 0 ) - opt_dom0_max_vcpus = num_online_cpus(); - if ( opt_dom0_max_vcpus > num_online_cpus() ) - opt_dom0_max_vcpus = num_online_cpus(); - if ( opt_dom0_max_vcpus > MAX_VIRT_CPUS ) - opt_dom0_max_vcpus = MAX_VIRT_CPUS; -#ifdef BITS_PER_GUEST_LONG - if ( opt_dom0_max_vcpus > BITS_PER_GUEST_LONG(d) ) - opt_dom0_max_vcpus = BITS_PER_GUEST_LONG(d); -#endif - printk("Dom0 has maximum %u VCPUs\n", opt_dom0_max_vcpus); - - for (vcpu = 0; vcpu < opt_dom0_max_vcpus; vcpu++) { - if (NULL == alloc_vcpu(dom0, vcpu, vcpu)) - panic("Error creating domain 0 vcpu %d\n", vcpu); - /* for now we pin Dom0 VCPUs to their coresponding CPUs */ - if (cpu_isset(vcpu, cpu_online_map)) - dom0->vcpu[vcpu]->cpu_affinity = cpumask_of_cpu(vcpu); - } - - /* Init VCPU0. */ - v = d->vcpu[0]; - cpu_init_vcpu(v); - - /* convert xen pointer shared_info into guest physical */ - shared_info_addr = (ulong)d->shared_info - page_to_maddr(d->arch.rma_page); - - /* start loading stuff */ - rc = elf_init(&elf, (void *)image_start, image_len); - if (rc) - return rc; -#ifdef VERBOSE - elf_set_verbose(&elf); -#endif - elf_parse_binary(&elf); - if (0 != (elf_xen_parse(&elf, &parms))) - return rc; - - printk("Dom0 kernel: %s, paddr 0x%" PRIx64 " -> 0x%" PRIx64 "\n", - elf_64bit(&elf) ? "64-bit" : "32-bit", - elf.pstart, elf.pend); - - /* elf contains virtual addresses that can have the upper bits - * masked while running in real mode, so we do the masking as well - * as well */ - parms.virt_kend = RM_MASK(parms.virt_kend, 42); - parms.virt_entry = RM_MASK(parms.virt_entry, 42); - - /* set the MSR bit correctly */ - if (elf_64bit(&elf)) - v->arch.ctxt.msr = MSR_SF; - else - v->arch.ctxt.msr = 0; - - /* Load the dom0 kernel. */ - elf.dest = (void *)(parms.virt_kstart + rma); - - elf_load_binary(&elf); - v->arch.ctxt.pc = parms.virt_entry; - - dst = ALIGN_UP(parms.virt_kend + rma, PAGE_SIZE); - - /* Load the initrd. */ - if (initrd_len > 0) { - ASSERT((dst - rma) + image_len < eomem); - - printk("loading initrd: 0x%lx, 0x%lx\n", dst, initrd_len); - memcpy((void *)dst, (void *)initrd_start, initrd_len); - - mod_start = dst - rma; - mod_len = image_len; - - dst = ALIGN_UP(dst + initrd_len, PAGE_SIZE); - } else { - printk("no initrd\n"); - } - - v->arch.ctxt.gprs[3] = mod_start; - v->arch.ctxt.gprs[4] = mod_len; - - /* OF usually sits here: - * - Linux needs it to be loaded before the vmlinux or initrd - * - AIX demands it to be @ 32M. - */ - firmware_base = (32 << 20); - if (dst - rma > firmware_base) - panic("Firmware [0x%lx] will over-write images ending: 0x%lx\n", - firmware_base, dst - rma); - dst = firmware_base + rma; - - /* Put stack below firmware. */ - v->arch.ctxt.gprs[1] = dst - rma - STACK_FRAME_OVERHEAD; - v->arch.ctxt.gprs[2] = 0; - - ASSERT((dst - rma) + (ulong)firmware_image_size < eomem); - printk("loading OFH: 0x%lx, RMA: 0x%lx\n", dst, dst - rma); - memcpy((void *)dst, firmware_image_start, (ulong)firmware_image_size); - - v->arch.ctxt.gprs[5] = (dst - rma); - ofh_tree = (u64 *)(dst + 0x10); - ASSERT(*ofh_tree == 0xdeadbeef00000000); - - /* accomodate for a modest bss section */ - dst = ALIGN_UP(dst + (ulong)firmware_image_size + PAGE_SIZE, PAGE_SIZE); - - ASSERT((dst - rma) + oftree_len < eomem); - - *ofh_tree = dst - rma; - printk("loading OFD: 0x%lx RMA: 0x%lx, 0x%lx\n", dst, dst - rma, - oftree_len); - memcpy((void *)dst, (void *)oftree, oftree_len); - - /* fixup and add stuff for dom0 */ - sz = ofd_dom0_fixup(d, *ofh_tree + rma, cmdline, shared_info_addr); - printk("modified OFD size: 0x%lx\n", sz); - dst = ALIGN_UP(dst + sz + PAGE_SIZE, PAGE_SIZE); - - printk("dom0 initial register state:\n" - " pc %016lx msr %016lx\n" - " r1 %016lx r2 %016lx r3 %016lx\n" - " r4 %016lx r5 %016lx\n", - v->arch.ctxt.pc, - v->arch.ctxt.msr, - v->arch.ctxt.gprs[1], - v->arch.ctxt.gprs[2], - v->arch.ctxt.gprs[3], - v->arch.ctxt.gprs[4], - v->arch.ctxt.gprs[5]); - - v->is_initialised = 1; - clear_bit(_VPF_down, &v->pause_flags); - - rc = 0; - - /* DOM0 is permitted full I/O capabilities. */ - rc |= iomem_permit_access(dom0, 0UL, ~0UL); - rc |= irqs_permit_access(dom0, 0, NR_IRQS-1); - - BUG_ON(rc != 0); - - return 0; -} diff -r ef290f39ae6b -r c96507e0c83d xen/arch/powerpc/domctl.c --- a/xen/arch/powerpc/domctl.c Thu May 15 14:53:48 2008 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,120 +0,0 @@ -/* - * 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. _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |