direct-io.hg

changeset 8429:5a790011259e

Merge
author djm@kirby.fc.hp.com
date Wed Dec 21 11:56:19 2005 -0600 (2005-12-21)
parents 2c75070e41a0 c259492dfb43
children 9b108cf447e5
files
line diff
     1.1 --- a/Makefile	Wed Dec 21 10:30:10 2005 -0600
     1.2 +++ b/Makefile	Wed Dec 21 11:56:19 2005 -0600
     1.3 @@ -10,7 +10,7 @@ XKERNELS := $(foreach kernel, $(KERNELS)
     1.4  # Export target architecture overrides to Xen and Linux sub-trees.
     1.5  ifneq ($(XEN_TARGET_ARCH),)
     1.6  SUBARCH := $(subst x86_32,i386,$(XEN_TARGET_ARCH))
     1.7 -export XEN_TARGET_ARCH SUBARCH
     1.8 +export XEN_TARGET_ARCH SUBARCH XEN_SYSTYPE
     1.9  endif
    1.10  
    1.11  # Default target must appear before any include lines
     2.1 --- a/buildconfigs/mk.linux-2.6-xen	Wed Dec 21 10:30:10 2005 -0600
     2.2 +++ b/buildconfigs/mk.linux-2.6-xen	Wed Dec 21 11:56:19 2005 -0600
     2.3 @@ -30,7 +30,7 @@ build: $(LINUX_DIR)/include/linux/autoco
     2.4  	CONFIG_VERSION=$$(sed -ne 's/^EXTRAVERSION = //p' $(LINUX_DIR)/Makefile); \
     2.5  	[ -r $(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) ] && \
     2.6  	  cp $(DESTDIR)/boot/config-$(LINUX_VER)$$CONFIG_VERSION-$(EXTRAVERSION) $(LINUX_DIR)/.config \
     2.7 -	  || cp $(LINUX_DIR)/arch/xen/configs/$(EXTRAVERSION)_defconfig_$(XEN_TARGET_ARCH) \
     2.8 +	  || cp $(LINUX_DIR)/arch/xen/configs/$(EXTRAVERSION)_defconfig_$(XEN_TARGET_ARCH)$(XEN_SYSTYPE) \
     2.9  		$(LINUX_DIR)/.config
    2.10  	# See if we need to munge config to enable PAE
    2.11  	$(MAKE) CONFIG_FILE=$(LINUX_DIR)/.config -f buildconfigs/Rules.mk config-update-pae
     3.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/acpi/boot.c	Wed Dec 21 10:30:10 2005 -0600
     3.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/acpi/boot.c	Wed Dec 21 11:56:19 2005 -0600
     3.3 @@ -660,8 +660,6 @@ acpi_find_rsdp (void)
     3.4  	if (!rsdp_phys)
     3.5  		rsdp_phys = acpi_scan_rsdp (0xE0000, 0x20000);
     3.6  
     3.7 -	set_fixmap(FIX_ACPI_RSDP_PAGE, rsdp_phys);
     3.8 -
     3.9  	return rsdp_phys;
    3.10  }
    3.11  
     4.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c	Wed Dec 21 10:30:10 2005 -0600
     4.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/ldt.c	Wed Dec 21 11:56:19 2005 -0600
     4.3 @@ -186,8 +186,7 @@ static int read_default_ldt(void __user 
     4.4  static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
     4.5  {
     4.6  	struct mm_struct * mm = current->mm;
     4.7 -	__u32 entry_1, entry_2, *lp;
     4.8 -	maddr_t mach_lp;
     4.9 +	__u32 entry_1, entry_2;
    4.10  	int error;
    4.11  	struct user_desc ldt_info;
    4.12  
    4.13 @@ -215,9 +214,6 @@ static int write_ldt(void __user * ptr, 
    4.14  			goto out_unlock;
    4.15  	}
    4.16  
    4.17 -	lp = (__u32 *) ((ldt_info.entry_number << 3) + (char *) mm->context.ldt);
    4.18 -	mach_lp = arbitrary_virt_to_machine(lp);
    4.19 -
    4.20     	/* Allow LDTs to be cleared by the user. */
    4.21     	if (ldt_info.base_addr == 0 && ldt_info.limit == 0) {
    4.22  		if (oldmode || LDT_empty(&ldt_info)) {
    4.23 @@ -234,8 +230,8 @@ static int write_ldt(void __user * ptr, 
    4.24  
    4.25  	/* Install the new entry ...  */
    4.26  install:
    4.27 -	error = HYPERVISOR_update_descriptor(
    4.28 -		mach_lp, (u64)entry_1 | ((u64)entry_2<<32));
    4.29 +	error = write_ldt_entry(mm->context.ldt, ldt_info.entry_number,
    4.30 +				entry_1, entry_2);
    4.31  
    4.32  out_unlock:
    4.33  	up(&mm->context.sem);
     5.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c	Wed Dec 21 10:30:10 2005 -0600
     5.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/swiotlb.c	Wed Dec 21 11:56:19 2005 -0600
     5.3 @@ -24,6 +24,7 @@
     5.4  #include <asm/io.h>
     5.5  #include <asm/pci.h>
     5.6  #include <asm/dma.h>
     5.7 +#include <asm/uaccess.h>
     5.8  #include <asm-xen/xen-public/memory.h>
     5.9  
    5.10  #define OFFSET(val,align) ((unsigned long)((val) & ( (align) - 1)))
    5.11 @@ -201,6 +202,12 @@ swiotlb_init(void)
    5.12  		printk(KERN_INFO "Software IO TLB disabled\n");
    5.13  }
    5.14  
    5.15 +/*
    5.16 + * We use __copy_to_user to transfer to the host buffer because the buffer
    5.17 + * may be mapped read-only (e.g, in blkback driver) but lower-level
    5.18 + * drivers map the buffer for DMA_BIDIRECTIONAL access. This causes an
    5.19 + * unnecessary copy from the aperture to the host buffer, and a page fault.
    5.20 + */
    5.21  static void
    5.22  __sync_single(struct phys_addr buffer, char *dma_addr, size_t size, int dir)
    5.23  {
    5.24 @@ -214,9 +221,11 @@ static void
    5.25  			kmp  = kmap_atomic(buffer.page, KM_SWIOTLB);
    5.26  			dev  = dma_addr + size - len;
    5.27  			host = kmp + buffer.offset;
    5.28 -			memcpy((dir == DMA_FROM_DEVICE) ? host : dev,
    5.29 -			       (dir == DMA_FROM_DEVICE) ? dev : host,
    5.30 -			       bytes);
    5.31 +			if (dir == DMA_FROM_DEVICE) {
    5.32 +				if (__copy_to_user(host, dev, bytes))
    5.33 +					/* inaccessible */;
    5.34 +			} else
    5.35 +				memcpy(dev, host, bytes);
    5.36  			kunmap_atomic(kmp, KM_SWIOTLB);
    5.37  			len -= bytes;
    5.38  			buffer.page++;
    5.39 @@ -225,9 +234,10 @@ static void
    5.40  	} else {
    5.41  		char *host = (char *)phys_to_virt(
    5.42  			page_to_pseudophys(buffer.page)) + buffer.offset;
    5.43 -		if (dir == DMA_FROM_DEVICE)
    5.44 -			memcpy(host, dma_addr, size);
    5.45 -		else if (dir == DMA_TO_DEVICE)
    5.46 +		if (dir == DMA_FROM_DEVICE) {
    5.47 +			if (__copy_to_user(host, dma_addr, size))
    5.48 +				/* inaccessible */;
    5.49 +		} else if (dir == DMA_TO_DEVICE)
    5.50  			memcpy(dma_addr, host, size);
    5.51  	}
    5.52  }
     6.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c	Wed Dec 21 10:30:10 2005 -0600
     6.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/hypervisor.c	Wed Dec 21 11:56:19 2005 -0600
     6.3 @@ -438,6 +438,16 @@ void xen_destroy_contiguous_region(unsig
     6.4  	balloon_unlock(flags);
     6.5  }
     6.6  
     6.7 +#ifdef __i386__
     6.8 +int write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b)
     6.9 +{
    6.10 +	__u32 *lp = (__u32 *)((char *)ldt + entry * 8);
    6.11 +	maddr_t mach_lp = arbitrary_virt_to_machine(lp);
    6.12 +	return HYPERVISOR_update_descriptor(
    6.13 +		mach_lp, (u64)entry_a | ((u64)entry_b<<32));
    6.14 +}
    6.15 +#endif
    6.16 +
    6.17  /*
    6.18   * Local variables:
    6.19   *  c-file-style: "linux"
     7.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Wed Dec 21 10:30:10 2005 -0600
     7.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c	Wed Dec 21 11:56:19 2005 -0600
     7.3 @@ -163,11 +163,10 @@ asmlinkage void evtchn_do_upcall(struct 
     7.4  	while (l1 != 0) {
     7.5  		l1i = __ffs(l1);
     7.6  		l1 &= ~(1UL << l1i);
     7.7 -        
     7.8 +
     7.9  		while ((l2 = active_evtchns(cpu, s, l1i)) != 0) {
    7.10  			l2i = __ffs(l2);
    7.11 -			l2 &= ~(1UL << l2i);
    7.12 -            
    7.13 +
    7.14  			port = (l1i * BITS_PER_LONG) + l2i;
    7.15  			if ((irq = evtchn_to_irq[port]) != -1)
    7.16  				do_IRQ(irq, regs);
     8.1 --- a/linux-2.6-xen-sparse/drivers/acpi/tables.c	Wed Dec 21 10:30:10 2005 -0600
     8.2 +++ b/linux-2.6-xen-sparse/drivers/acpi/tables.c	Wed Dec 21 11:56:19 2005 -0600
     8.3 @@ -566,8 +566,7 @@ acpi_table_get_sdt (
     8.4   * result: sdt_entry[] is initialized
     8.5   */
     8.6  #if defined(CONFIG_XEN_X86) || defined(CONFIG_XEN_X86_64)
     8.7 -#define acpi_rsdp_phys_to_va(rsdp_phys) (__fix_to_virt(FIX_ACPI_RSDP_PAGE) + \
     8.8 -					   (rsdp_phys & ~PAGE_MASK))
     8.9 +#define acpi_rsdp_phys_to_va(rsdp_phys) isa_bus_to_virt(rsdp_phys)
    8.10  #else
    8.11  #define acpi_rsdp_phys_to_va(rsdp_phys) __va(rsdp_phys)
    8.12  #endif
     9.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c	Wed Dec 21 10:30:10 2005 -0600
     9.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c	Wed Dec 21 11:56:19 2005 -0600
     9.3 @@ -628,6 +628,7 @@ static int __init xencons_init(void)
     9.4  	if (xencons_driver == NULL)
     9.5  		return -ENOMEM;
     9.6  
     9.7 +	DRV(xencons_driver)->name            = "xencons";
     9.8  	DRV(xencons_driver)->major           = TTY_MAJOR;
     9.9  	DRV(xencons_driver)->type            = TTY_DRIVER_TYPE_SERIAL;
    9.10  	DRV(xencons_driver)->subtype         = SERIAL_TYPE_NORMAL;
    10.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Wed Dec 21 10:30:10 2005 -0600
    10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c	Wed Dec 21 11:56:19 2005 -0600
    10.3 @@ -315,15 +315,16 @@ static void otherend_changed(struct xenb
    10.4  static int talk_to_otherend(struct xenbus_device *dev)
    10.5  {
    10.6  	struct xenbus_driver *drv = to_xenbus_driver(dev->dev.driver);
    10.7 -	int err;
    10.8  
    10.9  	free_otherend_watch(dev);
   10.10  	free_otherend_details(dev);
   10.11  
   10.12 -	err = drv->read_otherend_details(dev);
   10.13 -	if (err)
   10.14 -		return err;
   10.15 +	return drv->read_otherend_details(dev);
   10.16 +}
   10.17  
   10.18 +
   10.19 +static int watch_otherend(struct xenbus_device *dev)
   10.20 +{
   10.21  	return xenbus_watch_path2(dev, dev->otherend, "state",
   10.22  				  &dev->otherend_watch, otherend_changed);
   10.23  }
   10.24 @@ -338,14 +339,6 @@ static int xenbus_dev_probe(struct devic
   10.25  
   10.26  	DPRINTK("");
   10.27  
   10.28 -	err = talk_to_otherend(dev);
   10.29 -	if (err) {
   10.30 -		printk(KERN_WARNING
   10.31 -		       "xenbus_probe: talk_to_otherend on %s failed.\n",
   10.32 -		       dev->nodename);
   10.33 -		return err;
   10.34 -	}
   10.35 -
   10.36  	if (!drv->probe) {
   10.37  		err = -ENODEV;
   10.38  		goto fail;
   10.39 @@ -357,10 +350,26 @@ static int xenbus_dev_probe(struct devic
   10.40  		goto fail;
   10.41  	}
   10.42  
   10.43 +	err = talk_to_otherend(dev);
   10.44 +	if (err) {
   10.45 +		printk(KERN_WARNING
   10.46 +		       "xenbus_probe: talk_to_otherend on %s failed.\n",
   10.47 +		       dev->nodename);
   10.48 +		return err;
   10.49 +	}
   10.50 +
   10.51  	err = drv->probe(dev, id);
   10.52  	if (err)
   10.53  		goto fail;
   10.54  
   10.55 +	err = watch_otherend(dev);
   10.56 +	if (err) {
   10.57 +		printk(KERN_WARNING
   10.58 +		       "xenbus_probe: watch_otherend on %s failed.\n",
   10.59 +		       dev->nodename);
   10.60 +		return err;
   10.61 +	}
   10.62 +
   10.63  	return 0;
   10.64  fail:
   10.65  	xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
   10.66 @@ -826,6 +835,14 @@ static int resume_dev(struct device *dev
   10.67  		return err;
   10.68  	}
   10.69  
   10.70 +	err = watch_otherend(xdev);
   10.71 +	if (err) {
   10.72 +		printk(KERN_WARNING
   10.73 +		       "xenbus_probe: resume (watch_otherend) %s failed: "
   10.74 +		       "%d.\n", dev->bus_id, err);
   10.75 +		return err;
   10.76 +	}
   10.77 +
   10.78  	if (drv->resume)
   10.79  		err = drv->resume(xdev);
   10.80  	if (err)
    11.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/desc.h	Wed Dec 21 10:30:10 2005 -0600
    11.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/desc.h	Wed Dec 21 11:56:19 2005 -0600
    11.3 @@ -87,6 +87,8 @@ static inline void set_ldt_desc(unsigned
    11.4  	(info)->seg_not_present	== 1	&& \
    11.5  	(info)->useable		== 0	)
    11.6  
    11.7 +extern int write_ldt_entry(void *ldt, int entry, __u32 entry_a, __u32 entry_b);
    11.8 +
    11.9  #if TLS_SIZE != 24
   11.10  # error update this code.
   11.11  #endif
    12.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/fixmap.h	Wed Dec 21 10:30:10 2005 -0600
    12.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/fixmap.h	Wed Dec 21 11:56:19 2005 -0600
    12.3 @@ -80,7 +80,6 @@ enum fixed_addresses {
    12.4  #ifdef CONFIG_ACPI_BOOT
    12.5  	FIX_ACPI_BEGIN,
    12.6  	FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
    12.7 -	FIX_ACPI_RSDP_PAGE,
    12.8  #endif
    12.9  #ifdef CONFIG_PCI_MMCONFIG
   12.10  	FIX_PCIE_MCFG,
    13.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/io.h	Wed Dec 21 10:30:10 2005 -0600
    13.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/io.h	Wed Dec 21 11:56:19 2005 -0600
    13.3 @@ -309,15 +309,8 @@ static inline void flush_write_buffers(v
    13.4  
    13.5  #ifdef SLOW_IO_BY_JUMPING
    13.6  #define __SLOW_DOWN_IO "jmp 1f; 1: jmp 1f; 1:"
    13.7 -#elif defined(__UNSAFE_IO__)
    13.8 +#else
    13.9  #define __SLOW_DOWN_IO "outb %%al,$0x80;"
   13.10 -#else
   13.11 -#define __SLOW_DOWN_IO "\n1: outb %%al,$0x80\n"		\
   13.12 -		       "2:\n"				\
   13.13 -		       ".section __ex_table,\"a\"\n\t"	\
   13.14 -		       ".align 4\n\t"			\
   13.15 -		       ".long 1b,2b\n"			\
   13.16 -		       ".previous"
   13.17  #endif
   13.18  
   13.19  static inline void slow_down_io(void) {
   13.20 @@ -362,8 +355,7 @@ static inline unsigned type in##bwl(int 
   13.21  #endif
   13.22  
   13.23  
   13.24 -#if __UNSAFE_IO__
   13.25 -#define ____BUILDIO(bwl,bw,type) \
   13.26 +#define BUILDIO(bwl,bw,type) \
   13.27  static inline void out##bwl##_local(unsigned type value, int port) { \
   13.28  	__asm__ __volatile__("out" #bwl " %" #bw "0, %w1" : : "a"(value), "Nd"(port)); \
   13.29  } \
   13.30 @@ -371,35 +363,7 @@ static inline unsigned type in##bwl##_lo
   13.31  	unsigned type value; \
   13.32  	__asm__ __volatile__("in" #bwl " %w1, %" #bw "0" : "=a"(value) : "Nd"(port)); \
   13.33  	return value; \
   13.34 -}
   13.35 -#else
   13.36 -#define ____BUILDIO(bwl,bw,type) \
   13.37 -static inline void out##bwl##_local(unsigned type value, int port) { \
   13.38 -	__asm__ __volatile__("1: out" #bwl " %" #bw "0, %w1\n"		\
   13.39 -			     "2:\n"					\
   13.40 -			     ".section __ex_table,\"a\"\n\t"		\
   13.41 -			     ".align 4\n\t"				\
   13.42 -			     ".long 1b,2b\n"				\
   13.43 -			     ".previous" : : "a"(value), "Nd"(port));	\
   13.44  } \
   13.45 -static inline unsigned type in##bwl##_local(int port) { \
   13.46 -	unsigned type value; \
   13.47 -	__asm__ __volatile__("1:in" #bwl " %w1, %" #bw "0\n"		\
   13.48 -			     "2:\n"					\
   13.49 -			     ".section .fixup,\"ax\"\n"			\
   13.50 -			     "3: mov" #bwl " $~0,%" #bw "0\n\t"		\
   13.51 -			     "jmp 2b\n"					\
   13.52 -			     ".previous\n"				\
   13.53 -			     ".section __ex_table,\"a\"\n\t"		\
   13.54 -			     ".align 4\n\t"				\
   13.55 -			     ".long 1b,3b\n"				\
   13.56 -			     ".previous" : "=a"(value) : "Nd"(port));	\
   13.57 -	return value; \
   13.58 -}
   13.59 -#endif
   13.60 -
   13.61 -#define BUILDIO(bwl,bw,type) \
   13.62 -____BUILDIO(bwl,bw,type) \
   13.63  static inline void out##bwl##_local_p(unsigned type value, int port) { \
   13.64  	out##bwl##_local(value, port); \
   13.65  	slow_down_io(); \
    14.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/fixmap.h	Wed Dec 21 10:30:10 2005 -0600
    14.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/fixmap.h	Wed Dec 21 11:56:19 2005 -0600
    14.3 @@ -50,7 +50,6 @@ enum fixed_addresses {
    14.4  #ifdef CONFIG_ACPI_BOOT
    14.5  	FIX_ACPI_BEGIN,
    14.6  	FIX_ACPI_END = FIX_ACPI_BEGIN + FIX_ACPI_PAGES - 1,
    14.7 -	FIX_ACPI_RSDP_PAGE,
    14.8  #endif
    14.9  	FIX_SHARED_INFO,
   14.10  	FIX_GNTTAB_BEGIN,
    15.1 --- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c	Wed Dec 21 10:30:10 2005 -0600
    15.2 +++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c	Wed Dec 21 11:56:19 2005 -0600
    15.3 @@ -36,23 +36,41 @@
    15.4  #include <unistd.h>
    15.5  #include <errno.h>
    15.6  #include <xenctrl.h>
    15.7 +#include <thread_db.h>
    15.8 +#include <xc_ptrace.h>
    15.9 +
   15.10  #define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */
   15.11  
   15.12  long (*myptrace)(int xc_handle, enum __ptrace_request, uint32_t, long, long);
   15.13  int (*myxcwait)(int xc_handle, int domain, int *status, int options) ;
   15.14  static int xc_handle;
   15.15  
   15.16 +static inline int
   15.17 +curvcpuid()
   15.18 +{
   15.19 +  struct process_info *process;
   15.20 +  if (current_inferior == NULL)
   15.21 +      return 0;
   15.22 +  process = get_thread_process(current_inferior);
   15.23 +  return (process->thread_known ? process->tid : 0);
   15.24 +
   15.25 +}
   15.26 +
   15.27 +
   15.28  #define DOMFLAGS_DYING     (1<<0) /* Domain is scheduled to die.             */
   15.29  #define DOMFLAGS_SHUTDOWN  (1<<2) /* The guest OS has shut down.             */
   15.30  #define DOMFLAGS_PAUSED    (1<<3) /* Currently paused by control software.   */
   15.31  #define DOMFLAGS_BLOCKED   (1<<4) /* Currently blocked pending an event.     */
   15.32  #define DOMFLAGS_RUNNING   (1<<5) /* Domain is currently running.            */
   15.33  
   15.34 +
   15.35 +
   15.36  struct inferior_list all_processes;
   15.37 -static int current_domain;
   15.38 +static int current_domid;
   15.39  static int expect_signal = 0;
   15.40  static int signal_to_send = 0; 
   15.41  static void linux_resume (struct thread_resume *resume_info);
   15.42 +static void linux_set_inferior (void);
   15.43  
   15.44  int debug_threads;
   15.45  int using_threads;
   15.46 @@ -96,7 +114,6 @@ static int use_regsets_p = 1;
   15.47     point at the following instruction.  If we continue and hit a
   15.48     breakpoint instruction, our PC will point at the breakpoint
   15.49     instruction.  */
   15.50 -#if 0
   15.51  static CORE_ADDR
   15.52  get_stop_pc (void)
   15.53  {
   15.54 @@ -107,9 +124,9 @@ get_stop_pc (void)
   15.55    else
   15.56      return stop_pc - the_low_target.decr_pc_after_break;
   15.57  }
   15.58 -#endif
   15.59 +
   15.60  static void *
   15.61 -add_process (int pid)
   15.62 +add_process (int pid, long tid)
   15.63  {
   15.64    struct process_info *process;
   15.65  
   15.66 @@ -118,9 +135,8 @@ add_process (int pid)
   15.67  
   15.68    process->head.id = pid;
   15.69  
   15.70 -  /* Default to tid == lwpid == pid.  */
   15.71 -  process->tid = pid;
   15.72 -  process->lwpid = pid;
   15.73 +  process->tid = tid;
   15.74 +  process->lwpid = tid;
   15.75  
   15.76    add_inferior_to_list (&all_processes, &process->head);
   15.77  
   15.78 @@ -143,23 +159,25 @@ linux_create_inferior (char *program, ch
   15.79  }
   15.80  
   15.81  int
   15.82 -linux_attach (int domain)
   15.83 +linux_attach (int domid)
   15.84  {
   15.85      struct process_info *new_process;
   15.86 -    current_domain = domain;
   15.87 -    if (myptrace (xc_handle, PTRACE_ATTACH, domain, 0, 0) != 0) {
   15.88 -	fprintf (stderr, "Cannot attach to domain %d: %s (%d)\n", domain,
   15.89 +    current_domid = domid;
   15.90 +    /* this is handled for all active vcpus in PTRACE_ATTACH via the thread_create_callback */
   15.91 +    new_process = (struct process_info *) add_process (domid, curvcpuid());
   15.92 +    /* Don't ignore the initial SIGSTOP if we just attached to this process.  */
   15.93 +    /* vcpuid == 0 */
   15.94 +    add_thread (0, new_process);
   15.95 +    new_process->stop_expected = 0;
   15.96 +
   15.97 +    if (myptrace (xc_handle, PTRACE_ATTACH, domid, 0, 0) != 0) {
   15.98 +	fprintf (stderr, "Cannot attach to domain %d: %s (%d)\n", domid,
   15.99  		 strerror (errno), errno);
  15.100  	fflush (stderr);
  15.101 -	_exit (0177);
  15.102 +	if (!using_threads)
  15.103 +	    _exit (0177);
  15.104      }
  15.105 -    
  15.106 -    new_process = (struct process_info *) add_process (domain);
  15.107 -    add_thread (domain, new_process);
  15.108  
  15.109 -    /* Don't ignore the initial SIGSTOP if we just attached to this process.  */
  15.110 -    new_process->stop_expected = 0;
  15.111 -    
  15.112      return 0;
  15.113  }
  15.114  
  15.115 @@ -173,20 +191,18 @@ linux_kill_one_process (struct inferior_
  15.116    myptrace (xc_handle, PTRACE_KILL, pid_of (process), 0, 0);
  15.117  }
  15.118  
  15.119 +
  15.120  static void
  15.121  linux_kill (void)
  15.122  {
  15.123    for_each_inferior (&all_threads, linux_kill_one_process);
  15.124  }
  15.125  
  15.126 -
  15.127  static void
  15.128  linux_detach_one_process (struct inferior_list_entry *entry)
  15.129  {
  15.130 -  struct thread_info *thread = (struct thread_info *) entry;
  15.131 -  struct process_info *process = get_thread_process (thread);
  15.132  
  15.133 -  myptrace (xc_handle, PTRACE_DETACH, pid_of (process), 0, 0);
  15.134 +  myptrace (xc_handle, PTRACE_DETACH, current_domid, 0, 0);
  15.135  }
  15.136  
  15.137  
  15.138 @@ -212,14 +228,10 @@ static unsigned char
  15.139  linux_wait (char *status)
  15.140  {
  15.141    int w;
  15.142 -  if (myxcwait(xc_handle, current_domain, &w, 0))
  15.143 +  if (myxcwait(xc_handle, current_domid, &w, 0))
  15.144        return -1;
  15.145    
  15.146 -  if (w & (DOMFLAGS_SHUTDOWN|DOMFLAGS_DYING)) {
  15.147 -      *status = 'W';
  15.148 -      return 0;
  15.149 -  }
  15.150 -
  15.151 +  linux_set_inferior();
  15.152  
  15.153    *status = 'T';
  15.154    if (expect_signal)
  15.155 @@ -236,8 +248,10 @@ linux_resume (struct thread_resume *resu
  15.156    TRACE_ENTER;
  15.157    expect_signal = resume_info->sig;
  15.158    for_each_inferior(&all_threads, regcache_invalidate_one);
  15.159 -
  15.160 -  myptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT, current_domain, 0, 0);
  15.161 +  if (debug_threads)
  15.162 +    fprintf(stderr, "step: %d\n", step);
  15.163 +  myptrace (xc_handle, step ? PTRACE_SINGLESTEP : PTRACE_CONT, 
  15.164 +	    resume_info->thread, 0, 0);
  15.165  
  15.166  }
  15.167  
  15.168 @@ -261,7 +275,9 @@ regsets_fetch_inferior_registers ()
  15.169  	}
  15.170  
  15.171        buf = malloc (regset->size);
  15.172 -      res = myptrace (xc_handle, regset->get_request, inferior_pid, 0, (PTRACE_XFER_TYPE)buf);
  15.173 +      res = myptrace (xc_handle, regset->get_request, 
  15.174 +		      curvcpuid(),
  15.175 +		      0, (PTRACE_XFER_TYPE)buf);
  15.176        if (res < 0)
  15.177  	{
  15.178  	  if (errno == EIO)
  15.179 @@ -313,7 +329,7 @@ regsets_store_inferior_registers ()
  15.180  
  15.181        buf = malloc (regset->size);
  15.182        regset->fill_function (buf);
  15.183 -      res = myptrace (xc_handle, regset->set_request, inferior_pid, 0, (PTRACE_XFER_TYPE)buf);
  15.184 +      res = myptrace (xc_handle, regset->set_request, curvcpuid(), 0, (PTRACE_XFER_TYPE)buf);
  15.185        if (res < 0)
  15.186  	{
  15.187  	  if (errno == EIO)
  15.188 @@ -391,7 +407,7 @@ linux_read_memory (CORE_ADDR memaddr, ch
  15.189    for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
  15.190      {
  15.191        errno = 0;
  15.192 -      buffer[i] = myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, 0);
  15.193 +      buffer[i] = myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(), (PTRACE_ARG3_TYPE) addr, 0);
  15.194        if (errno)
  15.195  	return errno;
  15.196      }
  15.197 @@ -424,13 +440,13 @@ linux_write_memory (CORE_ADDR memaddr, c
  15.198  
  15.199    /* Fill start and end extra bytes of buffer with existing memory data.  */
  15.200  
  15.201 -  buffer[0] = myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid,
  15.202 +  buffer[0] = myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
  15.203  		      (PTRACE_ARG3_TYPE) addr, 0);
  15.204  
  15.205    if (count > 1)
  15.206      {
  15.207        buffer[count - 1]
  15.208 -	= myptrace (xc_handle, PTRACE_PEEKTEXT, inferior_pid,
  15.209 +	= myptrace (xc_handle, PTRACE_PEEKTEXT, curvcpuid(),
  15.210  		  (PTRACE_ARG3_TYPE) (addr + (count - 1)
  15.211  				      * sizeof (PTRACE_XFER_TYPE)),
  15.212  		  0);
  15.213 @@ -444,7 +460,8 @@ linux_write_memory (CORE_ADDR memaddr, c
  15.214    for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE))
  15.215      {
  15.216        errno = 0;
  15.217 -      myptrace (xc_handle, PTRACE_POKETEXT, inferior_pid, (PTRACE_ARG3_TYPE) addr, buffer[i]);
  15.218 +      myptrace (xc_handle, PTRACE_POKETEXT, curvcpuid(), 
  15.219 +		(PTRACE_ARG3_TYPE) addr, buffer[i]);
  15.220        if (errno)
  15.221  	return errno;
  15.222      }
  15.223 @@ -455,9 +472,11 @@ linux_write_memory (CORE_ADDR memaddr, c
  15.224  static void
  15.225  linux_look_up_symbols (void)
  15.226  {
  15.227 -#if 0
  15.228 +  if (using_threads) 
  15.229 +    return;
  15.230 +
  15.231    using_threads = thread_db_init ();
  15.232 -#endif
  15.233 +
  15.234  }
  15.235  
  15.236  static void
  15.237 @@ -535,6 +554,7 @@ linux_init_signals ()
  15.238  void
  15.239  initialize_low (void)
  15.240  {
  15.241 +  using_threads = 0;
  15.242    xc_handle = xc_interface_open();
  15.243    set_target_ops (&linux_xen_target_ops);
  15.244    set_breakpoint_data (the_low_target.breakpoint,
  15.245 @@ -548,5 +568,122 @@ initialize_low (void)
  15.246        myptrace = xc_ptrace;
  15.247        myxcwait = xc_waitdomain;
  15.248    }
  15.249 +  using_threads = thread_db_init ();
  15.250  
  15.251  }
  15.252 +
  15.253 +
  15.254 +static void
  15.255 +thread_create_callback(long vcpuid)
  15.256 +{
  15.257 +  struct thread_info *inferior;
  15.258 +  struct process_info *process;
  15.259 +
  15.260 +  /*  If we are attaching to our first thread, things are a little
  15.261 +   *  different.  
  15.262 +   */
  15.263 +  if (all_threads.head == all_threads.tail)
  15.264 +    {
  15.265 +      inferior = (struct thread_info *) all_threads.head;
  15.266 +      process = get_thread_process (inferior);
  15.267 +      if (process->thread_known == 0)
  15.268 +	{
  15.269 +	  /* Switch to indexing the threads list by TID.  */
  15.270 +	  change_inferior_id (&all_threads, vcpuid);
  15.271 +	  goto found;
  15.272 +	}
  15.273 +    }
  15.274 +  if (debug_threads)
  15.275 +    fprintf (stderr, "looking up thread %ld\n",
  15.276 +	     vcpuid);
  15.277 +  inferior = (struct thread_info *) find_inferior_id (&all_threads,
  15.278 +						      vcpuid);
  15.279 +  /* if vcpu alread registered - do nothing */
  15.280 +  if (inferior != NULL) 
  15.281 +    return;
  15.282 +
  15.283 +  if (debug_threads)
  15.284 +    fprintf (stderr, "Attaching to thread %ld\n",
  15.285 +	     vcpuid);
  15.286 +
  15.287 +  process = add_process(current_domid, vcpuid);
  15.288 +
  15.289 +  add_thread(vcpuid, process);
  15.290 +  inferior = (struct thread_info *) find_inferior_id (&all_threads,
  15.291 +						      vcpuid);
  15.292 +  if (inferior == NULL)
  15.293 +    {
  15.294 +      warning ("Could not attach to thread %ld\n",
  15.295 +	       vcpuid);
  15.296 +      return;
  15.297 +    }
  15.298 +
  15.299 +
  15.300 +found:
  15.301 +  if (debug_threads)
  15.302 +    fprintf (stderr, "notifying of new thread %ld\n",
  15.303 +	     vcpuid);
  15.304 +  new_thread_notify (vcpuid);
  15.305 +
  15.306 +  process->tid = vcpuid;
  15.307 +  process->lwpid = vcpuid;
  15.308 +
  15.309 +  process->thread_known = 1;
  15.310 +}
  15.311 +
  15.312 +static void
  15.313 +thread_death_callback(long vcpuid)
  15.314 +{
  15.315 +    if (debug_threads)
  15.316 +      fprintf (stderr, "Buuurp...! CPU down event.\n");
  15.317 +}
  15.318 +
  15.319 +int
  15.320 +thread_db_init(void)
  15.321 +{
  15.322 +  debug_threads = 0;
  15.323 +  xc_register_event_handler(thread_create_callback, TD_CREATE);
  15.324 +  xc_register_event_handler(thread_death_callback, TD_DEATH);
  15.325 +  return 1;
  15.326 +}
  15.327 +
  15.328 +/* XXX GAG ME */
  15.329 +static int breakpoint_found;
  15.330 +static void
  15.331 +set_breakpoint_inferior (struct inferior_list_entry *entry)
  15.332 +{
  15.333 +  struct thread_info *thread = (struct thread_info *) entry;
  15.334 +  struct thread_info *saved_inferior = current_inferior;
  15.335 +  CORE_ADDR eip;
  15.336 +  unsigned char buf[2] = {0, 0};
  15.337 +  current_inferior = thread;
  15.338 +  if (!breakpoint_found) {
  15.339 +    eip = get_stop_pc();
  15.340 +    linux_read_memory(eip, buf, 1);
  15.341 +    if (buf[0] == 0xcc) {
  15.342 +      breakpoint_found = 1;
  15.343 +      return;
  15.344 +    }
  15.345 +  } else if (breakpoint_found == 2) {
  15.346 +    if (get_thread_process (current_inferior)->stepping) {
  15.347 +      printf("stepping\n");
  15.348 +      breakpoint_found = 1;
  15.349 +      return;
  15.350 +    } 
  15.351 +  }
  15.352 +  current_inferior = saved_inferior;
  15.353 +
  15.354 +
  15.355 +}
  15.356 +
  15.357 +static void
  15.358 +linux_set_inferior (void)
  15.359 +{
  15.360 +  breakpoint_found = 0;
  15.361 +  for_each_inferior (&all_threads, set_breakpoint_inferior);
  15.362 +  if (!breakpoint_found) {
  15.363 +    breakpoint_found = 2;
  15.364 +    for_each_inferior (&all_threads, set_breakpoint_inferior);
  15.365 +  }
  15.366 +}
  15.367 +
    16.1 --- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/server.c	Wed Dec 21 10:30:10 2005 -0600
    16.2 +++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/server.c	Wed Dec 21 11:56:19 2005 -0600
    16.3 @@ -20,7 +20,7 @@
    16.4     Boston, MA 02111-1307, USA.  */
    16.5  
    16.6  #include "server.h"
    16.7 -
    16.8 +#include "linux-low.h"
    16.9  #include <unistd.h>
   16.10  #include <signal.h>
   16.11  #include <sys/wait.h>
   16.12 @@ -102,7 +102,15 @@ handle_query (char *own_buf)
   16.13        strcpy (own_buf, "OK");
   16.14        return;
   16.15      }
   16.16 +  if (strcmp ("qC", own_buf) == 0)
   16.17 +    {
   16.18 +      struct process_info *process;
   16.19 +      if (current_inferior == NULL)
   16.20 +	return;
   16.21 +      process = get_thread_process(current_inferior);
   16.22 +      sprintf(own_buf, "QC%x", process->thread_known ? process->tid : 0);
   16.23  
   16.24 +    }
   16.25    if (strcmp ("qfThreadInfo", own_buf) == 0)
   16.26      {
   16.27        thread_ptr = all_threads.head;
    17.1 --- a/tools/examples/xend-config.sxp	Wed Dec 21 10:30:10 2005 -0600
    17.2 +++ b/tools/examples/xend-config.sxp	Wed Dec 21 11:56:19 2005 -0600
    17.3 @@ -4,9 +4,9 @@
    17.4  # Xend configuration file.
    17.5  #
    17.6  
    17.7 -# This example configuration is appropriate for an installation that trusts
    17.8 -# only localhost connections, and is otherwise fully functional, with a
    17.9 -# bridged network configuration.
   17.10 +# This example configuration is appropriate for an installation that 
   17.11 +# utilizes a bridged network configuration. Access to xend via http
   17.12 +# is disabled.  
   17.13  
   17.14  # Commented out entries show the default for that entry, unless otherwise
   17.15  # specified.
   17.16 @@ -15,7 +15,6 @@
   17.17  #(loglevel DEBUG)
   17.18  
   17.19  #(xend-http-server no)
   17.20 -(xend-http-server yes)
   17.21  #(xend-unix-server yes)
   17.22  #(xend-relocation-server no)
   17.23  (xend-relocation-server yes)
   17.24 @@ -34,7 +33,7 @@
   17.25  # Specifying 'localhost' prevents remote connections.
   17.26  # Specifying the empty string '' (the default) allows all connections.
   17.27  #(xend-address '')
   17.28 -(xend-address localhost)
   17.29 +#(xend-address localhost)
   17.30  
   17.31  # Address xend should listen on for relocation-socket connections, if
   17.32  # xend-relocation-server is set.
    18.1 --- a/tools/examples/xmexample.vmx	Wed Dec 21 10:30:10 2005 -0600
    18.2 +++ b/tools/examples/xmexample.vmx	Wed Dec 21 11:56:19 2005 -0600
    18.3 @@ -135,7 +135,7 @@ ne2000=0
    18.4  
    18.5  #-----------------------------------------------------------------------------
    18.6  #   enable audio support
    18.7 -#enable-audio=1
    18.8 +#audio=1
    18.9  
   18.10  
   18.11  #-----------------------------------------------------------------------------
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/tools/ioemu/audio/audio.c	Wed Dec 21 11:56:19 2005 -0600
    19.3 @@ -0,0 +1,910 @@
    19.4 +/*
    19.5 + * QEMU Audio subsystem
    19.6 + * 
    19.7 + * Copyright (c) 2003-2004 Vassili Karpov (malc)
    19.8 + * 
    19.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   19.10 + * of this software and associated documentation files (the "Software"), to deal
   19.11 + * in the Software without restriction, including without limitation the rights
   19.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   19.13 + * copies of the Software, and to permit persons to whom the Software is
   19.14 + * furnished to do so, subject to the following conditions:
   19.15 + *
   19.16 + * The above copyright notice and this permission notice shall be included in
   19.17 + * all copies or substantial portions of the Software.
   19.18 + *
   19.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   19.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   19.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   19.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   19.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   19.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   19.25 + * THE SOFTWARE.
   19.26 + */
   19.27 +#include <assert.h>
   19.28 +#include "vl.h"
   19.29 +
   19.30 +#define USE_WAV_AUDIO
   19.31 +
   19.32 +#include "audio/audio_int.h"
   19.33 +
   19.34 +#define dolog(...) AUD_log ("audio", __VA_ARGS__)
   19.35 +#ifdef DEBUG
   19.36 +#define ldebug(...) dolog (__VA_ARGS__)
   19.37 +#else
   19.38 +#define ldebug(...)
   19.39 +#endif
   19.40 +
   19.41 +#define QC_AUDIO_DRV    "QEMU_AUDIO_DRV"
   19.42 +#define QC_VOICES       "QEMU_VOICES"
   19.43 +#define QC_FIXED_FORMAT "QEMU_FIXED_FORMAT"
   19.44 +#define QC_FIXED_FREQ   "QEMU_FIXED_FREQ"
   19.45 +
   19.46 +static HWVoice *hw_voices;
   19.47 +
   19.48 +AudioState audio_state = {
   19.49 +    1,                          /* use fixed settings */
   19.50 +    44100,                      /* fixed frequency */
   19.51 +    2,                          /* fixed channels */
   19.52 +    AUD_FMT_S16,                /* fixed format */
   19.53 +    1,                          /* number of hw voices */
   19.54 +    -1                          /* voice size */
   19.55 +};
   19.56 +
   19.57 +/* http://www.df.lth.se/~john_e/gems/gem002d.html */
   19.58 +/* http://www.multi-platforms.com/Tips/PopCount.htm */
   19.59 +uint32_t popcount (uint32_t u)
   19.60 +{
   19.61 +    u = ((u&0x55555555) + ((u>>1)&0x55555555));
   19.62 +    u = ((u&0x33333333) + ((u>>2)&0x33333333));
   19.63 +    u = ((u&0x0f0f0f0f) + ((u>>4)&0x0f0f0f0f));
   19.64 +    u = ((u&0x00ff00ff) + ((u>>8)&0x00ff00ff));
   19.65 +    u = ( u&0x0000ffff) + (u>>16);
   19.66 +    return u;
   19.67 +}
   19.68 +
   19.69 +inline uint32_t lsbindex (uint32_t u)
   19.70 +{
   19.71 +    return popcount ((u&-u)-1);
   19.72 +}
   19.73 +
   19.74 +int audio_get_conf_int (const char *key, int defval)
   19.75 +{
   19.76 +    int val = defval;
   19.77 +    char *strval;
   19.78 +
   19.79 +    strval = getenv (key);
   19.80 +    if (strval) {
   19.81 +        val = atoi (strval);
   19.82 +    }
   19.83 +
   19.84 +    return val;
   19.85 +}
   19.86 +
   19.87 +const char *audio_get_conf_str (const char *key, const char *defval)
   19.88 +{
   19.89 +    const char *val = getenv (key);
   19.90 +    if (!val)
   19.91 +        return defval;
   19.92 +    else
   19.93 +        return val;
   19.94 +}
   19.95 +
   19.96 +void AUD_log (const char *cap, const char *fmt, ...)
   19.97 +{
   19.98 +    va_list ap;
   19.99 +    fprintf (stderr, "%s: ", cap);
  19.100 +    va_start (ap, fmt);
  19.101 +    vfprintf (stderr, fmt, ap);
  19.102 +    va_end (ap);
  19.103 +}
  19.104 +
  19.105 +/*
  19.106 + * Soft Voice
  19.107 + */
  19.108 +void pcm_sw_free_resources (SWVoice *sw)
  19.109 +{
  19.110 +    if (sw->buf) qemu_free (sw->buf);
  19.111 +    if (sw->rate) st_rate_stop (sw->rate);
  19.112 +    sw->buf = NULL;
  19.113 +    sw->rate = NULL;
  19.114 +}
  19.115 +
  19.116 +int pcm_sw_alloc_resources (SWVoice *sw)
  19.117 +{
  19.118 +    sw->buf = qemu_mallocz (sw->hw->samples * sizeof (st_sample_t));
  19.119 +    if (!sw->buf)
  19.120 +        return -1;
  19.121 +
  19.122 +    sw->rate = st_rate_start (sw->freq, sw->hw->freq);
  19.123 +    if (!sw->rate) {
  19.124 +        qemu_free (sw->buf);
  19.125 +        sw->buf = NULL;
  19.126 +        return -1;
  19.127 +    }
  19.128 +    return 0;
  19.129 +}
  19.130 +
  19.131 +void pcm_sw_fini (SWVoice *sw)
  19.132 +{
  19.133 +    pcm_sw_free_resources (sw);
  19.134 +}
  19.135 +
  19.136 +int pcm_sw_init (SWVoice *sw, HWVoice *hw, int freq,
  19.137 +                 int nchannels, audfmt_e fmt)
  19.138 +{
  19.139 +    int bits = 8, sign = 0;
  19.140 +
  19.141 +    switch (fmt) {
  19.142 +    case AUD_FMT_S8:
  19.143 +        sign = 1;
  19.144 +    case AUD_FMT_U8:
  19.145 +        break;
  19.146 +
  19.147 +    case AUD_FMT_S16:
  19.148 +        sign = 1;
  19.149 +    case AUD_FMT_U16:
  19.150 +        bits = 16;
  19.151 +        break;
  19.152 +    }
  19.153 +
  19.154 +    sw->hw = hw;
  19.155 +    sw->freq = freq;
  19.156 +    sw->fmt = fmt;
  19.157 +    sw->nchannels = nchannels;
  19.158 +    sw->shift = (nchannels == 2) + (bits == 16);
  19.159 +    sw->align = (1 << sw->shift) - 1;
  19.160 +    sw->left = 0;
  19.161 +    sw->pos = 0;
  19.162 +    sw->wpos = 0;
  19.163 +    sw->live = 0;
  19.164 +    sw->ratio = (sw->hw->freq * ((int64_t) INT_MAX)) / sw->freq;
  19.165 +    sw->bytes_per_second = sw->freq << sw->shift;
  19.166 +    sw->conv = mixeng_conv[nchannels == 2][sign][bits == 16];
  19.167 +
  19.168 +    pcm_sw_free_resources (sw);
  19.169 +    return pcm_sw_alloc_resources (sw);
  19.170 +}
  19.171 +
  19.172 +/* Hard voice */
  19.173 +void pcm_hw_free_resources (HWVoice *hw)
  19.174 +{
  19.175 +    if (hw->mix_buf)
  19.176 +        qemu_free (hw->mix_buf);
  19.177 +    hw->mix_buf = NULL;
  19.178 +}
  19.179 +
  19.180 +int pcm_hw_alloc_resources (HWVoice *hw)
  19.181 +{
  19.182 +    hw->mix_buf = qemu_mallocz (hw->samples * sizeof (st_sample_t));
  19.183 +    if (!hw->mix_buf)
  19.184 +        return -1;
  19.185 +    return 0;
  19.186 +}
  19.187 +
  19.188 +void pcm_hw_fini (HWVoice *hw)
  19.189 +{
  19.190 +    if (hw->active) {
  19.191 +        ldebug ("pcm_hw_fini: %d %d %d\n", hw->freq, hw->nchannels, hw->fmt);
  19.192 +        pcm_hw_free_resources (hw);
  19.193 +        hw->pcm_ops->fini (hw);
  19.194 +        memset (hw, 0, audio_state.drv->voice_size);
  19.195 +    }
  19.196 +}
  19.197 +
  19.198 +void pcm_hw_gc (HWVoice *hw)
  19.199 +{
  19.200 +    if (hw->nb_voices)
  19.201 +        return;
  19.202 +
  19.203 +    pcm_hw_fini (hw);
  19.204 +}
  19.205 +
  19.206 +int pcm_hw_get_live (HWVoice *hw)
  19.207 +{
  19.208 +    int i, alive = 0, live = hw->samples;
  19.209 +
  19.210 +    for (i = 0; i < hw->nb_voices; i++) {
  19.211 +        if (hw->pvoice[i]->live) {
  19.212 +            live = audio_MIN (hw->pvoice[i]->live, live);
  19.213 +            alive += 1;
  19.214 +        }
  19.215 +    }
  19.216 +
  19.217 +    if (alive)
  19.218 +        return live;
  19.219 +    else
  19.220 +        return -1;
  19.221 +}
  19.222 +
  19.223 +int pcm_hw_get_live2 (HWVoice *hw, int *nb_active)
  19.224 +{
  19.225 +    int i, alive = 0, live = hw->samples;
  19.226 +
  19.227 +    *nb_active = 0;
  19.228 +    for (i = 0; i < hw->nb_voices; i++) {
  19.229 +        if (hw->pvoice[i]->live) {
  19.230 +            if (hw->pvoice[i]->live < live) {
  19.231 +                *nb_active = hw->pvoice[i]->active != 0;
  19.232 +                live = hw->pvoice[i]->live;
  19.233 +            }
  19.234 +            alive += 1;
  19.235 +        }
  19.236 +    }
  19.237 +
  19.238 +    if (alive)
  19.239 +        return live;
  19.240 +    else
  19.241 +        return -1;
  19.242 +}
  19.243 +
  19.244 +void pcm_hw_dec_live (HWVoice *hw, int decr)
  19.245 +{
  19.246 +    int i;
  19.247 +
  19.248 +    for (i = 0; i < hw->nb_voices; i++) {
  19.249 +        if (hw->pvoice[i]->live) {
  19.250 +            hw->pvoice[i]->live -= decr;
  19.251 +        }
  19.252 +    }
  19.253 +}
  19.254 +
  19.255 +void pcm_hw_clear (HWVoice *hw, void *buf, int len)
  19.256 +{
  19.257 +    if (!len)
  19.258 +        return;
  19.259 +
  19.260 +    switch (hw->fmt) {
  19.261 +    case AUD_FMT_S16:
  19.262 +    case AUD_FMT_S8:
  19.263 +        memset (buf, len << hw->shift, 0x00);
  19.264 +        break;
  19.265 +
  19.266 +    case AUD_FMT_U8:
  19.267 +        memset (buf, len << hw->shift, 0x80);
  19.268 +        break;
  19.269 +
  19.270 +    case AUD_FMT_U16:
  19.271 +        {
  19.272 +            unsigned int i;
  19.273 +            uint16_t *p = buf;
  19.274 +            int shift = hw->nchannels - 1;
  19.275 +
  19.276 +            for (i = 0; i < len << shift; i++) {
  19.277 +                p[i] = INT16_MAX;
  19.278 +            }
  19.279 +        }
  19.280 +        break;
  19.281 +    }
  19.282 +}
  19.283 +
  19.284 +int pcm_hw_write (SWVoice *sw, void *buf, int size)
  19.285 +{
  19.286 +    int hwsamples, samples, isamp, osamp, wpos, live, dead, left, swlim, blck;
  19.287 +    int ret = 0, pos = 0;
  19.288 +    if (!sw)
  19.289 +        return size;
  19.290 +
  19.291 +    hwsamples = sw->hw->samples;
  19.292 +    samples = size >> sw->shift;
  19.293 +
  19.294 +    if (!sw->live) {
  19.295 +        sw->wpos = sw->hw->rpos;
  19.296 +    }
  19.297 +    wpos = sw->wpos;
  19.298 +    live = sw->live;
  19.299 +    dead = hwsamples - live;
  19.300 +    swlim = (dead * ((int64_t) INT_MAX)) / sw->ratio;
  19.301 +    swlim = audio_MIN (swlim, samples);
  19.302 +
  19.303 +    ldebug ("size=%d live=%d dead=%d swlim=%d wpos=%d\n",
  19.304 +           size, live, dead, swlim, wpos);
  19.305 +    if (swlim)
  19.306 +        sw->conv (sw->buf, buf, swlim);
  19.307 +
  19.308 +    while (swlim) {
  19.309 +        dead = hwsamples - live;
  19.310 +        left = hwsamples - wpos;
  19.311 +        blck = audio_MIN (dead, left);
  19.312 +        if (!blck) {
  19.313 +            /* dolog ("swlim=%d\n", swlim); */
  19.314 +            break;
  19.315 +        }
  19.316 +        isamp = swlim;
  19.317 +        osamp = blck;
  19.318 +        st_rate_flow (sw->rate, sw->buf + pos, sw->hw->mix_buf + wpos, &isamp, &osamp);
  19.319 +        ret += isamp;
  19.320 +        swlim -= isamp;
  19.321 +        pos += isamp;
  19.322 +        live += osamp;
  19.323 +        wpos = (wpos + osamp) % hwsamples;
  19.324 +    }
  19.325 +
  19.326 +    sw->wpos = wpos;
  19.327 +    sw->live = live;
  19.328 +    return ret << sw->shift;
  19.329 +}
  19.330 +
  19.331 +int pcm_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
  19.332 +{
  19.333 +    int sign = 0, bits = 8;
  19.334 +
  19.335 +    pcm_hw_fini (hw);
  19.336 +    ldebug ("pcm_hw_init: %d %d %d\n", freq, nchannels, fmt);
  19.337 +    if (hw->pcm_ops->init (hw, freq, nchannels, fmt)) {
  19.338 +        memset (hw, 0, audio_state.drv->voice_size);
  19.339 +        return -1;
  19.340 +    }
  19.341 +
  19.342 +    switch (hw->fmt) {
  19.343 +    case AUD_FMT_S8:
  19.344 +        sign = 1;
  19.345 +    case AUD_FMT_U8:
  19.346 +        break;
  19.347 +
  19.348 +    case AUD_FMT_S16:
  19.349 +        sign = 1;
  19.350 +    case AUD_FMT_U16:
  19.351 +        bits = 16;
  19.352 +        break;
  19.353 +    }
  19.354 +
  19.355 +    hw->nb_voices = 0;
  19.356 +    hw->active = 1;
  19.357 +    hw->shift = (hw->nchannels == 2) + (bits == 16);
  19.358 +    hw->bytes_per_second = hw->freq << hw->shift;
  19.359 +    hw->align = (1 << hw->shift) - 1;
  19.360 +    hw->samples = hw->bufsize >> hw->shift;
  19.361 +    hw->clip = mixeng_clip[hw->nchannels == 2][sign][bits == 16];
  19.362 +    if (pcm_hw_alloc_resources (hw)) {
  19.363 +        pcm_hw_fini (hw);
  19.364 +        return -1;
  19.365 +    }
  19.366 +    return 0;
  19.367 +}
  19.368 +
  19.369 +static int dist (void *hw)
  19.370 +{
  19.371 +    if (hw) {
  19.372 +        return (((uint8_t *) hw - (uint8_t *) hw_voices)
  19.373 +                / audio_state.voice_size) + 1;
  19.374 +    }
  19.375 +    else {
  19.376 +        return 0;
  19.377 +    }
  19.378 +}
  19.379 +
  19.380 +#define ADVANCE(hw) hw ? advance (hw, audio_state.voice_size) : hw_voices
  19.381 +
  19.382 +HWVoice *pcm_hw_find_any (HWVoice *hw)
  19.383 +{
  19.384 +    int i = dist (hw);
  19.385 +    for (; i < audio_state.nb_hw_voices; i++) {
  19.386 +        hw = ADVANCE (hw);
  19.387 +        return hw;
  19.388 +    }
  19.389 +    return NULL;
  19.390 +}
  19.391 +
  19.392 +HWVoice *pcm_hw_find_any_active (HWVoice *hw)
  19.393 +{
  19.394 +    int i = dist (hw);
  19.395 +    for (; i < audio_state.nb_hw_voices; i++) {
  19.396 +        hw = ADVANCE (hw);
  19.397 +        if (hw->active)
  19.398 +            return hw;
  19.399 +    }
  19.400 +    return NULL;
  19.401 +}
  19.402 +
  19.403 +HWVoice *pcm_hw_find_any_active_enabled (HWVoice *hw)
  19.404 +{
  19.405 +    int i = dist (hw);
  19.406 +    for (; i < audio_state.nb_hw_voices; i++) {
  19.407 +        hw = ADVANCE (hw);
  19.408 +        if (hw->active && hw->enabled)
  19.409 +            return hw;
  19.410 +    }
  19.411 +    return NULL;
  19.412 +}
  19.413 +
  19.414 +HWVoice *pcm_hw_find_any_passive (HWVoice *hw)
  19.415 +{
  19.416 +    int i = dist (hw);
  19.417 +    for (; i < audio_state.nb_hw_voices; i++) {
  19.418 +        hw = ADVANCE (hw);
  19.419 +        if (!hw->active)
  19.420 +            return hw;
  19.421 +    }
  19.422 +    return NULL;
  19.423 +}
  19.424 +
  19.425 +HWVoice *pcm_hw_find_specific (HWVoice *hw, int freq,
  19.426 +                               int nchannels, audfmt_e fmt)
  19.427 +{
  19.428 +    while ((hw = pcm_hw_find_any_active (hw))) {
  19.429 +        if (hw->freq == freq &&
  19.430 +            hw->nchannels == nchannels &&
  19.431 +            hw->fmt == fmt)
  19.432 +            return hw;
  19.433 +    }
  19.434 +    return NULL;
  19.435 +}
  19.436 +
  19.437 +HWVoice *pcm_hw_add (int freq, int nchannels, audfmt_e fmt)
  19.438 +{
  19.439 +    HWVoice *hw;
  19.440 +
  19.441 +    if (audio_state.fixed_format) {
  19.442 +        freq = audio_state.fixed_freq;
  19.443 +        nchannels = audio_state.fixed_channels;
  19.444 +        fmt = audio_state.fixed_fmt;
  19.445 +    }
  19.446 +
  19.447 +    hw = pcm_hw_find_specific (NULL, freq, nchannels, fmt);
  19.448 +
  19.449 +    if (hw)
  19.450 +        return hw;
  19.451 +
  19.452 +    hw = pcm_hw_find_any_passive (NULL);
  19.453 +    if (hw) {
  19.454 +        hw->pcm_ops = audio_state.drv->pcm_ops;
  19.455 +        if (!hw->pcm_ops)
  19.456 +            return NULL;
  19.457 +
  19.458 +        if (pcm_hw_init (hw, freq, nchannels, fmt)) {
  19.459 +            pcm_hw_gc (hw);
  19.460 +            return NULL;
  19.461 +        }
  19.462 +        else
  19.463 +            return hw;
  19.464 +    }
  19.465 +
  19.466 +    return pcm_hw_find_any (NULL);
  19.467 +}
  19.468 +
  19.469 +int pcm_hw_add_sw (HWVoice *hw, SWVoice *sw)
  19.470 +{
  19.471 +    SWVoice **pvoice = qemu_mallocz ((hw->nb_voices + 1) * sizeof (sw));
  19.472 +    if (!pvoice)
  19.473 +        return -1;
  19.474 +
  19.475 +    memcpy (pvoice, hw->pvoice, hw->nb_voices * sizeof (sw));
  19.476 +    qemu_free (hw->pvoice);
  19.477 +    hw->pvoice = pvoice;
  19.478 +    hw->pvoice[hw->nb_voices++] = sw;
  19.479 +    return 0;
  19.480 +}
  19.481 +
  19.482 +int pcm_hw_del_sw (HWVoice *hw, SWVoice *sw)
  19.483 +{
  19.484 +    int i, j;
  19.485 +    if (hw->nb_voices > 1) {
  19.486 +        SWVoice **pvoice = qemu_mallocz ((hw->nb_voices - 1) * sizeof (sw));
  19.487 +
  19.488 +        if (!pvoice) {
  19.489 +            dolog ("Can not maintain consistent state (not enough memory)\n");
  19.490 +            return -1;
  19.491 +        }
  19.492 +
  19.493 +        for (i = 0, j = 0; i < hw->nb_voices; i++) {
  19.494 +            if (j >= hw->nb_voices - 1) {
  19.495 +                dolog ("Can not maintain consistent state "
  19.496 +                       "(invariant violated)\n");
  19.497 +                return -1;
  19.498 +            }
  19.499 +            if (hw->pvoice[i] != sw)
  19.500 +                pvoice[j++] = hw->pvoice[i];
  19.501 +        }
  19.502 +        qemu_free (hw->pvoice);
  19.503 +        hw->pvoice = pvoice;
  19.504 +        hw->nb_voices -= 1;
  19.505 +    }
  19.506 +    else {
  19.507 +        qemu_free (hw->pvoice);
  19.508 +        hw->pvoice = NULL;
  19.509 +        hw->nb_voices = 0;
  19.510 +    }
  19.511 +    return 0;
  19.512 +}
  19.513 +
  19.514 +SWVoice *pcm_create_voice_pair (int freq, int nchannels, audfmt_e fmt)
  19.515 +{
  19.516 +    SWVoice *sw;
  19.517 +    HWVoice *hw;
  19.518 +
  19.519 +    sw = qemu_mallocz (sizeof (*sw));
  19.520 +    if (!sw)
  19.521 +        goto err1;
  19.522 +
  19.523 +    hw = pcm_hw_add (freq, nchannels, fmt);
  19.524 +    if (!hw)
  19.525 +        goto err2;
  19.526 +
  19.527 +    if (pcm_hw_add_sw (hw, sw))
  19.528 +        goto err3;
  19.529 +
  19.530 +    if (pcm_sw_init (sw, hw, freq, nchannels, fmt))
  19.531 +        goto err4;
  19.532 +
  19.533 +    return sw;
  19.534 +
  19.535 +err4:
  19.536 +    pcm_hw_del_sw (hw, sw);
  19.537 +err3:
  19.538 +    pcm_hw_gc (hw);
  19.539 +err2:
  19.540 +    qemu_free (sw);
  19.541 +err1:
  19.542 +    return NULL;
  19.543 +}
  19.544 +
  19.545 +SWVoice *AUD_open (SWVoice *sw, const char *name,
  19.546 +                   int freq, int nchannels, audfmt_e fmt)
  19.547 +{
  19.548 +    if (!audio_state.drv) {
  19.549 +        return NULL;
  19.550 +    }
  19.551 +
  19.552 +    if (sw && freq == sw->freq && sw->nchannels == nchannels && sw->fmt == fmt) {
  19.553 +        return sw;
  19.554 +    }
  19.555 +
  19.556 +    if (sw) {
  19.557 +        ldebug ("Different format %s %d %d %d\n",
  19.558 +                name,
  19.559 +                sw->freq == freq,
  19.560 +                sw->nchannels == nchannels,
  19.561 +                sw->fmt == fmt);
  19.562 +    }
  19.563 +
  19.564 +    if (nchannels != 1 && nchannels != 2) {
  19.565 +        dolog ("Bogus channel count %d for voice %s\n", nchannels, name);
  19.566 +        return NULL;
  19.567 +    }
  19.568 +
  19.569 +    if (!audio_state.fixed_format && sw) {
  19.570 +        pcm_sw_fini (sw);
  19.571 +        pcm_hw_del_sw (sw->hw, sw);
  19.572 +        pcm_hw_gc (sw->hw);
  19.573 +        if (sw->name) {
  19.574 +            qemu_free (sw->name);
  19.575 +            sw->name = NULL;
  19.576 +        }
  19.577 +        qemu_free (sw);
  19.578 +        sw = NULL;
  19.579 +    }
  19.580 +
  19.581 +    if (sw) {
  19.582 +        HWVoice *hw = sw->hw;
  19.583 +        if (!hw) {
  19.584 +            dolog ("Internal logic error voice %s has no hardware store\n",
  19.585 +                   name);
  19.586 +            return sw;
  19.587 +        }
  19.588 +
  19.589 +        if (pcm_sw_init (sw, hw, freq, nchannels, fmt)) {
  19.590 +            pcm_sw_fini (sw);
  19.591 +            pcm_hw_del_sw (hw, sw);
  19.592 +            pcm_hw_gc (hw);
  19.593 +            if (sw->name) {
  19.594 +                qemu_free (sw->name);
  19.595 +                sw->name = NULL;
  19.596 +            }
  19.597 +            qemu_free (sw);
  19.598 +            return NULL;
  19.599 +        }
  19.600 +    }
  19.601 +    else {
  19.602 +        sw = pcm_create_voice_pair (freq, nchannels, fmt);
  19.603 +        if (!sw) {
  19.604 +            dolog ("Failed to create voice %s\n", name);
  19.605 +            return NULL;
  19.606 +        }
  19.607 +    }
  19.608 +
  19.609 +    if (sw->name) {
  19.610 +        qemu_free (sw->name);
  19.611 +        sw->name = NULL;
  19.612 +    }
  19.613 +    sw->name = qemu_strdup (name);
  19.614 +    return sw;
  19.615 +}
  19.616 +
  19.617 +void AUD_close (SWVoice *sw)
  19.618 +{
  19.619 +    if (!sw)
  19.620 +        return;
  19.621 +
  19.622 +    pcm_sw_fini (sw);
  19.623 +    pcm_hw_del_sw (sw->hw, sw);
  19.624 +    pcm_hw_gc (sw->hw);
  19.625 +    if (sw->name) {
  19.626 +        qemu_free (sw->name);
  19.627 +        sw->name = NULL;
  19.628 +    }
  19.629 +    qemu_free (sw);
  19.630 +}
  19.631 +
  19.632 +int AUD_write (SWVoice *sw, void *buf, int size)
  19.633 +{
  19.634 +    int bytes;
  19.635 +
  19.636 +    if (!sw->hw->enabled)
  19.637 +        dolog ("Writing to disabled voice %s\n", sw->name);
  19.638 +    bytes = sw->hw->pcm_ops->write (sw, buf, size);
  19.639 +    return bytes;
  19.640 +}
  19.641 +
  19.642 +void AUD_run (void)
  19.643 +{
  19.644 +    HWVoice *hw = NULL;
  19.645 +
  19.646 +    while ((hw = pcm_hw_find_any_active_enabled (hw))) {
  19.647 +        int i;
  19.648 +        if (hw->pending_disable && pcm_hw_get_live (hw) <= 0) {
  19.649 +            hw->enabled = 0;
  19.650 +            hw->pcm_ops->ctl (hw, VOICE_DISABLE);
  19.651 +            for (i = 0; i < hw->nb_voices; i++) {
  19.652 +                hw->pvoice[i]->live = 0;
  19.653 +                /* hw->pvoice[i]->old_ticks = 0; */
  19.654 +            }
  19.655 +            continue;
  19.656 +        }
  19.657 +
  19.658 +        hw->pcm_ops->run (hw);
  19.659 +        assert (hw->rpos < hw->samples);
  19.660 +        for (i = 0; i < hw->nb_voices; i++) {
  19.661 +            SWVoice *sw = hw->pvoice[i];
  19.662 +            if (!sw->active && !sw->live && sw->old_ticks) {
  19.663 +                int64_t delta = qemu_get_clock (vm_clock) - sw->old_ticks;
  19.664 +                if (delta > audio_state.ticks_threshold) {
  19.665 +                    ldebug ("resetting old_ticks for %s\n", sw->name);
  19.666 +                    sw->old_ticks = 0;
  19.667 +                }
  19.668 +            }
  19.669 +        }
  19.670 +    }
  19.671 +}
  19.672 +
  19.673 +int AUD_get_free (SWVoice *sw)
  19.674 +{
  19.675 +    int free;
  19.676 +
  19.677 +    if (!sw)
  19.678 +        return 4096;
  19.679 +
  19.680 +    free = ((sw->hw->samples - sw->live) << sw->hw->shift) * sw->ratio
  19.681 +        / INT_MAX;
  19.682 +
  19.683 +    free &= ~sw->hw->align;
  19.684 +    if (!free) return 0;
  19.685 +
  19.686 +    return free;
  19.687 +}
  19.688 +
  19.689 +int AUD_get_buffer_size (SWVoice *sw)
  19.690 +{
  19.691 +    return sw->hw->bufsize;
  19.692 +}
  19.693 +
  19.694 +void AUD_adjust (SWVoice *sw, int bytes)
  19.695 +{
  19.696 +    if (!sw)
  19.697 +        return;
  19.698 +    sw->old_ticks += (ticks_per_sec * (int64_t) bytes) / sw->bytes_per_second;
  19.699 +}
  19.700 +
  19.701 +void AUD_reset (SWVoice *sw)
  19.702 +{
  19.703 +    sw->active = 0;
  19.704 +    sw->old_ticks = 0;
  19.705 +}
  19.706 +
  19.707 +int AUD_calc_elapsed (SWVoice *sw)
  19.708 +{
  19.709 +    int64_t now, delta, bytes;
  19.710 +    int dead, swlim;
  19.711 +
  19.712 +    if (!sw)
  19.713 +        return 0;
  19.714 +
  19.715 +    now = qemu_get_clock (vm_clock);
  19.716 +    delta = now - sw->old_ticks;
  19.717 +    bytes = (delta * sw->bytes_per_second) / ticks_per_sec;
  19.718 +    if (delta < 0) {
  19.719 +        dolog ("whoops delta(<0)=%lld\n", delta);
  19.720 +        return 0;
  19.721 +    }
  19.722 +
  19.723 +    dead = sw->hw->samples - sw->live;
  19.724 +    swlim = ((dead * (int64_t) INT_MAX) / sw->ratio);
  19.725 +
  19.726 +    if (bytes > swlim) {
  19.727 +        return swlim;
  19.728 +    }
  19.729 +    else {
  19.730 +        return bytes;
  19.731 +    }
  19.732 +}
  19.733 +
  19.734 +void AUD_enable (SWVoice *sw, int on)
  19.735 +{
  19.736 +    int i;
  19.737 +    HWVoice *hw;
  19.738 +
  19.739 +    if (!sw)
  19.740 +        return;
  19.741 +
  19.742 +    hw = sw->hw;
  19.743 +    if (on) {
  19.744 +        if (!sw->live)
  19.745 +            sw->wpos = sw->hw->rpos;
  19.746 +        if (!sw->old_ticks) {
  19.747 +            sw->old_ticks = qemu_get_clock (vm_clock);
  19.748 +        }
  19.749 +    }
  19.750 +
  19.751 +    if (sw->active != on) {
  19.752 +        if (on) {
  19.753 +            hw->pending_disable = 0;
  19.754 +            if (!hw->enabled) {
  19.755 +                hw->enabled = 1;
  19.756 +                for (i = 0; i < hw->nb_voices; i++) {
  19.757 +                    ldebug ("resetting voice\n");
  19.758 +                    sw = hw->pvoice[i];
  19.759 +                    sw->old_ticks = qemu_get_clock (vm_clock);
  19.760 +                }
  19.761 +                hw->pcm_ops->ctl (hw, VOICE_ENABLE);
  19.762 +            }
  19.763 +        }
  19.764 +        else {
  19.765 +            if (hw->enabled && !hw->pending_disable) {
  19.766 +                int nb_active = 0;
  19.767 +                for (i = 0; i < hw->nb_voices; i++) {
  19.768 +                    nb_active += hw->pvoice[i]->active != 0;
  19.769 +                }
  19.770 +
  19.771 +                if (nb_active == 1) {
  19.772 +                    hw->pending_disable = 1;
  19.773 +                }
  19.774 +            }
  19.775 +        }
  19.776 +        sw->active = on;
  19.777 +    }
  19.778 +}
  19.779 +
  19.780 +static struct audio_output_driver *drvtab[] = {
  19.781 +#ifdef CONFIG_OSS
  19.782 +    &oss_output_driver,
  19.783 +#endif
  19.784 +#ifdef CONFIG_FMOD
  19.785 +    &fmod_output_driver,
  19.786 +#endif
  19.787 +#ifdef CONFIG_SDL
  19.788 +    &sdl_output_driver,
  19.789 +#endif
  19.790 +    &no_output_driver,
  19.791 +#ifdef USE_WAV_AUDIO
  19.792 +    &wav_output_driver,
  19.793 +#endif
  19.794 +};
  19.795 +
  19.796 +static int voice_init (struct audio_output_driver *drv)
  19.797 +{
  19.798 +    audio_state.opaque = drv->init ();
  19.799 +    if (audio_state.opaque) {
  19.800 +        if (audio_state.nb_hw_voices > drv->max_voices) {
  19.801 +            dolog ("`%s' does not support %d multiple hardware channels\n"
  19.802 +                   "Resetting to %d\n",
  19.803 +                   drv->name, audio_state.nb_hw_voices, drv->max_voices);
  19.804 +            audio_state.nb_hw_voices = drv->max_voices;
  19.805 +        }
  19.806 +        hw_voices = qemu_mallocz (audio_state.nb_hw_voices * drv->voice_size);
  19.807 +        if (hw_voices) {
  19.808 +            audio_state.drv = drv;
  19.809 +            return 1;
  19.810 +        }
  19.811 +        else {
  19.812 +            dolog ("Not enough memory for %d `%s' voices (each %d bytes)\n",
  19.813 +                   audio_state.nb_hw_voices, drv->name, drv->voice_size);
  19.814 +            drv->fini (audio_state.opaque);
  19.815 +            return 0;
  19.816 +        }
  19.817 +    }
  19.818 +    else {
  19.819 +        dolog ("Could not init `%s' audio\n", drv->name);
  19.820 +        return 0;
  19.821 +    }
  19.822 +}
  19.823 +
  19.824 +static void audio_vm_stop_handler (void *opaque, int reason)
  19.825 +{
  19.826 +    HWVoice *hw = NULL;
  19.827 +
  19.828 +    while ((hw = pcm_hw_find_any (hw))) {
  19.829 +        if (!hw->pcm_ops)
  19.830 +            continue;
  19.831 +
  19.832 +        hw->pcm_ops->ctl (hw, reason ? VOICE_ENABLE : VOICE_DISABLE);
  19.833 +    }
  19.834 +}
  19.835 +
  19.836 +static void audio_atexit (void)
  19.837 +{
  19.838 +    HWVoice *hw = NULL;
  19.839 +
  19.840 +    while ((hw = pcm_hw_find_any (hw))) {
  19.841 +        if (!hw->pcm_ops)
  19.842 +            continue;
  19.843 +
  19.844 +        hw->pcm_ops->ctl (hw, VOICE_DISABLE);
  19.845 +        hw->pcm_ops->fini (hw);
  19.846 +    }
  19.847 +    audio_state.drv->fini (audio_state.opaque);
  19.848 +}
  19.849 +
  19.850 +static void audio_save (QEMUFile *f, void *opaque)
  19.851 +{
  19.852 +}
  19.853 +
  19.854 +static int audio_load (QEMUFile *f, void *opaque, int version_id)
  19.855 +{
  19.856 +    if (version_id != 1)
  19.857 +        return -EINVAL;
  19.858 +
  19.859 +    return 0;
  19.860 +}
  19.861 +
  19.862 +void AUD_init (void)
  19.863 +{
  19.864 +    int i;
  19.865 +    int done = 0;
  19.866 +    const char *drvname;
  19.867 +
  19.868 +    audio_state.fixed_format =
  19.869 +        !!audio_get_conf_int (QC_FIXED_FORMAT, audio_state.fixed_format);
  19.870 +    audio_state.fixed_freq =
  19.871 +        audio_get_conf_int (QC_FIXED_FREQ, audio_state.fixed_freq);
  19.872 +    audio_state.nb_hw_voices =
  19.873 +        audio_get_conf_int (QC_VOICES, audio_state.nb_hw_voices);
  19.874 +
  19.875 +    if (audio_state.nb_hw_voices <= 0) {
  19.876 +        dolog ("Bogus number of voices %d, resetting to 1\n",
  19.877 +               audio_state.nb_hw_voices);
  19.878 +    }
  19.879 +
  19.880 +    drvname = audio_get_conf_str (QC_AUDIO_DRV, NULL);
  19.881 +    if (drvname) {
  19.882 +        int found = 0;
  19.883 +        for (i = 0; i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
  19.884 +            if (!strcmp (drvname, drvtab[i]->name)) {
  19.885 +                done = voice_init (drvtab[i]);
  19.886 +                found = 1;
  19.887 +                break;
  19.888 +            }
  19.889 +        }
  19.890 +        if (!found) {
  19.891 +            dolog ("Unknown audio driver `%s'\n", drvname);
  19.892 +        }
  19.893 +    }
  19.894 +
  19.895 +    qemu_add_vm_stop_handler (audio_vm_stop_handler, NULL);
  19.896 +    atexit (audio_atexit);
  19.897 +
  19.898 +    if (!done) {
  19.899 +        for (i = 0; !done && i < sizeof (drvtab) / sizeof (drvtab[0]); i++) {
  19.900 +            if (drvtab[i]->can_be_default)
  19.901 +                done = voice_init (drvtab[i]);
  19.902 +        }
  19.903 +    }
  19.904 +
  19.905 +    audio_state.ticks_threshold = ticks_per_sec / 50;
  19.906 +    audio_state.freq_threshold = 100;
  19.907 +
  19.908 +    register_savevm ("audio", 0, 1, audio_save, audio_load, NULL);
  19.909 +    if (!done) {
  19.910 +        dolog ("Can not initialize audio subsystem\n");
  19.911 +        voice_init (&no_output_driver);
  19.912 +    }
  19.913 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/tools/ioemu/audio/audio.h	Wed Dec 21 11:56:19 2005 -0600
    20.3 @@ -0,0 +1,65 @@
    20.4 +/*
    20.5 + * QEMU Audio subsystem header
    20.6 + * 
    20.7 + * Copyright (c) 2003-2004 Vassili Karpov (malc)
    20.8 + * 
    20.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   20.10 + * of this software and associated documentation files (the "Software"), to deal
   20.11 + * in the Software without restriction, including without limitation the rights
   20.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   20.13 + * copies of the Software, and to permit persons to whom the Software is
   20.14 + * furnished to do so, subject to the following conditions:
   20.15 + *
   20.16 + * The above copyright notice and this permission notice shall be included in
   20.17 + * all copies or substantial portions of the Software.
   20.18 + *
   20.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   20.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   20.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   20.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   20.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   20.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   20.25 + * THE SOFTWARE.
   20.26 + */
   20.27 +#ifndef QEMU_AUDIO_H
   20.28 +#define QEMU_AUDIO_H
   20.29 +
   20.30 +#include "mixeng.h"
   20.31 +
   20.32 +typedef enum {
   20.33 +  AUD_FMT_U8,
   20.34 +  AUD_FMT_S8,
   20.35 +  AUD_FMT_U16,
   20.36 +  AUD_FMT_S16
   20.37 +} audfmt_e;
   20.38 +
   20.39 +typedef struct SWVoice SWVoice;
   20.40 +
   20.41 +SWVoice * AUD_open (SWVoice *sw, const char *name, int freq,
   20.42 +                    int nchannels, audfmt_e fmt);
   20.43 +void   AUD_init (void);
   20.44 +void   AUD_log (const char *cap, const char *fmt, ...)
   20.45 +    __attribute__ ((__format__ (__printf__, 2, 3)));;
   20.46 +void   AUD_close (SWVoice *sw);
   20.47 +int    AUD_write (SWVoice *sw, void *pcm_buf, int size);
   20.48 +void   AUD_adjust (SWVoice *sw, int leftover);
   20.49 +void   AUD_reset (SWVoice *sw);
   20.50 +int    AUD_get_free (SWVoice *sw);
   20.51 +int    AUD_get_buffer_size (SWVoice *sw);
   20.52 +void   AUD_run (void);
   20.53 +void   AUD_enable (SWVoice *sw, int on);
   20.54 +int    AUD_calc_elapsed (SWVoice *sw);
   20.55 +
   20.56 +static inline void *advance (void *p, int incr)
   20.57 +{
   20.58 +    uint8_t *d = p;
   20.59 +    return (d + incr);
   20.60 +}
   20.61 +
   20.62 +uint32_t popcount (uint32_t u);
   20.63 +inline uint32_t lsbindex (uint32_t u);
   20.64 +
   20.65 +#define audio_MIN(a, b) ((a)>(b)?(b):(a))
   20.66 +#define audio_MAX(a, b) ((a)<(b)?(b):(a))
   20.67 +
   20.68 +#endif  /* audio.h */
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/tools/ioemu/audio/audio_int.h	Wed Dec 21 11:56:19 2005 -0600
    21.3 @@ -0,0 +1,164 @@
    21.4 +/*
    21.5 + * QEMU Audio subsystem header
    21.6 + * 
    21.7 + * Copyright (c) 2003-2004 Vassili Karpov (malc)
    21.8 + * 
    21.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   21.10 + * of this software and associated documentation files (the "Software"), to deal
   21.11 + * in the Software without restriction, including without limitation the rights
   21.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   21.13 + * copies of the Software, and to permit persons to whom the Software is
   21.14 + * furnished to do so, subject to the following conditions:
   21.15 + *
   21.16 + * The above copyright notice and this permission notice shall be included in
   21.17 + * all copies or substantial portions of the Software.
   21.18 + *
   21.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   21.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   21.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   21.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   21.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   21.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   21.25 + * THE SOFTWARE.
   21.26 + */
   21.27 +#ifndef QEMU_AUDIO_INT_H
   21.28 +#define QEMU_AUDIO_INT_H
   21.29 +
   21.30 +#include "vl.h"
   21.31 +
   21.32 +struct pcm_ops;
   21.33 +
   21.34 +typedef struct HWVoice {
   21.35 +    int active;
   21.36 +    int enabled;
   21.37 +    int pending_disable;
   21.38 +    int valid;
   21.39 +    int freq;
   21.40 +
   21.41 +    f_sample *clip;
   21.42 +    audfmt_e fmt;
   21.43 +    int nchannels;
   21.44 +
   21.45 +    int align;
   21.46 +    int shift;
   21.47 +
   21.48 +    int rpos;
   21.49 +    int bufsize;
   21.50 +
   21.51 +    int bytes_per_second;
   21.52 +    st_sample_t *mix_buf;
   21.53 +
   21.54 +    int samples;
   21.55 +    int64_t old_ticks;
   21.56 +    int nb_voices;
   21.57 +    struct SWVoice **pvoice;
   21.58 +    struct pcm_ops *pcm_ops;
   21.59 +} HWVoice;
   21.60 +
   21.61 +extern struct pcm_ops no_pcm_ops;
   21.62 +extern struct audio_output_driver no_output_driver;
   21.63 +
   21.64 +extern struct pcm_ops oss_pcm_ops;
   21.65 +extern struct audio_output_driver oss_output_driver;
   21.66 +
   21.67 +extern struct pcm_ops sdl_pcm_ops;
   21.68 +extern struct audio_output_driver sdl_output_driver;
   21.69 +
   21.70 +extern struct pcm_ops wav_pcm_ops;
   21.71 +extern struct audio_output_driver wav_output_driver;
   21.72 +
   21.73 +extern struct pcm_ops fmod_pcm_ops;
   21.74 +extern struct audio_output_driver fmod_output_driver;
   21.75 +
   21.76 +struct audio_output_driver {
   21.77 +    const char *name;
   21.78 +    void *(*init) (void);
   21.79 +    void (*fini) (void *);
   21.80 +    struct pcm_ops *pcm_ops;
   21.81 +    int can_be_default;
   21.82 +    int max_voices;
   21.83 +    int voice_size;
   21.84 +};
   21.85 +
   21.86 +typedef struct AudioState {
   21.87 +    int fixed_format;
   21.88 +    int fixed_freq;
   21.89 +    int fixed_channels;
   21.90 +    int fixed_fmt;
   21.91 +    int nb_hw_voices;
   21.92 +    int voice_size;
   21.93 +    int64_t ticks_threshold;
   21.94 +    int freq_threshold;
   21.95 +    void *opaque;
   21.96 +    struct audio_output_driver *drv;
   21.97 +} AudioState;
   21.98 +extern AudioState audio_state;
   21.99 +
  21.100 +struct SWVoice {
  21.101 +    int freq;
  21.102 +    audfmt_e fmt;
  21.103 +    int nchannels;
  21.104 +
  21.105 +    int shift;
  21.106 +    int align;
  21.107 +
  21.108 +    t_sample *conv;
  21.109 +
  21.110 +    int left;
  21.111 +    int pos;
  21.112 +    int bytes_per_second;
  21.113 +    int64_t ratio;
  21.114 +    st_sample_t *buf;
  21.115 +    void *rate;
  21.116 +
  21.117 +    int wpos;
  21.118 +    int live;
  21.119 +    int active;
  21.120 +    int64_t old_ticks;
  21.121 +    HWVoice *hw;
  21.122 +    char *name;
  21.123 +};
  21.124 +
  21.125 +struct pcm_ops {
  21.126 +    int  (*init)  (HWVoice *hw, int freq, int nchannels, audfmt_e fmt);
  21.127 +    void (*fini)  (HWVoice *hw);
  21.128 +    void (*run)   (HWVoice *hw);
  21.129 +    int  (*write) (SWVoice *sw, void *buf, int size);
  21.130 +    int  (*ctl)   (HWVoice *hw, int cmd, ...);
  21.131 +};
  21.132 +
  21.133 +void      pcm_sw_free_resources (SWVoice *sw);
  21.134 +int       pcm_sw_alloc_resources (SWVoice *sw);
  21.135 +void      pcm_sw_fini (SWVoice *sw);
  21.136 +int       pcm_sw_init (SWVoice *sw, HWVoice *hw, int freq,
  21.137 +                       int nchannels, audfmt_e fmt);
  21.138 +
  21.139 +void      pcm_hw_clear (HWVoice *hw, void *buf, int len);
  21.140 +HWVoice * pcm_hw_find_any (HWVoice *hw);
  21.141 +HWVoice * pcm_hw_find_any_active (HWVoice *hw);
  21.142 +HWVoice * pcm_hw_find_any_passive (HWVoice *hw);
  21.143 +HWVoice * pcm_hw_find_specific (HWVoice *hw, int freq,
  21.144 +                                int nchannels, audfmt_e fmt);
  21.145 +HWVoice * pcm_hw_add (int freq, int nchannels, audfmt_e fmt);
  21.146 +int       pcm_hw_add_sw (HWVoice *hw, SWVoice *sw);
  21.147 +int       pcm_hw_del_sw (HWVoice *hw, SWVoice *sw);
  21.148 +SWVoice * pcm_create_voice_pair (int freq, int nchannels, audfmt_e fmt);
  21.149 +
  21.150 +void      pcm_hw_free_resources (HWVoice *hw);
  21.151 +int       pcm_hw_alloc_resources (HWVoice *hw);
  21.152 +void      pcm_hw_fini (HWVoice *hw);
  21.153 +void      pcm_hw_gc (HWVoice *hw);
  21.154 +int       pcm_hw_get_live (HWVoice *hw);
  21.155 +int       pcm_hw_get_live2 (HWVoice *hw, int *nb_active);
  21.156 +void      pcm_hw_dec_live (HWVoice *hw, int decr);
  21.157 +int       pcm_hw_write (SWVoice *sw, void *buf, int len);
  21.158 +
  21.159 +int         audio_get_conf_int (const char *key, int defval);
  21.160 +const char *audio_get_conf_str (const char *key, const char *defval);
  21.161 +
  21.162 +struct audio_output_driver;
  21.163 +
  21.164 +#define VOICE_ENABLE 1
  21.165 +#define VOICE_DISABLE 2
  21.166 +
  21.167 +#endif /* audio_int.h */
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/tools/ioemu/audio/mixeng.c	Wed Dec 21 11:56:19 2005 -0600
    22.3 @@ -0,0 +1,255 @@
    22.4 +/*
    22.5 + * QEMU Mixing engine
    22.6 + *
    22.7 + * Copyright (c) 2004 Vassili Karpov (malc)
    22.8 + * Copyright (c) 1998 Fabrice Bellard
    22.9 + *
   22.10 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   22.11 + * of this software and associated documentation files (the "Software"), to deal
   22.12 + * in the Software without restriction, including without limitation the rights
   22.13 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   22.14 + * copies of the Software, and to permit persons to whom the Software is
   22.15 + * furnished to do so, subject to the following conditions:
   22.16 + *
   22.17 + * The above copyright notice and this permission notice shall be included in
   22.18 + * all copies or substantial portions of the Software.
   22.19 + *
   22.20 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   22.21 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   22.22 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   22.23 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   22.24 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   22.25 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   22.26 + * THE SOFTWARE.
   22.27 + */
   22.28 +#include "vl.h"
   22.29 +//#define DEBUG_FP
   22.30 +#include "audio/mixeng.h"
   22.31 +
   22.32 +#define IN_T int8_t
   22.33 +#define IN_MIN CHAR_MIN
   22.34 +#define IN_MAX CHAR_MAX
   22.35 +#define SIGNED
   22.36 +#include "mixeng_template.h"
   22.37 +#undef SIGNED
   22.38 +#undef IN_MAX
   22.39 +#undef IN_MIN
   22.40 +#undef IN_T
   22.41 +
   22.42 +#define IN_T uint8_t
   22.43 +#define IN_MIN 0
   22.44 +#define IN_MAX UCHAR_MAX
   22.45 +#include "mixeng_template.h"
   22.46 +#undef IN_MAX
   22.47 +#undef IN_MIN
   22.48 +#undef IN_T
   22.49 +
   22.50 +#define IN_T int16_t
   22.51 +#define IN_MIN SHRT_MIN
   22.52 +#define IN_MAX SHRT_MAX
   22.53 +#define SIGNED
   22.54 +#include "mixeng_template.h"
   22.55 +#undef SIGNED
   22.56 +#undef IN_MAX
   22.57 +#undef IN_MIN
   22.58 +#undef IN_T
   22.59 +
   22.60 +#define IN_T uint16_t
   22.61 +#define IN_MIN 0
   22.62 +#define IN_MAX USHRT_MAX
   22.63 +#include "mixeng_template.h"
   22.64 +#undef IN_MAX
   22.65 +#undef IN_MIN
   22.66 +#undef IN_T
   22.67 +
   22.68 +t_sample *mixeng_conv[2][2][2] = {
   22.69 +    {
   22.70 +        {
   22.71 +            conv_uint8_t_to_mono,
   22.72 +            conv_uint16_t_to_mono
   22.73 +        },
   22.74 +        {
   22.75 +            conv_int8_t_to_mono,
   22.76 +            conv_int16_t_to_mono
   22.77 +        }
   22.78 +    },
   22.79 +    {
   22.80 +        {
   22.81 +            conv_uint8_t_to_stereo,
   22.82 +            conv_uint16_t_to_stereo
   22.83 +        },
   22.84 +        {
   22.85 +            conv_int8_t_to_stereo,
   22.86 +            conv_int16_t_to_stereo
   22.87 +        }
   22.88 +    }
   22.89 +};
   22.90 +
   22.91 +f_sample *mixeng_clip[2][2][2] = {
   22.92 +    {
   22.93 +        {
   22.94 +            clip_uint8_t_from_mono,
   22.95 +            clip_uint16_t_from_mono
   22.96 +        },
   22.97 +        {
   22.98 +            clip_int8_t_from_mono,
   22.99 +            clip_int16_t_from_mono
  22.100 +        }
  22.101 +    },
  22.102 +    {
  22.103 +        {
  22.104 +            clip_uint8_t_from_stereo,
  22.105 +            clip_uint16_t_from_stereo
  22.106 +        },
  22.107 +        {
  22.108 +            clip_int8_t_from_stereo,
  22.109 +            clip_int16_t_from_stereo
  22.110 +        }
  22.111 +    }
  22.112 +};
  22.113 +
  22.114 +/*
  22.115 + * August 21, 1998
  22.116 + * Copyright 1998 Fabrice Bellard.
  22.117 + *
  22.118 + * [Rewrote completly the code of Lance Norskog And Sundry
  22.119 + * Contributors with a more efficient algorithm.]
  22.120 + *
  22.121 + * This source code is freely redistributable and may be used for
  22.122 + * any purpose.  This copyright notice must be maintained. 
  22.123 + * Lance Norskog And Sundry Contributors are not responsible for 
  22.124 + * the consequences of using this software.  
  22.125 + */
  22.126 +
  22.127 +/*
  22.128 + * Sound Tools rate change effect file.
  22.129 + */
  22.130 +/*
  22.131 + * Linear Interpolation.
  22.132 + *
  22.133 + * The use of fractional increment allows us to use no buffer. It
  22.134 + * avoid the problems at the end of the buffer we had with the old
  22.135 + * method which stored a possibly big buffer of size
  22.136 + * lcm(in_rate,out_rate).
  22.137 + *
  22.138 + * Limited to 16 bit samples and sampling frequency <= 65535 Hz. If
  22.139 + * the input & output frequencies are equal, a delay of one sample is
  22.140 + * introduced.  Limited to processing 32-bit count worth of samples.
  22.141 + *
  22.142 + * 1 << FRAC_BITS evaluating to zero in several places.  Changed with
  22.143 + * an (unsigned long) cast to make it safe.  MarkMLl 2/1/99
  22.144 + */
  22.145 +
  22.146 +/* Private data */
  22.147 +typedef struct ratestuff {
  22.148 +    uint64_t opos;
  22.149 +    uint64_t opos_inc;
  22.150 +    uint32_t ipos;              /* position in the input stream (integer) */
  22.151 +    st_sample_t ilast;          /* last sample in the input stream */
  22.152 +} *rate_t;
  22.153 +
  22.154 +/*
  22.155 + * Prepare processing.
  22.156 + */
  22.157 +void *st_rate_start (int inrate, int outrate)
  22.158 +{
  22.159 +    rate_t rate = (rate_t) qemu_mallocz (sizeof (struct ratestuff));
  22.160 +
  22.161 +    if (!rate) {
  22.162 +        exit (EXIT_FAILURE);
  22.163 +    }
  22.164 +
  22.165 +    if (inrate == outrate) {
  22.166 +        // exit (EXIT_FAILURE);
  22.167 +    }
  22.168 +
  22.169 +    if (inrate >= 65535 || outrate >= 65535) {
  22.170 +        // exit (EXIT_FAILURE);
  22.171 +    }
  22.172 +
  22.173 +    rate->opos = 0;
  22.174 +
  22.175 +    /* increment */
  22.176 +    rate->opos_inc = (inrate * ((int64_t) UINT_MAX)) / outrate;
  22.177 +
  22.178 +    rate->ipos = 0;
  22.179 +    rate->ilast.l = 0;
  22.180 +    rate->ilast.r = 0;
  22.181 +    return rate;
  22.182 +}
  22.183 +
  22.184 +/*
  22.185 + * Processed signed long samples from ibuf to obuf.
  22.186 + * Return number of samples processed.
  22.187 + */
  22.188 +void st_rate_flow (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,
  22.189 +                   int *isamp, int *osamp)
  22.190 +{
  22.191 +    rate_t rate = (rate_t) opaque;
  22.192 +    st_sample_t *istart, *iend;
  22.193 +    st_sample_t *ostart, *oend;
  22.194 +    st_sample_t ilast, icur, out;
  22.195 +    int64_t t;
  22.196 +
  22.197 +    ilast = rate->ilast;
  22.198 +
  22.199 +    istart = ibuf;
  22.200 +    iend = ibuf + *isamp;
  22.201 +
  22.202 +    ostart = obuf;
  22.203 +    oend = obuf + *osamp;
  22.204 +
  22.205 +    if (rate->opos_inc == 1ULL << 32) {
  22.206 +        int i, n = *isamp > *osamp ? *osamp : *isamp;
  22.207 +        for (i = 0; i < n; i++) {
  22.208 +            obuf[i].l += ibuf[i].r;
  22.209 +            obuf[i].r += ibuf[i].r;
  22.210 +        }
  22.211 +        *isamp = n;
  22.212 +        *osamp = n;
  22.213 +        return;
  22.214 +    }
  22.215 +
  22.216 +    while (obuf < oend) {
  22.217 +
  22.218 +        /* Safety catch to make sure we have input samples.  */
  22.219 +        if (ibuf >= iend)
  22.220 +            break;
  22.221 +
  22.222 +        /* read as many input samples so that ipos > opos */
  22.223 +
  22.224 +        while (rate->ipos <= (rate->opos >> 32)) {
  22.225 +            ilast = *ibuf++;
  22.226 +            rate->ipos++;
  22.227 +            /* See if we finished the input buffer yet */
  22.228 +            if (ibuf >= iend) goto the_end;
  22.229 +        }
  22.230 +
  22.231 +        icur = *ibuf;
  22.232 +
  22.233 +        /* interpolate */
  22.234 +        t = rate->opos & 0xffffffff;
  22.235 +        out.l = (ilast.l * (INT_MAX - t) + icur.l * t) / INT_MAX;
  22.236 +        out.r = (ilast.r * (INT_MAX - t) + icur.r * t) / INT_MAX;
  22.237 +
  22.238 +        /* output sample & increment position */
  22.239 +#if 0
  22.240 +        *obuf++ = out;
  22.241 +#else
  22.242 +        obuf->l += out.l;
  22.243 +        obuf->r += out.r;
  22.244 +        obuf += 1;
  22.245 +#endif
  22.246 +        rate->opos += rate->opos_inc;
  22.247 +    }
  22.248 +
  22.249 +the_end:
  22.250 +    *isamp = ibuf - istart;
  22.251 +    *osamp = obuf - ostart;
  22.252 +    rate->ilast = ilast;
  22.253 +}
  22.254 +
  22.255 +void st_rate_stop (void *opaque)
  22.256 +{
  22.257 +    qemu_free (opaque);
  22.258 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/tools/ioemu/audio/mixeng.h	Wed Dec 21 11:56:19 2005 -0600
    23.3 @@ -0,0 +1,39 @@
    23.4 +/*
    23.5 + * QEMU Mixing engine header
    23.6 + * 
    23.7 + * Copyright (c) 2004 Vassili Karpov (malc)
    23.8 + * 
    23.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   23.10 + * of this software and associated documentation files (the "Software"), to deal
   23.11 + * in the Software without restriction, including without limitation the rights
   23.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   23.13 + * copies of the Software, and to permit persons to whom the Software is
   23.14 + * furnished to do so, subject to the following conditions:
   23.15 + *
   23.16 + * The above copyright notice and this permission notice shall be included in
   23.17 + * all copies or substantial portions of the Software.
   23.18 + *
   23.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   23.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   23.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   23.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   23.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   23.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   23.25 + * THE SOFTWARE.
   23.26 + */
   23.27 +#ifndef QEMU_MIXENG_H
   23.28 +#define QEMU_MIXENG_H
   23.29 +
   23.30 +typedef void (t_sample) (void *dst, const void *src, int samples);
   23.31 +typedef void (f_sample) (void *dst, const void *src, int samples);
   23.32 +typedef struct { int64_t l; int64_t r; } st_sample_t;
   23.33 +
   23.34 +extern t_sample *mixeng_conv[2][2][2];
   23.35 +extern f_sample *mixeng_clip[2][2][2];
   23.36 +
   23.37 +void *st_rate_start (int inrate, int outrate);
   23.38 +void st_rate_flow (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,
   23.39 +                   int *isamp, int *osamp);
   23.40 +void st_rate_stop (void *opaque);
   23.41 +
   23.42 +#endif  /* mixeng.h */
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/tools/ioemu/audio/mixeng_template.h	Wed Dec 21 11:56:19 2005 -0600
    24.3 @@ -0,0 +1,111 @@
    24.4 +/*
    24.5 + * QEMU Mixing engine
    24.6 + * 
    24.7 + * Copyright (c) 2004 Vassili Karpov (malc)
    24.8 + * 
    24.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   24.10 + * of this software and associated documentation files (the "Software"), to deal
   24.11 + * in the Software without restriction, including without limitation the rights
   24.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   24.13 + * copies of the Software, and to permit persons to whom the Software is
   24.14 + * furnished to do so, subject to the following conditions:
   24.15 + *
   24.16 + * The above copyright notice and this permission notice shall be included in
   24.17 + * all copies or substantial portions of the Software.
   24.18 + *
   24.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   24.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   24.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   24.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   24.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   24.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   24.25 + * THE SOFTWARE.
   24.26 + */
   24.27 +
   24.28 +/*
   24.29 + * Tusen tack till Mike Nordell
   24.30 + * dec++'ified by Dscho
   24.31 + */
   24.32 +
   24.33 +#ifdef SIGNED
   24.34 +#define HALFT IN_MAX
   24.35 +#define HALF IN_MAX
   24.36 +#else
   24.37 +#define HALFT ((IN_MAX)>>1)
   24.38 +#define HALF HALFT
   24.39 +#endif
   24.40 +
   24.41 +static int64_t inline glue(conv_,IN_T) (IN_T v)
   24.42 +{
   24.43 +#ifdef SIGNED
   24.44 +    return (INT_MAX*(int64_t)v)/HALF;
   24.45 +#else
   24.46 +    return (INT_MAX*((int64_t)v-HALFT))/HALF;
   24.47 +#endif
   24.48 +}
   24.49 +
   24.50 +static IN_T inline glue(clip_,IN_T) (int64_t v)
   24.51 +{
   24.52 +    if (v >= INT_MAX)
   24.53 +        return IN_MAX;
   24.54 +    else if (v < -INT_MAX)
   24.55 +        return IN_MIN;
   24.56 +
   24.57 +#ifdef SIGNED
   24.58 +    return (IN_T) (v*HALF/INT_MAX);
   24.59 +#else
   24.60 +    return (IN_T) (v+INT_MAX/2)*HALF/INT_MAX;
   24.61 +#endif
   24.62 +}
   24.63 +
   24.64 +static void glue(glue(conv_,IN_T),_to_stereo) (void *dst, const void *src,
   24.65 +                                               int samples)
   24.66 +{
   24.67 +    st_sample_t *out = (st_sample_t *) dst;
   24.68 +    IN_T *in = (IN_T *) src;
   24.69 +    while (samples--) {
   24.70 +        out->l = glue(conv_,IN_T) (*in++);
   24.71 +        out->r = glue(conv_,IN_T) (*in++);
   24.72 +        out += 1;
   24.73 +    }
   24.74 +}
   24.75 +
   24.76 +static void glue(glue(conv_,IN_T),_to_mono) (void *dst, const void *src,
   24.77 +                                             int samples)
   24.78 +{
   24.79 +    st_sample_t *out = (st_sample_t *) dst;
   24.80 +    IN_T *in = (IN_T *) src;
   24.81 +    while (samples--) {
   24.82 +        out->l = glue(conv_,IN_T) (in[0]);
   24.83 +        out->r = out->l;
   24.84 +        out += 1;
   24.85 +        in += 1;
   24.86 +    }
   24.87 +}
   24.88 +
   24.89 +static void glue(glue(clip_,IN_T),_from_stereo) (void *dst, const void *src,
   24.90 +                                                 int samples)
   24.91 +{
   24.92 +    st_sample_t *in = (st_sample_t *) src;
   24.93 +    IN_T *out = (IN_T *) dst;
   24.94 +    while (samples--) {
   24.95 +        *out++ = glue(clip_,IN_T) (in->l);
   24.96 +        *out++ = glue(clip_,IN_T) (in->r);
   24.97 +        in += 1;
   24.98 +    }
   24.99 +}
  24.100 +
  24.101 +static void glue(glue(clip_,IN_T),_from_mono) (void *dst, const void *src,
  24.102 +                                               int samples)
  24.103 +{
  24.104 +    st_sample_t *in = (st_sample_t *) src;
  24.105 +    IN_T *out = (IN_T *) dst;
  24.106 +    while (samples--) {
  24.107 +        *out++ = glue(clip_,IN_T) (in->l + in->r);
  24.108 +        in += 1;
  24.109 +    }
  24.110 +}
  24.111 +
  24.112 +#undef HALF
  24.113 +#undef HALFT
  24.114 +
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/tools/ioemu/audio/noaudio.c	Wed Dec 21 11:56:19 2005 -0600
    25.3 @@ -0,0 +1,130 @@
    25.4 +/*
    25.5 + * QEMU NULL audio output driver
    25.6 + * 
    25.7 + * Copyright (c) 2004 Vassili Karpov (malc)
    25.8 + * 
    25.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   25.10 + * of this software and associated documentation files (the "Software"), to deal
   25.11 + * in the Software without restriction, including without limitation the rights
   25.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   25.13 + * copies of the Software, and to permit persons to whom the Software is
   25.14 + * furnished to do so, subject to the following conditions:
   25.15 + *
   25.16 + * The above copyright notice and this permission notice shall be included in
   25.17 + * all copies or substantial portions of the Software.
   25.18 + *
   25.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   25.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   25.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   25.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   25.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   25.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   25.25 + * THE SOFTWARE.
   25.26 + */
   25.27 +#include "vl.h"
   25.28 +
   25.29 +#include "audio/audio_int.h"
   25.30 +
   25.31 +typedef struct NoVoice {
   25.32 +    HWVoice hw;
   25.33 +    int64_t old_ticks;
   25.34 +} NoVoice;
   25.35 +
   25.36 +#define dolog(...) AUD_log ("noaudio", __VA_ARGS__)
   25.37 +#ifdef DEBUG
   25.38 +#define ldebug(...) dolog (__VA_ARGS__)
   25.39 +#else
   25.40 +#define ldebug(...)
   25.41 +#endif
   25.42 +
   25.43 +static void no_hw_run (HWVoice *hw)
   25.44 +{
   25.45 +    NoVoice *no = (NoVoice *) hw;
   25.46 +    int rpos, live, decr, samples;
   25.47 +    uint8_t *dst;
   25.48 +    st_sample_t *src;
   25.49 +    int64_t now = qemu_get_clock (vm_clock);
   25.50 +    int64_t ticks = now - no->old_ticks;
   25.51 +    int64_t bytes = (ticks * hw->bytes_per_second) / ticks_per_sec;
   25.52 +
   25.53 +    if (bytes > INT_MAX)
   25.54 +        samples = INT_MAX >> hw->shift;
   25.55 +    else
   25.56 +        samples = bytes >> hw->shift;
   25.57 +
   25.58 +    live = pcm_hw_get_live (hw);
   25.59 +    if (live <= 0)
   25.60 +        return;
   25.61 +
   25.62 +    no->old_ticks = now;
   25.63 +    decr = audio_MIN (live, samples);
   25.64 +    samples = decr;
   25.65 +    rpos = hw->rpos;
   25.66 +    while (samples) {
   25.67 +        int left_till_end_samples = hw->samples - rpos;
   25.68 +        int convert_samples = audio_MIN (samples, left_till_end_samples);
   25.69 +
   25.70 +        src = advance (hw->mix_buf, rpos * sizeof (st_sample_t));
   25.71 +        memset (src, 0, convert_samples * sizeof (st_sample_t));
   25.72 +
   25.73 +        rpos = (rpos + convert_samples) % hw->samples;
   25.74 +        samples -= convert_samples;
   25.75 +    }
   25.76 +
   25.77 +    pcm_hw_dec_live (hw, decr);
   25.78 +    hw->rpos = rpos;
   25.79 +}
   25.80 +
   25.81 +static int no_hw_write (SWVoice *sw, void *buf, int len)
   25.82 +{
   25.83 +    return pcm_hw_write (sw, buf, len);
   25.84 +}
   25.85 +
   25.86 +static int no_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
   25.87 +{
   25.88 +    NoVoice *no = (NoVoice *) hw;
   25.89 +    hw->freq = freq;
   25.90 +    hw->nchannels = nchannels;
   25.91 +    hw->fmt = fmt;
   25.92 +    hw->bufsize = 4096;
   25.93 +    return 0;
   25.94 +}
   25.95 +
   25.96 +static void no_hw_fini (HWVoice *hw)
   25.97 +{
   25.98 +    (void) hw;
   25.99 +}
  25.100 +
  25.101 +static int no_hw_ctl (HWVoice *hw, int cmd, ...)
  25.102 +{
  25.103 +    (void) hw;
  25.104 +    (void) cmd;
  25.105 +    return 0;
  25.106 +}
  25.107 +
  25.108 +static void *no_audio_init (void)
  25.109 +{
  25.110 +    return &no_audio_init;
  25.111 +}
  25.112 +
  25.113 +static void no_audio_fini (void *opaque)
  25.114 +{
  25.115 +}
  25.116 +
  25.117 +struct pcm_ops no_pcm_ops = {
  25.118 +    no_hw_init,
  25.119 +    no_hw_fini,
  25.120 +    no_hw_run,
  25.121 +    no_hw_write,
  25.122 +    no_hw_ctl
  25.123 +};
  25.124 +
  25.125 +struct audio_output_driver no_output_driver = {
  25.126 +    "none",
  25.127 +    no_audio_init,
  25.128 +    no_audio_fini,
  25.129 +    &no_pcm_ops,
  25.130 +    1,
  25.131 +    1,
  25.132 +    sizeof (NoVoice)
  25.133 +};
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/tools/ioemu/audio/ossaudio.c	Wed Dec 21 11:56:19 2005 -0600
    26.3 @@ -0,0 +1,475 @@
    26.4 +/*
    26.5 + * QEMU OSS audio output driver
    26.6 + * 
    26.7 + * Copyright (c) 2003-2004 Vassili Karpov (malc)
    26.8 + * 
    26.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   26.10 + * of this software and associated documentation files (the "Software"), to deal
   26.11 + * in the Software without restriction, including without limitation the rights
   26.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   26.13 + * copies of the Software, and to permit persons to whom the Software is
   26.14 + * furnished to do so, subject to the following conditions:
   26.15 + *
   26.16 + * The above copyright notice and this permission notice shall be included in
   26.17 + * all copies or substantial portions of the Software.
   26.18 + *
   26.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   26.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   26.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   26.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   26.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   26.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   26.25 + * THE SOFTWARE.
   26.26 + */
   26.27 +#include <sys/mman.h>
   26.28 +#include <sys/types.h>
   26.29 +#include <sys/ioctl.h>
   26.30 +#include <sys/soundcard.h>
   26.31 +#include <assert.h>
   26.32 +#include "vl.h"
   26.33 +
   26.34 +#include "audio/audio_int.h"
   26.35 +
   26.36 +typedef struct OSSVoice {
   26.37 +    HWVoice hw;
   26.38 +    void *pcm_buf;
   26.39 +    int fd;
   26.40 +    int nfrags;
   26.41 +    int fragsize;
   26.42 +    int mmapped;
   26.43 +    int old_optr;
   26.44 +} OSSVoice;
   26.45 +
   26.46 +#define dolog(...) AUD_log ("oss", __VA_ARGS__)
   26.47 +#ifdef DEBUG
   26.48 +#define ldebug(...) dolog (__VA_ARGS__)
   26.49 +#else
   26.50 +#define ldebug(...)
   26.51 +#endif
   26.52 +
   26.53 +#define QC_OSS_FRAGSIZE "QEMU_OSS_FRAGSIZE"
   26.54 +#define QC_OSS_NFRAGS   "QEMU_OSS_NFRAGS"
   26.55 +#define QC_OSS_MMAP     "QEMU_OSS_MMAP"
   26.56 +#define QC_OSS_DEV      "QEMU_OSS_DEV"
   26.57 +
   26.58 +#define errstr() strerror (errno)
   26.59 +
   26.60 +static struct {
   26.61 +    int try_mmap;
   26.62 +    int nfrags;
   26.63 +    int fragsize;
   26.64 +    const char *dspname;
   26.65 +} conf = {
   26.66 +    .try_mmap = 0,
   26.67 +    .nfrags = 4,
   26.68 +    .fragsize = 4096,
   26.69 +    .dspname = "/dev/dsp"
   26.70 +};
   26.71 +
   26.72 +struct oss_params {
   26.73 +    int freq;
   26.74 +    audfmt_e fmt;
   26.75 +    int nchannels;
   26.76 +    int nfrags;
   26.77 +    int fragsize;
   26.78 +};
   26.79 +
   26.80 +static int oss_hw_write (SWVoice *sw, void *buf, int len)
   26.81 +{
   26.82 +    return pcm_hw_write (sw, buf, len);
   26.83 +}
   26.84 +
   26.85 +static int AUD_to_ossfmt (audfmt_e fmt)
   26.86 +{
   26.87 +    switch (fmt) {
   26.88 +    case AUD_FMT_S8: return AFMT_S8;
   26.89 +    case AUD_FMT_U8: return AFMT_U8;
   26.90 +    case AUD_FMT_S16: return AFMT_S16_LE;
   26.91 +    case AUD_FMT_U16: return AFMT_U16_LE;
   26.92 +    default:
   26.93 +        dolog ("Internal logic error: Bad audio format %d\nAborting\n", fmt);
   26.94 +        exit (EXIT_FAILURE);
   26.95 +    }
   26.96 +}
   26.97 +
   26.98 +static int oss_to_audfmt (int fmt)
   26.99 +{
  26.100 +    switch (fmt) {
  26.101 +    case AFMT_S8: return AUD_FMT_S8;
  26.102 +    case AFMT_U8: return AUD_FMT_U8;
  26.103 +    case AFMT_S16_LE: return AUD_FMT_S16;
  26.104 +    case AFMT_U16_LE: return AUD_FMT_U16;
  26.105 +    default:
  26.106 +        dolog ("Internal logic error: Unrecognized OSS audio format %d\n"
  26.107 +               "Aborting\n",
  26.108 +               fmt);
  26.109 +        exit (EXIT_FAILURE);
  26.110 +    }
  26.111 +}
  26.112 +
  26.113 +#ifdef DEBUG_PCM
  26.114 +static void oss_dump_pcm_info (struct oss_params *req, struct oss_params *obt)
  26.115 +{
  26.116 +    dolog ("parameter | requested value | obtained value\n");
  26.117 +    dolog ("format    |      %10d |     %10d\n", req->fmt, obt->fmt);
  26.118 +    dolog ("channels  |      %10d |     %10d\n", req->nchannels, obt->nchannels);
  26.119 +    dolog ("frequency |      %10d |     %10d\n", req->freq, obt->freq);
  26.120 +    dolog ("nfrags    |      %10d |     %10d\n", req->nfrags, obt->nfrags);
  26.121 +    dolog ("fragsize  |      %10d |     %10d\n", req->fragsize, obt->fragsize);
  26.122 +}
  26.123 +#endif
  26.124 +
  26.125 +static int oss_open (struct oss_params *req, struct oss_params *obt, int *pfd)
  26.126 +{
  26.127 +    int fd;
  26.128 +    int mmmmssss;
  26.129 +    audio_buf_info abinfo;
  26.130 +    int fmt, freq, nchannels;
  26.131 +    const char *dspname = conf.dspname;
  26.132 +
  26.133 +    fd = open (dspname, O_RDWR | O_NONBLOCK);
  26.134 +    if (-1 == fd) {
  26.135 +        dolog ("Could not initialize audio hardware. Failed to open `%s':\n"
  26.136 +               "Reason:%s\n",
  26.137 +               dspname,
  26.138 +               errstr ());
  26.139 +        return -1;
  26.140 +    }
  26.141 +
  26.142 +    freq = req->freq;
  26.143 +    nchannels = req->nchannels;
  26.144 +    fmt = req->fmt;
  26.145 +
  26.146 +    if (ioctl (fd, SNDCTL_DSP_SAMPLESIZE, &fmt)) {
  26.147 +        dolog ("Could not initialize audio hardware\n"
  26.148 +               "Failed to set sample size\n"
  26.149 +               "Reason: %s\n",
  26.150 +               errstr ());
  26.151 +        goto err;
  26.152 +    }
  26.153 +
  26.154 +    if (ioctl (fd, SNDCTL_DSP_CHANNELS, &nchannels)) {
  26.155 +        dolog ("Could not initialize audio hardware\n"
  26.156 +               "Failed to set number of channels\n"
  26.157 +               "Reason: %s\n",
  26.158 +               errstr ());
  26.159 +        goto err;
  26.160 +    }
  26.161 +
  26.162 +    if (ioctl (fd, SNDCTL_DSP_SPEED, &freq)) {
  26.163 +        dolog ("Could not initialize audio hardware\n"
  26.164 +               "Failed to set frequency\n"
  26.165 +               "Reason: %s\n",
  26.166 +               errstr ());
  26.167 +        goto err;
  26.168 +    }
  26.169 +
  26.170 +    if (ioctl (fd, SNDCTL_DSP_NONBLOCK)) {
  26.171 +        dolog ("Could not initialize audio hardware\n"
  26.172 +               "Failed to set non-blocking mode\n"
  26.173 +               "Reason: %s\n",
  26.174 +               errstr ());
  26.175 +        goto err;
  26.176 +    }
  26.177 +
  26.178 +    mmmmssss = (req->nfrags << 16) | lsbindex (req->fragsize);
  26.179 +    if (ioctl (fd, SNDCTL_DSP_SETFRAGMENT, &mmmmssss)) {
  26.180 +        dolog ("Could not initialize audio hardware\n"
  26.181 +               "Failed to set buffer length (%d, %d)\n"
  26.182 +               "Reason:%s\n",
  26.183 +               conf.nfrags, conf.fragsize,
  26.184 +               errstr ());
  26.185 +        goto err;
  26.186 +    }
  26.187 +
  26.188 +    if (ioctl (fd, SNDCTL_DSP_GETOSPACE, &abinfo)) {
  26.189 +        dolog ("Could not initialize audio hardware\n"
  26.190 +               "Failed to get buffer length\n"
  26.191 +               "Reason:%s\n",
  26.192 +               errstr ());
  26.193 +        goto err;
  26.194 +    }
  26.195 +
  26.196 +    obt->fmt = fmt;
  26.197 +    obt->nchannels = nchannels;
  26.198 +    obt->freq = freq;
  26.199 +    obt->nfrags = abinfo.fragstotal;
  26.200 +    obt->fragsize = abinfo.fragsize;
  26.201 +    *pfd = fd;
  26.202 +
  26.203 +    if ((req->fmt != obt->fmt) ||
  26.204 +        (req->nchannels != obt->nchannels) ||
  26.205 +        (req->freq != obt->freq) ||
  26.206 +        (req->fragsize != obt->fragsize) ||
  26.207 +        (req->nfrags != obt->nfrags)) {
  26.208 +#ifdef DEBUG_PCM
  26.209 +        dolog ("Audio parameters mismatch\n");
  26.210 +        oss_dump_pcm_info (req, obt);
  26.211 +#endif
  26.212 +    }
  26.213 +
  26.214 +#ifdef DEBUG_PCM
  26.215 +    oss_dump_pcm_info (req, obt);
  26.216 +#endif
  26.217 +    return 0;
  26.218 +
  26.219 +err:
  26.220 +    close (fd);
  26.221 +    return -1;
  26.222 +}
  26.223 +
  26.224 +static void oss_hw_run (HWVoice *hw)
  26.225 +{
  26.226 +    OSSVoice *oss = (OSSVoice *) hw;
  26.227 +    int err, rpos, live, decr;
  26.228 +    int samples;
  26.229 +    uint8_t *dst;
  26.230 +    st_sample_t *src;
  26.231 +    struct audio_buf_info abinfo;
  26.232 +    struct count_info cntinfo;
  26.233 +
  26.234 +    live = pcm_hw_get_live (hw);
  26.235 +    if (live <= 0)
  26.236 +        return;
  26.237 +
  26.238 +    if (oss->mmapped) {
  26.239 +        int bytes;
  26.240 +
  26.241 +        err = ioctl (oss->fd, SNDCTL_DSP_GETOPTR, &cntinfo);
  26.242 +        if (err < 0) {
  26.243 +            dolog ("SNDCTL_DSP_GETOPTR failed\nReason: %s\n", errstr ());
  26.244 +            return;
  26.245 +        }
  26.246 +
  26.247 +        if (cntinfo.ptr == oss->old_optr) {
  26.248 +            if (abs (hw->samples - live) < 64)
  26.249 +                dolog ("overrun\n");
  26.250 +            return;
  26.251 +        }
  26.252 +
  26.253 +        if (cntinfo.ptr > oss->old_optr) {
  26.254 +            bytes = cntinfo.ptr - oss->old_optr;
  26.255 +        }
  26.256 +        else {
  26.257 +            bytes = hw->bufsize + cntinfo.ptr - oss->old_optr;
  26.258 +        }
  26.259 +
  26.260 +        decr = audio_MIN (bytes >> hw->shift, live);
  26.261 +    }
  26.262 +    else {
  26.263 +        err = ioctl (oss->fd, SNDCTL_DSP_GETOSPACE, &abinfo);
  26.264 +        if (err < 0) {
  26.265 +            dolog ("SNDCTL_DSP_GETOSPACE failed\nReason: %s\n", errstr ());
  26.266 +            return;
  26.267 +        }
  26.268 +
  26.269 +        decr = audio_MIN (abinfo.bytes >> hw->shift, live);
  26.270 +        if (decr <= 0)
  26.271 +            return;
  26.272 +    }
  26.273 +
  26.274 +    samples = decr;
  26.275 +    rpos = hw->rpos;
  26.276 +    while (samples) {
  26.277 +        int left_till_end_samples = hw->samples - rpos;
  26.278 +        int convert_samples = audio_MIN (samples, left_till_end_samples);
  26.279 +
  26.280 +        src = advance (hw->mix_buf, rpos * sizeof (st_sample_t));
  26.281 +        dst = advance (oss->pcm_buf, rpos << hw->shift);
  26.282 +
  26.283 +        hw->clip (dst, src, convert_samples);
  26.284 +        if (!oss->mmapped) {
  26.285 +            int written;
  26.286 +
  26.287 +            written = write (oss->fd, dst, convert_samples << hw->shift);
  26.288 +            /* XXX: follow errno recommendations ? */
  26.289 +            if (written == -1) {
  26.290 +                dolog ("Failed to write audio\nReason: %s\n", errstr ());
  26.291 +                continue;
  26.292 +            }
  26.293 +
  26.294 +            if (written != convert_samples << hw->shift) {
  26.295 +                int wsamples = written >> hw->shift;
  26.296 +                int wbytes = wsamples << hw->shift;
  26.297 +                if (wbytes != written) {
  26.298 +                    dolog ("Unaligned write %d, %d\n", wbytes, written);
  26.299 +                }
  26.300 +                memset (src, 0, wbytes);
  26.301 +                decr -= samples;
  26.302 +                rpos = (rpos + wsamples) % hw->samples;
  26.303 +                break;
  26.304 +            }
  26.305 +        }
  26.306 +        memset (src, 0, convert_samples * sizeof (st_sample_t));
  26.307 +
  26.308 +        rpos = (rpos + convert_samples) % hw->samples;
  26.309 +        samples -= convert_samples;
  26.310 +    }
  26.311 +    if (oss->mmapped) {
  26.312 +        oss->old_optr = cntinfo.ptr;
  26.313 +    }
  26.314 +
  26.315 +    pcm_hw_dec_live (hw, decr);
  26.316 +    hw->rpos = rpos;
  26.317 +}
  26.318 +
  26.319 +static void oss_hw_fini (HWVoice *hw)
  26.320 +{
  26.321 +    int err;
  26.322 +    OSSVoice *oss = (OSSVoice *) hw;
  26.323 +
  26.324 +    ldebug ("oss_hw_fini\n");
  26.325 +    err = close (oss->fd);
  26.326 +    if (err) {
  26.327 +        dolog ("Failed to close OSS descriptor\nReason: %s\n", errstr ());
  26.328 +    }
  26.329 +    oss->fd = -1;
  26.330 +
  26.331 +    if (oss->pcm_buf) {
  26.332 +        if (oss->mmapped) {
  26.333 +            err = munmap (oss->pcm_buf, hw->bufsize);
  26.334 +            if (err) {
  26.335 +                dolog ("Failed to unmap OSS buffer\nReason: %s\n",
  26.336 +                       errstr ());
  26.337 +            }
  26.338 +        }
  26.339 +        else {
  26.340 +            qemu_free (oss->pcm_buf);
  26.341 +        }
  26.342 +        oss->pcm_buf = NULL;
  26.343 +    }
  26.344 +}
  26.345 +
  26.346 +static int oss_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
  26.347 +{
  26.348 +    OSSVoice *oss = (OSSVoice *) hw;
  26.349 +    struct oss_params req, obt;
  26.350 +
  26.351 +    assert (!oss->fd);
  26.352 +    req.fmt = AUD_to_ossfmt (fmt);
  26.353 +    req.freq = freq;
  26.354 +    req.nchannels = nchannels;
  26.355 +    req.fragsize = conf.fragsize;
  26.356 +    req.nfrags = conf.nfrags;
  26.357 +
  26.358 +    if (oss_open (&req, &obt, &oss->fd))
  26.359 +        return -1;
  26.360 +
  26.361 +    hw->freq = obt.freq;
  26.362 +    hw->fmt = oss_to_audfmt (obt.fmt);
  26.363 +    hw->nchannels = obt.nchannels;
  26.364 +
  26.365 +    oss->nfrags = obt.nfrags;
  26.366 +    oss->fragsize = obt.fragsize;
  26.367 +    hw->bufsize = obt.nfrags * obt.fragsize;
  26.368 +
  26.369 +    oss->mmapped = 0;
  26.370 +    if (conf.try_mmap) {
  26.371 +        oss->pcm_buf = mmap (0, hw->bufsize, PROT_READ | PROT_WRITE,
  26.372 +                             MAP_SHARED, oss->fd, 0);
  26.373 +        if (oss->pcm_buf == MAP_FAILED) {
  26.374 +            dolog ("Failed to mmap OSS device\nReason: %s\n",
  26.375 +                   errstr ());
  26.376 +        } else {
  26.377 +            int err;
  26.378 +            int trig = 0;
  26.379 +            if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
  26.380 +                dolog ("SNDCTL_DSP_SETTRIGGER 0 failed\nReason: %s\n",
  26.381 +                       errstr ());
  26.382 +            }
  26.383 +            else {
  26.384 +                trig = PCM_ENABLE_OUTPUT;
  26.385 +                if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
  26.386 +                    dolog ("SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
  26.387 +                           "Reason: %s\n", errstr ());
  26.388 +                }
  26.389 +                else {
  26.390 +                    oss->mmapped = 1;
  26.391 +                }
  26.392 +            }
  26.393 +
  26.394 +            if (!oss->mmapped) {
  26.395 +                err = munmap (oss->pcm_buf, hw->bufsize);
  26.396 +                if (err) {
  26.397 +                    dolog ("Failed to unmap OSS device\nReason: %s\n",
  26.398 +                           errstr ());
  26.399 +                }
  26.400 +            }
  26.401 +        }
  26.402 +    }
  26.403 +
  26.404 +    if (!oss->mmapped) {
  26.405 +        oss->pcm_buf = qemu_mallocz (hw->bufsize);
  26.406 +        if (!oss->pcm_buf) {
  26.407 +            close (oss->fd);
  26.408 +            oss->fd = -1;
  26.409 +            return -1;
  26.410 +        }
  26.411 +    }
  26.412 +
  26.413 +    return 0;
  26.414 +}
  26.415 +
  26.416 +static int oss_hw_ctl (HWVoice *hw, int cmd, ...)
  26.417 +{
  26.418 +    int trig;
  26.419 +    OSSVoice *oss = (OSSVoice *) hw;
  26.420 +
  26.421 +    if (!oss->mmapped)
  26.422 +        return 0;
  26.423 +
  26.424 +    switch (cmd) {
  26.425 +    case VOICE_ENABLE:
  26.426 +        ldebug ("enabling voice\n");
  26.427 +        pcm_hw_clear (hw, oss->pcm_buf, hw->samples);
  26.428 +        trig = PCM_ENABLE_OUTPUT;
  26.429 +        if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
  26.430 +            dolog ("SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
  26.431 +                   "Reason: %s\n", errstr ());
  26.432 +            return -1;
  26.433 +        }
  26.434 +        break;
  26.435 +
  26.436 +    case VOICE_DISABLE:
  26.437 +        ldebug ("disabling voice\n");
  26.438 +        trig = 0;
  26.439 +        if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
  26.440 +            dolog ("SNDCTL_DSP_SETTRIGGER 0 failed\nReason: %s\n",
  26.441 +                   errstr ());
  26.442 +            return -1;
  26.443 +        }
  26.444 +        break;
  26.445 +    }
  26.446 +    return 0;
  26.447 +}
  26.448 +
  26.449 +static void *oss_audio_init (void)
  26.450 +{
  26.451 +    conf.fragsize = audio_get_conf_int (QC_OSS_FRAGSIZE, conf.fragsize);
  26.452 +    conf.nfrags = audio_get_conf_int (QC_OSS_NFRAGS, conf.nfrags);
  26.453 +    conf.try_mmap = audio_get_conf_int (QC_OSS_MMAP, conf.try_mmap);
  26.454 +    conf.dspname = audio_get_conf_str (QC_OSS_DEV, conf.dspname);
  26.455 +    return &conf;
  26.456 +}
  26.457 +
  26.458 +static void oss_audio_fini (void *opaque)
  26.459 +{
  26.460 +}
  26.461 +
  26.462 +struct pcm_ops oss_pcm_ops = {
  26.463 +    oss_hw_init,
  26.464 +    oss_hw_fini,
  26.465 +    oss_hw_run,
  26.466 +    oss_hw_write,
  26.467 +    oss_hw_ctl
  26.468 +};
  26.469 +
  26.470 +struct audio_output_driver oss_output_driver = {
  26.471 +    "oss",
  26.472 +    oss_audio_init,
  26.473 +    oss_audio_fini,
  26.474 +    &oss_pcm_ops,
  26.475 +    1,
  26.476 +    INT_MAX,
  26.477 +    sizeof (OSSVoice)
  26.478 +};
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/tools/ioemu/audio/sdlaudio.c	Wed Dec 21 11:56:19 2005 -0600
    27.3 @@ -0,0 +1,332 @@
    27.4 +/*
    27.5 + * QEMU SDL audio output driver
    27.6 + * 
    27.7 + * Copyright (c) 2004 Vassili Karpov (malc)
    27.8 + * 
    27.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   27.10 + * of this software and associated documentation files (the "Software"), to deal
   27.11 + * in the Software without restriction, including without limitation the rights
   27.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   27.13 + * copies of the Software, and to permit persons to whom the Software is
   27.14 + * furnished to do so, subject to the following conditions:
   27.15 + *
   27.16 + * The above copyright notice and this permission notice shall be included in
   27.17 + * all copies or substantial portions of the Software.
   27.18 + *
   27.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   27.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   27.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   27.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   27.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   27.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   27.25 + * THE SOFTWARE.
   27.26 + */
   27.27 +#include <SDL.h>
   27.28 +#include <SDL_thread.h>
   27.29 +#include "vl.h"
   27.30 +
   27.31 +#include "audio/audio_int.h"
   27.32 +
   27.33 +typedef struct SDLVoice {
   27.34 +    HWVoice hw;
   27.35 +} SDLVoice;
   27.36 +
   27.37 +#define dolog(...) AUD_log ("sdl", __VA_ARGS__)
   27.38 +#ifdef DEBUG
   27.39 +#define ldebug(...) dolog (__VA_ARGS__)
   27.40 +#else
   27.41 +#define ldebug(...)
   27.42 +#endif
   27.43 +
   27.44 +#define QC_SDL_SAMPLES "QEMU_SDL_SAMPLES"
   27.45 +
   27.46 +#define errstr() SDL_GetError ()
   27.47 +
   27.48 +static struct {
   27.49 +    int nb_samples;
   27.50 +} conf = {
   27.51 +    1024
   27.52 +};
   27.53 +
   27.54 +struct SDLAudioState {
   27.55 +    int exit;
   27.56 +    SDL_mutex *mutex;
   27.57 +    SDL_sem *sem;
   27.58 +    int initialized;
   27.59 +} glob_sdl;
   27.60 +typedef struct SDLAudioState SDLAudioState;
   27.61 +
   27.62 +static void sdl_hw_run (HWVoice *hw)
   27.63 +{
   27.64 +    (void) hw;
   27.65 +}
   27.66 +
   27.67 +static int sdl_lock (SDLAudioState *s)
   27.68 +{
   27.69 +    if (SDL_LockMutex (s->mutex)) {
   27.70 +        dolog ("SDL_LockMutex failed\nReason: %s\n", errstr ());
   27.71 +        return -1;
   27.72 +    }
   27.73 +    return 0;
   27.74 +}
   27.75 +
   27.76 +static int sdl_unlock (SDLAudioState *s)
   27.77 +{
   27.78 +    if (SDL_UnlockMutex (s->mutex)) {
   27.79 +        dolog ("SDL_UnlockMutex failed\nReason: %s\n", errstr ());
   27.80 +        return -1;
   27.81 +    }
   27.82 +    return 0;
   27.83 +}
   27.84 +
   27.85 +static int sdl_post (SDLAudioState *s)
   27.86 +{
   27.87 +    if (SDL_SemPost (s->sem)) {
   27.88 +        dolog ("SDL_SemPost failed\nReason: %s\n", errstr ());
   27.89 +        return -1;
   27.90 +    }
   27.91 +    return 0;
   27.92 +}
   27.93 +
   27.94 +static int sdl_wait (SDLAudioState *s)
   27.95 +{
   27.96 +    if (SDL_SemWait (s->sem)) {
   27.97 +        dolog ("SDL_SemWait failed\nReason: %s\n", errstr ());
   27.98 +        return -1;
   27.99 +    }
  27.100 +    return 0;
  27.101 +}
  27.102 +
  27.103 +static int sdl_unlock_and_post (SDLAudioState *s)
  27.104 +{
  27.105 +    if (sdl_unlock (s))
  27.106 +        return -1;
  27.107 +
  27.108 +    return sdl_post (s);
  27.109 +}
  27.110 +
  27.111 +static int sdl_hw_write (SWVoice *sw, void *buf, int len)
  27.112 +{
  27.113 +    int ret;
  27.114 +    SDLAudioState *s = &glob_sdl;
  27.115 +    sdl_lock (s);
  27.116 +    ret = pcm_hw_write (sw, buf, len);
  27.117 +    sdl_unlock_and_post (s);
  27.118 +    return ret;
  27.119 +}
  27.120 +
  27.121 +static int AUD_to_sdlfmt (audfmt_e fmt, int *shift)
  27.122 +{
  27.123 +    *shift = 0;
  27.124 +    switch (fmt) {
  27.125 +    case AUD_FMT_S8: return AUDIO_S8;
  27.126 +    case AUD_FMT_U8: return AUDIO_U8;
  27.127 +    case AUD_FMT_S16: *shift = 1; return AUDIO_S16LSB;
  27.128 +    case AUD_FMT_U16: *shift = 1; return AUDIO_U16LSB;
  27.129 +    default:
  27.130 +        dolog ("Internal logic error: Bad audio format %d\nAborting\n", fmt);
  27.131 +        exit (EXIT_FAILURE);
  27.132 +    }
  27.133 +}
  27.134 +
  27.135 +static int sdl_to_audfmt (int fmt)
  27.136 +{
  27.137 +    switch (fmt) {
  27.138 +    case AUDIO_S8: return AUD_FMT_S8;
  27.139 +    case AUDIO_U8: return AUD_FMT_U8;
  27.140 +    case AUDIO_S16LSB: return AUD_FMT_S16;
  27.141 +    case AUDIO_U16LSB: return AUD_FMT_U16;
  27.142 +    default:
  27.143 +        dolog ("Internal logic error: Unrecognized SDL audio format %d\n"
  27.144 +               "Aborting\n", fmt);
  27.145 +        exit (EXIT_FAILURE);
  27.146 +    }
  27.147 +}
  27.148 +
  27.149 +static int sdl_open (SDL_AudioSpec *req, SDL_AudioSpec *obt)
  27.150 +{
  27.151 +    int status;
  27.152 +
  27.153 +    status = SDL_OpenAudio (req, obt);
  27.154 +    if (status) {
  27.155 +        dolog ("SDL_OpenAudio failed\nReason: %s\n", errstr ());
  27.156 +    }
  27.157 +    return status;
  27.158 +}
  27.159 +
  27.160 +static void sdl_close (SDLAudioState *s)
  27.161 +{
  27.162 +    if (s->initialized) {
  27.163 +        sdl_lock (s);
  27.164 +        s->exit = 1;
  27.165 +        sdl_unlock_and_post (s);
  27.166 +        SDL_PauseAudio (1);
  27.167 +        SDL_CloseAudio ();
  27.168 +        s->initialized = 0;
  27.169 +    }
  27.170 +}
  27.171 +
  27.172 +static void sdl_callback (void *opaque, Uint8 *buf, int len)
  27.173 +{
  27.174 +    SDLVoice *sdl = opaque;
  27.175 +    SDLAudioState *s = &glob_sdl;
  27.176 +    HWVoice *hw = &sdl->hw;
  27.177 +    int samples = len >> hw->shift;
  27.178 +
  27.179 +    if (s->exit) {
  27.180 +        return;
  27.181 +    }
  27.182 +
  27.183 +    while (samples) {
  27.184 +        int to_mix, live, decr;
  27.185 +
  27.186 +        /* dolog ("in callback samples=%d\n", samples); */
  27.187 +        sdl_wait (s);
  27.188 +        if (s->exit) {
  27.189 +            return;
  27.190 +        }
  27.191 +
  27.192 +        sdl_lock (s);
  27.193 +        live = pcm_hw_get_live (hw);
  27.194 +        if (live <= 0)
  27.195 +            goto again;
  27.196 +
  27.197 +        /* dolog ("in callback live=%d\n", live); */
  27.198 +        to_mix = audio_MIN (samples, live);
  27.199 +        decr = to_mix;
  27.200 +        while (to_mix) {
  27.201 +            int chunk = audio_MIN (to_mix, hw->samples - hw->rpos);
  27.202 +            st_sample_t *src = hw->mix_buf + hw->rpos;
  27.203 +
  27.204 +            /* dolog ("in callback to_mix %d, chunk %d\n", to_mix, chunk); */
  27.205 +            hw->clip (buf, src, chunk);
  27.206 +            memset (src, 0, chunk * sizeof (st_sample_t));
  27.207 +            hw->rpos = (hw->rpos + chunk) % hw->samples;
  27.208 +            to_mix -= chunk;
  27.209 +            buf += chunk << hw->shift;
  27.210 +        }
  27.211 +        samples -= decr;
  27.212 +        pcm_hw_dec_live (hw, decr);
  27.213 +
  27.214 +    again:
  27.215 +        sdl_unlock (s);
  27.216 +    }
  27.217 +    /* dolog ("done len=%d\n", len); */
  27.218 +}
  27.219 +
  27.220 +static void sdl_hw_fini (HWVoice *hw)
  27.221 +{
  27.222 +    ldebug ("sdl_hw_fini %d fixed=%d\n",
  27.223 +             glob_sdl.initialized, audio_conf.fixed_format);
  27.224 +    sdl_close (&glob_sdl);
  27.225 +}
  27.226 +
  27.227 +static int sdl_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
  27.228 +{
  27.229 +    SDLVoice *sdl = (SDLVoice *) hw;
  27.230 +    SDLAudioState *s = &glob_sdl;
  27.231 +    SDL_AudioSpec req, obt;
  27.232 +    int shift;
  27.233 +
  27.234 +    ldebug ("sdl_hw_init %d freq=%d fixed=%d\n",
  27.235 +            s->initialized, freq, audio_conf.fixed_format);
  27.236 +
  27.237 +    if (nchannels != 2) {
  27.238 +        dolog ("Bogus channel count %d\n", nchannels);
  27.239 +        return -1;
  27.240 +    }
  27.241 +
  27.242 +    req.freq = freq;
  27.243 +    req.format = AUD_to_sdlfmt (fmt, &shift);
  27.244 +    req.channels = nchannels;
  27.245 +    req.samples = conf.nb_samples;
  27.246 +    shift <<= nchannels == 2;
  27.247 +
  27.248 +    req.callback = sdl_callback;
  27.249 +    req.userdata = sdl;
  27.250 +
  27.251 +    if (sdl_open (&req, &obt))
  27.252 +        return -1;
  27.253 +
  27.254 +    hw->freq = obt.freq;
  27.255 +    hw->fmt = sdl_to_audfmt (obt.format);
  27.256 +    hw->nchannels = obt.channels;
  27.257 +    hw->bufsize = obt.samples << shift;
  27.258 +
  27.259 +    s->initialized = 1;
  27.260 +    s->exit = 0;
  27.261 +    SDL_PauseAudio (0);
  27.262 +    return 0;
  27.263 +}
  27.264 +
  27.265 +static int sdl_hw_ctl (HWVoice *hw, int cmd, ...)
  27.266 +{
  27.267 +    (void) hw;
  27.268 +
  27.269 +    switch (cmd) {
  27.270 +    case VOICE_ENABLE:
  27.271 +        SDL_PauseAudio (0);
  27.272 +        break;
  27.273 +
  27.274 +    case VOICE_DISABLE:
  27.275 +        SDL_PauseAudio (1);
  27.276 +        break;
  27.277 +    }
  27.278 +    return 0;
  27.279 +}
  27.280 +
  27.281 +static void *sdl_audio_init (void)
  27.282 +{
  27.283 +    SDLAudioState *s = &glob_sdl;
  27.284 +    conf.nb_samples = audio_get_conf_int (QC_SDL_SAMPLES, conf.nb_samples);
  27.285 +
  27.286 +    if (SDL_InitSubSystem (SDL_INIT_AUDIO)) {
  27.287 +        dolog ("SDL failed to initialize audio subsystem\nReason: %s\n",
  27.288 +               errstr ());
  27.289 +        return NULL;
  27.290 +    }
  27.291 +
  27.292 +    s->mutex = SDL_CreateMutex ();
  27.293 +    if (!s->mutex) {
  27.294 +        dolog ("Failed to create SDL mutex\nReason: %s\n", errstr ());
  27.295 +        SDL_QuitSubSystem (SDL_INIT_AUDIO);
  27.296 +        return NULL;
  27.297 +    }
  27.298 +
  27.299 +    s->sem = SDL_CreateSemaphore (0);
  27.300 +    if (!s->sem) {
  27.301 +        dolog ("Failed to create SDL semaphore\nReason: %s\n", errstr ());
  27.302 +        SDL_DestroyMutex (s->mutex);
  27.303 +        SDL_QuitSubSystem (SDL_INIT_AUDIO);
  27.304 +        return NULL;
  27.305 +    }
  27.306 +
  27.307 +    return s;
  27.308 +}
  27.309 +
  27.310 +static void sdl_audio_fini (void *opaque)
  27.311 +{
  27.312 +    SDLAudioState *s = opaque;
  27.313 +    sdl_close (s);
  27.314 +    SDL_DestroySemaphore (s->sem);
  27.315 +    SDL_DestroyMutex (s->mutex);
  27.316 +    SDL_QuitSubSystem (SDL_INIT_AUDIO);
  27.317 +}
  27.318 +
  27.319 +struct pcm_ops sdl_pcm_ops = {
  27.320 +    sdl_hw_init,
  27.321 +    sdl_hw_fini,
  27.322 +    sdl_hw_run,
  27.323 +    sdl_hw_write,
  27.324 +    sdl_hw_ctl
  27.325 +};
  27.326 +
  27.327 +struct audio_output_driver sdl_output_driver = {
  27.328 +    "sdl",
  27.329 +    sdl_audio_init,
  27.330 +    sdl_audio_fini,
  27.331 +    &sdl_pcm_ops,
  27.332 +    1,
  27.333 +    1,
  27.334 +    sizeof (SDLVoice)
  27.335 +};
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/tools/ioemu/audio/wavaudio.c	Wed Dec 21 11:56:19 2005 -0600
    28.3 @@ -0,0 +1,217 @@
    28.4 +/*
    28.5 + * QEMU WAV audio output driver
    28.6 + * 
    28.7 + * Copyright (c) 2004 Vassili Karpov (malc)
    28.8 + * 
    28.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
   28.10 + * of this software and associated documentation files (the "Software"), to deal
   28.11 + * in the Software without restriction, including without limitation the rights
   28.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   28.13 + * copies of the Software, and to permit persons to whom the Software is
   28.14 + * furnished to do so, subject to the following conditions:
   28.15 + *
   28.16 + * The above copyright notice and this permission notice shall be included in
   28.17 + * all copies or substantial portions of the Software.
   28.18 + *
   28.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   28.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   28.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   28.22 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   28.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   28.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   28.25 + * THE SOFTWARE.
   28.26 + */
   28.27 +#include "vl.h"
   28.28 +
   28.29 +#include "audio/audio_int.h"
   28.30 +
   28.31 +typedef struct WAVVoice {
   28.32 +    HWVoice hw;
   28.33 +    QEMUFile *f;
   28.34 +    int64_t old_ticks;
   28.35 +    void *pcm_buf;
   28.36 +    int total_samples;
   28.37 +} WAVVoice;
   28.38 +
   28.39 +#define dolog(...) AUD_log ("wav", __VA_ARGS__)
   28.40 +#ifdef DEBUG
   28.41 +#define ldebug(...) dolog (__VA_ARGS__)
   28.42 +#else
   28.43 +#define ldebug(...)
   28.44 +#endif
   28.45 +
   28.46 +static struct {
   28.47 +    const char *wav_path;
   28.48 +} conf = {
   28.49 +    .wav_path = "qemu.wav"
   28.50 +};
   28.51 +
   28.52 +static void wav_hw_run (HWVoice *hw)
   28.53 +{
   28.54 +    WAVVoice *wav = (WAVVoice *) hw;
   28.55 +    int rpos, live, decr, samples;
   28.56 +    uint8_t *dst;
   28.57 +    st_sample_t *src;
   28.58 +    int64_t now = qemu_get_clock (vm_clock);
   28.59 +    int64_t ticks = now - wav->old_ticks;
   28.60 +    int64_t bytes = (ticks * hw->bytes_per_second) / ticks_per_sec;
   28.61 +
   28.62 +    if (bytes > INT_MAX)
   28.63 +        samples = INT_MAX >> hw->shift;
   28.64 +    else
   28.65 +        samples = bytes >> hw->shift;
   28.66 +
   28.67 +    live = pcm_hw_get_live (hw);
   28.68 +    if (live <= 0)
   28.69 +        return;
   28.70 +
   28.71 +    wav->old_ticks = now;
   28.72 +    decr = audio_MIN (live, samples);
   28.73 +    samples = decr;
   28.74 +    rpos = hw->rpos;
   28.75 +    while (samples) {
   28.76 +        int left_till_end_samples = hw->samples - rpos;
   28.77 +        int convert_samples = audio_MIN (samples, left_till_end_samples);
   28.78 +
   28.79 +        src = advance (hw->mix_buf, rpos * sizeof (st_sample_t));
   28.80 +        dst = advance (wav->pcm_buf, rpos << hw->shift);
   28.81 +
   28.82 +        hw->clip (dst, src, convert_samples);
   28.83 +        qemu_put_buffer (wav->f, dst, convert_samples << hw->shift);
   28.84 +        memset (src, 0, convert_samples * sizeof (st_sample_t));
   28.85 +
   28.86 +        rpos = (rpos + convert_samples) % hw->samples;
   28.87 +        samples -= convert_samples;
   28.88 +        wav->total_samples += convert_samples;
   28.89 +    }
   28.90 +
   28.91 +    pcm_hw_dec_live (hw, decr);
   28.92 +    hw->rpos = rpos;
   28.93 +}
   28.94 +
   28.95 +static int wav_hw_write (SWVoice *sw, void *buf, int len)
   28.96 +{
   28.97 +    return pcm_hw_write (sw, buf, len);
   28.98 +}
   28.99 +
  28.100 +/* VICE code: Store number as little endian. */
  28.101 +static void le_store (uint8_t *buf, uint32_t val, int len)
  28.102 +{
  28.103 +    int i;
  28.104 +    for (i = 0; i < len; i++) {
  28.105 +        buf[i] = (uint8_t) (val & 0xff);
  28.106 +        val >>= 8;
  28.107 +    }
  28.108 +}
  28.109 +
  28.110 +static int wav_hw_init (HWVoice *hw, int freq, int nchannels, audfmt_e fmt)
  28.111 +{
  28.112 +    WAVVoice *wav = (WAVVoice *) hw;
  28.113 +    int bits16 = 0, stereo = audio_state.fixed_channels == 2;
  28.114 +    uint8_t hdr[] = {
  28.115 +        0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
  28.116 +        0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
  28.117 +        0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
  28.118 +        0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
  28.119 +    };
  28.120 +
  28.121 +    switch (audio_state.fixed_fmt) {
  28.122 +    case AUD_FMT_S8:
  28.123 +    case AUD_FMT_U8:
  28.124 +        break;
  28.125 +
  28.126 +    case AUD_FMT_S16:
  28.127 +    case AUD_FMT_U16:
  28.128 +        bits16 = 1;
  28.129 +        break;
  28.130 +    }
  28.131 +
  28.132 +    hdr[34] = bits16 ? 0x10 : 0x08;
  28.133 +    hw->freq = 44100;
  28.134 +    hw->nchannels = stereo ? 2 : 1;
  28.135 +    hw->fmt = bits16 ? AUD_FMT_S16 : AUD_FMT_U8;
  28.136 +    hw->bufsize = 4096;
  28.137 +    wav->pcm_buf = qemu_mallocz (hw->bufsize);
  28.138 +    if (!wav->pcm_buf)
  28.139 +        return -1;
  28.140 +
  28.141 +    le_store (hdr + 22, hw->nchannels, 2);
  28.142 +    le_store (hdr + 24, hw->freq, 4);
  28.143 +    le_store (hdr + 28, hw->freq << (bits16 + stereo), 4);
  28.144 +    le_store (hdr + 32, 1 << (bits16 + stereo), 2);
  28.145 +
  28.146 +    wav->f = fopen (conf.wav_path, "wb");
  28.147 +    if (!wav->f) {
  28.148 +        dolog ("failed to open wave file `%s'\nReason: %s\n",
  28.149 +               conf.wav_path, strerror (errno));
  28.150 +        qemu_free (wav->pcm_buf);
  28.151 +        wav->pcm_buf = NULL;
  28.152 +        return -1;
  28.153 +    }
  28.154 +
  28.155 +    qemu_put_buffer (wav->f, hdr, sizeof (hdr));
  28.156 +    return 0;
  28.157 +}
  28.158 +
  28.159 +static void wav_hw_fini (HWVoice *hw)
  28.160 +{
  28.161 +    WAVVoice *wav = (WAVVoice *) hw;
  28.162 +    int stereo = hw->nchannels == 2;
  28.163 +    uint8_t rlen[4];
  28.164 +    uint8_t dlen[4];
  28.165 +    uint32_t rifflen = (wav->total_samples << stereo) + 36;
  28.166 +    uint32_t datalen = wav->total_samples << stereo;
  28.167 +
  28.168 +    if (!wav->f || !hw->active)
  28.169 +        return;
  28.170 +
  28.171 +    le_store (rlen, rifflen, 4);
  28.172 +    le_store (dlen, datalen, 4);
  28.173 +
  28.174 +    qemu_fseek (wav->f, 4, SEEK_SET);
  28.175 +    qemu_put_buffer (wav->f, rlen, 4);
  28.176 +
  28.177 +    qemu_fseek (wav->f, 32, SEEK_CUR);
  28.178 +    qemu_put_buffer (wav->f, dlen, 4);
  28.179 +
  28.180 +    fclose (wav->f);
  28.181 +    wav->f = NULL;
  28.182 +
  28.183 +    qemu_free (wav->pcm_buf);
  28.184 +    wav->pcm_buf = NULL;
  28.185 +}
  28.186 +
  28.187 +static int wav_hw_ctl (HWVoice *hw, int cmd, ...)
  28.188 +{
  28.189 +    (void) hw;
  28.190 +    (void) cmd;
  28.191 +    return 0;
  28.192 +}
  28.193 +
  28.194 +static void *wav_audio_init (void)
  28.195 +{
  28.196 +    return &conf;
  28.197 +}
  28.198 +
  28.199 +static void wav_audio_fini (void *opaque)
  28.200 +{
  28.201 +    ldebug ("wav_fini");
  28.202 +}
  28.203 +
  28.204 +struct pcm_ops wav_pcm_ops = {
  28.205 +    wav_hw_init,
  28.206 +    wav_hw_fini,
  28.207 +    wav_hw_run,
  28.208 +    wav_hw_write,
  28.209 +    wav_hw_ctl
  28.210 +};
  28.211 +
  28.212 +struct audio_output_driver wav_output_driver = {
  28.213 +    "wav",
  28.214 +    wav_audio_init,
  28.215 +    wav_audio_fini,
  28.216 +    &wav_pcm_ops,
  28.217 +    1,
  28.218 +    1,
  28.219 +    sizeof (WAVVoice)
  28.220 +};
    29.1 --- a/tools/ioemu/cpu-all.h	Wed Dec 21 10:30:10 2005 -0600
    29.2 +++ b/tools/ioemu/cpu-all.h	Wed Dec 21 11:56:19 2005 -0600
    29.3 @@ -668,7 +668,7 @@ static __inline__ void atomic_clear_bit(
    29.4  #endif
    29.5  /* memory API */
    29.6  
    29.7 -extern int phys_ram_size;
    29.8 +extern uint64_t phys_ram_size;
    29.9  extern int phys_ram_fd;
   29.10  extern uint8_t *phys_ram_base;
   29.11  extern uint8_t *phys_ram_dirty;
    30.1 --- a/tools/ioemu/exec.c	Wed Dec 21 10:30:10 2005 -0600
    30.2 +++ b/tools/ioemu/exec.c	Wed Dec 21 11:56:19 2005 -0600
    30.3 @@ -61,7 +61,7 @@ spinlock_t tb_lock = SPIN_LOCK_UNLOCKED;
    30.4  uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
    30.5  uint8_t *code_gen_ptr;
    30.6  
    30.7 -int phys_ram_size;
    30.8 +uint64_t phys_ram_size;
    30.9  int phys_ram_fd;
   30.10  uint8_t *phys_ram_base;
   30.11  uint8_t *phys_ram_dirty;
    31.1 --- a/tools/ioemu/hw/pc.c	Wed Dec 21 10:30:10 2005 -0600
    31.2 +++ b/tools/ioemu/hw/pc.c	Wed Dec 21 11:56:19 2005 -0600
    31.3 @@ -119,7 +119,7 @@ static void cmos_init_hd(int type_ofs, i
    31.4  }
    31.5  
    31.6  /* hd_table must contain 4 block drivers */
    31.7 -static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table)
    31.8 +static void cmos_init(uint64_t ram_size, int boot_device, BlockDriverState **hd_table)
    31.9  {
   31.10      RTCState *s = rtc_state;
   31.11      int val;
   31.12 @@ -375,7 +375,7 @@ static int serial_irq[MAX_SERIAL_PORTS] 
   31.13  #define NOBIOS 1
   31.14  
   31.15  /* PC hardware initialisation */
   31.16 -void pc_init(int ram_size, int vga_ram_size, int boot_device,
   31.17 +void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device,
   31.18               DisplayState *ds, const char **fd_filename, int snapshot,
   31.19               const char *kernel_filename, const char *kernel_cmdline,
   31.20               const char *initrd_filename)
   31.21 @@ -563,6 +563,15 @@ void pc_init(int ram_size, int vga_ram_s
   31.22  
   31.23      kbd_init();
   31.24      DMA_init(0);
   31.25 +   
   31.26 +    if (audio_enabled) {
   31.27 +        AUD_init();
   31.28 +#ifdef USE_SB16
   31.29 +        if (sb16_enabled)
   31.30 +            SB16_init();
   31.31 +#endif
   31.32 +    }
   31.33 +    
   31.34  
   31.35      floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
   31.36  
    32.1 --- a/tools/ioemu/hw/pcnet.h	Wed Dec 21 10:30:10 2005 -0600
    32.2 +++ b/tools/ioemu/hw/pcnet.h	Wed Dec 21 11:56:19 2005 -0600
    32.3 @@ -92,7 +92,7 @@
    32.4  #define CSR_NRBA(S)      ((S)->csr[22] | ((S)->csr[23] << 16))
    32.5  #define CSR_BADR(S)      ((S)->csr[24] | ((S)->csr[25] << 16))
    32.6  #define CSR_NRDA(S)      ((S)->csr[26] | ((S)->csr[27] << 16))
    32.7 -#define CSR_CRDA(S)      ((S)->csr[28] | ((S)->csr[29] << 16))
    32.8 +#define CSR_CRDA(S)      ((S)->csr[28] | (((uint32_t)((S)->csr[29])) << 16))
    32.9  #define CSR_BADX(S)      ((S)->csr[30] | ((S)->csr[31] << 16))
   32.10  #define CSR_NXDA(S)      ((S)->csr[32] | ((S)->csr[33] << 16))
   32.11  #define CSR_CXDA(S)      ((S)->csr[34] | ((S)->csr[35] << 16))
   32.12 @@ -102,7 +102,7 @@
   32.13  #define CSR_NXBA(S)      ((S)->csr[64] | ((S)->csr[65] << 16))
   32.14  
   32.15  #define PHYSADDR(S,A) \
   32.16 -  (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(s)->csr[2])<<16))
   32.17 +  (BCR_SSIZE32(S) ? (A) : (A) | ((0xff00 & (uint32_t)(S)->csr[2])<<16))
   32.18  
   32.19  struct pcnet_initblk16 {
   32.20      uint16_t mode;
    33.1 --- a/tools/ioemu/target-i386-dm/Makefile	Wed Dec 21 10:30:10 2005 -0600
    33.2 +++ b/tools/ioemu/target-i386-dm/Makefile	Wed Dec 21 11:56:19 2005 -0600
    33.3 @@ -272,6 +272,7 @@ endif
    33.4  VL_OBJS+= ide.o ne2000.o pckbd.o vga.o dma.o
    33.5  VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259_stub.o i8254.o pc.o port-e9.o
    33.6  VL_OBJS+= cirrus_vga.o pcnet.o
    33.7 +VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o
    33.8  
    33.9  ifeq ($(TARGET_ARCH), ppc)
   33.10  VL_OBJS+= ppc.o ide.o ne2000.o pckbd.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
    34.1 --- a/tools/ioemu/vl.c	Wed Dec 21 10:30:10 2005 -0600
    34.2 +++ b/tools/ioemu/vl.c	Wed Dec 21 11:56:19 2005 -0600
    34.3 @@ -119,7 +119,7 @@ const char* vncconnect; /* do a reverse 
    34.4  const char* keyboard_layout = 0;
    34.5  int64_t ticks_per_sec;
    34.6  int boot_device = 'c';
    34.7 -int ram_size;
    34.8 +uint64_t ram_size;
    34.9  int domid = -1;
   34.10  static char network_script[1024];
   34.11  int pit_min_timer_count = 0;
   34.12 @@ -2906,7 +2906,7 @@ int main(int argc, char **argv)
   34.13                  help();
   34.14                  break;
   34.15              case QEMU_OPTION_m:
   34.16 -                ram_size = atoi(optarg) * 1024 * 1024;
   34.17 +                ram_size = atol(optarg) * 1024 * 1024;
   34.18                  if (ram_size <= 0)
   34.19                      help();
   34.20                  break;
    35.1 --- a/tools/ioemu/vl.h	Wed Dec 21 10:30:10 2005 -0600
    35.2 +++ b/tools/ioemu/vl.h	Wed Dec 21 11:56:19 2005 -0600
    35.3 @@ -37,6 +37,7 @@
    35.4  #include <unistd.h>
    35.5  #include <fcntl.h>
    35.6  #include <sys/stat.h>
    35.7 +#include "audio/audio.h"
    35.8  
    35.9  #ifndef O_LARGEFILE
   35.10  #define O_LARGEFILE 0
   35.11 @@ -116,7 +117,7 @@ extern int audio_enabled;
   35.12  extern int sb16_enabled;
   35.13  extern int adlib_enabled;
   35.14  extern int gus_enabled;
   35.15 -extern int ram_size;
   35.16 +extern uint64_t ram_size;
   35.17  extern int bios_size;
   35.18  extern int rtc_utc;
   35.19  extern int cirrus_vga_enabled;
   35.20 @@ -649,7 +650,7 @@ int pit_get_gate(PITState *pit, int chan
   35.21  int pit_get_out(PITState *pit, int channel, int64_t current_time);
   35.22  
   35.23  /* pc.c */
   35.24 -void pc_init(int ram_size, int vga_ram_size, int boot_device,
   35.25 +void pc_init(uint64_t ram_size, int vga_ram_size, int boot_device,
   35.26               DisplayState *ds, const char **fd_filename, int snapshot,
   35.27               const char *kernel_filename, const char *kernel_cmdline,
   35.28               const char *initrd_filename);
    36.1 --- a/tools/libxc/xc_domain.c	Wed Dec 21 10:30:10 2005 -0600
    36.2 +++ b/tools/libxc/xc_domain.c	Wed Dec 21 11:56:19 2005 -0600
    36.3 @@ -380,6 +380,30 @@ int xc_domain_ioport_permission(int xc_h
    36.4      return do_dom0_op(xc_handle, &op);
    36.5  }
    36.6  
    36.7 +int xc_domain_setinfo(int xc_handle,
    36.8 +                      uint32_t domid,
    36.9 +                      uint32_t vcpu,
   36.10 +                      vcpu_guest_context_t *ctxt)
   36.11 +{
   36.12 +    dom0_op_t op;
   36.13 +    int rc;
   36.14 +
   36.15 +    op.cmd = DOM0_SETDOMAININFO;
   36.16 +    op.u.setdomaininfo.domain = domid;
   36.17 +    op.u.setdomaininfo.vcpu = vcpu;
   36.18 +    op.u.setdomaininfo.ctxt = ctxt;
   36.19 +
   36.20 +    if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 )
   36.21 +        return rc;
   36.22 +
   36.23 +    rc = do_dom0_op(xc_handle, &op);
   36.24 +
   36.25 +    safe_munlock(ctxt, sizeof(*ctxt));
   36.26 +
   36.27 +    return rc;
   36.28 +
   36.29 +}
   36.30 +
   36.31  /*
   36.32   * Local variables:
   36.33   * mode: C
    37.1 --- a/tools/libxc/xc_ptrace.c	Wed Dec 21 10:30:10 2005 -0600
    37.2 +++ b/tools/libxc/xc_ptrace.c	Wed Dec 21 11:56:19 2005 -0600
    37.3 @@ -1,138 +1,141 @@
    37.4 +#define XC_PTRACE_PRIVATE
    37.5 +
    37.6 +
    37.7  #include <sys/ptrace.h>
    37.8  #include <sys/wait.h>
    37.9 -#include "xc_private.h"
   37.10 -#include "xg_private.h"
   37.11  #include <time.h>
   37.12  
   37.13 -#define X86_CR0_PE              0x00000001 /* Enable Protected Mode    (RW) */
   37.14 -#define X86_CR0_PG              0x80000000 /* Paging                   (RW) */
   37.15 -#define BSD_PAGE_MASK (PAGE_SIZE-1)
   37.16 -#define PDRSHIFT        22
   37.17 -#define PSL_T  0x00000100 /* trace enable bit */
   37.18 -#define VCPU            0               /* XXX */
   37.19 +#include "xc_private.h"
   37.20 +#include "xg_private.h"
   37.21 +#include <thread_db.h>
   37.22 +#include "xc_ptrace.h"
   37.23 +
   37.24  
   37.25 -char * ptrace_names[] = {
   37.26 -    "PTRACE_TRACEME",
   37.27 -    "PTRACE_PEEKTEXT",
   37.28 -    "PTRACE_PEEKDATA",
   37.29 -    "PTRACE_PEEKUSER",
   37.30 -    "PTRACE_POKETEXT",
   37.31 -    "PTRACE_POKEDATA",
   37.32 -    "PTRACE_POKEUSER",
   37.33 -    "PTRACE_CONT",
   37.34 -    "PTRACE_KILL",
   37.35 -    "PTRACE_SINGLESTEP",
   37.36 -    "PTRACE_INVALID",
   37.37 -    "PTRACE_INVALID",
   37.38 -    "PTRACE_GETREGS",
   37.39 -    "PTRACE_SETREGS",
   37.40 -    "PTRACE_GETFPREGS",
   37.41 -    "PTRACE_SETFPREGS",
   37.42 -    "PTRACE_ATTACH",
   37.43 -    "PTRACE_DETACH",
   37.44 -    "PTRACE_GETFPXREGS",
   37.45 -    "PTRACE_SETFPXREGS",
   37.46 -    "PTRACE_INVALID",
   37.47 -    "PTRACE_INVALID",
   37.48 -    "PTRACE_INVALID",
   37.49 -    "PTRACE_INVALID",
   37.50 -    "PTRACE_SYSCALL",
   37.51 -};
   37.52 +/* XXX application state */
   37.53 +static long                     nr_pages = 0;
   37.54 +static unsigned long           *page_array = NULL;
   37.55 +static int                      current_domid = -1;
   37.56 +
   37.57 +static cpumap_t                 online_cpumap;
   37.58 +static cpumap_t                 regs_valid;
   37.59 +static vcpu_guest_context_t     ctxt[MAX_VIRT_CPUS];
   37.60 +
   37.61 +extern int ffsll(long long int);
   37.62 +#define FOREACH_CPU(cpumap, i)  for ( cpumap = online_cpumap; (i = ffsll(cpumap)); cpumap &= ~(1 << (index - 1)) ) 
   37.63 +
   37.64  
   37.65 -struct gdb_regs {
   37.66 -    long ebx; /* 0 */
   37.67 -    long ecx; /* 4 */
   37.68 -    long edx; /* 8 */
   37.69 -    long esi; /* 12 */
   37.70 -    long edi; /* 16 */
   37.71 -    long ebp; /* 20 */
   37.72 -    long eax; /* 24 */ 
   37.73 -    int  xds; /* 28 */
   37.74 -    int  xes; /* 32 */
   37.75 -    int  xfs; /* 36 */
   37.76 -    int  xgs; /* 40 */
   37.77 -    long orig_eax; /* 44 */
   37.78 -    long eip;    /* 48 */
   37.79 -    int  xcs;    /* 52 */
   37.80 -    long eflags; /* 56 */
   37.81 -    long esp;    /* 60 */     
   37.82 -    int  xss;    /* 64 */
   37.83 -};
   37.84 +static int
   37.85 +fetch_regs(int xc_handle, int cpu, int *online)
   37.86 +{
   37.87 +    xc_vcpuinfo_t info;
   37.88 +    int retval = 0;
   37.89  
   37.90 -#define FETCH_REGS(cpu)                                         \
   37.91 -    if (!regs_valid[cpu])                                       \
   37.92 -    {                                                           \
   37.93 -        int retval = xc_domain_get_vcpu_context(                \
   37.94 -            xc_handle, domid, cpu, &ctxt[cpu]);                 \
   37.95 -        if (retval)                                             \
   37.96 -            goto error_out;                                     \
   37.97 -        cr3[cpu] = ctxt[cpu].ctrlreg[3]; /* physical address */ \
   37.98 -        regs_valid[cpu] = 1;                                    \
   37.99 -    }
  37.100 +    if (online)
  37.101 +        *online = 0;
  37.102 +    if ( !(regs_valid & (1 << cpu)) ) { 
  37.103 +        retval = xc_domain_get_vcpu_context(xc_handle, current_domid, 
  37.104 +						cpu, &ctxt[cpu]);
  37.105 +        if ( retval ) 
  37.106 +            goto done;
  37.107 +	regs_valid |= (1 << cpu);
  37.108  
  37.109 -#define printval(x) printf("%s = %lx\n", #x, (long)x);
  37.110 -#define SET_PT_REGS(pt, xc)                     \
  37.111 -{                                               \
  37.112 -    pt.ebx = xc.ebx;                            \
  37.113 -    pt.ecx = xc.ecx;                            \
  37.114 -    pt.edx = xc.edx;                            \
  37.115 -    pt.esi = xc.esi;                            \
  37.116 -    pt.edi = xc.edi;                            \
  37.117 -    pt.ebp = xc.ebp;                            \
  37.118 -    pt.eax = xc.eax;                            \
  37.119 -    pt.eip = xc.eip;                            \
  37.120 -    pt.xcs = xc.cs;                             \
  37.121 -    pt.eflags = xc.eflags;                      \
  37.122 -    pt.esp = xc.esp;                            \
  37.123 -    pt.xss = xc.ss;                             \
  37.124 -    pt.xes = xc.es;                             \
  37.125 -    pt.xds = xc.ds;                             \
  37.126 -    pt.xfs = xc.fs;                             \
  37.127 -    pt.xgs = xc.gs;                             \
  37.128 +    }
  37.129 +	if ( online == NULL )
  37.130 +	    goto done;
  37.131 +
  37.132 +	retval = xc_domain_get_vcpu_info(xc_handle, current_domid,
  37.133 +					 cpu, &info);
  37.134 +	*online = info.online;
  37.135 +    
  37.136 + done:
  37.137 +    return retval;    
  37.138  }
  37.139  
  37.140 -#define SET_XC_REGS(pt, xc)                     \
  37.141 -{                                               \
  37.142 -    xc.ebx = pt->ebx;                           \
  37.143 -    xc.ecx = pt->ecx;                           \
  37.144 -    xc.edx = pt->edx;                           \
  37.145 -    xc.esi = pt->esi;                           \
  37.146 -    xc.edi = pt->edi;                           \
  37.147 -    xc.ebp = pt->ebp;                           \
  37.148 -    xc.eax = pt->eax;                           \
  37.149 -    xc.eip = pt->eip;                           \
  37.150 -    xc.cs = pt->xcs;                            \
  37.151 -    xc.eflags = pt->eflags;                     \
  37.152 -    xc.esp = pt->esp;                           \
  37.153 -    xc.ss = pt->xss;                            \
  37.154 -    xc.es = pt->xes;                            \
  37.155 -    xc.ds = pt->xds;                            \
  37.156 -    xc.fs = pt->xfs;                            \
  37.157 -    xc.gs = pt->xgs;                            \
  37.158 +#define FETCH_REGS(cpu) if (fetch_regs(xc_handle, cpu, NULL)) goto error_out;
  37.159 +
  37.160 +
  37.161 +static struct thr_ev_handlers {
  37.162 +    thr_ev_handler_t td_create;
  37.163 +    thr_ev_handler_t td_death;
  37.164 +} handlers;
  37.165 +
  37.166 +void 
  37.167 +xc_register_event_handler(thr_ev_handler_t h, 
  37.168 +                          td_event_e e)
  37.169 +{
  37.170 +    switch (e) {
  37.171 +    case TD_CREATE:
  37.172 +        handlers.td_create = h;
  37.173 +        break;
  37.174 +    case TD_DEATH:
  37.175 +        handlers.td_death = h;
  37.176 +        break;
  37.177 +    default:
  37.178 +        abort(); /* XXX */
  37.179 +    }
  37.180  }
  37.181  
  37.182 -#define vtopdi(va) ((va) >> PDRSHIFT)
  37.183 -#define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff)
  37.184 -
  37.185 -/* XXX application state */
  37.186 -static long   nr_pages = 0;
  37.187 -unsigned long   *page_array = NULL;
  37.188 -static int                      regs_valid[MAX_VIRT_CPUS];
  37.189 -static unsigned long            cr3[MAX_VIRT_CPUS];
  37.190 -static vcpu_guest_context_t ctxt[MAX_VIRT_CPUS];
  37.191 -
  37.192 -static inline int paging_enabled(vcpu_guest_context_t *v)
  37.193 +static inline int 
  37.194 +paging_enabled(vcpu_guest_context_t *v)
  37.195  {
  37.196      unsigned long cr0 = v->ctrlreg[0];
  37.197      return (cr0 & X86_CR0_PE) && (cr0 & X86_CR0_PG);
  37.198  }
  37.199  
  37.200 +/*
  37.201 + * Fetch registers for all online cpus and set the cpumap
  37.202 + * to indicate which cpus are online
  37.203 + *
  37.204 + */
  37.205 +
  37.206 +static int
  37.207 +get_online_cpumap(int xc_handle, dom0_getdomaininfo_t *d, cpumap_t *cpumap)
  37.208 +{
  37.209 +    int i, online, retval;
  37.210 +    
  37.211 +    *cpumap = 0;
  37.212 +    for (i = 0; i <= d->max_vcpu_id; i++) {
  37.213 +        if ((retval = fetch_regs(xc_handle, i, &online)))
  37.214 +            goto error_out;        
  37.215 +        if (online)
  37.216 +            *cpumap |= (1 << i);            
  37.217 +    }
  37.218 +    
  37.219 +    return 0;
  37.220 + error_out:
  37.221 +    return retval;
  37.222 +}
  37.223 +
  37.224 +/* 
  37.225 + * Notify GDB of any vcpus that have come online or gone offline
  37.226 + * update online_cpumap
  37.227 + *
  37.228 + */
  37.229 +
  37.230 +static void
  37.231 +online_vcpus_changed(cpumap_t cpumap)
  37.232 +{
  37.233 +    cpumap_t changed_cpumap = cpumap ^ online_cpumap;
  37.234 +    int index;
  37.235 +    
  37.236 +    while ( (index = ffsll(changed_cpumap)) ) {
  37.237 +        if ( cpumap & (1 << (index - 1)) ) {
  37.238 +            if (handlers.td_create) handlers.td_create(index - 1);
  37.239 +        } else {
  37.240 +            printf("thread death: %d\n", index - 1);
  37.241 +            if (handlers.td_death) handlers.td_death(index - 1);
  37.242 +        }
  37.243 +        changed_cpumap &= ~(1 << (index - 1));
  37.244 +    }
  37.245 +    online_cpumap = cpumap;
  37.246 +    
  37.247 +}
  37.248 +
  37.249  /* --------------------- */
  37.250  
  37.251  static void *
  37.252  map_domain_va_pae(
  37.253      int xc_handle,
  37.254 -    unsigned long domid,
  37.255      int cpu,
  37.256      void *guest_va,
  37.257      int perm)
  37.258 @@ -144,24 +147,24 @@ map_domain_va_pae(
  37.259      FETCH_REGS(cpu);
  37.260  
  37.261      l3 = xc_map_foreign_range(
  37.262 -        xc_handle, domid, PAGE_SIZE, PROT_READ, cr3[cpu] >> PAGE_SHIFT);
  37.263 +        xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT);
  37.264      if ( l3 == NULL )
  37.265          goto error_out;
  37.266  
  37.267      l2p = l3[l3_table_offset_pae(va)] >> PAGE_SHIFT;
  37.268 -    l2 = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, PROT_READ, l2p);
  37.269 +    l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p);
  37.270      if ( l2 == NULL )
  37.271          goto error_out;
  37.272  
  37.273      l1p = l2[l2_table_offset_pae(va)] >> PAGE_SHIFT;
  37.274 -    l1 = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, perm, l1p);
  37.275 +    l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p);
  37.276      if ( l1 == NULL )
  37.277          goto error_out;
  37.278  
  37.279      p = l1[l1_table_offset_pae(va)] >> PAGE_SHIFT;
  37.280      if ( v != NULL )
  37.281          munmap(v, PAGE_SIZE);
  37.282 -    v = xc_map_foreign_range(xc_handle, domid, PAGE_SIZE, perm, p);
  37.283 +    v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p);
  37.284      if ( v == NULL )
  37.285          goto error_out;
  37.286  
  37.287 @@ -174,16 +177,17 @@ map_domain_va_pae(
  37.288  static void *
  37.289  map_domain_va(
  37.290      int xc_handle,
  37.291 -    unsigned long domid,
  37.292      int cpu,
  37.293      void *guest_va,
  37.294      int perm)
  37.295  {
  37.296 +
  37.297      unsigned long pde, page;
  37.298      unsigned long va = (unsigned long)guest_va;
  37.299 -    long npgs = xc_get_tot_pages(xc_handle, domid);
  37.300 +    long npgs = xc_get_tot_pages(xc_handle, current_domid);
  37.301  
  37.302 -    static unsigned long  cr3_phys[MAX_VIRT_CPUS];
  37.303 +
  37.304 +    static uint32_t  cr3_phys[MAX_VIRT_CPUS];
  37.305      static unsigned long *cr3_virt[MAX_VIRT_CPUS];
  37.306      static unsigned long  pde_phys[MAX_VIRT_CPUS];
  37.307      static unsigned long *pde_virt[MAX_VIRT_CPUS];
  37.308 @@ -202,7 +206,7 @@ map_domain_va(
  37.309      }
  37.310  
  37.311      if ( mode == MODE_PAE )
  37.312 -        return map_domain_va_pae(xc_handle, domid, cpu, guest_va, perm);
  37.313 +        return map_domain_va_pae(xc_handle, cpu, guest_va, perm);
  37.314  
  37.315      if ( nr_pages != npgs )
  37.316      {
  37.317 @@ -214,7 +218,7 @@ map_domain_va(
  37.318              printf("Could not allocate memory\n");
  37.319              goto error_out;
  37.320          }
  37.321 -        if ( xc_get_pfn_list(xc_handle, domid,
  37.322 +        if ( xc_get_pfn_list(xc_handle, current_domid,
  37.323                               page_array, nr_pages) != nr_pages )
  37.324          {
  37.325              printf("Could not get the page frame list\n");
  37.326 @@ -224,13 +228,13 @@ map_domain_va(
  37.327  
  37.328      FETCH_REGS(cpu);
  37.329  
  37.330 -    if ( cr3[cpu] != cr3_phys[cpu] )
  37.331 +    if ( ctxt[cpu].ctrlreg[3] != cr3_phys[cpu] )
  37.332      {
  37.333 -        cr3_phys[cpu] = cr3[cpu];
  37.334 +        cr3_phys[cpu] = ctxt[cpu].ctrlreg[3];
  37.335          if ( cr3_virt[cpu] )
  37.336              munmap(cr3_virt[cpu], PAGE_SIZE);
  37.337          cr3_virt[cpu] = xc_map_foreign_range(
  37.338 -            xc_handle, domid, PAGE_SIZE, PROT_READ,
  37.339 +            xc_handle, current_domid, PAGE_SIZE, PROT_READ,
  37.340              cr3_phys[cpu] >> PAGE_SHIFT);
  37.341          if ( cr3_virt[cpu] == NULL )
  37.342              goto error_out;
  37.343 @@ -245,7 +249,7 @@ map_domain_va(
  37.344          if ( pde_virt[cpu] )
  37.345              munmap(pde_virt[cpu], PAGE_SIZE);
  37.346          pde_virt[cpu] = xc_map_foreign_range(
  37.347 -            xc_handle, domid, PAGE_SIZE, PROT_READ,
  37.348 +            xc_handle, current_domid, PAGE_SIZE, PROT_READ,
  37.349              pde_phys[cpu] >> PAGE_SHIFT);
  37.350          if ( pde_virt[cpu] == NULL )
  37.351              goto error_out;
  37.352 @@ -260,7 +264,7 @@ map_domain_va(
  37.353          if ( page_virt[cpu] )
  37.354              munmap(page_virt[cpu], PAGE_SIZE);
  37.355          page_virt[cpu] = xc_map_foreign_range(
  37.356 -            xc_handle, domid, PAGE_SIZE, perm,
  37.357 +            xc_handle, current_domid, PAGE_SIZE, perm,
  37.358              page_phys[cpu] >> PAGE_SHIFT);
  37.359          if ( page_virt[cpu] == NULL )
  37.360          {
  37.361 @@ -286,12 +290,15 @@ xc_waitdomain(
  37.362      DECLARE_DOM0_OP;
  37.363      int retval;
  37.364      struct timespec ts;
  37.365 +    cpumap_t cpumap;
  37.366 +
  37.367      ts.tv_sec = 0;
  37.368      ts.tv_nsec = 10*1000*1000;
  37.369  
  37.370      op.cmd = DOM0_GETDOMAININFO;
  37.371      op.u.getdomaininfo.domain = domain;
  37.372 -
  37.373 +    
  37.374 +    
  37.375   retry:
  37.376      retval = do_dom0_op(xc_handle, &op);
  37.377      if ( retval || (op.u.getdomaininfo.domain != domain) )
  37.378 @@ -309,17 +316,22 @@ xc_waitdomain(
  37.379          nanosleep(&ts,NULL);
  37.380          goto retry;
  37.381      }
  37.382 -
  37.383 +    /* XXX check for ^C here */
  37.384   done:
  37.385 +    if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap))
  37.386 +        printf("get_online_cpumap failed\n");
  37.387 +    if (online_cpumap != cpumap)
  37.388 +        online_vcpus_changed(cpumap);
  37.389      return retval;
  37.390  
  37.391  }
  37.392  
  37.393 +
  37.394  long
  37.395  xc_ptrace(
  37.396      int xc_handle,
  37.397      enum __ptrace_request request,
  37.398 -    uint32_t domid,
  37.399 +    uint32_t domid_tid,
  37.400      long eaddr,
  37.401      long edata)
  37.402  {
  37.403 @@ -328,18 +340,19 @@ xc_ptrace(
  37.404      struct gdb_regs pt;
  37.405      long            retval = 0;
  37.406      unsigned long  *guest_va;
  37.407 -    int             cpu = VCPU;
  37.408 +    cpumap_t        cpumap;
  37.409 +    int             cpu, index;
  37.410      void           *addr = (char *)eaddr;
  37.411      void           *data = (char *)edata;
  37.412  
  37.413 -    op.interface_version = DOM0_INTERFACE_VERSION;
  37.414 +    cpu = (request != PTRACE_ATTACH) ? domid_tid : 0;
  37.415      
  37.416      switch ( request )
  37.417      { 
  37.418      case PTRACE_PEEKTEXT:
  37.419      case PTRACE_PEEKDATA:
  37.420          guest_va = (unsigned long *)map_domain_va(
  37.421 -            xc_handle, domid, cpu, addr, PROT_READ);
  37.422 +            xc_handle, cpu, addr, PROT_READ);
  37.423          if ( guest_va == NULL )
  37.424          {
  37.425              status = EFAULT;
  37.426 @@ -350,10 +363,10 @@ xc_ptrace(
  37.427  
  37.428      case PTRACE_POKETEXT:
  37.429      case PTRACE_POKEDATA:
  37.430 +        /* XXX assume that all CPUs have the same address space */
  37.431          guest_va = (unsigned long *)map_domain_va(
  37.432 -            xc_handle, domid, cpu, addr, PROT_READ|PROT_WRITE);
  37.433 -        if ( guest_va == NULL )
  37.434 -        {
  37.435 +                            xc_handle, cpu, addr, PROT_READ|PROT_WRITE);
  37.436 +        if ( guest_va == NULL ) {
  37.437              status = EFAULT;
  37.438              goto error_out;
  37.439          }
  37.440 @@ -363,6 +376,7 @@ xc_ptrace(
  37.441      case PTRACE_GETREGS:
  37.442      case PTRACE_GETFPREGS:
  37.443      case PTRACE_GETFPXREGS:
  37.444 +        
  37.445          FETCH_REGS(cpu);
  37.446          if ( request == PTRACE_GETREGS )
  37.447          {
  37.448 @@ -380,44 +394,18 @@ xc_ptrace(
  37.449          break;
  37.450  
  37.451      case PTRACE_SETREGS:
  37.452 -        op.cmd = DOM0_SETDOMAININFO;
  37.453 -        SET_XC_REGS(((struct gdb_regs *)data), ctxt[VCPU].user_regs);
  37.454 -        op.u.setdomaininfo.domain = domid;
  37.455 -        /* XXX need to understand multiple vcpus */
  37.456 -        op.u.setdomaininfo.vcpu = cpu;
  37.457 -        op.u.setdomaininfo.ctxt = &ctxt[cpu];
  37.458 -        retval = do_dom0_op(xc_handle, &op);
  37.459 +        SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].user_regs);
  37.460 +        retval = xc_domain_setinfo(xc_handle, current_domid, cpu, &ctxt[cpu]);
  37.461          if (retval)
  37.462              goto error_out;
  37.463          break;
  37.464  
  37.465 -    case PTRACE_ATTACH:
  37.466 -        op.cmd = DOM0_GETDOMAININFO;
  37.467 -        op.u.getdomaininfo.domain = domid;
  37.468 -        retval = do_dom0_op(xc_handle, &op);
  37.469 -        if ( retval || (op.u.getdomaininfo.domain != domid) )
  37.470 -        {
  37.471 -            perror("dom0 op failed");
  37.472 -            goto error_out;
  37.473 -        }
  37.474 -        if ( op.u.getdomaininfo.flags & DOMFLAGS_PAUSED )
  37.475 -        {
  37.476 -            printf("domain currently paused\n");
  37.477 -            goto error_out;
  37.478 -        }
  37.479 -        printf("domain not currently paused\n");
  37.480 -        op.cmd = DOM0_PAUSEDOMAIN;
  37.481 -        op.u.pausedomain.domain = domid;
  37.482 -        retval = do_dom0_op(xc_handle, &op);
  37.483 -        break;
  37.484 -
  37.485      case PTRACE_SINGLESTEP:
  37.486 -        ctxt[VCPU].user_regs.eflags |= PSL_T;
  37.487 -        op.cmd = DOM0_SETDOMAININFO;
  37.488 -        op.u.setdomaininfo.domain = domid;
  37.489 -        op.u.setdomaininfo.vcpu = 0;
  37.490 -        op.u.setdomaininfo.ctxt = &ctxt[cpu];
  37.491 -        retval = do_dom0_op(xc_handle, &op); 
  37.492 +        /*  XXX we can still have problems if the user switches threads
  37.493 +         *  during single-stepping - but that just seems retarded
  37.494 +         */
  37.495 +        ctxt[cpu].user_regs.eflags |= PSL_T; 
  37.496 +        retval = xc_domain_setinfo(xc_handle, current_domid, cpu, &ctxt[cpu]);
  37.497          if ( retval )
  37.498          {
  37.499              perror("dom0 op failed");
  37.500 @@ -429,27 +417,56 @@ xc_ptrace(
  37.501      case PTRACE_DETACH:
  37.502          if ( request != PTRACE_SINGLESTEP )
  37.503          {
  37.504 -            FETCH_REGS(cpu);
  37.505 -            /* Clear trace flag */
  37.506 -            if ( ctxt[cpu].user_regs.eflags & PSL_T )
  37.507 -            {
  37.508 -                ctxt[cpu].user_regs.eflags &= ~PSL_T;
  37.509 -                op.cmd = DOM0_SETDOMAININFO;
  37.510 -                op.u.setdomaininfo.domain = domid;
  37.511 -                op.u.setdomaininfo.vcpu = cpu;
  37.512 -                op.u.setdomaininfo.ctxt = &ctxt[cpu];
  37.513 -                retval = do_dom0_op(xc_handle, &op); 
  37.514 -                if ( retval )
  37.515 -                {
  37.516 -                    perror("dom0 op failed");
  37.517 -                    goto error_out;
  37.518 +            FOREACH_CPU(cpumap, index) {
  37.519 +                cpu = index - 1;
  37.520 +                FETCH_REGS(cpu);
  37.521 +                /* Clear trace flag */
  37.522 +                if ( ctxt[cpu].user_regs.eflags & PSL_T ) {
  37.523 +                    ctxt[cpu].user_regs.eflags &= ~PSL_T;
  37.524 +                    retval = xc_domain_setinfo(xc_handle, current_domid, 
  37.525 +                                               cpu, &ctxt[cpu]);
  37.526 +                    if ( retval ) {
  37.527 +                        perror("dom0 op failed");
  37.528 +                        goto error_out;
  37.529 +                    }
  37.530                  }
  37.531              }
  37.532          }
  37.533 -        regs_valid[cpu] = 0;
  37.534 -        op.cmd = DOM0_UNPAUSEDOMAIN;
  37.535 -        op.u.unpausedomain.domain = domid > 0 ? domid : -domid;
  37.536 +        if ( request == PTRACE_DETACH )
  37.537 +        {
  37.538 +            op.cmd = DOM0_SETDEBUGGING;
  37.539 +            op.u.setdebugging.domain = current_domid;
  37.540 +            op.u.setdebugging.enable = 0;
  37.541 +            retval = do_dom0_op(xc_handle, &op);
  37.542 +        }
  37.543 +        regs_valid = 0;
  37.544 +        xc_domain_unpause(xc_handle, current_domid > 0 ? current_domid : -current_domid);
  37.545 +        break;
  37.546 +
  37.547 +    case PTRACE_ATTACH:
  37.548 +        current_domid = domid_tid;
  37.549 +        op.cmd = DOM0_GETDOMAININFO;
  37.550 +        op.u.getdomaininfo.domain = current_domid;
  37.551          retval = do_dom0_op(xc_handle, &op);
  37.552 +        if ( retval || (op.u.getdomaininfo.domain != current_domid) )
  37.553 +        {
  37.554 +            perror("dom0 op failed");
  37.555 +            goto error_out;
  37.556 +        }
  37.557 +        if ( op.u.getdomaininfo.flags & DOMFLAGS_PAUSED )
  37.558 +        {
  37.559 +            printf("domain currently paused\n");
  37.560 +        } else
  37.561 +            retval = xc_domain_pause(xc_handle, current_domid);
  37.562 +        op.cmd = DOM0_SETDEBUGGING;
  37.563 +        op.u.setdebugging.domain = current_domid;
  37.564 +        op.u.setdebugging.enable = 1;
  37.565 +        retval = do_dom0_op(xc_handle, &op);
  37.566 +
  37.567 +        if (get_online_cpumap(xc_handle, &op.u.getdomaininfo, &cpumap))
  37.568 +            printf("get_online_cpumap failed\n");
  37.569 +        if (online_cpumap != cpumap)
  37.570 +            online_vcpus_changed(cpumap);
  37.571          break;
  37.572  
  37.573      case PTRACE_SETFPREGS:
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/tools/libxc/xc_ptrace.h	Wed Dec 21 11:56:19 2005 -0600
    38.3 @@ -0,0 +1,124 @@
    38.4 +#ifndef XC_PTRACE_
    38.5 +#define XC_PTRACE_
    38.6 +
    38.7 +#ifdef XC_PTRACE_PRIVATE
    38.8 +#define X86_CR0_PE              0x00000001 /* Enable Protected Mode    (RW) */
    38.9 +#define X86_CR0_PG              0x80000000 /* Paging                   (RW) */
   38.10 +#define BSD_PAGE_MASK (PAGE_SIZE-1)
   38.11 +#define PDRSHIFT        22
   38.12 +#define PSL_T  0x00000100 /* trace enable bit */
   38.13 +
   38.14 +char * ptrace_names[] = {
   38.15 +    "PTRACE_TRACEME",
   38.16 +    "PTRACE_PEEKTEXT",
   38.17 +    "PTRACE_PEEKDATA",
   38.18 +    "PTRACE_PEEKUSER",
   38.19 +    "PTRACE_POKETEXT",
   38.20 +    "PTRACE_POKEDATA",
   38.21 +    "PTRACE_POKEUSER",
   38.22 +    "PTRACE_CONT",
   38.23 +    "PTRACE_KILL",
   38.24 +    "PTRACE_SINGLESTEP",
   38.25 +    "PTRACE_INVALID",
   38.26 +    "PTRACE_INVALID",
   38.27 +    "PTRACE_GETREGS",
   38.28 +    "PTRACE_SETREGS",
   38.29 +    "PTRACE_GETFPREGS",
   38.30 +    "PTRACE_SETFPREGS",
   38.31 +    "PTRACE_ATTACH",
   38.32 +    "PTRACE_DETACH",
   38.33 +    "PTRACE_GETFPXREGS",
   38.34 +    "PTRACE_SETFPXREGS",
   38.35 +    "PTRACE_INVALID",
   38.36 +    "PTRACE_INVALID",
   38.37 +    "PTRACE_INVALID",
   38.38 +    "PTRACE_INVALID",
   38.39 +    "PTRACE_SYSCALL",
   38.40 +};
   38.41 +
   38.42 +struct gdb_regs {
   38.43 +    long ebx; /* 0 */
   38.44 +    long ecx; /* 4 */
   38.45 +    long edx; /* 8 */
   38.46 +    long esi; /* 12 */
   38.47 +    long edi; /* 16 */
   38.48 +    long ebp; /* 20 */
   38.49 +    long eax; /* 24 */ 
   38.50 +    int  xds; /* 28 */
   38.51 +    int  xes; /* 32 */
   38.52 +    int  xfs; /* 36 */
   38.53 +    int  xgs; /* 40 */
   38.54 +    long orig_eax; /* 44 */
   38.55 +    long eip;    /* 48 */
   38.56 +    int  xcs;    /* 52 */
   38.57 +    long eflags; /* 56 */
   38.58 +    long esp;    /* 60 */     
   38.59 +    int  xss;    /* 64 */
   38.60 +};
   38.61 +
   38.62 +
   38.63 +#define printval(x) printf("%s = %lx\n", #x, (long)x);
   38.64 +#define SET_PT_REGS(pt, xc)                     \
   38.65 +{                                               \
   38.66 +    pt.ebx = xc.ebx;                            \
   38.67 +    pt.ecx = xc.ecx;                            \
   38.68 +    pt.edx = xc.edx;                            \
   38.69 +    pt.esi = xc.esi;                            \
   38.70 +    pt.edi = xc.edi;                            \
   38.71 +    pt.ebp = xc.ebp;                            \
   38.72 +    pt.eax = xc.eax;                            \
   38.73 +    pt.eip = xc.eip;                            \
   38.74 +    pt.xcs = xc.cs;                             \
   38.75 +    pt.eflags = xc.eflags;                      \
   38.76 +    pt.esp = xc.esp;                            \
   38.77 +    pt.xss = xc.ss;                             \
   38.78 +    pt.xes = xc.es;                             \
   38.79 +    pt.xds = xc.ds;                             \
   38.80 +    pt.xfs = xc.fs;                             \
   38.81 +    pt.xgs = xc.gs;                             \
   38.82 +}
   38.83 +
   38.84 +#define SET_XC_REGS(pt, xc)                     \
   38.85 +{                                               \
   38.86 +    xc.ebx = pt->ebx;                           \
   38.87 +    xc.ecx = pt->ecx;                           \
   38.88 +    xc.edx = pt->edx;                           \
   38.89 +    xc.esi = pt->esi;                           \
   38.90 +    xc.edi = pt->edi;                           \
   38.91 +    xc.ebp = pt->ebp;                           \
   38.92 +    xc.eax = pt->eax;                           \
   38.93 +    xc.eip = pt->eip;                           \
   38.94 +    xc.cs = pt->xcs;                            \
   38.95 +    xc.eflags = pt->eflags;                     \
   38.96 +    xc.esp = pt->esp;                           \
   38.97 +    xc.ss = pt->xss;                            \
   38.98 +    xc.es = pt->xes;                            \
   38.99 +    xc.ds = pt->xds;                            \
  38.100 +    xc.fs = pt->xfs;                            \
  38.101 +    xc.gs = pt->xgs;                            \
  38.102 +}
  38.103 +
  38.104 +#define vtopdi(va) ((va) >> PDRSHIFT)
  38.105 +#define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff)
  38.106 +#endif
  38.107 +
  38.108 +typedef void (*thr_ev_handler_t)(long);
  38.109 +
  38.110 +void xc_register_event_handler(
  38.111 +    thr_ev_handler_t h, 
  38.112 +    td_event_e e);
  38.113 +
  38.114 +long xc_ptrace(
  38.115 +    int xc_handle,
  38.116 +    enum __ptrace_request request, 
  38.117 +    uint32_t  domid,
  38.118 +    long addr, 
  38.119 +    long data);
  38.120 +
  38.121 +int xc_waitdomain(
  38.122 +    int xc_handle,
  38.123 +    int domain, 
  38.124 +    int *status, 
  38.125 +    int options);
  38.126 +
  38.127 +#endif /* XC_PTRACE */
    39.1 --- a/tools/libxc/xc_vmx_build.c	Wed Dec 21 10:30:10 2005 -0600
    39.2 +++ b/tools/libxc/xc_vmx_build.c	Wed Dec 21 11:56:19 2005 -0600
    39.3 @@ -288,11 +288,11 @@ static int setup_guest(int xc_handle,
    39.4      l2_pgentry_t *vl2tab=NULL, *vl2e=NULL;
    39.5      unsigned long *page_array = NULL;
    39.6  #ifdef __x86_64__
    39.7 -    l3_pgentry_t *vl3tab=NULL, *vl3e=NULL;
    39.8 +    l3_pgentry_t *vl3tab=NULL;
    39.9      unsigned long l3tab;
   39.10  #endif
   39.11 -    unsigned long l2tab;
   39.12 -    unsigned long l1tab;
   39.13 +    unsigned long l2tab = 0;
   39.14 +    unsigned long l1tab = 0;
   39.15      unsigned long count, i;
   39.16      shared_info_t *shared_info;
   39.17      void *e820_page;
   39.18 @@ -323,7 +323,7 @@ static int setup_guest(int xc_handle,
   39.19      }
   39.20  
   39.21      /* memsize is in megabytes */
   39.22 -    v_end              = memsize << 20;
   39.23 +    v_end              = (unsigned long)memsize << 20;
   39.24  
   39.25  #ifdef __i386__
   39.26      nr_pt_pages = 1 + ((memsize + 3) >> 2);
   39.27 @@ -435,15 +435,16 @@ static int setup_guest(int xc_handle,
   39.28              goto error_out;
   39.29          memset(vl2tab, 0, PAGE_SIZE);
   39.30          munmap(vl2tab, PAGE_SIZE);
   39.31 +        vl2tab = NULL;
   39.32          vl3tab[i] = l2tab | L3_PROT;
   39.33      }
   39.34  
   39.35 -    vl3e = &vl3tab[l3_table_offset(0)];
   39.36      for ( count = 0; count < (v_end >> PAGE_SHIFT); count++ )
   39.37      {
   39.38 -        if (!(count & (1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))){
   39.39 +        if ( !(count & ((1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)) - 1)) )
   39.40 +        {
   39.41              l2tab = vl3tab[count >> (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)]
   39.42 -                & PAGE_MASK;
   39.43 +                    & PAGE_MASK;
   39.44  
   39.45              if (vl2tab != NULL)
   39.46                  munmap(vl2tab, PAGE_SIZE);
    40.1 --- a/tools/libxc/xenctrl.h	Wed Dec 21 10:30:10 2005 -0600
    40.2 +++ b/tools/libxc/xenctrl.h	Wed Dec 21 11:56:19 2005 -0600
    40.3 @@ -94,13 +94,6 @@ typedef struct xc_core_header {
    40.4  } xc_core_header_t;
    40.5  
    40.6  
    40.7 -long xc_ptrace(
    40.8 -    int xc_handle,
    40.9 -    enum __ptrace_request request, 
   40.10 -    uint32_t  domid,
   40.11 -    long addr, 
   40.12 -    long data);
   40.13 -
   40.14  long xc_ptrace_core(
   40.15      int xc_handle,
   40.16      enum __ptrace_request request, 
   40.17 @@ -108,12 +101,6 @@ long xc_ptrace_core(
   40.18      long addr, 
   40.19      long data);
   40.20  
   40.21 -int xc_waitdomain(
   40.22 -    int xc_handle,
   40.23 -    int domain, 
   40.24 -    int *status, 
   40.25 -    int options);
   40.26 -
   40.27  int xc_waitdomain_core(
   40.28      int xc_handle,
   40.29      int domain, 
   40.30 @@ -219,6 +206,20 @@ int xc_domain_getinfo(int xc_handle,
   40.31                        unsigned int max_doms,
   40.32                        xc_dominfo_t *info);
   40.33  
   40.34 +
   40.35 +/**
   40.36 + * This function will set the vcpu context for the specified domain.
   40.37 + *
   40.38 + * @parm xc_handle a handle to an open hypervisor interface
   40.39 + * @parm domid the domain to set the vcpu context for
   40.40 + * @parm vcpu the vcpu number for the context
   40.41 + * @parm ctxt pointer to the the cpu context with the values to set
   40.42 + * @return the number of domains enumerated or -1 on error
   40.43 + */
   40.44 +int xc_domain_setinfo(int xc_handle,
   40.45 +                      uint32_t domid,
   40.46 +                      uint32_t vcpu,
   40.47 +                      vcpu_guest_context_t *ctxt);
   40.48  /**
   40.49   * This function will return information about one or more domains, using a
   40.50   * single hypercall.  The domain information will be stored into the supplied
    41.1 --- a/tools/python/xen/xend/image.py	Wed Dec 21 10:30:10 2005 -0600
    41.2 +++ b/tools/python/xen/xend/image.py	Wed Dec 21 11:56:19 2005 -0600
    41.3 @@ -237,7 +237,7 @@ class VmxImageHandler(ImageHandler):
    41.4      # Return a list of cmd line args to the device models based on the
    41.5      # xm config file
    41.6      def parseDeviceModelArgs(self, imageConfig, deviceConfig):
    41.7 -        dmargs = [ 'cdrom', 'boot', 'fda', 'fdb', 'ne2000', 
    41.8 +        dmargs = [ 'cdrom', 'boot', 'fda', 'fdb', 'ne2000', 'audio',
    41.9                     'localtime', 'serial', 'stdvga', 'isa', 'vcpus']
   41.10          ret = []
   41.11          for a in dmargs:
   41.12 @@ -246,9 +246,10 @@ class VmxImageHandler(ImageHandler):
   41.13              # python doesn't allow '-' in variable names
   41.14              if a == 'stdvga': a = 'std-vga'
   41.15              if a == 'ne2000': a = 'nic-ne2000'
   41.16 +            if a == 'audio': a = 'enable-audio'
   41.17  
   41.18              # Handle booleans gracefully
   41.19 -            if a in ['localtime', 'std-vga', 'isa', 'nic-ne2000']:
   41.20 +            if a in ['localtime', 'std-vga', 'isa', 'nic-ne2000', 'enable-audio']:
   41.21                  if v != None: v = int(v)
   41.22                  if v: ret.append("-%s" % a)
   41.23              else:
    42.1 --- a/tools/python/xen/xend/uuid.py	Wed Dec 21 10:30:10 2005 -0600
    42.2 +++ b/tools/python/xen/xend/uuid.py	Wed Dec 21 11:56:19 2005 -0600
    42.3 @@ -17,8 +17,13 @@
    42.4  #============================================================================
    42.5  
    42.6  
    42.7 -"""Universal(ly) Unique Identifiers (UUIDs).
    42.8 -"""
    42.9 +"""Universal Unique Identifiers (UUIDs).  By default, UUIDs generated here are
   42.10 +purely random, with no internal structure.  However, they are the same size,
   42.11 +and are formatted by the same conventions, as the UUIDs in the Open Software
   42.12 +Foundation's Distributed Computing Environment (OSF DCE).  This allows Xend to
   42.13 +be used with UUIDs generated as per the DCE specification, should that be
   42.14 +required.  These UUIDs are also, by no coincidence, the same size as the
   42.15 +'handle' stored by the Xen hypervisor along with the domain structure."""
   42.16  
   42.17  
   42.18  import commands
   42.19 @@ -54,7 +59,8 @@ def create():
   42.20  
   42.21  
   42.22  def toString(u):
   42.23 -    return "-".join(["%02x" * 4] * 4) % tuple(u)
   42.24 +    return "-".join(["%02x" * 4, "%02x" * 2, "%02x" * 2, "%02x" * 2,
   42.25 +                     "%02x" * 6]) % tuple(u)
   42.26  
   42.27  def fromString(s):
   42.28      s = s.replace('-', '')
    43.1 --- a/tools/python/xen/xm/create.py	Wed Dec 21 10:30:10 2005 -0600
    43.2 +++ b/tools/python/xen/xm/create.py	Wed Dec 21 11:56:19 2005 -0600
    43.3 @@ -372,6 +372,10 @@ gopts.var('ne2000', val='no|yes',
    43.4            fn=set_bool, default=0,
    43.5            use="Should device models use ne2000?")
    43.6  
    43.7 +gopts.var('audio', val='no|yes',
    43.8 +          fn=set_bool, default=0,
    43.9 +          use="Should device models enable audio?")
   43.10 +
   43.11  gopts.var('vnc', val='',
   43.12            fn=set_value, default=None,
   43.13            use="""Should the device model use VNC?""")
   43.14 @@ -521,7 +525,7 @@ def configure_vmx(config_image, vals):
   43.15      """Create the config for VMX devices.
   43.16      """
   43.17      args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb',
   43.18 -             'localtime', 'serial', 'stdvga', 'isa', 'nographic',
   43.19 +             'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio',
   43.20               'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic']
   43.21      for a in args:
   43.22          if (vals.__dict__[a]):
    44.1 --- a/tools/tests/Makefile	Wed Dec 21 10:30:10 2005 -0600
    44.2 +++ b/tools/tests/Makefile	Wed Dec 21 11:56:19 2005 -0600
    44.3 @@ -7,6 +7,8 @@ TARGET := test_x86_emulator
    44.4  CC     := gcc
    44.5  CFLAGS := -O2 -Wall -Werror -D__TEST_HARNESS__
    44.6  
    44.7 +all: $(TARGET)
    44.8 +
    44.9  $(TARGET): x86_emulate.o test_x86_emulator.o
   44.10  	$(CC) -o $@ $^
   44.11  
    45.1 --- a/tools/tests/test_x86_emulator.c	Wed Dec 21 10:30:10 2005 -0600
    45.2 +++ b/tools/tests/test_x86_emulator.c	Wed Dec 21 11:56:19 2005 -0600
    45.3 @@ -254,6 +254,36 @@ int main(int argc, char **argv)
    45.4          goto fail;
    45.5      printf("okay\n");
    45.6  
    45.7 +    printf("%-40s", "Testing movsxbd (%%eax),%%ecx...");
    45.8 +    instr[0] = 0x0f; instr[1] = 0xbe; instr[2] = 0x08;
    45.9 +    regs.eip    = (unsigned long)&instr[0];
   45.10 +    regs.ecx    = 0x12345678;
   45.11 +    cr2         = (unsigned long)&res;
   45.12 +    res         = 0x82;
   45.13 +    rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
   45.14 +    if ( (rc != 0) ||
   45.15 +         (res != 0x82) ||
   45.16 +         (regs.ecx != 0xFFFFFF82) ||
   45.17 +         ((regs.eflags&0x240) != 0x200) ||
   45.18 +         (regs.eip != (unsigned long)&instr[3]) )
   45.19 +        goto fail;
   45.20 +    printf("okay\n");
   45.21 +
   45.22 +    printf("%-40s", "Testing movzxwd (%%eax),%%ecx...");
   45.23 +    instr[0] = 0x0f; instr[1] = 0xb7; instr[2] = 0x08;
   45.24 +    regs.eip    = (unsigned long)&instr[0];
   45.25 +    regs.ecx    = 0x12345678;
   45.26 +    cr2         = (unsigned long)&res;
   45.27 +    res         = 0x1234aa82;
   45.28 +    rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
   45.29 +    if ( (rc != 0) ||
   45.30 +         (res != 0x1234aa82) ||
   45.31 +         (regs.ecx != 0xaa82) ||
   45.32 +         ((regs.eflags&0x240) != 0x200) ||
   45.33 +         (regs.eip != (unsigned long)&instr[3]) )
   45.34 +        goto fail;
   45.35 +    printf("okay\n");
   45.36 +
   45.37      return 0;
   45.38  
   45.39   fail:
    46.1 --- a/tools/vtpm_manager/manager/securestorage.c	Wed Dec 21 10:30:10 2005 -0600
    46.2 +++ b/tools/vtpm_manager/manager/securestorage.c	Wed Dec 21 11:56:19 2005 -0600
    46.3 @@ -54,31 +54,28 @@
    46.4  #include "buffer.h"
    46.5  #include "log.h"
    46.6  
    46.7 -TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI, 
    46.8 -				const buffer_t *inbuf, 
    46.9 -				buffer_t *outbuf) {
   46.10 -  
   46.11 +TPM_RESULT envelope_encrypt(const buffer_t     *inbuf,
   46.12 +                            CRYPTO_INFO  *asymkey,
   46.13 +                            buffer_t           *sealed_data) {
   46.14    TPM_RESULT status = TPM_SUCCESS;
   46.15    symkey_t    symkey;
   46.16 -  buffer_t    state_cipher = NULL_BUF,
   46.17 +  buffer_t    data_cipher = NULL_BUF,
   46.18                symkey_cipher = NULL_BUF;
   46.19 -  int fh;
   46.20 -  long bytes_written;
   46.21 -  BYTE *sealed_NVM=NULL;
   46.22 -  UINT32 sealed_NVM_size, i;
   46.23 -  struct pack_constbuf_t symkey_cipher32, state_cipher32;
   46.24    
   46.25 -  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x", buffer_len(inbuf));
   46.26 +  UINT32 i;
   46.27 +  struct pack_constbuf_t symkey_cipher32, data_cipher32;
   46.28 +  
   46.29 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping[%d]: 0x", buffer_len(inbuf));
   46.30    for (i=0; i< buffer_len(inbuf); i++)
   46.31      vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
   46.32    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
   46.33    
   46.34    // Generate a sym key and encrypt state with it
   46.35    TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_genkey (&symkey) );
   46.36 -  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf, &state_cipher) );
   46.37 +  TPMTRY(TPM_ENCRYPT_ERROR, Crypto_symcrypto_encrypt (&symkey, inbuf, &data_cipher) );
   46.38    
   46.39    // Encrypt symmetric key
   46.40 -  TPMTRYRETURN( VTSP_Bind(    &vtpm_globals->storageKey, 
   46.41 +  TPMTRYRETURN( VTSP_Bind(    asymkey, 
   46.42  			      &symkey.key, 
   46.43  			      &symkey_cipher) );
   46.44    
   46.45 @@ -87,15 +84,108 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI
   46.46    symkey_cipher32.size = buffer_len(&symkey_cipher);
   46.47    symkey_cipher32.data = symkey_cipher.bytes;
   46.48    
   46.49 -  state_cipher32.size = buffer_len(&state_cipher);
   46.50 -  state_cipher32.data = state_cipher.bytes;
   46.51 +  data_cipher32.size = buffer_len(&data_cipher);
   46.52 +  data_cipher32.data = data_cipher.bytes;
   46.53 +  
   46.54 +  TPMTRYRETURN( buffer_init(sealed_data, 2 * sizeof(UINT32) + symkey_cipher32.size + data_cipher32.size, NULL));
   46.55 +  
   46.56 +  BSG_PackList(sealed_data->bytes, 2,
   46.57 +	       BSG_TPM_SIZE32_DATA, &symkey_cipher32,
   46.58 +	       BSG_TPM_SIZE32_DATA, &data_cipher32);
   46.59 +
   46.60 +  vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of E(data)\n", buffer_len(&symkey_cipher), buffer_len(&data_cipher));
   46.61 +  goto egress;
   46.62 +
   46.63 + abort_egress:
   46.64 +  vtpmlogerror(VTPM_LOG_VTPM, "Failed to envelope encrypt\n.");
   46.65 +  
   46.66 + egress:
   46.67 +  
   46.68 +  buffer_free ( &data_cipher);
   46.69 +  buffer_free ( &symkey_cipher);
   46.70 +  Crypto_symcrypto_freekey (&symkey);
   46.71    
   46.72 -  sealed_NVM = (BYTE *) malloc( 2 * sizeof(UINT32) + symkey_cipher32.size + state_cipher32.size);
   46.73 +  return status;
   46.74 +}
   46.75 +
   46.76 +TPM_RESULT envelope_decrypt(const long         cipher_size,
   46.77 +                            const BYTE         *cipher,
   46.78 +                            TCS_CONTEXT_HANDLE TCSContext,
   46.79 +			    TPM_HANDLE         keyHandle,
   46.80 +			    const TPM_AUTHDATA *key_usage_auth,
   46.81 +                            buffer_t           *unsealed_data) {
   46.82 +
   46.83 +  TPM_RESULT status = TPM_SUCCESS;
   46.84 +  symkey_t    symkey;
   46.85 +  buffer_t    data_cipher = NULL_BUF, 
   46.86 +              symkey_clear = NULL_BUF, 
   46.87 +              symkey_cipher = NULL_BUF;
   46.88 +  struct pack_buf_t symkey_cipher32, data_cipher32;
   46.89 +  int i;
   46.90 +
   46.91 +  memset(&symkey, 0, sizeof(symkey_t));
   46.92 +
   46.93 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "envelope decrypting[%ld]: 0x", cipher_size);
   46.94 +  for (i=0; i< cipher_size; i++)
   46.95 +    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher[i]);
   46.96 +  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
   46.97 +  
   46.98 +  BSG_UnpackList(cipher, 2,
   46.99 +		 BSG_TPM_SIZE32_DATA, &symkey_cipher32,
  46.100 +		 BSG_TPM_SIZE32_DATA, &data_cipher32);
  46.101    
  46.102 -  sealed_NVM_size = BSG_PackList(sealed_NVM, 2,
  46.103 -				 BSG_TPM_SIZE32_DATA, &symkey_cipher32,
  46.104 -				 BSG_TPM_SIZE32_DATA, &state_cipher32);
  46.105 +  TPMTRYRETURN( buffer_init_convert (&symkey_cipher, 
  46.106 +				     symkey_cipher32.size, 
  46.107 +				     symkey_cipher32.data) );
  46.108 +  
  46.109 +  TPMTRYRETURN( buffer_init_convert (&data_cipher, 
  46.110 +				     data_cipher32.size, 
  46.111 +				     data_cipher32.data) );
  46.112 +
  46.113 +  // Decrypt Symmetric Key
  46.114 +  TPMTRYRETURN( VTSP_Unbind(  TCSContext,
  46.115 +			      keyHandle,
  46.116 +			      &symkey_cipher,
  46.117 +			      key_usage_auth,
  46.118 +			      &symkey_clear,
  46.119 +			      &(vtpm_globals->keyAuth) ) );
  46.120 +  
  46.121 +  // create symmetric key using saved bits
  46.122 +  Crypto_symcrypto_initkey (&symkey, &symkey_clear);
  46.123 +  
  46.124 +  // Decrypt State
  46.125 +  TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &data_cipher, unsealed_data) );
  46.126 +  
  46.127 +  goto egress;
  46.128    
  46.129 + abort_egress:
  46.130 +  vtpmlogerror(VTPM_LOG_VTPM, "Failed to envelope decrypt data\n.");
  46.131 +  
  46.132 + egress:
  46.133 +  buffer_free ( &data_cipher);
  46.134 +  buffer_free ( &symkey_clear);
  46.135 +  buffer_free ( &symkey_cipher);
  46.136 +  Crypto_symcrypto_freekey (&symkey);
  46.137 +  
  46.138 +  return status;
  46.139 +}
  46.140 +
  46.141 +TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI_RESOURCE *myDMI, 
  46.142 +				const buffer_t *inbuf, 
  46.143 +				buffer_t *outbuf) {
  46.144 +  
  46.145 +  TPM_RESULT status = TPM_SUCCESS;
  46.146 +  int fh;
  46.147 +  long bytes_written;
  46.148 +  buffer_t sealed_NVM;
  46.149 +  
  46.150 +  
  46.151 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Save_NVMing[%d]: 0x\n", buffer_len(inbuf));
  46.152 +
  46.153 +  TPMTRYRETURN( envelope_encrypt(inbuf,
  46.154 +                                 &vtpm_globals->storageKey,
  46.155 +                                 &sealed_NVM) );
  46.156 +				  
  46.157    // Mark DMI Table so new save state info will get pushed to disk on return.
  46.158    vtpm_globals->DMI_table_dirty = TRUE;
  46.159    
  46.160 @@ -104,28 +194,22 @@ TPM_RESULT VTPM_Handle_Save_NVM(VTPM_DMI
  46.161    //       after writing the file? We can't get the old one back.
  46.162    // TODO: Backup old file and try and recover that way.
  46.163    fh = open(myDMI->NVMLocation, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
  46.164 -  if ( (bytes_written = write(fh, sealed_NVM, sealed_NVM_size) ) != (long) sealed_NVM_size) {
  46.165 -    vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to finish. %ld/%ld bytes.\n", bytes_written, (long)sealed_NVM_size);
  46.166 +  if ( (bytes_written = write(fh, sealed_NVM.bytes, buffer_len(&sealed_NVM) ) != (long) buffer_len(&sealed_NVM))) {
  46.167 +    vtpmlogerror(VTPM_LOG_VTPM, "We just overwrote a DMI_NVM and failed to finish. %ld/%ld bytes.\n", bytes_written, (long)buffer_len(&sealed_NVM));
  46.168      status = TPM_IOERROR;
  46.169      goto abort_egress;
  46.170    }
  46.171    close(fh);
  46.172    
  46.173 -  Crypto_SHA1Full (sealed_NVM, sealed_NVM_size, (BYTE *) &myDMI->NVM_measurement);   
  46.174 +  Crypto_SHA1Full (sealed_NVM.bytes, buffer_len(&sealed_NVM), (BYTE *) &myDMI->NVM_measurement);   
  46.175    
  46.176 -  vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of E(NVM)\n", buffer_len(&symkey_cipher), buffer_len(&state_cipher));
  46.177    goto egress;
  46.178    
  46.179   abort_egress:
  46.180 -  vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
  46.181 +  vtpmlogerror(VTPM_LOG_VTPM, "Failed to save NVM\n.");
  46.182    
  46.183   egress:
  46.184 -  
  46.185 -  buffer_free ( &state_cipher);
  46.186 -  buffer_free ( &symkey_cipher);
  46.187 -  free(sealed_NVM);
  46.188 -  Crypto_symcrypto_freekey (&symkey);
  46.189 -  
  46.190 +  buffer_free(&sealed_NVM);
  46.191    return status;
  46.192  }
  46.193  
  46.194 @@ -136,11 +220,7 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI
  46.195  				buffer_t *outbuf) {
  46.196    
  46.197    TPM_RESULT status = TPM_SUCCESS;
  46.198 -  symkey_t    symkey;
  46.199 -  buffer_t    state_cipher = NULL_BUF, 
  46.200 -              symkey_clear = NULL_BUF, 
  46.201 -              symkey_cipher = NULL_BUF;
  46.202 -  struct pack_buf_t symkey_cipher32, state_cipher32;
  46.203 +
  46.204    
  46.205    UINT32 sealed_NVM_size;
  46.206    BYTE *sealed_NVM = NULL;
  46.207 @@ -148,9 +228,7 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI
  46.208    int fh, stat_ret, i;
  46.209    struct stat file_stat;
  46.210    TPM_DIGEST sealedNVMHash;
  46.211 -  
  46.212 -  memset(&symkey, 0, sizeof(symkey_t));
  46.213 -  
  46.214 +   
  46.215    if (myDMI->NVMLocation == NULL) {
  46.216      vtpmlogerror(VTPM_LOG_VTPM, "Unable to load NVM because the file name NULL.\n");
  46.217      status = TPM_AUTHFAIL;
  46.218 @@ -168,28 +246,14 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI
  46.219    }
  46.220    
  46.221    sealed_NVM = (BYTE *) malloc(fh_size);
  46.222 +  sealed_NVM_size = (UINT32) fh_size;
  46.223    if (read(fh, sealed_NVM, fh_size) != fh_size) {
  46.224      status = TPM_IOERROR;
  46.225      goto abort_egress;
  46.226    }
  46.227    close(fh);
  46.228    
  46.229 -  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld]: 0x", fh_size);
  46.230 -  for (i=0; i< fh_size; i++)
  46.231 -    vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_NVM[i]);
  46.232 -  vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
  46.233 -  
  46.234 -  sealed_NVM_size = BSG_UnpackList(sealed_NVM, 2,
  46.235 -				   BSG_TPM_SIZE32_DATA, &symkey_cipher32,
  46.236 -				   BSG_TPM_SIZE32_DATA, &state_cipher32);
  46.237 -  
  46.238 -  TPMTRYRETURN( buffer_init_convert (&symkey_cipher, 
  46.239 -				     symkey_cipher32.size, 
  46.240 -				     symkey_cipher32.data) );
  46.241 -  
  46.242 -  TPMTRYRETURN( buffer_init_convert (&state_cipher, 
  46.243 -				     state_cipher32.size, 
  46.244 -				     state_cipher32.data) );
  46.245 +  vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Load_NVMing[%ld],\n", fh_size);
  46.246    
  46.247    Crypto_SHA1Full(sealed_NVM, sealed_NVM_size, (BYTE *) &sealedNVMHash);    
  46.248    
  46.249 @@ -210,32 +274,19 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI
  46.250      goto abort_egress;
  46.251    }
  46.252    
  46.253 -  // Decrypt Symmetric Key
  46.254 -  TPMTRYRETURN( VTSP_Unbind(  myDMI->TCSContext,
  46.255 -			      vtpm_globals->storageKeyHandle,
  46.256 -			      &symkey_cipher,
  46.257 -			      (const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
  46.258 -			      &symkey_clear,
  46.259 -			      &(vtpm_globals->keyAuth) ) );
  46.260 -  
  46.261 -  // create symmetric key using saved bits
  46.262 -  Crypto_symcrypto_initkey (&symkey, &symkey_clear);
  46.263 -  
  46.264 -  // Decrypt State
  46.265 -  TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &state_cipher, outbuf) );
  46.266 -  
  46.267 +    TPMTRYRETURN( envelope_decrypt(fh_size,
  46.268 +                                 sealed_NVM,
  46.269 +                                 myDMI->TCSContext,
  46.270 +		        	 vtpm_globals->storageKeyHandle,
  46.271 +			         (const TPM_AUTHDATA*)&vtpm_globals->storage_key_usage_auth,
  46.272 +                                 outbuf) );  
  46.273    goto egress;
  46.274    
  46.275   abort_egress:
  46.276    vtpmlogerror(VTPM_LOG_VTPM, "Failed to load NVM\n.");
  46.277    
  46.278   egress:
  46.279 -  
  46.280 -  buffer_free ( &state_cipher);
  46.281 -  buffer_free ( &symkey_clear);
  46.282 -  buffer_free ( &symkey_cipher);
  46.283    free( sealed_NVM );
  46.284 -  Crypto_symcrypto_freekey (&symkey);
  46.285    
  46.286    return status;
  46.287  }
    47.1 --- a/tools/xm-test/README	Wed Dec 21 10:30:10 2005 -0600
    47.2 +++ b/tools/xm-test/README	Wed Dec 21 11:56:19 2005 -0600
    47.3 @@ -55,6 +55,26 @@ you should not attempt to use a ramdisk 
    47.4  of xm-test (i.e., don't use a ramdisk from 0.4.0 with 0.5.0.  0.5.0
    47.5  should work for 0.5.3 though)
    47.6  
    47.7 +If you'd like to build and run this with hardware virtual machine assist
    47.8 +(HVM) support to test fully virtualized disk images on VMX hardware, 
    47.9 +please add the --enable-vmx-support option to configure:
   47.10 +
   47.11 +  # ./autogen
   47.12 +  # ./configure --enable-vmx-support
   47.13 +  # make
   47.14 +
   47.15 +The ramdisk/bin/create_disk_image script, which builds the full virt
   47.16 +disk.img, requires Lilo 22.7+ to be installed on the system. Lilo is 
   47.17 +used to install the bootloader on the disk.img.
   47.18 +
   47.19 +If HVM / VMX support is enabled, the ramdisk/bin/create_disk_image script
   47.20 +will be run to create a full virt disk.img in the ramdisk directory. The
   47.21 +script, by default, will look in /boot for the first non-Xen kernel it
   47.22 +runs across. If you wish to use a different kernel or the script fails
   47.23 +to find a kernel, please run the script manually to make a disk.img 
   47.24 +using the -k option. Xm-test will look for disk.img in the ramdisk
   47.25 +directory when run by default.
   47.26 +
   47.27  
   47.28  Running
   47.29  =======
    48.1 --- a/tools/xm-test/ramdisk/Makefile.am	Wed Dec 21 10:30:10 2005 -0600
    48.2 +++ b/tools/xm-test/ramdisk/Makefile.am	Wed Dec 21 11:56:19 2005 -0600
    48.3 @@ -45,7 +45,7 @@ initrd.img: $(XMTEST_VER_IMG)
    48.4  
    48.5  disk.img: $(XMTEST_VER_IMG)
    48.6  	chmod a+x $(VMX_SCRIPT)
    48.7 -	$(VMX_SCRIPT) -r $(XMTEST_VER_IMG) -i disk.img
    48.8 +	$(VMX_SCRIPT) -r $(XMTEST_VER_IMG)
    48.9  
   48.10  existing:
   48.11  	@[ -f $(XMTEST_VER_IMG) ] && ln -sf $(XMTEST_VER_IMG) initrd.img || \
    49.1 --- a/tools/xm-test/ramdisk/bin/create_disk_image	Wed Dec 21 10:30:10 2005 -0600
    49.2 +++ b/tools/xm-test/ramdisk/bin/create_disk_image	Wed Dec 21 11:56:19 2005 -0600
    49.3 @@ -77,7 +77,7 @@ function check_dependencies()
    49.4  function initialize_globals()
    49.5  {
    49.6  	PROGNAME="create_disk_image"
    49.7 -	IMAGE="hvm.img"
    49.8 +	IMAGE="disk.img"
    49.9  	KERNEL=""
   49.10  	LCONF="lilo.conf"
   49.11  	LOOPD=""    # Loop device for entire disk image
    50.1 --- a/tools/xm-test/tests/block-create/11_block_attach_shared_dom0.py	Wed Dec 21 10:30:10 2005 -0600
    50.2 +++ b/tools/xm-test/tests/block-create/11_block_attach_shared_dom0.py	Wed Dec 21 11:56:19 2005 -0600
    50.3 @@ -34,3 +34,5 @@ try:
    50.4      FAIL("Bug #331: Started a DomU with write access to a rw mounted block device")
    50.5  except DomainError, e:
    50.6      s, o = traceCommand("umount mnt")
    50.7 +
    50.8 +domain.destroy()
    51.1 --- a/tools/xm-test/tests/block-create/12_block_attach_shared_domU.py	Wed Dec 21 10:30:10 2005 -0600
    51.2 +++ b/tools/xm-test/tests/block-create/12_block_attach_shared_domU.py	Wed Dec 21 11:56:19 2005 -0600
    51.3 @@ -20,8 +20,11 @@ except DomainError, e:
    51.4      FAIL("Unable to start domain")
    51.5  
    51.6  try:
    51.7 -    dom2.start()
    51.8 +    try:
    51.9 +        dom2.start()
   51.10 +        FAIL("Bug #331: Started a DomU with write access to an in-use block device")
   51.11 +    except DomainError, e:
   51.12 +        pass
   51.13 +finally:
   51.14      dom1.destroy()
   51.15 -    FAIL("Bug #331: Started a DomU with write access to an in-use block device")
   51.16 -except DomainError, e:
   51.17 -    dom1.destroy()
   51.18 +    dom2.destroy()
    52.1 --- a/tools/xm-test/tests/network/11_network_domU_ping_pos.py	Wed Dec 21 10:30:10 2005 -0600
    52.2 +++ b/tools/xm-test/tests/network/11_network_domU_ping_pos.py	Wed Dec 21 11:56:19 2005 -0600
    52.3 @@ -19,7 +19,7 @@ from XmTestLib import *
    52.4  
    52.5  def netDomain(ip):
    52.6      config = {"vif"  : ["ip=%s" % ip]}
    52.7 -    domain = XmTestDomain(extraConfig=config)
    52.8 +    dom = XmTestDomain(extraConfig=config)
    52.9      try:
   52.10          dom.start()
   52.11      except DomainError, e:
    53.1 --- a/tools/xm-test/tests/vcpu-disable/01_vcpu-disable_basic_pos.py	Wed Dec 21 10:30:10 2005 -0600
    53.2 +++ b/tools/xm-test/tests/vcpu-disable/01_vcpu-disable_basic_pos.py	Wed Dec 21 11:56:19 2005 -0600
    53.3 @@ -50,7 +50,7 @@ except DomainError, e:
    53.4      FAIL(str(e))
    53.5  
    53.6  # Disable VCPU 1
    53.7 -cmd = "xm set-vcpus %s 1" % domain.getName()
    53.8 +cmd = "xm vcpu-set %s 1" % domain.getName()
    53.9  status, output = safecmd(cmd)
   53.10  if check_status and status != 0:
   53.11      FAIL("\"%s\" returned invalid %i != 0" %(cmd,status))
   53.12 @@ -68,7 +68,7 @@ if domUvcpu1 is not None:
   53.13      FAIL("failed to disable VCPU1")
   53.14  
   53.15  # Enable VCPU 1
   53.16 -cmd = "xm set-vcpus %s 2" % domain.getName()
   53.17 +cmd = "xm vcpu-set %s 2" % domain.getName()
   53.18  status, output = safecmd(cmd)
   53.19  if check_status and status != 0:
   53.20      FAIL("\"%s\" returned invalid %i != 0" %(cmd,status))
    54.1 --- a/xen/Rules.mk	Wed Dec 21 10:30:10 2005 -0600
    54.2 +++ b/xen/Rules.mk	Wed Dec 21 11:56:19 2005 -0600
    54.3 @@ -6,7 +6,6 @@ verbose     ?= n
    54.4  debug       ?= n
    54.5  perfc       ?= n
    54.6  perfc_arrays?= n
    54.7 -domu_debug  ?= n
    54.8  crash_debug ?= n
    54.9  
   54.10  XEN_ROOT=$(BASEDIR)/..
   54.11 @@ -54,10 +53,6 @@ else
   54.12  CFLAGS += -g -DVERBOSE
   54.13  endif
   54.14  
   54.15 -ifeq ($(domu_debug),y)
   54.16 -CFLAGS += -DDOMU_DEBUG
   54.17 -endif
   54.18 -
   54.19  ifeq ($(crash_debug),y)
   54.20  CFLAGS += -g -DCRASH_DEBUG
   54.21  endif
    55.1 --- a/xen/arch/ia64/vmx/vlsapic.c	Wed Dec 21 10:30:10 2005 -0600
    55.2 +++ b/xen/arch/ia64/vmx/vlsapic.c	Wed Dec 21 11:56:19 2005 -0600
    55.3 @@ -476,19 +476,20 @@ static int irq_masked(VCPU *vcpu, int h_
    55.4   * May come from virtualization fault or
    55.5   * nested host interrupt.
    55.6   */
    55.7 -void vmx_vcpu_pend_interrupt(VCPU *vcpu, UINT64 vector)
    55.8 +int vmx_vcpu_pend_interrupt(VCPU *vcpu, uint8_t vector)
    55.9  {
   55.10      uint64_t    spsr;
   55.11 +    int ret;
   55.12  
   55.13      if (vector & ~0xff) {
   55.14          DPRINTK("vmx_vcpu_pend_interrupt: bad vector\n");
   55.15          return;
   55.16      }
   55.17      local_irq_save(spsr);
   55.18 -    VCPU(vcpu,irr[vector>>6]) |= 1UL<<(vector&63);
   55.19 -    //vlapic_update_shared_irr(vcpu);
   55.20 +    ret = test_and_set_bit(vector, &VCPU(vcpu, irr[0]));
   55.21      local_irq_restore(spsr);
   55.22      vcpu->arch.irq_new_pending = 1;
   55.23 +    return ret;
   55.24  }
   55.25  
   55.26  /*
   55.27 @@ -505,7 +506,6 @@ void vmx_vcpu_pend_batch_interrupt(VCPU 
   55.28      for (i=0 ; i<4; i++ ) {
   55.29          VCPU(vcpu,irr[i]) |= pend_irr[i];
   55.30      }
   55.31 -    //vlapic_update_shared_irr(vcpu);
   55.32      local_irq_restore(spsr);
   55.33      vcpu->arch.irq_new_pending = 1;
   55.34  }
   55.35 @@ -592,7 +592,6 @@ uint64_t guest_read_vivr(VCPU *vcpu)
   55.36      VLSAPIC_INSVC(vcpu,vec>>6) |= (1UL <<(vec&63));
   55.37      VCPU(vcpu, irr[vec>>6]) &= ~(1UL <<(vec&63));
   55.38      update_vhpi(vcpu, NULL_VECTOR);     // clear VHPI till EOI or IRR write
   55.39 -    //vlapic_update_shared_irr(vcpu);
   55.40      local_irq_restore(spsr);
   55.41      return (uint64_t)vec;
   55.42  }
    56.1 --- a/xen/arch/x86/audit.c	Wed Dec 21 10:30:10 2005 -0600
    56.2 +++ b/xen/arch/x86/audit.c	Wed Dec 21 11:56:19 2005 -0600
    56.3 @@ -61,7 +61,7 @@ int audit_adjust_pgtables(struct domain 
    56.4  #ifdef __i386__
    56.5  #ifdef CONFIG_X86_PAE
    56.6          /* 32b PAE */
    56.7 -        if ( (( frame_table[mfn].u.inuse.type_info & PGT_va_mask ) 
    56.8 +        if ( (( pfn_to_page(mfn)->u.inuse.type_info & PGT_va_mask ) 
    56.9  	    >> PGT_va_shift) == 3 )
   56.10              return l2_table_offset(HYPERVISOR_VIRT_START); 
   56.11          else
   56.12 @@ -364,7 +364,7 @@ int audit_adjust_pgtables(struct domain 
   56.13              {
   56.14                  gmfn = __gpfn_to_mfn(d, a->gpfn_and_flags & PGT_mfn_mask);
   56.15                  smfn = a->smfn;
   56.16 -                page = &frame_table[smfn];
   56.17 +                page = pfn_to_page(smfn);
   56.18  
   56.19                  switch ( a->gpfn_and_flags & PGT_type_mask ) {
   56.20                  case PGT_writable_pred:
   56.21 @@ -433,11 +433,13 @@ int audit_adjust_pgtables(struct domain 
   56.22          for_each_vcpu(d, v)
   56.23          {
   56.24              if ( pagetable_get_paddr(v->arch.guest_table) )
   56.25 -                adjust(&frame_table[pagetable_get_pfn(v->arch.guest_table)], !shadow_mode_refcounts(d));
   56.26 +                adjust(pfn_to_page(pagetable_get_pfn(v->arch.guest_table)),
   56.27 +                       !shadow_mode_refcounts(d));
   56.28              if ( pagetable_get_paddr(v->arch.shadow_table) )
   56.29 -                adjust(&frame_table[pagetable_get_pfn(v->arch.shadow_table)], 0);
   56.30 +                adjust(pfn_to_page(pagetable_get_pfn(v->arch.shadow_table)),
   56.31 +                       0);
   56.32              if ( v->arch.monitor_shadow_ref )
   56.33 -                adjust(&frame_table[v->arch.monitor_shadow_ref], 0);
   56.34 +                adjust(pfn_to_page(v->arch.monitor_shadow_ref), 0);
   56.35          }
   56.36      }
   56.37  
   56.38 @@ -617,7 +619,7 @@ void _audit_domain(struct domain *d, int
   56.39      void scan_for_pfn_in_mfn(struct domain *d, unsigned long xmfn,
   56.40                               unsigned long mfn)
   56.41      {
   56.42 -        struct pfn_info *page = &frame_table[mfn];
   56.43 +        struct pfn_info *page = pfn_to_page(mfn);
   56.44          l1_pgentry_t *pt = map_domain_page(mfn);
   56.45          int i;
   56.46  
    57.1 --- a/xen/arch/x86/dm/vmx_vioapic.c	Wed Dec 21 10:30:10 2005 -0600
    57.2 +++ b/xen/arch/x86/dm/vmx_vioapic.c	Wed Dec 21 11:56:19 2005 -0600
    57.3 @@ -306,14 +306,8 @@ static int ioapic_inj_irq(vmx_vioapic_t 
    57.4      switch (delivery_mode) {
    57.5      case VLAPIC_DELIV_MODE_FIXED:
    57.6      case VLAPIC_DELIV_MODE_LPRI:
    57.7 -        if (test_and_set_bit(vector, &VLAPIC_IRR(target)) && trig_mode == 1) {
    57.8 -            /* the level interrupt should not happen before it is cleard */
    57.9 +        if (vlapic_set_irq(target, vector, trig_mode) && (trig_mode == 1))
   57.10              printk("<ioapic_inj_irq> level interrupt happen before cleard\n");
   57.11 -        }
   57.12 -#ifndef __ia64__
   57.13 -        if (trig_mode)
   57.14 -            test_and_set_bit(vector, &target->tmr[0]);
   57.15 -#endif
   57.16          result = 1;
   57.17          break;
   57.18      default:
    58.1 --- a/xen/arch/x86/dom0_ops.c	Wed Dec 21 10:30:10 2005 -0600
    58.2 +++ b/xen/arch/x86/dom0_ops.c	Wed Dec 21 11:56:19 2005 -0600
    58.3 @@ -210,7 +210,7 @@ long arch_do_dom0_op(dom0_op_t *op, dom0
    58.4               unlikely((d = find_domain_by_id(dom)) == NULL) )
    58.5              break;
    58.6  
    58.7 -        page = &frame_table[pfn];
    58.8 +        page = pfn_to_page(pfn);
    58.9  
   58.10          if ( likely(get_page(page, d)) )
   58.11          {
   58.12 @@ -285,7 +285,7 @@ long arch_do_dom0_op(dom0_op_t *op, dom0
   58.13                  struct pfn_info *page;
   58.14                  unsigned long mfn = l_arr[j];
   58.15  
   58.16 -                page = &frame_table[mfn];
   58.17 +                page = pfn_to_page(mfn);
   58.18  
   58.19                  if ( likely(pfn_valid(mfn) && get_page(page, d)) ) 
   58.20                  {
   58.21 @@ -350,15 +350,14 @@ long arch_do_dom0_op(dom0_op_t *op, dom0
   58.22              list_ent = d->page_list.next;
   58.23              for ( i = 0; (i < max_pfns) && (list_ent != &d->page_list); i++ )
   58.24              {
   58.25 -                pfn = list_entry(list_ent, struct pfn_info, list) - 
   58.26 -                    frame_table;
   58.27 +                pfn = page_to_pfn(list_entry(list_ent, struct pfn_info, list));
   58.28                  if ( put_user(pfn, buffer) )
   58.29                  {
   58.30                      ret = -EFAULT;
   58.31                      break;
   58.32                  }
   58.33                  buffer++;
   58.34 -                list_ent = frame_table[pfn].list.next;
   58.35 +                list_ent = pfn_to_page(pfn)->list.next;
   58.36              }
   58.37              spin_unlock(&d->page_alloc_lock);
   58.38  
    59.1 --- a/xen/arch/x86/domain.c	Wed Dec 21 10:30:10 2005 -0600
    59.2 +++ b/xen/arch/x86/domain.c	Wed Dec 21 11:56:19 2005 -0600
    59.3 @@ -190,7 +190,7 @@ void dump_pageframe_info(struct domain *
    59.4          list_for_each_entry ( page, &d->page_list, list )
    59.5          {
    59.6              printk("Page %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
    59.7 -                   _p(page_to_phys(page)), _p(page - frame_table),
    59.8 +                   _p(page_to_phys(page)), _p(page_to_pfn(page)),
    59.9                     page->count_info, page->u.inuse.type_info);
   59.10          }
   59.11      }
   59.12 @@ -198,13 +198,13 @@ void dump_pageframe_info(struct domain *
   59.13      list_for_each_entry ( page, &d->xenpage_list, list )
   59.14      {
   59.15          printk("XenPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
   59.16 -               _p(page_to_phys(page)), _p(page - frame_table),
   59.17 +               _p(page_to_phys(page)), _p(page_to_pfn(page)),
   59.18                 page->count_info, page->u.inuse.type_info);
   59.19      }
   59.20  
   59.21      page = virt_to_page(d->shared_info);
   59.22      printk("Shared_info@%p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
   59.23 -           _p(page_to_phys(page)), _p(page - frame_table), page->count_info,
   59.24 +           _p(page_to_phys(page)), _p(page_to_pfn(page)), page->count_info,
   59.25             page->u.inuse.type_info);
   59.26  }
   59.27  
   59.28 @@ -391,19 +391,19 @@ int arch_set_info_guest(
   59.29  
   59.30      if ( shadow_mode_refcounts(d) )
   59.31      {
   59.32 -        if ( !get_page(&frame_table[phys_basetab>>PAGE_SHIFT], d) )
   59.33 +        if ( !get_page(pfn_to_page(phys_basetab>>PAGE_SHIFT), d) )
   59.34              return -EINVAL;
   59.35      }
   59.36      else if ( !(c->flags & VGCF_VMX_GUEST) )
   59.37      {
   59.38 -        if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d,
   59.39 +        if ( !get_page_and_type(pfn_to_page(phys_basetab>>PAGE_SHIFT), d,
   59.40                                  PGT_base_page_table) )
   59.41              return -EINVAL;
   59.42      }
   59.43  
   59.44      if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 )
   59.45      {
   59.46 -        put_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT]);
   59.47 +        put_page_and_type(pfn_to_page(phys_basetab>>PAGE_SHIFT));
   59.48          return rc;
   59.49      }
   59.50  
    60.1 --- a/xen/arch/x86/domain_build.c	Wed Dec 21 10:30:10 2005 -0600
    60.2 +++ b/xen/arch/x86/domain_build.c	Wed Dec 21 11:56:19 2005 -0600
    60.3 @@ -405,7 +405,7 @@ int construct_dom0(struct domain *d,
    60.4          *l1tab = l1e_from_pfn(mfn, L1_PROT);
    60.5          l1tab++;
    60.6          
    60.7 -        page = &frame_table[mfn];
    60.8 +        page = pfn_to_page(mfn);
    60.9          if ( !get_page_and_type(page, d, PGT_writable_page) )
   60.10              BUG();
   60.11  
   60.12 @@ -418,7 +418,7 @@ int construct_dom0(struct domain *d,
   60.13      l1tab += l1_table_offset(vpt_start);
   60.14      for ( count = 0; count < nr_pt_pages; count++ ) 
   60.15      {
   60.16 -        page = &frame_table[l1e_get_pfn(*l1tab)];
   60.17 +        page = pfn_to_page(l1e_get_pfn(*l1tab));
   60.18          if ( !opt_dom0_shadow )
   60.19              l1e_remove_flags(*l1tab, _PAGE_RW);
   60.20          else
   60.21 @@ -548,7 +548,7 @@ int construct_dom0(struct domain *d,
   60.22          *l1tab = l1e_from_pfn(mfn, L1_PROT);
   60.23          l1tab++;
   60.24  
   60.25 -        page = &frame_table[mfn];
   60.26 +        page = pfn_to_page(mfn);
   60.27          if ( (page->u.inuse.type_info == 0) &&
   60.28               !get_page_and_type(page, d, PGT_writable_page) )
   60.29              BUG();
   60.30 @@ -567,7 +567,7 @@ int construct_dom0(struct domain *d,
   60.31      for ( count = 0; count < nr_pt_pages; count++ ) 
   60.32      {
   60.33          l1e_remove_flags(*l1tab, _PAGE_RW);
   60.34 -        page = &frame_table[l1e_get_pfn(*l1tab)];
   60.35 +        page = pfn_to_page(l1e_get_pfn(*l1tab));
   60.36  
   60.37          /* Read-only mapping + PGC_allocated + page-table page. */
   60.38          page->count_info         = PGC_allocated | 3;
    61.1 --- a/xen/arch/x86/mm.c	Wed Dec 21 10:30:10 2005 -0600
    61.2 +++ b/xen/arch/x86/mm.c	Wed Dec 21 11:56:19 2005 -0600
    61.3 @@ -202,7 +202,7 @@ void arch_init_memory(void)
    61.4      /* First 1MB of RAM is historically marked as I/O. */
    61.5      for ( i = 0; i < 0x100; i++ )
    61.6      {
    61.7 -        page = &frame_table[i];
    61.8 +        page = pfn_to_page(i);
    61.9          page->count_info        = PGC_allocated | 1;
   61.10          page->u.inuse.type_info = PGT_writable_page | PGT_validated | 1;
   61.11          page_set_owner(page, dom_io);
   61.12 @@ -216,10 +216,10 @@ void arch_init_memory(void)
   61.13          /* Every page from cursor to start of next RAM region is I/O. */
   61.14          rstart_pfn = PFN_UP(e820.map[i].addr);
   61.15          rend_pfn   = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
   61.16 -        while ( pfn < rstart_pfn )
   61.17 +        for ( ; pfn < rstart_pfn; pfn++ )
   61.18          {
   61.19              BUG_ON(!pfn_valid(pfn));
   61.20 -            page = &frame_table[pfn++];
   61.21 +            page = pfn_to_page(pfn);
   61.22              page->count_info        = PGC_allocated | 1;
   61.23              page->u.inuse.type_info = PGT_writable_page | PGT_validated | 1;
   61.24              page_set_owner(page, dom_io);
   61.25 @@ -253,7 +253,7 @@ void invalidate_shadow_ldt(struct vcpu *
   61.26          pfn = l1e_get_pfn(v->arch.perdomain_ptes[i]);
   61.27          if ( pfn == 0 ) continue;
   61.28          v->arch.perdomain_ptes[i] = l1e_empty();
   61.29 -        page = &frame_table[pfn];
   61.30 +        page = pfn_to_page(pfn);
   61.31          ASSERT_PAGE_IS_TYPE(page, PGT_ldt_page);
   61.32          ASSERT_PAGE_IS_DOMAIN(page, v->domain);
   61.33          put_page_and_type(page);
   61.34 @@ -320,13 +320,13 @@ int map_ldt_shadow_page(unsigned int off
   61.35      if ( unlikely(!VALID_MFN(gmfn)) )
   61.36          return 0;
   61.37  
   61.38 -    res = get_page_and_type(&frame_table[gmfn], d, PGT_ldt_page);
   61.39 +    res = get_page_and_type(pfn_to_page(gmfn), d, PGT_ldt_page);
   61.40  
   61.41      if ( !res && unlikely(shadow_mode_refcounts(d)) )
   61.42      {
   61.43          shadow_lock(d);
   61.44          shadow_remove_all_write_access(d, gpfn, gmfn);
   61.45 -        res = get_page_and_type(&frame_table[gmfn], d, PGT_ldt_page);
   61.46 +        res = get_page_and_type(pfn_to_page(gmfn), d, PGT_ldt_page);
   61.47          shadow_unlock(d);
   61.48      }
   61.49  
   61.50 @@ -344,7 +344,7 @@ int map_ldt_shadow_page(unsigned int off
   61.51  
   61.52  static int get_page_from_pagenr(unsigned long page_nr, struct domain *d)
   61.53  {
   61.54 -    struct pfn_info *page = &frame_table[page_nr];
   61.55 +    struct pfn_info *page = pfn_to_page(page_nr);
   61.56  
   61.57      if ( unlikely(!pfn_valid(page_nr)) || unlikely(!get_page(page, d)) )
   61.58      {
   61.59 @@ -360,7 +360,7 @@ static int get_page_and_type_from_pagenr
   61.60                                           unsigned long type,
   61.61                                           struct domain *d)
   61.62  {
   61.63 -    struct pfn_info *page = &frame_table[page_nr];
   61.64 +    struct pfn_info *page = pfn_to_page(page_nr);
   61.65  
   61.66      if ( unlikely(!get_page_from_pagenr(page_nr, d)) )
   61.67          return 0;
   61.68 @@ -412,7 +412,7 @@ get_linear_pagetable(
   61.69           * Make sure that the mapped frame is an already-validated L2 table. 
   61.70           * If so, atomically increment the count (checking for overflow).
   61.71           */
   61.72 -        page = &frame_table[pfn];
   61.73 +        page = pfn_to_page(pfn);
   61.74          y = page->u.inuse.type_info;
   61.75          do {
   61.76              x = y;
   61.77 @@ -435,7 +435,7 @@ get_page_from_l1e(
   61.78      l1_pgentry_t l1e, struct domain *d)
   61.79  {
   61.80      unsigned long mfn = l1e_get_pfn(l1e);
   61.81 -    struct pfn_info *page = &frame_table[mfn];
   61.82 +    struct pfn_info *page = pfn_to_page(mfn);
   61.83      int okay;
   61.84      extern int domain_iomem_in_pfn(struct domain *d, unsigned long pfn);
   61.85  
   61.86 @@ -587,7 +587,7 @@ get_page_from_l4e(
   61.87  void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d)
   61.88  {
   61.89      unsigned long    pfn  = l1e_get_pfn(l1e);
   61.90 -    struct pfn_info *page = &frame_table[pfn];
   61.91 +    struct pfn_info *page = pfn_to_page(pfn);
   61.92      struct domain   *e;
   61.93      struct vcpu     *v;
   61.94  
   61.95 @@ -645,7 +645,7 @@ static void put_page_from_l2e(l2_pgentry
   61.96  {
   61.97      if ( (l2e_get_flags(l2e) & _PAGE_PRESENT) && 
   61.98           (l2e_get_pfn(l2e) != pfn) )
   61.99 -        put_page_and_type(&frame_table[l2e_get_pfn(l2e)]);
  61.100 +        put_page_and_type(pfn_to_page(l2e_get_pfn(l2e)));
  61.101  }
  61.102  
  61.103  
  61.104 @@ -655,7 +655,7 @@ static void put_page_from_l3e(l3_pgentry
  61.105  {
  61.106      if ( (l3e_get_flags(l3e) & _PAGE_PRESENT) && 
  61.107           (l3e_get_pfn(l3e) != pfn) )
  61.108 -        put_page_and_type(&frame_table[l3e_get_pfn(l3e)]);
  61.109 +        put_page_and_type(pfn_to_page(l3e_get_pfn(l3e)));
  61.110  }
  61.111  
  61.112  #endif
  61.113 @@ -666,7 +666,7 @@ static void put_page_from_l4e(l4_pgentry
  61.114  {
  61.115      if ( (l4e_get_flags(l4e) & _PAGE_PRESENT) && 
  61.116           (l4e_get_pfn(l4e) != pfn) )
  61.117 -        put_page_and_type(&frame_table[l4e_get_pfn(l4e)]);
  61.118 +        put_page_and_type(pfn_to_page(l4e_get_pfn(l4e)));
  61.119  }
  61.120  
  61.121  #endif
  61.122 @@ -1584,9 +1584,9 @@ int new_guest_cr3(unsigned long mfn)
  61.123          write_ptbase(v);
  61.124  
  61.125          if ( shadow_mode_refcounts(d) )
  61.126 -            put_page(&frame_table[old_base_mfn]);
  61.127 +            put_page(pfn_to_page(old_base_mfn));
  61.128          else
  61.129 -            put_page_and_type(&frame_table[old_base_mfn]);
  61.130 +            put_page_and_type(pfn_to_page(old_base_mfn));
  61.131  
  61.132          /* CR3 also holds a ref to its shadow... */
  61.133          if ( shadow_mode_enabled(d) )
  61.134 @@ -1595,7 +1595,7 @@ int new_guest_cr3(unsigned long mfn)
  61.135                  put_shadow_ref(v->arch.monitor_shadow_ref);
  61.136              v->arch.monitor_shadow_ref =
  61.137                  pagetable_get_pfn(v->arch.monitor_table);
  61.138 -            ASSERT(!page_get_owner(&frame_table[v->arch.monitor_shadow_ref]));
  61.139 +            ASSERT(!page_get_owner(pfn_to_page(v->arch.monitor_shadow_ref)));
  61.140              get_shadow_ref(v->arch.monitor_shadow_ref);
  61.141          }
  61.142      }
  61.143 @@ -1763,7 +1763,7 @@ int do_mmuext_op(
  61.144  
  61.145          okay = 1;
  61.146          mfn  = op.arg1.mfn;
  61.147 -        page = &frame_table[mfn];
  61.148 +        page = pfn_to_page(mfn);
  61.149  
  61.150          switch ( op.cmd )
  61.151          {
  61.152 @@ -1845,7 +1845,7 @@ int do_mmuext_op(
  61.153                      pagetable_get_pfn(v->arch.guest_table_user);
  61.154                  v->arch.guest_table_user = mk_pagetable(mfn << PAGE_SHIFT);
  61.155                  if ( old_mfn != 0 )
  61.156 -                    put_page_and_type(&frame_table[old_mfn]);
  61.157 +                    put_page_and_type(pfn_to_page(old_mfn));
  61.158              }
  61.159              break;
  61.160  #endif
  61.161 @@ -2145,7 +2145,7 @@ int do_mmu_update(
  61.162              va = map_domain_page_with_cache(mfn, &mapcache);
  61.163              va = (void *)((unsigned long)va +
  61.164                            (unsigned long)(req.ptr & ~PAGE_MASK));
  61.165 -            page = &frame_table[mfn];
  61.166 +            page = pfn_to_page(mfn);
  61.167  
  61.168              switch ( (type_info = page->u.inuse.type_info) & PGT_type_mask )
  61.169              {
  61.170 @@ -2285,7 +2285,7 @@ int do_mmu_update(
  61.171  
  61.172              mark_dirty(FOREIGNDOM, mfn);
  61.173  
  61.174 -            put_page(&frame_table[mfn]);
  61.175 +            put_page(pfn_to_page(mfn));
  61.176              break;
  61.177  
  61.178          default:
  61.179 @@ -2728,7 +2728,7 @@ void destroy_gdt(struct vcpu *v)
  61.180      for ( i = 0; i < FIRST_RESERVED_GDT_PAGE; i++ )
  61.181      {
  61.182          if ( (pfn = l1e_get_pfn(v->arch.perdomain_ptes[i])) != 0 )
  61.183 -            put_page_and_type(&frame_table[pfn]);
  61.184 +            put_page_and_type(pfn_to_page(pfn));
  61.185          v->arch.perdomain_ptes[i] = l1e_empty();
  61.186          v->arch.guest_context.gdt_frames[i] = 0;
  61.187      }
  61.188 @@ -2753,7 +2753,7 @@ long set_gdt(struct vcpu *v,
  61.189      for ( i = 0; i < nr_pages; i++ ) {
  61.190          pfn = frames[i];
  61.191          if ((pfn >= max_page) ||
  61.192 -            !get_page_and_type(&frame_table[pfn], d, PGT_gdt_page) )
  61.193 +            !get_page_and_type(pfn_to_page(pfn), d, PGT_gdt_page) )
  61.194              goto fail;
  61.195      }
  61.196  
  61.197 @@ -2773,7 +2773,7 @@ long set_gdt(struct vcpu *v,
  61.198  
  61.199   fail:
  61.200      while ( i-- > 0 )
  61.201 -        put_page_and_type(&frame_table[frames[i]]);
  61.202 +        put_page_and_type(pfn_to_page(frames[i]));
  61.203      return -EINVAL;
  61.204  }
  61.205  
  61.206 @@ -2827,7 +2827,7 @@ long do_update_descriptor(u64 pa, u64 de
  61.207          return -EINVAL;
  61.208      }
  61.209  
  61.210 -    page = &frame_table[mfn];
  61.211 +    page = pfn_to_page(mfn);
  61.212      if ( unlikely(!get_page(page, dom)) )
  61.213      {
  61.214          UNLOCK_BIGLOCK(dom);
  61.215 @@ -3037,7 +3037,7 @@ int revalidate_l1(
  61.216          if ( likely(l1e_get_intpte(ol1e) == (l1e_get_intpte(nl1e)|_PAGE_RW)) )
  61.217          {
  61.218              if ( likely(l1e_get_flags(nl1e) & _PAGE_PRESENT) )
  61.219 -                put_page_type(&frame_table[l1e_get_pfn(nl1e)]);
  61.220 +                put_page_type(pfn_to_page(l1e_get_pfn(nl1e)));
  61.221              continue;
  61.222          }
  61.223  
  61.224 @@ -3220,7 +3220,7 @@ static int ptwr_emulated_update(
  61.225      }
  61.226  
  61.227      pfn  = l1e_get_pfn(pte);
  61.228 -    page = &frame_table[pfn];
  61.229 +    page = pfn_to_page(pfn);
  61.230  
  61.231      /* We are looking only for read-only mappings of p.t. pages. */
  61.232      if ( ((l1e_get_flags(pte) & (_PAGE_RW|_PAGE_PRESENT)) != _PAGE_PRESENT) ||
  61.233 @@ -3331,7 +3331,7 @@ int ptwr_do_page_fault(struct domain *d,
  61.234      }
  61.235  
  61.236      pfn  = l1e_get_pfn(pte);
  61.237 -    page = &frame_table[pfn];
  61.238 +    page = pfn_to_page(pfn);
  61.239  
  61.240  #ifdef CONFIG_X86_64
  61.241  #define WRPT_PTE_FLAGS (_PAGE_RW | _PAGE_PRESENT | _PAGE_USER)
    62.1 --- a/xen/arch/x86/setup.c	Wed Dec 21 10:30:10 2005 -0600
    62.2 +++ b/xen/arch/x86/setup.c	Wed Dec 21 11:56:19 2005 -0600
    62.3 @@ -264,7 +264,7 @@ void __init __start_xen(multiboot_info_t
    62.4      unsigned long _initrd_start = 0, _initrd_len = 0;
    62.5      unsigned int initrdidx = 1;
    62.6      physaddr_t s, e;
    62.7 -    int i, e820_raw_nr = 0, bytes = 0;
    62.8 +    int i, e820_warn = 0, e820_raw_nr = 0, bytes = 0;
    62.9      struct ns16550_defaults ns16550 = {
   62.10          .data_bits = 8,
   62.11          .parity    = 'n',
   62.12 @@ -313,6 +313,22 @@ void __init __start_xen(multiboot_info_t
   62.13          while ( bytes < mbi->mmap_length )
   62.14          {
   62.15              memory_map_t *map = __va(mbi->mmap_addr + bytes);
   62.16 +
   62.17 +            /*
   62.18 +             * This is a gross workaround for a BIOS bug. Some bootloaders do
   62.19 +             * not write e820 map entries into pre-zeroed memory. This is
   62.20 +             * okay if the BIOS fills in all fields of the map entry, but
   62.21 +             * some broken BIOSes do not bother to write the high word of
   62.22 +             * the length field if the length is smaller than 4GB. We
   62.23 +             * detect and fix this by flagging sections below 4GB that
   62.24 +             * appear to be larger than 4GB in size.
   62.25 +             */
   62.26 +            if ( (map->base_addr_high == 0) && (map->length_high != 0) )
   62.27 +            {
   62.28 +                e820_warn = 1;
   62.29 +                map->length_high = 0;
   62.30 +            }
   62.31 +
   62.32              e820_raw[e820_raw_nr].addr = 
   62.33                  ((u64)map->base_addr_high << 32) | (u64)map->base_addr_low;
   62.34              e820_raw[e820_raw_nr].size = 
   62.35 @@ -320,6 +336,7 @@ void __init __start_xen(multiboot_info_t
   62.36              e820_raw[e820_raw_nr].type = 
   62.37                  (map->type > E820_SHARED_PAGE) ? E820_RESERVED : map->type;
   62.38              e820_raw_nr++;
   62.39 +
   62.40              bytes += map->size + 4;
   62.41          }
   62.42      }
   62.43 @@ -339,6 +356,10 @@ void __init __start_xen(multiboot_info_t
   62.44          for ( ; ; ) ;
   62.45      }
   62.46  
   62.47 +    if ( e820_warn )
   62.48 +        printk("WARNING: Buggy e820 map detected and fixed "
   62.49 +               "(truncated length fields).\n");
   62.50 +
   62.51      max_page = init_e820(e820_raw, &e820_raw_nr);
   62.52  
   62.53      modules_length = mod[mbi->mods_count-1].mod_end - mod[0].mod_start;
    63.1 --- a/xen/arch/x86/shadow.c	Wed Dec 21 10:30:10 2005 -0600
    63.2 +++ b/xen/arch/x86/shadow.c	Wed Dec 21 11:56:19 2005 -0600
    63.3 @@ -504,7 +504,7 @@ static unsigned long shadow_l2_table(
    63.4              l2e_from_pfn(smfn, __PAGE_HYPERVISOR);
    63.5  
    63.6          spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
    63.7 -            l2e_from_paddr(__pa(page_get_owner(&frame_table[gmfn])->arch.mm_perdomain_pt),
    63.8 +            l2e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt),
    63.9                              __PAGE_HYPERVISOR);
   63.10  
   63.11          if ( shadow_mode_translate(d) ) // NB: not external
   63.12 @@ -670,7 +670,7 @@ static void shadow_map_l1_into_current_l
   63.13              set_guest_back_ptr(d, sl1e, sl1mfn, i);
   63.14          }
   63.15  
   63.16 -        frame_table[sl1mfn].tlbflush_timestamp =
   63.17 +        pfn_to_page(sl1mfn)->tlbflush_timestamp =
   63.18              SHADOW_ENCODE_MIN_MAX(min, max);
   63.19  
   63.20          unmap_domain_page(gpl1e);
   63.21 @@ -907,7 +907,7 @@ shadow_make_snapshot(
   63.22      u32 min_max = 0;
   63.23      int min, max, length;
   63.24  
   63.25 -    if ( test_and_set_bit(_PGC_out_of_sync, &frame_table[gmfn].count_info) )
   63.26 +    if ( test_and_set_bit(_PGC_out_of_sync, &pfn_to_page(gmfn)->count_info) )
   63.27      {
   63.28          ASSERT(__shadow_status(d, gpfn, PGT_snapshot));
   63.29          return SHADOW_SNAPSHOT_ELSEWHERE;
   63.30 @@ -953,7 +953,7 @@ static struct out_of_sync_entry *
   63.31                               unsigned long mfn)
   63.32  {
   63.33      struct domain *d = v->domain;
   63.34 -    struct pfn_info *page = &frame_table[mfn];
   63.35 +    struct pfn_info *page = pfn_to_page(mfn);
   63.36      struct out_of_sync_entry *entry = shadow_alloc_oos_entry(d);
   63.37  
   63.38      ASSERT(shadow_lock_is_acquired(d));
   63.39 @@ -1174,7 +1174,7 @@ static int is_out_of_sync(struct vcpu *v
   63.40                  && i == PAGING_L4)
   63.41                  continue;       /* skip the top-level for 3-level */
   63.42  
   63.43 -            if ( page_out_of_sync(&frame_table[gmfn]) &&
   63.44 +            if ( page_out_of_sync(pfn_to_page(gmfn)) &&
   63.45                   !snapshot_entry_matches(
   63.46                       d, guest_pt, gpfn, table_offset_64(va, i)) )
   63.47              {
   63.48 @@ -1200,7 +1200,7 @@ static int is_out_of_sync(struct vcpu *v
   63.49          }
   63.50  
   63.51          /* L2 */
   63.52 -        if ( page_out_of_sync(&frame_table[gmfn]) &&
   63.53 +        if ( page_out_of_sync(pfn_to_page(gmfn)) &&
   63.54               !snapshot_entry_matches(d, guest_pt, gpfn, l2_table_offset(va)) )
   63.55          {
   63.56              unmap_and_return (1);
   63.57 @@ -1214,7 +1214,7 @@ static int is_out_of_sync(struct vcpu *v
   63.58  #undef unmap_and_return
   63.59  #endif /* CONFIG_PAGING_LEVELS >= 3 */
   63.60      {
   63.61 -        if ( page_out_of_sync(&frame_table[l2mfn]) &&
   63.62 +        if ( page_out_of_sync(pfn_to_page(l2mfn)) &&
   63.63               !snapshot_entry_matches(d, (guest_l1_pgentry_t *)v->arch.guest_vtable,
   63.64                                       l2pfn, guest_l2_table_offset(va)) )
   63.65              return 1;
   63.66 @@ -1234,7 +1234,7 @@ static int is_out_of_sync(struct vcpu *v
   63.67  
   63.68      guest_pt = (guest_l1_pgentry_t *) map_domain_page(l1mfn);
   63.69  
   63.70 -    if ( page_out_of_sync(&frame_table[l1mfn]) &&
   63.71 +    if ( page_out_of_sync(pfn_to_page(l1mfn)) &&
   63.72           !snapshot_entry_matches(
   63.73               d, guest_pt, l1pfn, guest_l1_table_offset(va)) ) 
   63.74      {
   63.75 @@ -1324,18 +1324,18 @@ static u32 remove_all_write_access_in_pt
   63.76      int i;
   63.77      u32 found = 0;
   63.78      int is_l1_shadow =
   63.79 -        ((frame_table[pt_mfn].u.inuse.type_info & PGT_type_mask) ==
   63.80 +        ((pfn_to_page(pt_mfn)->u.inuse.type_info & PGT_type_mask) ==
   63.81           PGT_l1_shadow);
   63.82  #if CONFIG_PAGING_LEVELS == 4
   63.83      is_l1_shadow |=
   63.84 -      ((frame_table[pt_mfn].u.inuse.type_info & PGT_type_mask) ==
   63.85 +      ((pfn_to_page(pt_mfn)->u.inuse.type_info & PGT_type_mask) ==
   63.86                  PGT_fl1_shadow);
   63.87  #endif
   63.88  
   63.89      match = l1e_from_pfn(readonly_gmfn, flags);
   63.90  
   63.91      if ( shadow_mode_external(d) ) {
   63.92 -        i = (frame_table[readonly_gmfn].u.inuse.type_info & PGT_va_mask)
   63.93 +        i = (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_va_mask)
   63.94              >> PGT_va_shift;
   63.95  
   63.96          if ( (i >= 0 && i < L1_PAGETABLE_ENTRIES) &&
   63.97 @@ -1373,7 +1373,7 @@ static int remove_all_write_access(
   63.98  
   63.99      // If it's not a writable page, then no writable refs can be outstanding.
  63.100      //
  63.101 -    if ( (frame_table[readonly_gmfn].u.inuse.type_info & PGT_type_mask) !=
  63.102 +    if ( (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_type_mask) !=
  63.103           PGT_writable_page )
  63.104      {
  63.105          perfc_incrc(remove_write_not_writable);
  63.106 @@ -1383,7 +1383,7 @@ static int remove_all_write_access(
  63.107      // How many outstanding writable PTEs for this page are there?
  63.108      //
  63.109      write_refs =
  63.110 -        (frame_table[readonly_gmfn].u.inuse.type_info & PGT_count_mask);
  63.111 +        (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_count_mask);
  63.112      if ( write_refs && MFN_PINNED(readonly_gmfn) )
  63.113      {
  63.114          write_refs--;
  63.115 @@ -1401,7 +1401,7 @@ static int remove_all_write_access(
  63.116  
  63.117           // Use the back pointer to locate the shadow page that can contain
  63.118           // the PTE of interest
  63.119 -         if ( (predicted_smfn = frame_table[readonly_gmfn].tlbflush_timestamp) ) {
  63.120 +         if ( (predicted_smfn = pfn_to_page(readonly_gmfn)->tlbflush_timestamp) ) {
  63.121               found += remove_all_write_access_in_ptpage(
  63.122                   d, predicted_smfn, predicted_smfn, readonly_gpfn, readonly_gmfn, write_refs, 0);
  63.123               if ( found == write_refs )
  63.124 @@ -1670,7 +1670,7 @@ static int resync_all(struct domain *d, 
  63.125                      if ( !(entry_get_flags(guest_pt[i]) & _PAGE_PRESENT) &&
  63.126                           unlikely(entry_get_value(guest_pt[i]) != 0) &&
  63.127                           !unshadow &&
  63.128 -                         (frame_table[smfn].u.inuse.type_info & PGT_pinned) )
  63.129 +                         (pfn_to_page(smfn)->u.inuse.type_info & PGT_pinned) )
  63.130                          unshadow = 1;
  63.131                  }
  63.132  #endif
  63.133 @@ -1718,7 +1718,7 @@ static int resync_all(struct domain *d, 
  63.134                  if ( !(guest_root_get_flags(new_root_e) & _PAGE_PRESENT) &&
  63.135                       unlikely(guest_root_get_intpte(new_root_e) != 0) &&
  63.136                       !unshadow &&
  63.137 -                     (frame_table[smfn].u.inuse.type_info & PGT_pinned) )
  63.138 +                     (pfn_to_page(smfn)->u.inuse.type_info & PGT_pinned) )
  63.139                      unshadow = 1;
  63.140              }
  63.141              if ( max == -1 )
  63.142 @@ -2401,7 +2401,7 @@ static int check_pte(
  63.143      {
  63.144          printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=0x%08lx page_table_page=%d\n",
  63.145                 eff_guest_pfn, eff_guest_mfn, shadow_mfn,
  63.146 -               frame_table[eff_guest_mfn].u.inuse.type_info,
  63.147 +               pfn_to_page(eff_guest_mfn)->u.inuse.type_info,
  63.148                 page_table_page);
  63.149          FAIL("RW coherence");
  63.150      }
  63.151 @@ -2412,7 +2412,7 @@ static int check_pte(
  63.152      {
  63.153          printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=0x%08lx page_table_page=%d\n",
  63.154                 eff_guest_pfn, eff_guest_mfn, shadow_mfn,
  63.155 -               frame_table[eff_guest_mfn].u.inuse.type_info,
  63.156 +               pfn_to_page(eff_guest_mfn)->u.inuse.type_info,
  63.157                 page_table_page);
  63.158          FAIL("RW2 coherence");
  63.159      }
  63.160 @@ -2781,7 +2781,7 @@ static unsigned long shadow_l3_table(
  63.161           * When we free L2 pages, we need to tell if the page contains
  63.162           * Xen private mappings. Use the va_mask part.
  63.163           */
  63.164 -        frame_table[s2mfn].u.inuse.type_info |= 
  63.165 +        pfn_to_page(s2mfn)->u.inuse.type_info |= 
  63.166              (unsigned long) 3 << PGT_score_shift; 
  63.167  
  63.168          memset(spl2e, 0, 
  63.169 @@ -2794,7 +2794,7 @@ static unsigned long shadow_l3_table(
  63.170          for ( i = 0; i < PDPT_L2_ENTRIES; i++ )
  63.171              spl2e[l2_table_offset(PERDOMAIN_VIRT_START) + i] =
  63.172                  l2e_from_page(
  63.173 -                    virt_to_page(page_get_owner(&frame_table[gmfn])->arch.mm_perdomain_pt) + i, 
  63.174 +                    virt_to_page(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt) + i, 
  63.175                      __PAGE_HYPERVISOR);
  63.176          for ( i = 0; i < (LINEARPT_MBYTES >> (L2_PAGETABLE_SHIFT - 20)); i++ )
  63.177              spl2e[l2_table_offset(LINEAR_PT_VIRT_START) + i] =
  63.178 @@ -2896,7 +2896,7 @@ static unsigned long shadow_l4_table(
  63.179             ROOT_PAGETABLE_XEN_SLOTS * sizeof(l4_pgentry_t));
  63.180  
  63.181          spl4e[l4_table_offset(PERDOMAIN_VIRT_START)] =
  63.182 -            l4e_from_paddr(__pa(page_get_owner(&frame_table[gmfn])->arch.mm_perdomain_l3),
  63.183 +            l4e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_l3),
  63.184                              __PAGE_HYPERVISOR);
  63.185  
  63.186          if ( shadow_mode_translate(d) ) // NB: not external
    64.1 --- a/xen/arch/x86/shadow32.c	Wed Dec 21 10:30:10 2005 -0600
    64.2 +++ b/xen/arch/x86/shadow32.c	Wed Dec 21 11:56:19 2005 -0600
    64.3 @@ -30,7 +30,7 @@
    64.4  #include <xen/sched.h>
    64.5  #include <xen/trace.h>
    64.6  
    64.7 -#define MFN_PINNED(_x) (frame_table[_x].u.inuse.type_info & PGT_pinned)
    64.8 +#define MFN_PINNED(_x) (pfn_to_page(_x)->u.inuse.type_info & PGT_pinned)
    64.9  #define va_to_l1mfn(_ed, _va) \
   64.10      (l2e_get_pfn(linear_l2_table(_ed)[_va>>L2_PAGETABLE_SHIFT]))
   64.11  
   64.12 @@ -144,11 +144,11 @@ shadow_demote(struct domain *d, unsigned
   64.13      if ( !shadow_mode_refcounts(d) )
   64.14          return;
   64.15  
   64.16 -    ASSERT(frame_table[gmfn].count_info & PGC_page_table);
   64.17 +    ASSERT(pfn_to_page(gmfn)->count_info & PGC_page_table);
   64.18  
   64.19      if ( shadow_max_pgtable_type(d, gpfn, NULL) == PGT_none )
   64.20      {
   64.21 -        clear_bit(_PGC_page_table, &frame_table[gmfn].count_info);
   64.22 +        clear_bit(_PGC_page_table, &pfn_to_page(gmfn)->count_info);
   64.23  
   64.24          if ( page_out_of_sync(pfn_to_page(gmfn)) )
   64.25          {
   64.26 @@ -380,7 +380,7 @@ free_shadow_l2_table(struct domain *d, u
   64.27  
   64.28  void free_shadow_page(unsigned long smfn)
   64.29  {
   64.30 -    struct pfn_info *page = &frame_table[smfn];
   64.31 +    struct pfn_info *page = pfn_to_page(smfn);
   64.32      unsigned long gmfn = page->u.inuse.type_info & PGT_mfn_mask;
   64.33      struct domain *d = page_get_owner(pfn_to_page(gmfn));
   64.34      unsigned long gpfn = __mfn_to_gpfn(d, gmfn);
   64.35 @@ -465,8 +465,8 @@ release_out_of_sync_entry(struct domain 
   64.36  {
   64.37      struct pfn_info *page;
   64.38  
   64.39 -    page = &frame_table[entry->gmfn];
   64.40 -        
   64.41 +    page = pfn_to_page(entry->gmfn);
   64.42 +
   64.43      // Decrement ref count of guest & shadow pages
   64.44      //
   64.45      put_page(page);
   64.46 @@ -795,7 +795,7 @@ void free_monitor_pagetable(struct vcpu 
   64.47       */
   64.48      mfn = pagetable_get_pfn(v->arch.monitor_table);
   64.49      unmap_domain_page(v->arch.monitor_vtable);
   64.50 -    free_domheap_page(&frame_table[mfn]);
   64.51 +    free_domheap_page(pfn_to_page(mfn));
   64.52  
   64.53      v->arch.monitor_table = mk_pagetable(0);
   64.54      v->arch.monitor_vtable = 0;
   64.55 @@ -1018,8 +1018,8 @@ int __shadow_mode_enable(struct domain *
   64.56          {
   64.57              // external guests provide their own memory for their P2M maps.
   64.58              //
   64.59 -            ASSERT( d == page_get_owner(
   64.60 -                        &frame_table[pagetable_get_pfn(d->arch.phys_table)]) );
   64.61 +            ASSERT(d == page_get_owner(pfn_to_page(pagetable_get_pfn(
   64.62 +                d->arch.phys_table))));
   64.63          }
   64.64      }
   64.65  
   64.66 @@ -1543,7 +1543,7 @@ static unsigned long shadow_l2_table(
   64.67              l2e_from_pfn(smfn, __PAGE_HYPERVISOR);
   64.68  
   64.69          spl2e[l2_table_offset(PERDOMAIN_VIRT_START)] =
   64.70 -            l2e_from_paddr(__pa(page_get_owner(&frame_table[gmfn])->arch.mm_perdomain_pt),
   64.71 +            l2e_from_paddr(__pa(page_get_owner(pfn_to_page(gmfn))->arch.mm_perdomain_pt),
   64.72                              __PAGE_HYPERVISOR);
   64.73  
   64.74          if ( shadow_mode_translate(d) ) // NB: not external
   64.75 @@ -1675,7 +1675,7 @@ void shadow_map_l1_into_current_l2(unsig
   64.76              set_guest_back_ptr(d, sl1e, sl1mfn, i);
   64.77          }
   64.78  
   64.79 -        frame_table[sl1mfn].tlbflush_timestamp =
   64.80 +        pfn_to_page(sl1mfn)->tlbflush_timestamp =
   64.81              SHADOW_ENCODE_MIN_MAX(min, max);
   64.82      }
   64.83  }
   64.84 @@ -1758,7 +1758,7 @@ shadow_make_snapshot(
   64.85      u32 min_max = 0;
   64.86      int min, max, length;
   64.87  
   64.88 -    if ( test_and_set_bit(_PGC_out_of_sync, &frame_table[gmfn].count_info) )
   64.89 +    if ( test_and_set_bit(_PGC_out_of_sync, &pfn_to_page(gmfn)->count_info) )
   64.90      {
   64.91          ASSERT(__shadow_status(d, gpfn, PGT_snapshot));
   64.92          return SHADOW_SNAPSHOT_ELSEWHERE;
   64.93 @@ -1809,7 +1809,7 @@ shadow_free_snapshot(struct domain *d, s
   64.94  
   64.95      // Clear the out_of_sync bit.
   64.96      //
   64.97 -    clear_bit(_PGC_out_of_sync, &frame_table[entry->gmfn].count_info);
   64.98 +    clear_bit(_PGC_out_of_sync, &pfn_to_page(entry->gmfn)->count_info);
   64.99  
  64.100      // XXX Need to think about how to protect the domain's
  64.101      // information less expensively.
  64.102 @@ -1826,7 +1826,7 @@ struct out_of_sync_entry *
  64.103                               unsigned long mfn)
  64.104  {
  64.105      struct domain *d = v->domain;
  64.106 -    struct pfn_info *page = &frame_table[mfn];
  64.107 +    struct pfn_info *page = pfn_to_page(mfn);
  64.108      struct out_of_sync_entry *entry = shadow_alloc_oos_entry(d);
  64.109  
  64.110      ASSERT(shadow_lock_is_acquired(d));
  64.111 @@ -1992,7 +1992,7 @@ int __shadow_out_of_sync(struct vcpu *v,
  64.112  
  64.113      perfc_incrc(shadow_out_of_sync_calls);
  64.114  
  64.115 -    if ( page_out_of_sync(&frame_table[l2mfn]) &&
  64.116 +    if ( page_out_of_sync(pfn_to_page(l2mfn)) &&
  64.117           !snapshot_entry_matches(d, (l1_pgentry_t *)v->arch.guest_vtable,
  64.118                                   l2pfn, l2_table_offset(va)) )
  64.119          return 1;
  64.120 @@ -2008,7 +2008,7 @@ int __shadow_out_of_sync(struct vcpu *v,
  64.121      if ( !VALID_MFN(l1mfn) )
  64.122          return 0;
  64.123  
  64.124 -    if ( page_out_of_sync(&frame_table[l1mfn]) &&
  64.125 +    if ( page_out_of_sync(pfn_to_page(l1mfn)) &&
  64.126           !snapshot_entry_matches(
  64.127               d, &linear_pg_table[l1_linear_offset(va) & ~(L1_PAGETABLE_ENTRIES-1)],
  64.128               l1pfn, l1_table_offset(va)) )
  64.129 @@ -2136,13 +2136,13 @@ static u32 remove_all_write_access_in_pt
  64.130      int i;
  64.131      u32 found = 0;
  64.132      int is_l1_shadow =
  64.133 -        ((frame_table[pt_mfn].u.inuse.type_info & PGT_type_mask) ==
  64.134 +        ((pfn_to_page(pt_mfn)->u.inuse.type_info & PGT_type_mask) ==
  64.135           PGT_l1_shadow);
  64.136  
  64.137      match = l1e_from_pfn(readonly_gmfn, flags);
  64.138  
  64.139      if ( shadow_mode_external(d) ) {
  64.140 -        i = (frame_table[readonly_gmfn].u.inuse.type_info & PGT_va_mask) 
  64.141 +        i = (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_va_mask) 
  64.142              >> PGT_va_shift;
  64.143  
  64.144          if ( (i >= 0 && i < L1_PAGETABLE_ENTRIES) &&
  64.145 @@ -2180,7 +2180,7 @@ int shadow_remove_all_write_access(
  64.146  
  64.147      // If it's not a writable page, then no writable refs can be outstanding.
  64.148      //
  64.149 -    if ( (frame_table[readonly_gmfn].u.inuse.type_info & PGT_type_mask) !=
  64.150 +    if ( (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_type_mask) !=
  64.151           PGT_writable_page )
  64.152      {
  64.153          perfc_incrc(remove_write_not_writable);
  64.154 @@ -2190,7 +2190,7 @@ int shadow_remove_all_write_access(
  64.155      // How many outstanding writable PTEs for this page are there?
  64.156      //
  64.157      write_refs =
  64.158 -        (frame_table[readonly_gmfn].u.inuse.type_info & PGT_count_mask);
  64.159 +        (pfn_to_page(readonly_gmfn)->u.inuse.type_info & PGT_count_mask);
  64.160      if ( write_refs && MFN_PINNED(readonly_gmfn) )
  64.161      {
  64.162          write_refs--;
  64.163 @@ -2208,7 +2208,7 @@ int shadow_remove_all_write_access(
  64.164  
  64.165           // Use the back pointer to locate the shadow page that can contain
  64.166           // the PTE of interest
  64.167 -         if ( (predicted_smfn = frame_table[readonly_gmfn].tlbflush_timestamp) ) {
  64.168 +         if ( (predicted_smfn = pfn_to_page(readonly_gmfn)->tlbflush_timestamp) ) {
  64.169               found += remove_all_write_access_in_ptpage(
  64.170                   d, predicted_smfn, predicted_smfn, readonly_gpfn, readonly_gmfn, write_refs, 0);
  64.171               if ( found == write_refs )
  64.172 @@ -2249,7 +2249,7 @@ static u32 remove_all_access_in_page(
  64.173      int i;
  64.174      u32 count = 0;
  64.175      int is_l1_shadow =
  64.176 -        ((frame_table[l1mfn].u.inuse.type_info & PGT_type_mask) ==
  64.177 +        ((pfn_to_page(l1mfn)->u.inuse.type_info & PGT_type_mask) ==
  64.178           PGT_l1_shadow);
  64.179  
  64.180      match = l1e_from_pfn(forbidden_gmfn, flags);
  64.181 @@ -2266,7 +2266,7 @@ static u32 remove_all_access_in_page(
  64.182          if ( is_l1_shadow )
  64.183              shadow_put_page_from_l1e(ol2e, d);
  64.184          else /* must be an hl2 page */
  64.185 -            put_page(&frame_table[forbidden_gmfn]);
  64.186 +            put_page(pfn_to_page(forbidden_gmfn));
  64.187      }
  64.188  
  64.189      unmap_domain_page(pl1e);
  64.190 @@ -2982,6 +2982,23 @@ void __update_pagetables(struct vcpu *v)
  64.191      }
  64.192  }
  64.193  
  64.194 +void clear_all_shadow_status(struct domain *d)
  64.195 +{
  64.196 +    shadow_lock(d);
  64.197 +    free_shadow_pages(d);
  64.198 +    free_shadow_ht_entries(d);
  64.199 +    d->arch.shadow_ht = 
  64.200 +        xmalloc_array(struct shadow_status, shadow_ht_buckets);
  64.201 +    if ( d->arch.shadow_ht == NULL ) {
  64.202 +        printk("clear all shadow status:xmalloc fail\n");
  64.203 +        domain_crash_synchronous();
  64.204 +    }
  64.205 +    memset(d->arch.shadow_ht, 0,
  64.206 +           shadow_ht_buckets * sizeof(struct shadow_status));
  64.207 +
  64.208 +    free_out_of_sync_entries(d);
  64.209 +    shadow_unlock(d);
  64.210 +}
  64.211  
  64.212  /************************************************************************/
  64.213  /************************************************************************/
  64.214 @@ -3139,7 +3156,7 @@ static int check_pte(
  64.215      {
  64.216          printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=%lx page_table_page=%d\n",
  64.217                 eff_guest_pfn, eff_guest_mfn, shadow_mfn,
  64.218 -               frame_table[eff_guest_mfn].u.inuse.type_info,
  64.219 +               pfn_to_page(eff_guest_mfn)->u.inuse.type_info,
  64.220                 page_table_page);
  64.221          FAIL("RW coherence");
  64.222      }
  64.223 @@ -3150,7 +3167,7 @@ static int check_pte(
  64.224      {
  64.225          printk("eff_guest_pfn=%lx eff_guest_mfn=%lx shadow_mfn=%lx t=%lx page_table_page=%d\n",
  64.226                 eff_guest_pfn, eff_guest_mfn, shadow_mfn,
  64.227 -               frame_table[eff_guest_mfn].u.inuse.type_info,
  64.228 +               pfn_to_page(eff_guest_mfn)->u.inuse.type_info,
  64.229                 page_table_page);
  64.230          FAIL("RW2 coherence");
  64.231      }
    65.1 --- a/xen/arch/x86/shadow_public.c	Wed Dec 21 10:30:10 2005 -0600
    65.2 +++ b/xen/arch/x86/shadow_public.c	Wed Dec 21 11:56:19 2005 -0600
    65.3 @@ -168,14 +168,14 @@ free_shadow_tables(struct domain *d, uns
    65.4  #if CONFIG_PAGING_LEVELS >=3
    65.5      if ( d->arch.ops->guest_paging_levels == PAGING_L2 )
    65.6      {
    65.7 -        struct pfn_info *page = &frame_table[smfn];
    65.8 +        struct pfn_info *page = pfn_to_page(smfn);
    65.9          for ( i = 0; i < PDP_ENTRIES; i++ )
   65.10          {
   65.11              if ( entry_get_flags(ple[i]) & _PAGE_PRESENT )
   65.12                  free_fake_shadow_l2(d,entry_get_pfn(ple[i]));
   65.13          }
   65.14  
   65.15 -        page = &frame_table[entry_get_pfn(ple[0])];
   65.16 +        page = pfn_to_page(entry_get_pfn(ple[0]));
   65.17          free_domheap_pages(page, SL2_ORDER);
   65.18          unmap_domain_page(ple);
   65.19      }
   65.20 @@ -208,7 +208,7 @@ free_shadow_tables(struct domain *d, uns
   65.21                      break;
   65.22                  if ( level == PAGING_L2 )
   65.23                  {
   65.24 -                    struct pfn_info *page = &frame_table[smfn]; 
   65.25 +                    struct pfn_info *page = pfn_to_page(smfn);
   65.26                      if ( is_xen_l2_slot(page->u.inuse.type_info, i) )
   65.27                          continue;
   65.28                  }
   65.29 @@ -299,7 +299,7 @@ void free_monitor_pagetable(struct vcpu 
   65.30       */
   65.31      mfn = pagetable_get_pfn(v->arch.monitor_table);
   65.32      unmap_domain_page(v->arch.monitor_vtable);
   65.33 -    free_domheap_page(&frame_table[mfn]);
   65.34 +    free_domheap_page(pfn_to_page(mfn));
   65.35  
   65.36      v->arch.monitor_table = mk_pagetable(0);
   65.37      v->arch.monitor_vtable = 0;
   65.38 @@ -394,7 +394,7 @@ void free_monitor_pagetable(struct vcpu 
   65.39       */
   65.40      mfn = pagetable_get_pfn(v->arch.monitor_table);
   65.41      unmap_domain_page(v->arch.monitor_vtable);
   65.42 -    free_domheap_page(&frame_table[mfn]);
   65.43 +    free_domheap_page(pfn_to_page(mfn));
   65.44  
   65.45      v->arch.monitor_table = mk_pagetable(0);
   65.46      v->arch.monitor_vtable = 0;
   65.47 @@ -411,7 +411,7 @@ shadow_free_snapshot(struct domain *d, s
   65.48  
   65.49      // Clear the out_of_sync bit.
   65.50      //
   65.51 -    clear_bit(_PGC_out_of_sync, &frame_table[entry->gmfn].count_info);
   65.52 +    clear_bit(_PGC_out_of_sync, &pfn_to_page(entry->gmfn)->count_info);
   65.53  
   65.54      // XXX Need to think about how to protect the domain's
   65.55      // information less expensively.
   65.56 @@ -428,7 +428,7 @@ release_out_of_sync_entry(struct domain 
   65.57  {
   65.58      struct pfn_info *page;
   65.59  
   65.60 -    page = &frame_table[entry->gmfn];
   65.61 +    page = pfn_to_page(entry->gmfn);
   65.62          
   65.63      // Decrement ref count of guest & shadow pages
   65.64      //
   65.65 @@ -501,11 +501,11 @@ shadow_demote(struct domain *d, unsigned
   65.66      if ( !shadow_mode_refcounts(d) )
   65.67          return;
   65.68  
   65.69 -    ASSERT(frame_table[gmfn].count_info & PGC_page_table);
   65.70 +    ASSERT(pfn_to_page(gmfn)->count_info & PGC_page_table);
   65.71  
   65.72      if ( shadow_max_pgtable_type(d, gpfn, NULL) == PGT_none )
   65.73      {
   65.74 -        clear_bit(_PGC_page_table, &frame_table[gmfn].count_info);
   65.75 +        clear_bit(_PGC_page_table, &pfn_to_page(gmfn)->count_info);
   65.76  
   65.77          if ( page_out_of_sync(pfn_to_page(gmfn)) )
   65.78          {
   65.79 @@ -600,7 +600,7 @@ void free_fake_shadow_l2(struct domain *
   65.80  
   65.81  void free_shadow_page(unsigned long smfn)
   65.82  {
   65.83 -    struct pfn_info *page = &frame_table[smfn];
   65.84 +    struct pfn_info *page = pfn_to_page(smfn);
   65.85  
   65.86      unsigned long gmfn = page->u.inuse.type_info & PGT_mfn_mask;
   65.87      struct domain *d = page_get_owner(pfn_to_page(gmfn));
   65.88 @@ -1067,8 +1067,8 @@ int __shadow_mode_enable(struct domain *
   65.89          {
   65.90              // external guests provide their own memory for their P2M maps.
   65.91              //
   65.92 -            ASSERT( d == page_get_owner(
   65.93 -                &frame_table[pagetable_get_pfn(d->arch.phys_table)]) );
   65.94 +            ASSERT(d == page_get_owner(pfn_to_page(pagetable_get_pfn(
   65.95 +                d->arch.phys_table))));
   65.96          }
   65.97      }
   65.98  
   65.99 @@ -1643,7 +1643,7 @@ static u32 remove_all_access_in_page(
  65.100      int i;
  65.101      u32 count = 0;
  65.102      int is_l1_shadow =
  65.103 -        ((frame_table[l1mfn].u.inuse.type_info & PGT_type_mask) ==
  65.104 +        ((pfn_to_page(l1mfn)->u.inuse.type_info & PGT_type_mask) ==
  65.105           PGT_l1_shadow);
  65.106  
  65.107      match = l1e_from_pfn(forbidden_gmfn, flags);
  65.108 @@ -1660,7 +1660,7 @@ static u32 remove_all_access_in_page(
  65.109          if ( is_l1_shadow )
  65.110              shadow_put_page_from_l1e(ol2e, d);
  65.111          else /* must be an hl2 page */
  65.112 -            put_page(&frame_table[forbidden_gmfn]);
  65.113 +            put_page(pfn_to_page(forbidden_gmfn));
  65.114      }
  65.115  
  65.116      unmap_domain_page(pl1e);
  65.117 @@ -1747,6 +1747,24 @@ void shadow_sync_and_drop_references(
  65.118      shadow_unlock(d);
  65.119  }
  65.120  
  65.121 +void clear_all_shadow_status(struct domain *d)
  65.122 +{
  65.123 +    shadow_lock(d);
  65.124 +    free_shadow_pages(d);
  65.125 +    free_shadow_ht_entries(d);
  65.126 +    d->arch.shadow_ht = 
  65.127 +        xmalloc_array(struct shadow_status, shadow_ht_buckets);
  65.128 +    if ( d->arch.shadow_ht == NULL ) {
  65.129 +        printk("clear all shadow status:xmalloc fail\n");
  65.130 +        domain_crash_synchronous();
  65.131 +    }
  65.132 +    memset(d->arch.shadow_ht, 0,
  65.133 +           shadow_ht_buckets * sizeof(struct shadow_status));
  65.134 +
  65.135 +    free_out_of_sync_entries(d);
  65.136 +    shadow_unlock(d);
  65.137 +}
  65.138 +
  65.139  /*
  65.140   * Local variables:
  65.141   * mode: C
    66.1 --- a/xen/arch/x86/traps.c	Wed Dec 21 10:30:10 2005 -0600
    66.2 +++ b/xen/arch/x86/traps.c	Wed Dec 21 11:56:19 2005 -0600
    66.3 @@ -1074,29 +1074,35 @@ asmlinkage int do_general_protection(str
    66.4      return 0;
    66.5  }
    66.6  
    66.7 -unsigned long nmi_softirq_reason;
    66.8 -static void nmi_softirq(void)
    66.9 +
   66.10 +/* Defer dom0 notification to softirq context (unsafe in NMI context). */
   66.11 +static unsigned long nmi_dom0_softirq_reason;
   66.12 +#define NMI_DOM0_PARITY_ERR 0
   66.13 +#define NMI_DOM0_IO_ERR     1
   66.14 +#define NMI_DOM0_UNKNOWN    2
   66.15 +
   66.16 +static void nmi_dom0_softirq(void)
   66.17  {
   66.18      if ( dom0 == NULL )
   66.19          return;
   66.20  
   66.21 -    if ( test_and_clear_bit(0, &nmi_softirq_reason) )
   66.22 +    if ( test_and_clear_bit(NMI_DOM0_PARITY_ERR, &nmi_dom0_softirq_reason) )
   66.23          send_guest_virq(dom0->vcpu[0], VIRQ_PARITY_ERR);
   66.24  
   66.25 -    if ( test_and_clear_bit(1, &nmi_softirq_reason) )
   66.26 +    if ( test_and_clear_bit(NMI_DOM0_IO_ERR, &nmi_dom0_softirq_reason) )
   66.27          send_guest_virq(dom0->vcpu[0], VIRQ_IO_ERR);
   66.28 +
   66.29 +    if ( test_and_clear_bit(NMI_DOM0_UNKNOWN, &nmi_dom0_softirq_reason) )
   66.30 +        send_guest_virq(dom0->vcpu[0], VIRQ_NMI);
   66.31  }
   66.32  
   66.33  asmlinkage void mem_parity_error(struct cpu_user_regs *regs)
   66.34  {
   66.35 -    /* Clear and disable the parity-error line. */
   66.36 -    outb((inb(0x61)&15)|4,0x61);
   66.37 -
   66.38      switch ( opt_nmi[0] )
   66.39      {
   66.40      case 'd': /* 'dom0' */
   66.41 -        set_bit(0, &nmi_softirq_reason);
   66.42 -        raise_softirq(NMI_SOFTIRQ);
   66.43 +        set_bit(NMI_DOM0_PARITY_ERR, &nmi_dom0_softirq_reason);
   66.44 +        raise_softirq(NMI_DOM0_SOFTIRQ);
   66.45      case 'i': /* 'ignore' */
   66.46          break;
   66.47      default:  /* 'fatal' */
   66.48 @@ -1104,18 +1110,19 @@ asmlinkage void mem_parity_error(struct 
   66.49          printk("\n\nNMI - MEMORY ERROR\n");
   66.50          fatal_trap(TRAP_nmi, regs);
   66.51      }
   66.52 +
   66.53 +    outb((inb(0x61) & 0x0f) | 0x04, 0x61); /* clear-and-disable parity check */
   66.54 +    mdelay(1);
   66.55 +    outb((inb(0x61) & 0x0b) | 0x00, 0x61); /* enable parity check */
   66.56  }
   66.57  
   66.58  asmlinkage void io_check_error(struct cpu_user_regs *regs)
   66.59  {
   66.60 -    /* Clear and disable the I/O-error line. */
   66.61 -    outb((inb(0x61)&15)|8,0x61);
   66.62 -
   66.63      switch ( opt_nmi[0] )
   66.64      {
   66.65      case 'd': /* 'dom0' */
   66.66 -        set_bit(0, &nmi_softirq_reason);
   66.67 -        raise_softirq(NMI_SOFTIRQ);
   66.68 +        set_bit(NMI_DOM0_IO_ERR, &nmi_dom0_softirq_reason);
   66.69 +        raise_softirq(NMI_DOM0_SOFTIRQ);
   66.70      case 'i': /* 'ignore' */
   66.71          break;
   66.72      default:  /* 'fatal' */
   66.73 @@ -1123,43 +1130,59 @@ asmlinkage void io_check_error(struct cp
   66.74          printk("\n\nNMI - I/O ERROR\n");
   66.75          fatal_trap(TRAP_nmi, regs);
   66.76      }
   66.77 +
   66.78 +    outb((inb(0x61) & 0x0f) | 0x08, 0x61); /* clear-and-disable IOCK */
   66.79 +    mdelay(1);
   66.80 +    outb((inb(0x61) & 0x07) | 0x00, 0x61); /* enable IOCK */
   66.81  }
   66.82  
   66.83  static void unknown_nmi_error(unsigned char reason)
   66.84  {
   66.85 -    printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
   66.86 -    printk("Dazed and confused, but trying to continue\n");
   66.87 -    printk("Do you have a strange power saving mode enabled?\n");
   66.88 -}
   66.89 -
   66.90 -static void default_do_nmi(struct cpu_user_regs *regs, unsigned long reason)
   66.91 -{
   66.92 -    if ( nmi_watchdog )
   66.93 -        nmi_watchdog_tick(regs);
   66.94 -
   66.95 -    if ( reason & 0x80 )
   66.96 -        mem_parity_error(regs);
   66.97 -    else if ( reason & 0x40 )
   66.98 -        io_check_error(regs);
   66.99 -    else if ( !nmi_watchdog )
  66.100 -        unknown_nmi_error((unsigned char)(reason&0xff));
  66.101 +    switch ( opt_nmi[0] )
  66.102 +    {
  66.103 +    case 'd': /* 'dom0' */
  66.104 +        set_bit(NMI_DOM0_UNKNOWN, &nmi_dom0_softirq_reason);
  66.105 +        raise_softirq(NMI_DOM0_SOFTIRQ);
  66.106 +    case 'i': /* 'ignore' */
  66.107 +        break;
  66.108 +    default:  /* 'fatal' */
  66.109 +        printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
  66.110 +        printk("Dazed and confused, but trying to continue\n");
  66.111 +        printk("Do you have a strange power saving mode enabled?\n");
  66.112 +    }
  66.113  }
  66.114  
  66.115  static int dummy_nmi_callback(struct cpu_user_regs *regs, int cpu)
  66.116  {
  66.117 -	return 0;
  66.118 +    return 0;
  66.119  }
  66.120   
  66.121  static nmi_callback_t nmi_callback = dummy_nmi_callback;
  66.122   
  66.123 -asmlinkage void do_nmi(struct cpu_user_regs *regs, unsigned long reason)
  66.124 +asmlinkage void do_nmi(struct cpu_user_regs *regs)
  66.125  {
  66.126      unsigned int cpu = smp_processor_id();
  66.127 +    unsigned char reason;
  66.128  
  66.129      ++nmi_count(cpu);
  66.130  
  66.131 -	if ( !nmi_callback(regs, cpu) )
  66.132 -		default_do_nmi(regs, reason);
  66.133 +    if ( nmi_callback(regs, cpu) )
  66.134 +        return;
  66.135 +
  66.136 +    if ( nmi_watchdog )
  66.137 +        nmi_watchdog_tick(regs);
  66.138 +
  66.139 +    /* Only the BSP gets external NMIs from the system. */
  66.140 +    if ( cpu == 0 )
  66.141 +    {
  66.142 +        reason = inb(0x61);
  66.143 +        if ( reason & 0x80 )
  66.144 +            mem_parity_error(regs);
  66.145 +        else if ( reason & 0x40 )
  66.146 +            io_check_error(regs);
  66.147 +        else if ( !nmi_watchdog )
  66.148 +            unknown_nmi_error((unsigned char)(reason&0xff));
  66.149 +    }
  66.150  }
  66.151  
  66.152  void set_nmi_callback(nmi_callback_t callback)
  66.153 @@ -1169,7 +1192,7 @@ void set_nmi_callback(nmi_callback_t cal
  66.154  
  66.155  void unset_nmi_callback(void)
  66.156  {
  66.157 -	nmi_callback = dummy_nmi_callback;
  66.158 +    nmi_callback = dummy_nmi_callback;
  66.159  }
  66.160  
  66.161  asmlinkage int math_state_restore(struct cpu_user_regs *regs)
  66.162 @@ -1318,7 +1341,7 @@ void __init trap_init(void)
  66.163  
  66.164      cpu_init();
  66.165  
  66.166 -    open_softirq(NMI_SOFTIRQ, nmi_softirq);
  66.167 +    open_softirq(NMI_DOM0_SOFTIRQ, nmi_dom0_softirq);
  66.168  }
  66.169  
  66.170  
    67.1 --- a/xen/arch/x86/vmx.c	Wed Dec 21 10:30:10 2005 -0600
    67.2 +++ b/xen/arch/x86/vmx.c	Wed Dec 21 11:56:19 2005 -0600
    67.3 @@ -102,7 +102,8 @@ void vmx_relinquish_resources(struct vcp
    67.4      if (v->vcpu_id == 0) {
    67.5          /* unmap IO shared page */
    67.6          struct domain *d = v->domain;
    67.7 -        unmap_domain_page((void *)d->arch.vmx_platform.shared_page_va);
    67.8 +        if ( d->arch.vmx_platform.shared_page_va )
    67.9 +            unmap_domain_page((void *)d->arch.vmx_platform.shared_page_va);
   67.10      }
   67.11  
   67.12      destroy_vmcs(&v->arch.arch_vmx);
   67.13 @@ -110,12 +111,12 @@ void vmx_relinquish_resources(struct vcp
   67.14      vpit = &v->domain->arch.vmx_platform.vmx_pit;
   67.15      if ( active_ac_timer(&(vpit->pit_timer)) )
   67.16          rem_ac_timer(&vpit->pit_timer);
   67.17 -    if ( active_ac_timer(&v->arch.arch_vmx.hlt_timer) ) {
   67.18 +    if ( active_ac_timer(&v->arch.arch_vmx.hlt_timer) )
   67.19          rem_ac_timer(&v->arch.arch_vmx.hlt_timer);
   67.20 -    }
   67.21 -    if ( vmx_apic_support(v->domain) ) {
   67.22 -        rem_ac_timer( &(VLAPIC(v)->vlapic_timer) );
   67.23 -        xfree( VLAPIC(v) );
   67.24 +    if ( vmx_apic_support(v->domain) && (VLAPIC(v) != NULL) )
   67.25 +    {
   67.26 +        rem_ac_timer(&VLAPIC(v)->vlapic_timer);
   67.27 +        xfree(VLAPIC(v));
   67.28      }
   67.29  }
   67.30  
   67.31 @@ -334,7 +335,7 @@ static inline int  long_mode_do_msr_writ
   67.32  
   67.33  extern long evtchn_send(int lport);
   67.34  extern long do_block(void);
   67.35 -void do_nmi(struct cpu_user_regs *, unsigned long);
   67.36 +void do_nmi(struct cpu_user_regs *);
   67.37  
   67.38  static int check_vmx_controls(ctrls, msr)
   67.39  {
   67.40 @@ -503,6 +504,8 @@ static void vmx_do_no_device_fault(void)
   67.41      __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_NM);
   67.42  }
   67.43  
   67.44 +/* Reserved bits: [31:15], [12:11], [9], [6], [2:1] */
   67.45 +#define VMX_VCPU_CPUID_L1_RESERVED 0xffff9a46 
   67.46  
   67.47  static void vmx_vmexit_do_cpuid(unsigned long input, struct cpu_user_regs *regs)
   67.48  {
   67.49 @@ -537,9 +540,17 @@ static void vmx_vmexit_do_cpuid(unsigned
   67.50          }
   67.51  
   67.52          /* Unsupportable for virtualised CPUs. */
   67.53 +        ecx &= ~VMX_VCPU_CPUID_L1_RESERVED; /* mask off reserved bits */
   67.54          clear_bit(X86_FEATURE_VMXE & 31, &ecx);
   67.55          clear_bit(X86_FEATURE_MWAIT & 31, &ecx);
   67.56      }
   67.57 +#ifdef __i386__
   67.58 +    else if ( input == 0x80000001 )
   67.59 +    {
   67.60 +        /* Mask feature for Intel ia32e or AMD long mode. */
   67.61 +        clear_bit(X86_FEATURE_LM & 31, &edx);
   67.62 +    }
   67.63 +#endif
   67.64  
   67.65      regs->eax = (unsigned long) eax;
   67.66      regs->ebx = (unsigned long) ebx;
   67.67 @@ -1091,11 +1102,21 @@ static int vmx_set_cr0(unsigned long val
   67.68      unsigned long eip;
   67.69      int paging_enabled;
   67.70      unsigned long vm_entry_value;
   67.71 +    unsigned long old_cr0;
   67.72  
   67.73      /*
   67.74       * CR0: We don't want to lose PE and PG.
   67.75       */
   67.76 -    paging_enabled = vmx_paging_enabled(v);
   67.77 +    __vmread_vcpu(v, CR0_READ_SHADOW, &old_cr0);
   67.78 +    paging_enabled = (old_cr0 & X86_CR0_PE) && (old_cr0 & X86_CR0_PG);
   67.79 +    /* If OS don't use clts to clear TS bit...*/
   67.80 +    if((old_cr0 & X86_CR0_TS) && !(value & X86_CR0_TS))
   67.81 +    {
   67.82 +            clts();
   67.83 +            setup_fpu(v);
   67.84 +    }
   67.85 +
   67.86 +
   67.87      __vmwrite(GUEST_CR0, value | X86_CR0_PE | X86_CR0_PG | X86_CR0_NE);
   67.88      __vmwrite(CR0_READ_SHADOW, value);
   67.89  
   67.90 @@ -1210,6 +1231,7 @@ static int vmx_set_cr0(unsigned long val
   67.91              }
   67.92          }
   67.93  
   67.94 +        clear_all_shadow_status(v->domain);
   67.95          if (vmx_assist(v, VMX_ASSIST_INVOKE)) {
   67.96              set_bit(VMX_CPU_STATE_ASSIST_ENABLED, &v->arch.arch_vmx.cpu_state);
   67.97              __vmread(GUEST_RIP, &eip);
   67.98 @@ -1828,7 +1850,7 @@ asmlinkage void vmx_vmexit_handler(struc
   67.99              break;
  67.100          }
  67.101          case TRAP_nmi:
  67.102 -            do_nmi(&regs, 0);
  67.103 +            do_nmi(&regs);
  67.104              break;
  67.105          default:
  67.106              vmx_reflect_exception(v);
    68.1 --- a/xen/arch/x86/vmx_intercept.c	Wed Dec 21 10:30:10 2005 -0600
    68.2 +++ b/xen/arch/x86/vmx_intercept.c	Wed Dec 21 11:56:19 2005 -0600
    68.3 @@ -203,6 +203,12 @@ static void pit_cal_count(struct vmx_vir
    68.4      u64 nsec_delta = (unsigned int)((NOW() - vpit->inject_point));
    68.5      if (nsec_delta > vpit->period)
    68.6          VMX_DBG_LOG(DBG_LEVEL_1, "VMX_PIT:long time has passed from last injection!");
    68.7 +    if(vpit->init_val == 0)
    68.8 +    {
    68.9 +        printk("PIT init value == 0!\n");
   68.10 +        domain_crash_synchronous();
   68.11 +    }
   68.12 +
   68.13      vpit->count = vpit->init_val - ((nsec_delta * PIT_FREQ / 1000000000ULL) % vpit->init_val );
   68.14  }
   68.15  
    69.1 --- a/xen/arch/x86/x86_32/entry.S	Wed Dec 21 10:30:10 2005 -0600
    69.2 +++ b/xen/arch/x86/x86_32/entry.S	Wed Dec 21 11:56:19 2005 -0600
    69.3 @@ -601,15 +601,7 @@ ENTRY(nmi)
    69.4  	pushl %eax
    69.5  	SAVE_ALL_NOSEGREGS(a)
    69.6  
    69.7 -        # Check for hardware problems.
    69.8 -        inb   $0x61,%al
    69.9 -        testb $0x80,%al
   69.10 -        jne   nmi_parity_err
   69.11 -        testb $0x40,%al
   69.12 -        jne   nmi_io_err
   69.13 -        movl  %eax,%ebx
   69.14 -        
   69.15 -        # Okay, its almost a normal NMI tick. We can only process it if:
   69.16 +        # We can only process the NMI if:
   69.17          #  A. We are the outermost Xen activation (in which case we have
   69.18          #     the selectors safely saved on our stack)
   69.19          #  B. DS and ES contain sane Xen values.
   69.20 @@ -619,7 +611,7 @@ ENTRY(nmi)
   69.21          movl  UREGS_eflags(%esp),%eax
   69.22          movb  UREGS_cs(%esp),%al
   69.23          testl $(3|X86_EFLAGS_VM),%eax
   69.24 -        jnz   do_watchdog_tick
   69.25 +        jnz   continue_nmi
   69.26          movl  %ds,%eax
   69.27          cmpw  $(__HYPERVISOR_DS),%ax
   69.28          jne   defer_nmi
   69.29 @@ -627,15 +619,14 @@ ENTRY(nmi)
   69.30          cmpw  $(__HYPERVISOR_DS),%ax
   69.31          jne   defer_nmi
   69.32  
   69.33 -do_watchdog_tick:
   69.34 +continue_nmi:
   69.35          movl  $(__HYPERVISOR_DS),%edx
   69.36          movl  %edx,%ds
   69.37          movl  %edx,%es
   69.38          movl  %esp,%edx
   69.39 -        pushl %ebx   # reason
   69.40 -        pushl %edx   # regs
   69.41 +        pushl %edx
   69.42          call  do_nmi
   69.43 -        addl  $8,%esp
   69.44 +        addl  $4,%esp
   69.45          jmp   ret_from_intr
   69.46  
   69.47  defer_nmi:
   69.48 @@ -649,55 +640,6 @@ 1:      movl  %ss:APIC_ICR(%eax),%ebx
   69.49                  TRAP_deferred_nmi),%ss:APIC_ICR(%eax)
   69.50          jmp   restore_all_xen
   69.51  
   69.52 -nmi_parity_err:
   69.53 -        # Clear and disable the parity-error line
   69.54 -        andb $0xf,%al
   69.55 -        orb  $0x4,%al
   69.56 -        outb %al,$0x61
   69.57 -        cmpb $'i',%ss:opt_nmi # nmi=ignore
   69.58 -        je   nmi_out
   69.59 -        bts  $0,%ss:nmi_softirq_reason
   69.60 -        bts  $NMI_SOFTIRQ,%ss:irq_stat
   69.61 -        cmpb $'d',%ss:opt_nmi # nmi=dom0
   69.62 -        je   nmi_out
   69.63 -        movl $(__HYPERVISOR_DS),%edx       # nmi=fatal
   69.64 -        movl %edx,%ds
   69.65 -        movl %edx,%es
   69.66 -        movl %esp,%edx
   69.67 -        push %edx
   69.68 -        call mem_parity_error
   69.69 -        addl $4,%esp
   69.70 -nmi_out:movl  %ss:UREGS_eflags(%esp),%eax
   69.71 -        movb  %ss:UREGS_cs(%esp),%al
   69.72 -        testl $(3|X86_EFLAGS_VM),%eax
   69.73 -        jz    restore_all_xen
   69.74 -        movl  $(__HYPERVISOR_DS),%edx
   69.75 -        movl  %edx,%ds
   69.76 -        movl  %edx,%es
   69.77 -        GET_CURRENT(%ebx)
   69.78 -        jmp   test_all_events
   69.79 -                
   69.80 -nmi_io_err: 
   69.81 -        # Clear and disable the I/O-error line
   69.82 -        andb $0xf,%al
   69.83 -        orb  $0x8,%al
   69.84 -        outb %al,$0x61
   69.85 -        cmpb $'i',%ss:opt_nmi # nmi=ignore
   69.86 -        je   nmi_out
   69.87 -        bts  $1,%ss:nmi_softirq_reason
   69.88 -        bts  $NMI_SOFTIRQ,%ss:irq_stat
   69.89 -        cmpb $'d',%ss:opt_nmi # nmi=dom0
   69.90 -        je   nmi_out
   69.91 -        movl $(__HYPERVISOR_DS),%edx       # nmi=fatal
   69.92 -        movl %edx,%ds
   69.93 -        movl %edx,%es
   69.94 -        movl %esp,%edx
   69.95 -        push %edx
   69.96 -        call io_check_error                        
   69.97 -        addl $4,%esp
   69.98 -        jmp  nmi_out
   69.99 -
  69.100 -
  69.101  ENTRY(setup_vm86_frame)
  69.102          # Copies the entire stack frame forwards by 16 bytes.
  69.103          .macro copy_vm86_words count=18
    70.1 --- a/xen/arch/x86/x86_32/mm.c	Wed Dec 21 10:30:10 2005 -0600
    70.2 +++ b/xen/arch/x86/x86_32/mm.c	Wed Dec 21 11:56:19 2005 -0600
    70.3 @@ -177,10 +177,11 @@ void subarch_init_memory(struct domain *
    70.4              idle_pg_table_l2[l2_linear_offset(RDWR_MPT_VIRT_START) + i]);
    70.5          for ( j = 0; j < L2_PAGETABLE_ENTRIES; j++ )
    70.6          {
    70.7 -            frame_table[m2p_start_mfn+j].count_info = PGC_allocated | 1;
    70.8 +            struct pfn_info *page = pfn_to_page(m2p_start_mfn + j);
    70.9 +            page->count_info = PGC_allocated | 1;
   70.10              /* Ensure it's only mapped read-only by domains. */
   70.11 -            frame_table[m2p_start_mfn+j].u.inuse.type_info = PGT_gdt_page | 1;
   70.12 -            page_set_owner(&frame_table[m2p_start_mfn+j], dom_xen);
   70.13 +            page->u.inuse.type_info = PGT_gdt_page | 1;
   70.14 +            page_set_owner(page, dom_xen);
   70.15          }
   70.16      }
   70.17  }
    71.1 --- a/xen/arch/x86/x86_32/traps.c	Wed Dec 21 10:30:10 2005 -0600
    71.2 +++ b/xen/arch/x86/x86_32/traps.c	Wed Dec 21 11:56:19 2005 -0600
    71.3 @@ -160,9 +160,9 @@ asmlinkage void do_double_fault(void)
    71.4  BUILD_SMP_INTERRUPT(deferred_nmi, TRAP_deferred_nmi)
    71.5  asmlinkage void smp_deferred_nmi(struct cpu_user_regs regs)
    71.6  {
    71.7 -    asmlinkage void do_nmi(struct cpu_user_regs *, unsigned long);
    71.8 +    asmlinkage void do_nmi(struct cpu_user_regs *);
    71.9      ack_APIC_irq();
   71.10 -    do_nmi(&regs, 0);
   71.11 +    do_nmi(&regs);
   71.12  }
   71.13  
   71.14  void __init percpu_traps_init(void)
    72.1 --- a/xen/arch/x86/x86_64/entry.S	Wed Dec 21 10:30:10 2005 -0600
    72.2 +++ b/xen/arch/x86/x86_64/entry.S	Wed Dec 21 11:56:19 2005 -0600
    72.3 @@ -567,9 +567,7 @@ ENTRY(double_fault)
    72.4  ENTRY(nmi)
    72.5          pushq $0
    72.6          SAVE_ALL
    72.7 -        inb   $0x61,%al
    72.8 -        movl  %eax,%esi # reason
    72.9 -        movq  %rsp,%rdi # regs
   72.10 +        movq  %rsp,%rdi
   72.11          call  do_nmi
   72.12  	jmp   restore_all_xen
   72.13  
    73.1 --- a/xen/arch/x86/x86_64/mm.c	Wed Dec 21 10:30:10 2005 -0600
    73.2 +++ b/xen/arch/x86/x86_64/mm.c	Wed Dec 21 11:56:19 2005 -0600
    73.3 @@ -166,11 +166,12 @@ void subarch_init_memory(struct domain *
    73.4  
    73.5          for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
    73.6          {
    73.7 -            frame_table[m2p_start_mfn+i].count_info = PGC_allocated | 1;
    73.8 +            struct pfn_info *page = pfn_to_page(m2p_start_mfn + i);
    73.9 +            page->count_info = PGC_allocated | 1;
   73.10              /* gdt to make sure it's only mapped read-only by non-privileged
   73.11                 domains. */
   73.12 -            frame_table[m2p_start_mfn+i].u.inuse.type_info = PGT_gdt_page | 1;
   73.13 -            page_set_owner(&frame_table[m2p_start_mfn+i], dom_xen);
   73.14 +            page->u.inuse.type_info = PGT_gdt_page | 1;
   73.15 +            page_set_owner(page, dom_xen);
   73.16          }
   73.17      }
   73.18  }
    74.1 --- a/xen/arch/x86/x86_emulate.c	Wed Dec 21 10:30:10 2005 -0600
    74.2 +++ b/xen/arch/x86/x86_emulate.c	Wed Dec 21 11:56:19 2005 -0600
    74.3 @@ -9,14 +9,6 @@
    74.4  #ifdef __TEST_HARNESS__
    74.5  #include <stdio.h>
    74.6  #include <stdint.h>
    74.7 -typedef uint8_t            u8;
    74.8 -typedef uint16_t           u16;
    74.9 -typedef uint32_t           u32;
   74.10 -typedef uint64_t           u64;
   74.11 -typedef int8_t             s8;
   74.12 -typedef int16_t            s16;
   74.13 -typedef int32_t            s32;
   74.14 -typedef int64_t            s64;
   74.15  #include <public/xen.h>
   74.16  #define DPRINTF(_f, _a...) printf( _f , ## _a )
   74.17  #else
   74.18 @@ -50,15 +42,17 @@ typedef int64_t            s64;
   74.19  #define SrcImplicit (0<<3) /* Source operand is implicit in the opcode. */
   74.20  #define SrcReg      (1<<3) /* Register operand. */
   74.21  #define SrcMem      (2<<3) /* Memory operand. */
   74.22 -#define SrcImm      (3<<3) /* Immediate operand. */
   74.23 -#define SrcImmByte  (4<<3) /* 8-bit sign-extended immediate operand. */
   74.24 +#define SrcMem16    (3<<3) /* Memory operand (16-bit). */
   74.25 +#define SrcMem32    (4<<3) /* Memory operand (32-bit). */
   74.26 +#define SrcImm      (5<<3) /* Immediate operand. */
   74.27 +#define SrcImmByte  (6<<3) /* 8-bit sign-extended immediate operand. */
   74.28  #define SrcMask     (7<<3)
   74.29  /* Generic ModRM decode. */
   74.30  #define ModRM       (1<<6)
   74.31  /* Destination is only written; never read. */
   74.32  #define Mov         (1<<7)
   74.33  
   74.34 -static u8 opcode_table[256] = {
   74.35 +static uint8_t opcode_table[256] = {
   74.36      /* 0x00 - 0x07 */
   74.37      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
   74.38      ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM,
   74.39 @@ -96,7 +90,8 @@ static u8 opcode_table[256] = {
   74.40      /* 0x50 - 0x5F */
   74.41      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   74.42      /* 0x60 - 0x6F */
   74.43 -    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   74.44 +    0, 0, 0, DstReg|SrcMem32|ModRM|Mov /* movsxd (x86/64) */,
   74.45 +    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   74.46      /* 0x70 - 0x7F */
   74.47      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   74.48      /* 0x80 - 0x87 */
   74.49 @@ -142,7 +137,7 @@ static u8 opcode_table[256] = {
   74.50      0, 0, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM
   74.51  };
   74.52  
   74.53 -static u8 twobyte_table[256] = {
   74.54 +static uint8_t twobyte_table[256] = {
   74.55      /* 0x00 - 0x0F */
   74.56      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0,
   74.57      /* 0x10 - 0x1F */
   74.58 @@ -177,9 +172,10 @@ static u8 twobyte_table[256] = {
   74.59      0, 0, 0, DstMem|SrcReg|ModRM, 0, 0, 0, 0,
   74.60      /* 0xB0 - 0xB7 */
   74.61      ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, DstMem|SrcReg|ModRM,
   74.62 -    0, 0, 0, 0,
   74.63 +    0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
   74.64      /* 0xB8 - 0xBF */
   74.65 -    0, 0, DstMem|SrcImmByte|ModRM, DstMem|SrcReg|ModRM, 0, 0, 0, 0,
   74.66 +    0, 0, DstMem|SrcImmByte|ModRM, DstMem|SrcReg|ModRM,
   74.67 +    0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
   74.68      /* 0xC0 - 0xCF */
   74.69      0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0, 0, 0, 0, 0, 0, 0,
   74.70      /* 0xD0 - 0xDF */
   74.71 @@ -377,7 +373,7 @@ do{ __asm__ __volatile__ (              
   74.72  
   74.73  void *
   74.74  decode_register(
   74.75 -    u8 modrm_reg, struct cpu_user_regs *regs, int highbyte_regs)
   74.76 +    uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs)
   74.77  {
   74.78      void *p;
   74.79  
   74.80 @@ -422,8 +418,8 @@ x86_emulate_memop(
   74.81      struct x86_mem_emulator *ops,
   74.82      int mode)
   74.83  {
   74.84 -    u8 b, d, sib, twobyte = 0, rex_prefix = 0;
   74.85 -    u8 modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
   74.86 +    uint8_t b, d, sib, twobyte = 0, rex_prefix = 0;
   74.87 +    uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
   74.88      unsigned int op_bytes = (mode == 8) ? 4 : mode, ad_bytes = mode;
   74.89      unsigned int lock_prefix = 0, rep_prefix = 0, i;
   74.90      int rc = 0;
   74.91 @@ -435,7 +431,7 @@ x86_emulate_memop(
   74.92      /* Legacy prefixes. */
   74.93      for ( i = 0; i < 8; i++ )
   74.94      {
   74.95 -        switch ( b = insn_fetch(u8, 1, _regs.eip) )
   74.96 +        switch ( b = insn_fetch(uint8_t, 1, _regs.eip) )
   74.97          {
   74.98          case 0x66: /* operand-size override */
   74.99              op_bytes ^= 6;                    /* switch between 2/4 bytes */
  74.100 @@ -465,12 +461,6 @@ x86_emulate_memop(
  74.101      }
  74.102   done_prefixes:
  74.103  
  74.104 -    if ( ad_bytes == 2 )
  74.105 -    {
  74.106 -        DPRINTF("Cannot parse 16-bit effective addresses.\n");
  74.107 -        goto cannot_emulate;
  74.108 -    }
  74.109 -
  74.110      /* REX prefix. */
  74.111      if ( (mode == 8) && ((b & 0xf0) == 0x40) )
  74.112      {
  74.113 @@ -479,7 +469,7 @@ x86_emulate_memop(
  74.114              op_bytes = 8;          /* REX.W */
  74.115          modrm_reg = (b & 4) << 1;  /* REX.R */
  74.116          /* REX.B and REX.X do not need to be decoded. */
  74.117 -        b = insn_fetch(u8, 1, _regs.eip);
  74.118 +        b = insn_fetch(uint8_t, 1, _regs.eip);
  74.119      }
  74.120  
  74.121      /* Opcode byte(s). */
  74.122 @@ -490,7 +480,7 @@ x86_emulate_memop(
  74.123          if ( b == 0x0f )
  74.124          {
  74.125              twobyte = 1;
  74.126 -            b = insn_fetch(u8, 1, _regs.eip);
  74.127 +            b = insn_fetch(uint8_t, 1, _regs.eip);
  74.128              d = twobyte_table[b];
  74.129          }
  74.130  
  74.131 @@ -502,33 +492,58 @@ x86_emulate_memop(
  74.132      /* ModRM and SIB bytes. */
  74.133      if ( d & ModRM )
  74.134      {
  74.135 -        modrm = insn_fetch(u8, 1, _regs.eip);
  74.136 +        modrm = insn_fetch(uint8_t, 1, _regs.eip);
  74.137          modrm_mod |= (modrm & 0xc0) >> 6;
  74.138          modrm_reg |= (modrm & 0x38) >> 3;
  74.139          modrm_rm  |= (modrm & 0x07);
  74.140 -        switch ( modrm_mod )
  74.141 +
  74.142 +        if ( modrm_mod == 3 )
  74.143          {
  74.144 -        case 0:
  74.145 -            if ( (modrm_rm == 4) && 
  74.146 -                 (((sib = insn_fetch(u8, 1, _regs.eip)) & 7) == 5) )
  74.147 -                _regs.eip += 4; /* skip disp32 specified by SIB.base */
  74.148 -            else if ( modrm_rm == 5 )
  74.149 -                _regs.eip += 4; /* skip disp32 */
  74.150 -            break;
  74.151 -        case 1:
  74.152 -            if ( modrm_rm == 4 )
  74.153 -                sib = insn_fetch(u8, 1, _regs.eip);
  74.154 -            _regs.eip += 1; /* skip disp8 */
  74.155 -            break;
  74.156 -        case 2:
  74.157 -            if ( modrm_rm == 4 )
  74.158 -                sib = insn_fetch(u8, 1, _regs.eip);
  74.159 -            _regs.eip += 4; /* skip disp32 */
  74.160 -            break;
  74.161 -        case 3:
  74.162              DPRINTF("Cannot parse ModRM.mod == 3.\n");
  74.163              goto cannot_emulate;
  74.164          }
  74.165 +
  74.166 +        if ( ad_bytes == 2 )
  74.167 +        {
  74.168 +            /* 16-bit ModR/M decode. */
  74.169 +            switch ( modrm_mod )
  74.170 +            {
  74.171 +            case 0:
  74.172 +                if ( modrm_rm == 6 )
  74.173 +                    _regs.eip += 2; /* skip disp16 */
  74.174 +                break;
  74.175 +            case 1:
  74.176 +                _regs.eip += 1; /* skip disp8 */
  74.177 +                break;
  74.178 +            case 2:
  74.179 +                _regs.eip += 2; /* skip disp16 */
  74.180 +                break;
  74.181 +            }
  74.182 +        }
  74.183 +        else
  74.184 +        {
  74.185 +            /* 32/64-bit ModR/M decode. */
  74.186 +            switch ( modrm_mod )
  74.187 +            {
  74.188 +            case 0:
  74.189 +                if ( (modrm_rm == 4) && 
  74.190 +                     (((sib = insn_fetch(uint8_t, 1, _regs.eip)) & 7) == 5) )
  74.191 +                    _regs.eip += 4; /* skip disp32 specified by SIB.base */
  74.192 +                else if ( modrm_rm == 5 )
  74.193 +                    _regs.eip += 4; /* skip disp32 */
  74.194 +                break;
  74.195 +            case 1:
  74.196 +                if ( modrm_rm == 4 )
  74.197 +                    sib = insn_fetch(uint8_t, 1, _regs.eip);
  74.198 +                _regs.eip += 1; /* skip disp8 */
  74.199 +                break;
  74.200 +            case 2:
  74.201 +                if ( modrm_rm == 4 )
  74.202 +                    sib = insn_fetch(uint8_t, 1, _regs.eip);
  74.203 +                _regs.eip += 4; /* skip disp32 */
  74.204 +                break;
  74.205 +            }
  74.206 +        }
  74.207      }
  74.208  
  74.209      /* Decode and fetch the destination operand: register or memory. */
  74.210 @@ -542,7 +557,7 @@ x86_emulate_memop(
  74.211          if ( d & ByteOp )
  74.212          {
  74.213              dst.ptr = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
  74.214 -            dst.val = *(u8 *)dst.ptr;
  74.215 +            dst.val = *(uint8_t *)dst.ptr;
  74.216              dst.bytes = 1;
  74.217          }
  74.218          else
  74.219 @@ -550,9 +565,9 @@ x86_emulate_memop(
  74.220              dst.ptr = decode_register(modrm_reg, &_regs, 0);
  74.221              switch ( (dst.bytes = op_bytes) )
  74.222              {
  74.223 -            case 2: dst.val = *(u16 *)dst.ptr; break;
  74.224 -            case 4: dst.val = *(u32 *)dst.ptr; break;
  74.225 -            case 8: dst.val = *(u64 *)dst.ptr; break;
  74.226 +            case 2: dst.val = *(uint16_t *)dst.ptr; break;
  74.227 +            case 4: dst.val = *(uint32_t *)dst.ptr; break;
  74.228 +            case 8: dst.val = *(uint64_t *)dst.ptr; break;
  74.229              }
  74.230          }
  74.231          break;
  74.232 @@ -578,7 +593,7 @@ x86_emulate_memop(
  74.233          if ( d & ByteOp )
  74.234          {
  74.235              src.ptr = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
  74.236 -            src.val = src.orig_val = *(u8 *)src.ptr;
  74.237 +            src.val = src.orig_val = *(uint8_t *)src.ptr;
  74.238              src.bytes = 1;
  74.239          }
  74.240          else
  74.241 @@ -586,16 +601,23 @@ x86_emulate_memop(
  74.242              src.ptr = decode_register(modrm_reg, &_regs, 0);
  74.243              switch ( (src.bytes = op_bytes) )
  74.244              {
  74.245 -            case 2: src.val = src.orig_val = *(u16 *)src.ptr; break;
  74.246 -            case 4: src.val = src.orig_val = *(u32 *)src.ptr; break;
  74.247 -            case 8: src.val = src.orig_val = *(u64 *)src.ptr; break;
  74.248 +            case 2: src.val = src.orig_val = *(uint16_t *)src.ptr; break;
  74.249 +            case 4: src.val = src.orig_val = *(uint32_t *)src.ptr; break;
  74.250 +            case 8: src.val = src.orig_val = *(uint64_t *)src.ptr; break;
  74.251              }
  74.252          }
  74.253          break;
  74.254 +    case SrcMem16:
  74.255 +        src.bytes = 2;
  74.256 +        goto srcmem_common;
  74.257 +    case SrcMem32:
  74.258 +        src.bytes = 4;
  74.259 +        goto srcmem_common;
  74.260      case SrcMem:
  74.261 +        src.bytes = (d & ByteOp) ? 1 : op_bytes;
  74.262 +    srcmem_common:
  74.263          src.type  = OP_MEM;
  74.264          src.ptr   = (unsigned long *)cr2;
  74.265 -        src.bytes = (d & ByteOp) ? 1 : op_bytes;
  74.266          if ( (rc = ops->read_emulated((unsigned long)src.ptr, 
  74.267                                        &src.val, src.bytes)) != 0 )
  74.268              goto done;
  74.269 @@ -609,16 +631,16 @@ x86_emulate_memop(
  74.270          /* NB. Immediates are sign-extended as necessary. */
  74.271          switch ( src.bytes )
  74.272          {
  74.273 -        case 1: src.val = insn_fetch(s8,  1, _regs.eip); break;
  74.274 -        case 2: src.val = insn_fetch(s16, 2, _regs.eip); break;
  74.275 -        case 4: src.val = insn_fetch(s32, 4, _regs.eip); break;
  74.276 +        case 1: src.val = insn_fetch(int8_t,  1, _regs.eip); break;
  74.277 +        case 2: src.val = insn_fetch(int16_t, 2, _regs.eip); break;
  74.278 +        case 4: src.val = insn_fetch(int32_t, 4, _regs.eip); break;
  74.279          }
  74.280          break;
  74.281      case SrcImmByte:
  74.282          src.type  = OP_IMM;
  74.283          src.ptr   = (unsigned long *)_regs.eip;
  74.284          src.bytes = 1;
  74.285 -        src.val   = insn_fetch(s8,  1, _regs.eip);
  74.286 +        src.val   = insn_fetch(int8_t,  1, _regs.eip);
  74.287          break;
  74.288      }
  74.289  
  74.290 @@ -651,6 +673,11 @@ x86_emulate_memop(
  74.291      case 0x38 ... 0x3d: cmp: /* cmp */
  74.292          emulate_2op_SrcV("cmp", src, dst, _regs.eflags);
  74.293          break;
  74.294 +    case 0x63: /* movsxd */
  74.295 +        if ( mode != 8 ) /* x86/64 long mode only */
  74.296 +            goto cannot_emulate;
  74.297 +        dst.val = (int32_t)src.val;
  74.298 +        break;
  74.299      case 0x80 ... 0x83: /* Grp1 */
  74.300          switch ( modrm_reg )
  74.301          {
  74.302 @@ -671,9 +698,9 @@ x86_emulate_memop(
  74.303          /* Write back the register source. */
  74.304          switch ( dst.bytes )
  74.305          {
  74.306 -        case 1: *(u8  *)src.ptr = (u8)dst.val; break;
  74.307 -        case 2: *(u16 *)src.ptr = (u16)dst.val; break;
  74.308 -        case 4: *src.ptr = (u32)dst.val; break; /* 64b mode: zero-extend */
  74.309 +        case 1: *(uint8_t  *)src.ptr = (uint8_t)dst.val; break;
  74.310 +        case 2: *(uint16_t *)src.ptr = (uint16_t)dst.val; break;
  74.311 +        case 4: *src.ptr = (uint32_t)dst.val; break; /* 64b reg: zero-extend */
  74.312          case 8: *src.ptr = dst.val; break;
  74.313          }
  74.314          /* Write back the memory destination with implicit LOCK prefix. */
  74.315 @@ -745,9 +772,9 @@ x86_emulate_memop(
  74.316              if ( src.bytes == 8 ) src.bytes = 4;
  74.317              switch ( src.bytes )
  74.318              {
  74.319 -            case 1: src.val = insn_fetch(s8,  1, _regs.eip); break;
  74.320 -            case 2: src.val = insn_fetch(s16, 2, _regs.eip); break;
  74.321 -            case 4: src.val = insn_fetch(s32, 4, _regs.eip); break;
  74.322 +            case 1: src.val = insn_fetch(int8_t,  1, _regs.eip); break;
  74.323 +            case 2: src.val = insn_fetch(int16_t, 2, _regs.eip); break;
  74.324 +            case 4: src.val = insn_fetch(int32_t, 4, _regs.eip); break;
  74.325              }
  74.326              goto test;
  74.327          case 2: /* not */
  74.328 @@ -798,9 +825,9 @@ x86_emulate_memop(
  74.329              /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */
  74.330              switch ( dst.bytes )
  74.331              {
  74.332 -            case 1: *(u8  *)dst.ptr = (u8)dst.val; break;
  74.333 -            case 2: *(u16 *)dst.ptr = (u16)dst.val; break;
  74.334 -            case 4: *dst.ptr = (u32)dst.val; break; /* 64b mode: zero-extend */
  74.335 +            case 1: *(uint8_t  *)dst.ptr = (uint8_t)dst.val; break;
  74.336 +            case 2: *(uint16_t *)dst.ptr = (uint16_t)dst.val; break;
  74.337 +            case 4: *dst.ptr = (uint32_t)dst.val; break; /* 64b: zero-ext */
  74.338              case 8: *dst.ptr = dst.val; break;
  74.339              }
  74.340              break;
  74.341 @@ -953,6 +980,10 @@ x86_emulate_memop(
  74.342          src.val &= (dst.bytes << 3) - 1; /* only subword offset */
  74.343          emulate_2op_SrcV_nobyte("bts", src, dst, _regs.eflags);
  74.344          break;
  74.345 +    case 0xb6 ... 0xb7: /* movzx */
  74.346 +        dst.bytes = op_bytes;
  74.347 +        dst.val = (d & ByteOp) ? (uint8_t)src.val : (uint16_t)src.val;
  74.348 +        break;
  74.349      case 0xbb: btc: /* btc */
  74.350          src.val &= (dst.bytes << 3) - 1; /* only subword offset */
  74.351          emulate_2op_SrcV_nobyte("btc", src, dst, _regs.eflags);
  74.352 @@ -966,6 +997,10 @@ x86_emulate_memop(
  74.353          case 3: goto btc;
  74.354          }
  74.355          break;
  74.356 +    case 0xbe ... 0xbf: /* movsx */
  74.357 +        dst.bytes = op_bytes;
  74.358 +        dst.val = (d & ByteOp) ? (int8_t)src.val : (int16_t)src.val;
  74.359 +        break;
  74.360      }
  74.361      goto writeback;
  74.362  
  74.363 @@ -1009,16 +1044,16 @@ x86_emulate_memop(
  74.364          unsigned long old, new;
  74.365          if ( (rc = ops->read_emulated(cr2, &old, 8)) != 0 )
  74.366              goto done;
  74.367 -        if ( ((u32)(old>>0) != (u32)_regs.eax) ||
  74.368 -             ((u32)(old>>32) != (u32)_regs.edx) )
  74.369 +        if ( ((uint32_t)(old>>0) != (uint32_t)_regs.eax) ||
  74.370 +             ((uint32_t)(old>>32) != (uint32_t)_regs.edx) )
  74.371          {
  74.372 -            _regs.eax = (u32)(old>>0);
  74.373 -            _regs.edx = (u32)(old>>32);
  74.374 +            _regs.eax = (uint32_t)(old>>0);
  74.375 +            _regs.edx = (uint32_t)(old>>32);
  74.376              _regs.eflags &= ~EFLG_ZF;
  74.377          }
  74.378          else
  74.379          {
  74.380 -            new = (_regs.ecx<<32)|(u32)_regs.ebx;
  74.381 +            new = (_regs.ecx<<32)|(uint32_t)_regs.ebx;
  74.382              if ( (rc = ops->cmpxchg_emulated(cr2, old, new, 8)) != 0 )
  74.383                  goto done;
  74.384              _regs.eflags |= EFLG_ZF;
    75.1 --- a/xen/common/dom0_ops.c	Wed Dec 21 10:30:10 2005 -0600
    75.2 +++ b/xen/common/dom0_ops.c	Wed Dec 21 11:56:19 2005 -0600
    75.3 @@ -358,12 +358,17 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
    75.4      case DOM0_GETDOMAININFO:
    75.5      { 
    75.6          struct domain *d;
    75.7 +        domid_t dom;
    75.8 +
    75.9 +        dom = op->u.getdomaininfo.domain;
   75.10 +        if ( dom == DOMID_SELF )
   75.11 +            dom = current->domain->domain_id;
   75.12  
   75.13          read_lock(&domlist_lock);
   75.14  
   75.15          for_each_domain ( d )
   75.16          {
   75.17 -            if ( d->domain_id >= op->u.getdomaininfo.domain )
   75.18 +            if ( d->domain_id >= dom )
   75.19                  break;
   75.20          }
   75.21  
   75.22 @@ -577,6 +582,22 @@ long do_dom0_op(dom0_op_t *u_dom0_op)
   75.23          }
   75.24      }
   75.25      break;
   75.26 +    case DOM0_SETDEBUGGING:
   75.27 +    {
   75.28 +        struct domain *d; 
   75.29 +        ret = -ESRCH;
   75.30 +        d = find_domain_by_id(op->u.setdebugging.domain);
   75.31 +        if ( d != NULL )
   75.32 +        {
   75.33 +            if ( op->u.setdebugging.enable )
   75.34 +                set_bit(_DOMF_debugging, &d->domain_flags);
   75.35 +            else
   75.36 +                clear_bit(_DOMF_debugging, &d->domain_flags);
   75.37 +            put_domain(d);
   75.38 +            ret = 0;
   75.39 +        }
   75.40 +    }
   75.41 +    break;
   75.42  
   75.43  #ifdef PERF_COUNTERS
   75.44      case DOM0_PERFCCONTROL:
    76.1 --- a/xen/common/grant_table.c	Wed Dec 21 10:30:10 2005 -0600
    76.2 +++ b/xen/common/grant_table.c	Wed Dec 21 11:56:19 2005 -0600
    76.3 @@ -238,8 +238,8 @@ static int
    76.4  
    76.5          if ( unlikely(!pfn_valid(frame)) ||
    76.6               unlikely(!((dev_hst_ro_flags & GNTMAP_readonly) ?
    76.7 -                        get_page(&frame_table[frame], rd) :
    76.8 -                        get_page_and_type(&frame_table[frame], rd,
    76.9 +                        get_page(pfn_to_page(frame), rd) :
   76.10 +                        get_page_and_type(pfn_to_page(frame), rd,
   76.11                                            PGT_writable_page))) )
   76.12          {
   76.13              clear_bit(_GTF_writing, &sha->flags);
   76.14 @@ -301,7 +301,7 @@ static int
   76.15                  sflags = prev_sflags;
   76.16              }
   76.17  
   76.18 -            if ( unlikely(!get_page_type(&frame_table[frame],
   76.19 +            if ( unlikely(!get_page_type(pfn_to_page(frame),
   76.20                                           PGT_writable_page)) )
   76.21              {
   76.22                  clear_bit(_GTF_writing, &sha->flags);
   76.23 @@ -347,14 +347,14 @@ static int
   76.24                  if ( (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) == 0 )
   76.25                  {
   76.26                      clear_bit(_GTF_writing, &sha->flags);
   76.27 -                    put_page_type(&frame_table[frame]);
   76.28 +                    put_page_type(pfn_to_page(frame));
   76.29                  }
   76.30              }
   76.31  
   76.32              if ( act->pin == 0 )
   76.33              {
   76.34                  clear_bit(_GTF_reading, &sha->flags);
   76.35 -                put_page(&frame_table[frame]);
   76.36 +                put_page(pfn_to_page(frame));
   76.37              }
   76.38  
   76.39              spin_unlock(&rd->grant_table->lock);
   76.40 @@ -500,14 +500,14 @@ static int
   76.41           !(flags & GNTMAP_readonly) )
   76.42      {
   76.43          clear_bit(_GTF_writing, &sha->flags);
   76.44 -        put_page_type(&frame_table[frame]);
   76.45 +        put_page_type(pfn_to_page(frame));
   76.46      }
   76.47  
   76.48      if ( act->pin == 0 )
   76.49      {
   76.50          act->frame = 0xdeadbeef;
   76.51          clear_bit(_GTF_reading, &sha->flags);
   76.52 -        put_page(&frame_table[frame]);
   76.53 +        put_page(pfn_to_page(frame));
   76.54      }
   76.55  
   76.56   unmap_out:
   76.57 @@ -691,7 +691,7 @@ gnttab_transfer(
   76.58          }
   76.59  
   76.60          /* Check the passed page frame for basic validity. */
   76.61 -        page = &frame_table[gop.mfn];
   76.62 +        page = pfn_to_page(gop.mfn);
   76.63          if ( unlikely(!pfn_valid(gop.mfn) || IS_XEN_HEAP_FRAME(page)) )
   76.64          { 
   76.65              DPRINTK("gnttab_transfer: out-of-range or xen frame %lx\n",
   76.66 @@ -1016,14 +1016,14 @@ gnttab_release_mappings(
   76.67              if ( (act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) == 0 )
   76.68              {
   76.69                  clear_bit(_GTF_writing, &sha->flags);
   76.70 -                put_page_type(&frame_table[act->frame]);
   76.71 +                put_page_type(pfn_to_page(act->frame));
   76.72              }
   76.73          }
   76.74  
   76.75          if ( act->pin == 0 )
   76.76          {
   76.77              clear_bit(_GTF_reading, &sha->flags);
   76.78 -            put_page(&frame_table[act->frame]);
   76.79 +            put_page(pfn_to_page(act->frame));
   76.80          }
   76.81  
   76.82          spin_unlock(&rd->grant_table->lock);
    77.1 --- a/xen/common/keyhandler.c	Wed Dec 21 10:30:10 2005 -0600
    77.2 +++ b/xen/common/keyhandler.c	Wed Dec 21 11:56:19 2005 -0600
    77.3 @@ -112,8 +112,11 @@ static void do_task_queues(unsigned char
    77.4          printk("Xen: DOM %u, flags=%lx refcnt=%d nr_pages=%d "
    77.5                 "xenheap_pages=%d\n", d->domain_id, d->domain_flags,
    77.6                 atomic_read(&d->refcnt), d->tot_pages, d->xenheap_pages);
    77.7 -        printk("     handle=%02x%02x%02x%02x-%02x%02x%02x%02x-"
    77.8 -               "%02x%02x%02x%02x-%02x%02x%02x%02x\n",
    77.9 +        /* The handle is printed according to the OSF DCE UUID spec., even
   77.10 +           though it is not necessarily such a thing, for ease of use when it
   77.11 +           _is_ one of those. */
   77.12 +        printk("     handle=%02x%02x%02x%02x-%02x%02x-%02x%02x-"
   77.13 +               "%02x%02x-%02x%02x%02x%02x%02x%02x\n",
   77.14                 d->handle[ 0], d->handle[ 1], d->handle[ 2], d->handle[ 3],
   77.15                 d->handle[ 4], d->handle[ 5], d->handle[ 6], d->handle[ 7],
   77.16                 d->handle[ 8], d->handle[ 9], d->handle[10], d->handle[11],
    78.1 --- a/xen/common/memory.c	Wed Dec 21 10:30:10 2005 -0600
    78.2 +++ b/xen/common/memory.c	Wed Dec 21 11:56:19 2005 -0600
    78.3 @@ -102,7 +102,7 @@ decrease_reservation(
    78.4                  return i;
    78.5              }
    78.6              
    78.7 -            page = &frame_table[mpfn + j];
    78.8 +            page = pfn_to_page(mpfn + j);
    78.9              if ( unlikely(!get_page(page, d)) )
   78.10              {
   78.11                  DPRINTK("Bad page free for domain %u\n", d->domain_id);
    79.1 --- a/xen/include/asm-ia64/vmx_platform.h	Wed Dec 21 10:30:10 2005 -0600
    79.2 +++ b/xen/include/asm-ia64/vmx_platform.h	Wed Dec 21 11:56:19 2005 -0600
    79.3 @@ -55,6 +55,12 @@ extern uint64_t dummy_tmr[];
    79.4  #define VLAPIC_ID(l) (uint16_t)(VCPU((l)->vcpu, lid) >> 16)
    79.5  #define VLAPIC_IRR(l) VCPU((l)->vcpu, irr[0])
    79.6  
    79.7 +extern int vmx_vcpu_pend_interrupt(struct vcpu *vcpu, uint8_t vector);
    79.8 +static inline int vlapic_set_irq(struct vlapic *t, uint8_t vec, uint8_t trig)
    79.9 +{
   79.10 +    return vmx_vcpu_pend_interrupt(t->vcpu, vec);
   79.11 +}
   79.12 +
   79.13  /* As long as we register vlsapic to ioapic controller, it's said enabled */
   79.14  #define vlapic_enabled(l) 1
   79.15  #define vmx_apic_support(d) 1
    80.1 --- a/xen/include/asm-ia64/vmx_vcpu.h	Wed Dec 21 10:30:10 2005 -0600
    80.2 +++ b/xen/include/asm-ia64/vmx_vcpu.h	Wed Dec 21 11:56:19 2005 -0600
    80.3 @@ -112,7 +112,7 @@ extern int vmx_check_pending_irq(VCPU *v
    80.4  extern void guest_write_eoi(VCPU *vcpu);
    80.5  extern uint64_t guest_read_vivr(VCPU *vcpu);
    80.6  extern void vmx_inject_vhpi(VCPU *vcpu, u8 vec);
    80.7 -extern void vmx_vcpu_pend_interrupt(VCPU *vcpu, UINT64 vector);
    80.8 +extern int vmx_vcpu_pend_interrupt(VCPU *vcpu, uint8_t vector);
    80.9  extern struct virutal_platform_def *vmx_vcpu_get_plat(VCPU *vcpu);
   80.10  extern void memread_p(VCPU *vcpu, u64 *src, u64 *dest, size_t s);
   80.11  extern void memread_v(VCPU *vcpu, thash_data_t *vtlb, u64 *src, u64 *dest, size_t s);
   80.12 @@ -474,4 +474,7 @@ vmx_vrrtomrr(VCPU *v, unsigned long val)
   80.13  #endif 
   80.14  
   80.15  }
   80.16 +
   80.17 +#define check_work_pending(v)	\
   80.18 +    (event_pending((v)) || ((v)->arch.irq_new_pending))
   80.19  #endif
    81.1 --- a/xen/include/asm-x86/debugger.h	Wed Dec 21 10:30:10 2005 -0600
    81.2 +++ b/xen/include/asm-x86/debugger.h	Wed Dec 21 11:56:19 2005 -0600
    81.3 @@ -30,6 +30,8 @@
    81.4  #ifndef __X86_DEBUGGER_H__
    81.5  #define __X86_DEBUGGER_H__
    81.6  
    81.7 +#include <xen/sched.h>
    81.8 +#include <asm/regs.h>
    81.9  #include <asm/processor.h>
   81.10  
   81.11  /* The main trap handlers use these helper macros which include early bail. */
   81.12 @@ -41,9 +43,10 @@
   81.13  #if defined(CRASH_DEBUG)
   81.14  
   81.15  extern int __trap_to_cdb(struct cpu_user_regs *r);
   81.16 -#define debugger_trap_entry(_v, _r) (0)
   81.17  
   81.18 -static inline int debugger_trap_fatal(
   81.19 +#define __debugger_trap_entry(_v, _r) (0)
   81.20 +
   81.21 +static inline int __debugger_trap_fatal(
   81.22      unsigned int vector, struct cpu_user_regs *regs)
   81.23  {
   81.24      (void)__trap_to_cdb(regs);
   81.25 @@ -51,60 +54,52 @@ static inline int debugger_trap_fatal(
   81.26  }
   81.27  
   81.28  /* Int3 is a trivial way to gather cpu_user_regs context. */
   81.29 -#define debugger_trap_immediate() __asm__ __volatile__ ( "int3" );
   81.30 +#define __debugger_trap_immediate() __asm__ __volatile__ ( "int3" );
   81.31 +
   81.32 +#elif 0
   81.33 +
   81.34 +extern int kdb_trap(int, int, struct cpu_user_regs *);
   81.35 +
   81.36 +static inline int __debugger_trap_entry(
   81.37 +    unsigned int vector, struct cpu_user_regs *regs)
   81.38 +{
   81.39 +    return 0;
   81.40 +}
   81.41  
   81.42 -#elif defined(DOMU_DEBUG)
   81.43 +static inline int __debugger_trap_fatal(
   81.44 +    unsigned int vector, struct cpu_user_regs *regs)
   81.45 +{
   81.46 +    return kdb_trap(vector, 0, regs);
   81.47 +}
   81.48  
   81.49 -#include <xen/sched.h>
   81.50 -#include <asm/regs.h>
   81.51 +/* Int3 is a trivial way to gather cpu_user_regs context. */
   81.52 +#define __debugger_trap_immediate() __asm__ __volatile__ ( "int3" )
   81.53 +
   81.54 +#else
   81.55 +
   81.56 +#define __debugger_trap_entry(_v, _r) (0)
   81.57 +#define __debugger_trap_fatal(_v, _r) (0)
   81.58 +#define __debugger_trap_immediate()   ((void)0)
   81.59 +
   81.60 +#endif
   81.61  
   81.62  static inline int debugger_trap_entry(
   81.63      unsigned int vector, struct cpu_user_regs *regs)
   81.64  {
   81.65      struct vcpu *v = current;
   81.66  
   81.67 -    if ( !KERNEL_MODE(v, regs) || (v->domain->domain_id == 0) )
   81.68 -        return 0;
   81.69 -    
   81.70 -    switch ( vector )
   81.71 +    if ( KERNEL_MODE(v, regs) &&
   81.72 +         test_bit(_DOMF_debugging, &v->domain->domain_flags) &&
   81.73 +         ((vector == TRAP_int3) || (vector == TRAP_debug)) )
   81.74      {
   81.75 -    case TRAP_int3:
   81.76 -    case TRAP_debug:
   81.77          domain_pause_for_debugger();
   81.78          return 1;
   81.79      }
   81.80  
   81.81 -    return 0;
   81.82 -}
   81.83 -
   81.84 -#define debugger_trap_fatal(_v, _r) (0)
   81.85 -#define debugger_trap_immediate()
   81.86 -
   81.87 -#elif 0
   81.88 -
   81.89 -extern int kdb_trap(int, int, struct cpu_user_regs *);
   81.90 -
   81.91 -static inline int debugger_trap_entry(
   81.92 -    unsigned int vector, struct cpu_user_regs *regs)
   81.93 -{
   81.94 -    return 0;
   81.95 +    return __debugger_trap_entry(vector, regs);
   81.96  }
   81.97  
   81.98 -static inline int debugger_trap_fatal(
   81.99 -    unsigned int vector, struct cpu_user_regs *regs)
  81.100 -{
  81.101 -    return kdb_trap(vector, 0, regs);
  81.102 -}
  81.103 -
  81.104 -/* Int3 is a trivial way to gather cpu_user_regs context. */
  81.105 -#define debugger_trap_immediate() __asm__ __volatile__ ( "int3" );
  81.106 -
  81.107 -#else
  81.108 -
  81.109 -#define debugger_trap_entry(_v, _r) (0)
  81.110 -#define debugger_trap_fatal(_v, _r) (0)
  81.111 -#define debugger_trap_immediate()
  81.112 -
  81.113 -#endif
  81.114 +#define debugger_trap_fatal(v, r) (__debugger_trap_fatal(v, r))
  81.115 +#define debugger_trap_immediate() (__debugger_trap_immediate())
  81.116  
  81.117  #endif /* __X86_DEBUGGER_H__ */
    82.1 --- a/xen/include/asm-x86/shadow.h	Wed Dec 21 10:30:10 2005 -0600
    82.2 +++ b/xen/include/asm-x86/shadow.h	Wed Dec 21 11:56:19 2005 -0600
    82.3 @@ -493,9 +493,9 @@ static inline void __mark_dirty(struct d
    82.4          SH_VLOG("mark_dirty OOR! mfn=%x pfn=%lx max=%x (dom %p)",
    82.5                 mfn, pfn, d->arch.shadow_dirty_bitmap_size, d);
    82.6          SH_VLOG("dom=%p caf=%08x taf=%" PRtype_info, 
    82.7 -               page_get_owner(&frame_table[mfn]),
    82.8 -               frame_table[mfn].count_info, 
    82.9 -               frame_table[mfn].u.inuse.type_info );
   82.10 +                page_get_owner(pfn_to_page(mfn)),
   82.11 +                pfn_to_page(mfn)->count_info, 
   82.12 +                pfn_to_page(mfn)->u.inuse.type_info );
   82.13      }
   82.14  #endif
   82.15  }
   82.16 @@ -648,20 +648,20 @@ get_shadow_ref(unsigned long smfn)
   82.17  
   82.18      ASSERT(pfn_valid(smfn));
   82.19  
   82.20 -    x = frame_table[smfn].count_info;
   82.21 +    x = pfn_to_page(smfn)->count_info;
   82.22      nx = x + 1;
   82.23  
   82.24      if ( unlikely(nx == 0) )
   82.25      {
   82.26          printk("get_shadow_ref overflow, gmfn=%" PRtype_info  " smfn=%lx\n",
   82.27 -               frame_table[smfn].u.inuse.type_info & PGT_mfn_mask,
   82.28 +               pfn_to_page(smfn)->u.inuse.type_info & PGT_mfn_mask,
   82.29                 smfn);
   82.30          BUG();
   82.31      }
   82.32      
   82.33      // Guarded by the shadow lock...
   82.34      //
   82.35 -    frame_table[smfn].count_info = nx;
   82.36 +    pfn_to_page(smfn)->count_info = nx;
   82.37  
   82.38      return 1;
   82.39  }
   82.40 @@ -678,7 +678,7 @@ put_shadow_ref(unsigned long smfn)
   82.41  
   82.42      ASSERT(pfn_valid(smfn));
   82.43  
   82.44 -    x = frame_table[smfn].count_info;
   82.45 +    x = pfn_to_page(smfn)->count_info;
   82.46      nx = x - 1;
   82.47  
   82.48      if ( unlikely(x == 0) )
   82.49 @@ -686,14 +686,14 @@ put_shadow_ref(unsigned long smfn)
   82.50          printk("put_shadow_ref underflow, smfn=%lx oc=%08x t=%" 
   82.51                 PRtype_info "\n",
   82.52                 smfn,
   82.53 -               frame_table[smfn].count_info,
   82.54 -               frame_table[smfn].u.inuse.type_info);
   82.55 +               pfn_to_page(smfn)->count_info,
   82.56 +               pfn_to_page(smfn)->u.inuse.type_info);
   82.57          BUG();
   82.58      }
   82.59  
   82.60      // Guarded by the shadow lock...
   82.61      //
   82.62 -    frame_table[smfn].count_info = nx;
   82.63 +    pfn_to_page(smfn)->count_info = nx;
   82.64  
   82.65      if ( unlikely(nx == 0) )
   82.66      {
   82.67 @@ -704,9 +704,9 @@ put_shadow_ref(unsigned long smfn)
   82.68  static inline void
   82.69  shadow_pin(unsigned long smfn)
   82.70  {
   82.71 -    ASSERT( !(frame_table[smfn].u.inuse.type_info & PGT_pinned) );
   82.72 +    ASSERT( !(pfn_to_page(smfn)->u.inuse.type_info & PGT_pinned) );
   82.73  
   82.74 -    frame_table[smfn].u.inuse.type_info |= PGT_pinned;
   82.75 +    pfn_to_page(smfn)->u.inuse.type_info |= PGT_pinned;
   82.76      if ( unlikely(!get_shadow_ref(smfn)) )
   82.77          BUG();
   82.78  }
   82.79 @@ -714,9 +714,9 @@ shadow_pin(unsigned long smfn)
   82.80  static inline void
   82.81  shadow_unpin(unsigned long smfn)
   82.82  {
   82.83 -    ASSERT( (frame_table[smfn].u.inuse.type_info & PGT_pinned) );
   82.84 +    ASSERT( (pfn_to_page(smfn)->u.inuse.type_info & PGT_pinned) );
   82.85  
   82.86 -    frame_table[smfn].u.inuse.type_info &= ~PGT_pinned;
   82.87 +    pfn_to_page(smfn)->u.inuse.type_info &= ~PGT_pinned;
   82.88      put_shadow_ref(smfn);
   82.89  }
   82.90  
   82.91 @@ -732,9 +732,9 @@ static inline void set_guest_back_ptr(
   82.92  
   82.93          ASSERT(shadow_lock_is_acquired(d));
   82.94          gmfn = l1e_get_pfn(spte);
   82.95 -        frame_table[gmfn].tlbflush_timestamp = smfn;
   82.96 -        frame_table[gmfn].u.inuse.type_info &= ~PGT_va_mask;
   82.97 -        frame_table[gmfn].u.inuse.type_info |= (unsigned long) index << PGT_va_shift;
   82.98 +        pfn_to_page(gmfn)->tlbflush_timestamp = smfn;
   82.99 +        pfn_to_page(gmfn)->u.inuse.type_info &= ~PGT_va_mask;
  82.100 +        pfn_to_page(gmfn)->u.inuse.type_info |= (unsigned long) index << PGT_va_shift;
  82.101      }
  82.102  }
  82.103  
  82.104 @@ -941,7 +941,7 @@ validate_pte_change(
  82.105              //
  82.106              perfc_incrc(validate_pte_changes2);
  82.107              if ( likely(l1e_get_flags(new_spte) & _PAGE_PRESENT) )
  82.108 -                shadow_put_page_type(d, &frame_table[l1e_get_pfn(new_spte)]);
  82.109 +                shadow_put_page_type(d, pfn_to_page(l1e_get_pfn(new_spte)));
  82.110          }
  82.111          else if ( ((l1e_get_flags(old_spte) | l1e_get_flags(new_spte)) &
  82.112                     _PAGE_PRESENT ) &&
  82.113 @@ -1216,8 +1216,8 @@ static inline unsigned long __shadow_sta
  82.114              printk("d->id=%d gpfn=%lx gmfn=%lx stype=%lx c=%x t=%" PRtype_info " "
  82.115                     "mfn_out_of_sync(gmfn)=%d mfn_is_page_table(gmfn)=%d\n",
  82.116                     d->domain_id, gpfn, gmfn, stype,
  82.117 -                   frame_table[gmfn].count_info,
  82.118 -                   frame_table[gmfn].u.inuse.type_info,
  82.119 +                   pfn_to_page(gmfn)->count_info,
  82.120 +                   pfn_to_page(gmfn)->u.inuse.type_info,
  82.121                     mfn_out_of_sync(gmfn), mfn_is_page_table(gmfn));
  82.122              BUG();
  82.123          }
  82.124 @@ -1597,7 +1597,7 @@ shadow_mode_page_writable(unsigned long 
  82.125      struct vcpu *v = current;
  82.126      struct domain *d = v->domain;
  82.127      unsigned long mfn = __gpfn_to_mfn(d, gpfn);
  82.128 -    u32 type = frame_table[mfn].u.inuse.type_info & PGT_type_mask;
  82.129 +    u32 type = pfn_to_page(mfn)->u.inuse.type_info & PGT_type_mask;
  82.130  
  82.131      if ( shadow_mode_refcounts(d) &&
  82.132           (type == PGT_writable_page) )
  82.133 @@ -1707,6 +1707,8 @@ static inline void update_pagetables(str
  82.134      }
  82.135  }
  82.136  
  82.137 +void clear_all_shadow_status(struct domain *d);
  82.138 +
  82.139  #if SHADOW_DEBUG
  82.140  extern int _check_pagetable(struct vcpu *v, char *s);
  82.141  extern int _check_all_pagetables(struct vcpu *v, char *s);
    83.1 --- a/xen/include/asm-x86/shadow_public.h	Wed Dec 21 10:30:10 2005 -0600
    83.2 +++ b/xen/include/asm-x86/shadow_public.h	Wed Dec 21 11:56:19 2005 -0600
    83.3 @@ -22,7 +22,7 @@
    83.4  #ifndef _XEN_SHADOW_PUBLIC_H
    83.5  #define _XEN_SHADOW_PUBLIC_H
    83.6  #if CONFIG_PAGING_LEVELS >= 3
    83.7 -#define MFN_PINNED(_x) (frame_table[_x].u.inuse.type_info & PGT_pinned)
    83.8 +#define MFN_PINNED(_x) (pfn_to_page(_x)->u.inuse.type_info & PGT_pinned)
    83.9  
   83.10  extern int alloc_p2m_table(struct domain *d);
   83.11  
    84.1 --- a/xen/include/asm-x86/vmx_vlapic.h	Wed Dec 21 10:30:10 2005 -0600
    84.2 +++ b/xen/include/asm-x86/vmx_vlapic.h	Wed Dec 21 11:56:19 2005 -0600
    84.3 @@ -202,6 +202,18 @@ struct vlapic
    84.4      struct domain      *domain;
    84.5  };
    84.6  
    84.7 +static inline int vlapic_set_irq(struct vlapic *t, uint8_t vec, uint8_t trig)
    84.8 +{
    84.9 +    int ret;
   84.10 +
   84.11 +    ret = test_and_set_bit(vec, &t->irr[0]);
   84.12 +    if (trig)
   84.13 +	test_and_set_bit(vec, &t->tmr[0]);
   84.14 +
   84.15 +    /* We may need to wake up target vcpu, besides set pending bit here */
   84.16 +    return ret;
   84.17 +}
   84.18 +
   84.19  static inline int  vlapic_timer_active(struct vlapic *vlapic)
   84.20  {
   84.21      return  active_ac_timer(&(vlapic->vlapic_timer));
    85.1 --- a/xen/include/asm-x86/x86_emulate.h	Wed Dec 21 10:30:10 2005 -0600
    85.2 +++ b/xen/include/asm-x86/x86_emulate.h	Wed Dec 21 11:56:19 2005 -0600
    85.3 @@ -164,6 +164,6 @@ x86_emulate_memop(
    85.4   */
    85.5  extern void *
    85.6  decode_register(
    85.7 -    u8 modrm_reg, struct cpu_user_regs *regs, int highbyte_regs);
    85.8 +    uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs);
    85.9  
   85.10  #endif /* __X86_EMULATE_H__ */
    86.1 --- a/xen/include/public/acm.h	Wed Dec 21 10:30:10 2005 -0600
    86.2 +++ b/xen/include/public/acm.h	Wed Dec 21 11:56:19 2005 -0600
    86.3 @@ -1,25 +1,8 @@
    86.4 -/****************************************************************
    86.5 - * acm.h
    86.6 - * 
    86.7 - * Copyright (C) 2005 IBM Corporation
    86.8 - *
    86.9 - * Author:
   86.10 - * Reiner Sailer <sailer@watson.ibm.com>
   86.11 +/*
   86.12 + * acm.h: Xen access control module interface defintions
   86.13   *
   86.14 - * Contributors:
   86.15 - * Stefan Berger <stefanb@watson.ibm.com> 
   86.16 - * added network byte order support for binary policies
   86.17 - *
   86.18 - * This program is free software; you can redistribute it and/or
   86.19 - * modify it under the terms of the GNU General Public License as
   86.20 - * published by the Free Software Foundation, version 2 of the
   86.21 - * License.
   86.22 - *
   86.23 - * sHype general access control module header file.
   86.24 - *     here are all definitions that are shared between
   86.25 - *     xen-core, guest-kernels, and applications.
   86.26 - *
   86.27 - * todo: move from static policy choice to compile option.
   86.28 + * Reiner Sailer <sailer@watson.ibm.com>
   86.29 + * Copyright (c) 2005, International Business Machines Corporation.
   86.30   */
   86.31  
   86.32  #ifndef _XEN_PUBLIC_ACM_H
    87.1 --- a/xen/include/public/acm_ops.h	Wed Dec 21 10:30:10 2005 -0600
    87.2 +++ b/xen/include/public/acm_ops.h	Wed Dec 21 11:56:19 2005 -0600
    87.3 @@ -1,19 +1,8 @@
    87.4 -/******************************************************************************
    87.5 - * acm_ops.h
    87.6 - *
    87.7 - * Copyright (C) 2005 IBM Corporation
    87.8 - *
    87.9 - * Author:
   87.10 - * Reiner Sailer <sailer@watson.ibm.com>
   87.11 +/*
   87.12 + * acm_ops.h: Xen access control module hypervisor commands
   87.13   *
   87.14 - * This program is free software; you can redistribute it and/or
   87.15 - * modify it under the terms of the GNU General Public License as
   87.16 - * published by the Free Software Foundation, version 2 of the
   87.17 - * License.
   87.18 - *
   87.19 - * Process acm policy command requests from guest OS.
   87.20 - * access checked by policy; not restricted to DOM0
   87.21 - *
   87.22 + * Reiner Sailer <sailer@watson.ibm.com>
   87.23 + * Copyright (c) 2005, International Business Machines Corporation.
   87.24   */
   87.25  
   87.26  #ifndef __XEN_PUBLIC_ACM_OPS_H__
    88.1 --- a/xen/include/public/dom0_ops.h	Wed Dec 21 10:30:10 2005 -0600
    88.2 +++ b/xen/include/public/dom0_ops.h	Wed Dec 21 11:56:19 2005 -0600
    88.3 @@ -404,6 +404,12 @@ typedef struct {
    88.4      xen_domain_handle_t handle;
    88.5  } dom0_setdomainhandle_t;
    88.6  
    88.7 +#define DOM0_SETDEBUGGING 45
    88.8 +typedef struct {
    88.9 +    domid_t domain;
   88.10 +    uint8_t enable;
   88.11 +} dom0_setdebugging_t;
   88.12 +
   88.13  typedef struct {
   88.14      uint32_t cmd;
   88.15      uint32_t interface_version; /* DOM0_INTERFACE_VERSION */
   88.16 @@ -440,7 +446,8 @@ typedef struct {
   88.17          dom0_platform_quirk_t    platform_quirk;
   88.18          dom0_physical_memory_map_t physical_memory_map;
   88.19          dom0_max_vcpus_t         max_vcpus;
   88.20 -        dom0_setdomainhandle_t   setdomainhandle;
   88.21 +        dom0_setdomainhandle_t   setdomainhandle;        
   88.22 +        dom0_setdebugging_t      setdebugging;
   88.23          uint8_t                  pad[128];
   88.24      } u;
   88.25  } dom0_op_t;
    89.1 --- a/xen/include/public/vmx_assist.h	Wed Dec 21 10:30:10 2005 -0600
    89.2 +++ b/xen/include/public/vmx_assist.h	Wed Dec 21 11:56:19 2005 -0600
    89.3 @@ -3,21 +3,8 @@
    89.4   *
    89.5   * Leendert van Doorn, leendert@watson.ibm.com
    89.6   * Copyright (c) 2005, International Business Machines Corporation.
    89.7 - *
    89.8 - * This program is free software; you can redistribute it and/or modify it
    89.9 - * under the terms and conditions of the GNU General Public License,
   89.10 - * version 2, as published by the Free Software Foundation.
   89.11 - *
   89.12 - * This program is distributed in the hope it will be useful, but WITHOUT
   89.13 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   89.14 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
   89.15 - * more details.
   89.16 - *
   89.17 - * You should have received a copy of the GNU General Public License along with
   89.18 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
   89.19 - * Place - Suite 330, Boston, MA 02111-1307 USA.
   89.20 - *
   89.21   */
   89.22 +
   89.23  #ifndef _VMX_ASSIST_H_
   89.24  #define _VMX_ASSIST_H_
   89.25  
    90.1 --- a/xen/include/public/xen.h	Wed Dec 21 10:30:10 2005 -0600
    90.2 +++ b/xen/include/public/xen.h	Wed Dec 21 11:56:19 2005 -0600
    90.3 @@ -67,12 +67,13 @@
    90.4   */
    90.5  #define VIRQ_TIMER      0  /* Timebase update, and/or requested timeout.  */
    90.6  #define VIRQ_DEBUG      1  /* Request guest to dump debug info.           */
    90.7 -#define VIRQ_CONSOLE    2  /* (DOM0) bytes received on emergency console. */
    90.8 +#define VIRQ_CONSOLE    2  /* (DOM0) Bytes received on emergency console. */
    90.9  #define VIRQ_DOM_EXC    3  /* (DOM0) Exceptional event for some domain.   */
   90.10 -#define VIRQ_PARITY_ERR 4  /* (DOM0) NMI parity error.                    */
   90.11 -#define VIRQ_IO_ERR     5  /* (DOM0) NMI I/O error.                       */
   90.12 +#define VIRQ_PARITY_ERR 4  /* (DOM0) NMI parity error (port 0x61, bit 7). */
   90.13 +#define VIRQ_IO_ERR     5  /* (DOM0) NMI I/O error    (port 0x61, bit 6). */
   90.14  #define VIRQ_DEBUGGER   6  /* (DOM0) A domain has paused for debugging.   */
   90.15 -#define NR_VIRQS        7
   90.16 +#define VIRQ_NMI        7  /* (DOM0) Unknown NMI (not from ISA port 0x61).*/
   90.17 +#define NR_VIRQS        8
   90.18  
   90.19  /*
   90.20   * MMU-UPDATE REQUESTS
    91.1 --- a/xen/include/xen/sched.h	Wed Dec 21 10:30:10 2005 -0600
    91.2 +++ b/xen/include/xen/sched.h	Wed Dec 21 11:56:19 2005 -0600
    91.3 @@ -393,6 +393,10 @@ extern struct domain *domain_list;
    91.4   /* Domain is paused by controller software. */
    91.5  #define _DOMF_ctrl_pause       6
    91.6  #define DOMF_ctrl_pause        (1UL<<_DOMF_ctrl_pause)
    91.7 + /* Domain is being debugged by controller software. */
    91.8 +#define _DOMF_debugging        7
    91.9 +#define DOMF_debugging         (1UL<<_DOMF_debugging)
   91.10 +
   91.11  
   91.12  static inline int domain_runnable(struct vcpu *v)
   91.13  {
    92.1 --- a/xen/include/xen/softirq.h	Wed Dec 21 10:30:10 2005 -0600
    92.2 +++ b/xen/include/xen/softirq.h	Wed Dec 21 11:56:19 2005 -0600
    92.3 @@ -6,7 +6,7 @@
    92.4  #define SCHEDULE_SOFTIRQ                  1
    92.5  #define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 2
    92.6  #define KEYPRESS_SOFTIRQ                  3
    92.7 -#define NMI_SOFTIRQ                       4
    92.8 +#define NMI_DOM0_SOFTIRQ                  4
    92.9  #define PAGE_SCRUB_SOFTIRQ                5
   92.10  #define DOMAIN_SHUTDOWN_FINALISE_SOFTIRQ  6
   92.11  #define NR_SOFTIRQS                       7