aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-06-29 16:18:51 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-06-29 16:18:51 +0000
commitfa819b0ee16a650dc4013a7da98e9c9d6e56a1dc (patch)
treee687b9d58bfe9eabe99ebb72a23babdeccd34b88
parent2e18b662f8c13b1bc98426a46999118c84b1c95e (diff)
downloadxen-fa819b0ee16a650dc4013a7da98e9c9d6e56a1dc.tar.gz
xen-fa819b0ee16a650dc4013a7da98e9c9d6e56a1dc.tar.bz2
xen-fa819b0ee16a650dc4013a7da98e9c9d6e56a1dc.zip
bitkeeper revision 1.1026.3.1 (40e1966bdTS8WBGJY9WhLRE3t6GBdQ)
More cleanups for x86-64.
-rw-r--r--.rootkeys4
-rw-r--r--xen/arch/x86/boot/boot.S4
-rw-r--r--xen/arch/x86/mm.c2
-rw-r--r--xen/common/kernel.c87
-rw-r--r--xen/common/memory.c21
-rw-r--r--xen/common/shadow.c6
-rw-r--r--xen/include/asm-x86/config.h15
-rw-r--r--xen/include/asm-x86/page.h16
-rw-r--r--xen/include/asm-x86/string.h488
-rw-r--r--xen/include/asm-x86/types.h3
-rw-r--r--xen/include/asm-x86/x86_32/string.h485
-rw-r--r--xen/include/asm-x86/x86_64/string.h69
-rw-r--r--xen/include/xen/mm.h4
13 files changed, 663 insertions, 541 deletions
diff --git a/.rootkeys b/.rootkeys
index 7bfcd6a45e..9ed95dbc18 100644
--- a/.rootkeys
+++ b/.rootkeys
@@ -414,18 +414,20 @@
3ddb79c3Hgbb2g8CyWLMCK-6_ZVQSQ xen/include/asm-x86/smp.h
3ddb79c3jn8ALV_S9W5aeTYUQRKBpg xen/include/asm-x86/smpboot.h
3ddb79c3NiyQE2vQnyGiaBnNjBO1rA xen/include/asm-x86/spinlock.h
-3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/string.h
+40e1966akOHWvvunCED7x3HPv35QvQ xen/include/asm-x86/string.h
3ddb79c3ezddh34MdelJpa5tNR00Dw xen/include/asm-x86/system.h
3ddb79c4HugMq7IYGxcQKFBpKwKhzA xen/include/asm-x86/types.h
40cf1596saFaHD5DC5zvrSn7CDCWGQ xen/include/asm-x86/uaccess.h
3ddb79c2ADvRmdexd9y3AYK9_NTx-Q xen/include/asm-x86/x86_32/current.h
3ddb79c3mbqEM7QQr3zVq7NiBNhouA xen/include/asm-x86/x86_32/ptrace.h
+3e7f358aG11EvMI9VJ4_9hD4LUO7rQ xen/include/asm-x86/x86_32/string.h
3ddb79c3M2n1ROZH6xk3HbyN4CPDqg xen/include/asm-x86/x86_32/uaccess.h
404f1b9ceJeGVaPNIENm2FkK0AgEOQ xen/include/asm-x86/x86_64/current.h
404f1b9fl6AQ_a-T1TDK3fuwTPXmHw xen/include/asm-x86/x86_64/desc.h
404f1badfXZJZ2sU8sh9PS2EZvd19Q xen/include/asm-x86/x86_64/ldt.h
404f1bb1LSCqrMDSfRAti5NdMQPJBQ xen/include/asm-x86/x86_64/page.h
404f1bb86rAXB3aLS1vYdcqpJiEcyg xen/include/asm-x86/x86_64/ptrace.h
+40e1966azOJZfNI6Ilthe6Q-T3Hewg xen/include/asm-x86/x86_64/string.h
404f1bc4tWkB9Qr8RkKtZGW5eMQzhw xen/include/asm-x86/x86_64/uaccess.h
400304fcmRQmDdFYEzDh0wcBba9alg xen/include/hypervisor-ifs/COPYING
404f1bc68SXxmv0zQpXBWGrCzSyp8w xen/include/hypervisor-ifs/arch-x86_32.h
diff --git a/xen/arch/x86/boot/boot.S b/xen/arch/x86/boot/boot.S
index ebb74c6562..55a4cc4cc2 100644
--- a/xen/arch/x86/boot/boot.S
+++ b/xen/arch/x86/boot/boot.S
@@ -101,7 +101,7 @@ continue_boot_cpu:
mov 0x4(%eax),%eax /* %eax = mod[mod_count-1]->end */
mov %eax,%ecx
sub %ebx,%ecx /* %ecx = byte len of all mods */
- mov $(MAX_DIRECTMAP_ADDRESS), %edi
+ mov $(DIRECTMAP_PHYS_END), %edi
add %ecx, %edi /* %edi = src + length */
shr $2,%ecx /* %ecx = length/4 */
1: sub $4,%eax /* %eax = src, %edi = dst */
@@ -117,7 +117,7 @@ skip_dom0_copy:
1: mov %eax,__PAGE_OFFSET>>20(%edi) /* high mapping */
stosl /* low mapping */
add $(1<<L2_PAGETABLE_SHIFT),%eax
- cmp $MAX_DIRECTMAP_ADDRESS+0x1e3,%eax
+ cmp $DIRECTMAP_PHYS_END+0x1e3,%eax
jne 1b
call start_paging
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index d61df0d9a1..59e304e4a7 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -347,7 +347,7 @@ void *memguard_init(void *heap_start)
PAGE_MASK);
/* Memory guarding is incompatible with super pages. */
- for ( i = 0; i < (MAX_XENHEAP_ADDRESS >> L2_PAGETABLE_SHIFT); i++ )
+ for ( i = 0; i < (xenheap_phys_end >> L2_PAGETABLE_SHIFT); i++ )
{
l1 = (l1_pgentry_t *)heap_start;
heap_start = (void *)((unsigned long)heap_start + PAGE_SIZE);
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index 001227257e..92602e0bf5 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -27,6 +27,8 @@
#include <asm/domain_page.h>
#include <hypervisor-ifs/dom0_ops.h>
+unsigned long xenheap_phys_end;
+
kmem_cache_t *domain_struct_cachep;
struct e820entry {
@@ -69,6 +71,11 @@ char opt_physdev_dom0_hide[200] = "";
/* level- or edge-triggered. */
/* Example: 'leveltrigger=4,5,6,20 edgetrigger=21'. */
char opt_leveltrigger[30] = "", opt_edgetrigger[30] = "";
+/*
+ * opt_xenheap_megabytes: Size of Xen heap in megabytes, excluding the
+ * pfn_info table and allocation bitmap.
+ */
+unsigned int opt_xenheap_megabytes = XENHEAP_DEFAULT_MB;
static struct {
unsigned char *name;
@@ -91,6 +98,7 @@ static struct {
{ "physdev_dom0_hide", OPT_STR, &opt_physdev_dom0_hide },
{ "leveltrigger", OPT_STR, &opt_leveltrigger },
{ "edgetrigger", OPT_STR, &opt_edgetrigger },
+ { "xenheap_megabytes", OPT_UINT, &opt_xenheap_megabytes },
{ NULL, 0, NULL }
};
@@ -180,52 +188,78 @@ void cmain(unsigned long magic, multiboot_info_t *mbi)
for ( ; ; ) ;
}
+ if ( opt_xenheap_megabytes < 4 )
+ {
+ printk("Xen heap size is too small to safely continue!\n");
+ for ( ; ; ) ;
+ }
+
+ set_current(&idle0_task);
+
+ xenheap_phys_end = opt_xenheap_megabytes << 20;
+
max_mem = max_page = (mbi->mem_upper+1024) >> (PAGE_SHIFT - 10);
- /* The array of pfn_info structures must fit into the reserved area. */
- if ( (sizeof(struct pfn_info) * max_page) >
- (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START) )
+#if defined(__i386__)
+
+ if ( opt_xenheap_megabytes > XENHEAP_DEFAULT_MB )
{
- unsigned long new_max =
- (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START) /
- sizeof(struct pfn_info);
- printk("Truncating available memory to %lu/%luMB\n",
- new_max >> (20 - PAGE_SHIFT), max_page >> (20 - PAGE_SHIFT));
- max_page = new_max;
+ printk("Xen heap size is limited to %dMB - you specified %dMB.\n",
+ XENHEAP_DEFAULT_MB, opt_xenheap_megabytes);
+ for ( ; ; ) ;
}
- set_current(&idle0_task);
+ ASSERT((sizeof(struct pfn_info) << 20) >
+ (FRAMETABLE_VIRT_END - FRAMETABLE_VIRT_START));
- init_frametable(max_page);
- printk("Initialised %luMB memory (%lu pages) on a %luMB machine\n",
- max_page >> (20-PAGE_SHIFT), max_page,
- max_mem >> (20-PAGE_SHIFT));
+ init_frametable((void *)FRAMETABLE_VIRT_START, max_page);
- initial_images_start = MAX_DIRECTMAP_ADDRESS;
+ /* Initial images stashed away above DIRECTMAP area in boot.S. */
+ initial_images_start = DIRECTMAP_PHYS_END;
initial_images_end = initial_images_start +
(mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+
+#elif defined(__x86_64__)
+
+ init_frametable(__va(xenheap_phys_end), max_page);
+
+ initial_images_start = __pa(frame_table) + frame_table_size;
+ initial_images_end = initial_images_start +
+ (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+ if ( initial_images_end > (max_page << PAGE_SHIFT) )
+ {
+ printk("Not enough memory to stash the DOM0 kernel image.\n");
+ for ( ; ; ) ;
+ }
+ memmove(__va(initial_images_start),
+ __va(mod[0].mod_start),
+ mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+
+#endif
+
dom0_memory_start = (initial_images_end + ((4<<20)-1)) & ~((4<<20)-1);
dom0_memory_end = dom0_memory_start + (opt_dom0_mem << 10);
dom0_memory_end = (dom0_memory_end + PAGE_SIZE - 1) & PAGE_MASK;
/* Cheesy sanity check: enough memory for DOM0 allocation + some slack? */
- if ( (dom0_memory_end + (8<<20)) > (max_page<<PAGE_SHIFT) )
- panic("Not enough memory to craete initial domain!\n");
+ if ( (dom0_memory_end + (8<<20)) > (max_page << PAGE_SHIFT) )
+ {
+ printk("Not enough memory for DOM0 memory reservation.\n");
+ for ( ; ; ) ;
+ }
+
+ printk("Initialised %luMB memory (%lu pages) on a %luMB machine\n",
+ max_page >> (20-PAGE_SHIFT), max_page,
+ max_mem >> (20-PAGE_SHIFT));
add_to_domain_alloc_list(dom0_memory_end, max_page << PAGE_SHIFT);
heap_start = memguard_init(&_end);
printk("Xen heap size is %luKB\n",
- (MAX_XENHEAP_ADDRESS-__pa(heap_start))/1024 );
-
- if ( ((MAX_XENHEAP_ADDRESS-__pa(heap_start))/1024) <= 4096 )
- {
- printk("Xen heap size is too small to safely continue!\n");
- for ( ; ; ) ;
- }
+ (xenheap_phys_end-__pa(heap_start))/1024 );
- init_page_allocator(__pa(heap_start), MAX_XENHEAP_ADDRESS);
+ init_page_allocator(__pa(heap_start), xenheap_phys_end);
/* Initialise the slab allocator. */
kmem_cache_init();
@@ -253,8 +287,7 @@ void cmain(unsigned long magic, multiboot_info_t *mbi)
/*
* We're going to setup domain0 using the module(s) that we stashed safely
- * above our MAX_DIRECTMAP_ADDRESS in boot/boot.S. The second module, if
- * present, is an initrd ramdisk.
+ * above our heap. The second module, if present, is an initrd ramdisk.
*/
if ( construct_dom0(new_dom, dom0_memory_start, dom0_memory_end,
(char *)initial_images_start,
diff --git a/xen/common/memory.c b/xen/common/memory.c
index 08e0b05285..4675a95d2e 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -144,7 +144,7 @@ static struct {
#define GPS (percpu_info[smp_processor_id()].gps ? : current)
-void __init init_frametable(unsigned long nr_pages)
+void __init init_frametable(void *frametable_vstart, unsigned long nr_pages)
{
unsigned long mfn;
@@ -153,22 +153,23 @@ void __init init_frametable(unsigned long nr_pages)
max_page = nr_pages;
frame_table_size = nr_pages * sizeof(struct pfn_info);
frame_table_size = (frame_table_size + PAGE_SIZE - 1) & PAGE_MASK;
- frame_table = (struct pfn_info *)FRAMETABLE_VIRT_START;
+ frame_table = frametable_vstart;
+
+ if ( (__pa(frame_table) + frame_table_size) > (max_page << PAGE_SHIFT) )
+ panic("Not enough memory for frame table - reduce Xen heap size?\n");
+
memset(frame_table, 0, frame_table_size);
spin_lock_init(&free_list_lock);
INIT_LIST_HEAD(&free_list);
free_pfns = 0;
- /* initialise to a magic of 0x55555555 so easier to spot bugs later */
- memset( machine_to_phys_mapping, 0x55, 4*1024*1024 );
-
- /* The array is sized for a 4GB machine regardless of actuall mem size.
- This costs 4MB -- may want to fix some day */
+ /* Initialise to a magic of 0x55555555 so easier to spot bugs later. */
+ memset(machine_to_phys_mapping, 0x55, 4<<20);
/* Pin the ownership of the MP table so that DOM0 can map it later. */
- for ( mfn = virt_to_phys(&machine_to_phys_mapping[0])>>PAGE_SHIFT;
- mfn < virt_to_phys(&machine_to_phys_mapping[1024*1024])>>PAGE_SHIFT;
+ for ( mfn = virt_to_phys(&machine_to_phys_mapping[0<<20])>>PAGE_SHIFT;
+ mfn < virt_to_phys(&machine_to_phys_mapping[1<<20])>>PAGE_SHIFT;
mfn++ )
{
frame_table[mfn].count_and_flags = 1 | PGC_allocated;
@@ -471,6 +472,7 @@ static int alloc_l2_table(struct pfn_info *page)
if ( unlikely(!get_page_from_l2e(pl2e[i], page_nr)) )
goto fail;
+#if defined(__i386__)
/* Now we add our private high mappings. */
memcpy(&pl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
&idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
@@ -480,6 +482,7 @@ static int alloc_l2_table(struct pfn_info *page)
pl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] =
mk_l2_pgentry(__pa(page->u.domain->mm.perdomain_pt) |
__PAGE_HYPERVISOR);
+#endif
unmap_domain_mem(pl2e);
return 1;
diff --git a/xen/common/shadow.c b/xen/common/shadow.c
index de5fe4b4fa..dc08bd0199 100644
--- a/xen/common/shadow.c
+++ b/xen/common/shadow.c
@@ -151,7 +151,9 @@ static inline int shadow_page_op( struct mm_struct *m, unsigned int op,
PGT_l2_page_table )
{
unsigned long * spl1e = map_domain_mem( spfn<<PAGE_SHIFT );
- memset( spl1e, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE * sizeof(*spl1e) );
+#ifdef __i386__
+ memset(spl1e, 0, DOMAIN_ENTRIES_PER_L2_PAGETABLE * sizeof(*spl1e));
+#endif
unmap_domain_mem( spl1e );
}
}
@@ -574,6 +576,7 @@ unsigned long shadow_l2_table(
// we need to do this before the linear map is set up
spl2e = (l2_pgentry_t *) map_domain_mem(spfn << PAGE_SHIFT);
+#ifdef __i386__
// get hypervisor and 2x linear PT mapings installed
memcpy(&spl2e[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
&idle_pg_table[DOMAIN_ENTRIES_PER_L2_PAGETABLE],
@@ -585,6 +588,7 @@ unsigned long shadow_l2_table(
spl2e[PERDOMAIN_VIRT_START >> L2_PAGETABLE_SHIFT] =
mk_l2_pgentry(__pa(frame_table[gpfn].u.domain->mm.perdomain_pt) |
__PAGE_HYPERVISOR);
+#endif
// can't use the linear map as we may not be in the right PT
gpl2e = (l2_pgentry_t *) map_domain_mem(gpfn << PAGE_SHIFT);
diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h
index c38304ab8b..af0172df90 100644
--- a/xen/include/asm-x86/config.h
+++ b/xen/include/asm-x86/config.h
@@ -93,6 +93,8 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn));
#if defined(__x86_64__)
+#define XENHEAP_DEFAULT_MB (16)
+
#define PML4_ENTRY_BITS 39
#define PML4_ENTRY_BYTES (1UL<<PML4_ENTRY_BITS)
@@ -158,9 +160,8 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn));
#elif defined(__i386__)
-/* The following are machine addresses. */
-#define MAX_XENHEAP_ADDRESS (12*1024*1024)
-#define MAX_DIRECTMAP_ADDRESS (40*1024*1024)
+#define XENHEAP_DEFAULT_MB (12)
+#define DIRECTMAP_PHYS_END (40*1024*1024)
/* Hypervisor owns top 64MB of virtual address space. */
#define HYPERVISOR_VIRT_START (0xFC000000UL)
@@ -173,9 +174,9 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn));
#define RO_MPT_VIRT_END (RO_MPT_VIRT_START + (4*1024*1024))
/* The virtual addresses for the 40MB direct-map region. */
#define DIRECTMAP_VIRT_START (RO_MPT_VIRT_END)
-#define DIRECTMAP_VIRT_END (DIRECTMAP_VIRT_START + MAX_DIRECTMAP_ADDRESS)
+#define DIRECTMAP_VIRT_END (DIRECTMAP_VIRT_START + DIRECTMAP_PHYS_END)
#define XENHEAP_VIRT_START (DIRECTMAP_VIRT_START)
-#define XENHEAP_VIRT_END (XENHEAP_VIRT_START + MAX_XENHEAP_ADDRESS)
+#define XENHEAP_VIRT_END (XENHEAP_VIRT_START + (XENHEAP_DEFAULT_MB<<20))
#define RDWR_MPT_VIRT_START (XENHEAP_VIRT_END)
#define RDWR_MPT_VIRT_END (RDWR_MPT_VIRT_START + (4*1024*1024))
#define FRAMETABLE_VIRT_START (RDWR_MPT_VIRT_END)
@@ -207,6 +208,10 @@ extern void __out_of_line_bug(int line) __attribute__((noreturn));
#endif /* __i386__ */
+#ifndef __ASSEMBLY__
+extern unsigned long xenheap_phys_end; /* user-configurable */
+#endif
+
#define GDT_VIRT_START (PERDOMAIN_VIRT_START)
#define GDT_VIRT_END (GDT_VIRT_START + (64*1024))
#define LDT_VIRT_START (GDT_VIRT_END)
diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h
index 95cbb4b514..8eb30e35ea 100644
--- a/xen/include/asm-x86/page.h
+++ b/xen/include/asm-x86/page.h
@@ -95,12 +95,12 @@ typedef struct { unsigned long pt_lo; } pagetable_t;
extern l2_pgentry_t idle_pg_table[ENTRIES_PER_L2_PAGETABLE];
extern void paging_init(void);
-#define __flush_tlb() \
- do { \
- __asm__ __volatile__ ( \
- "movl %%cr3, %%eax; movl %%eax, %%cr3" \
- : : : "memory", "eax" ); \
- tlb_clocktick(); \
+#define __flush_tlb() \
+ do { \
+ __asm__ __volatile__ ( \
+ "mov %%cr3, %%"__OP"ax; mov %%"__OP"ax, %%cr3" \
+ : : : "memory", __OP"ax" ); \
+ tlb_clocktick(); \
} while ( 0 )
/* Flush global pages as well. */
@@ -108,14 +108,14 @@ extern void paging_init(void);
#define __pge_off() \
do { \
__asm__ __volatile__( \
- "movl %0, %%cr4; # turn off PGE " \
+ "mov %0, %%cr4; # turn off PGE " \
:: "r" (mmu_cr4_features & ~X86_CR4_PGE)); \
} while (0)
#define __pge_on() \
do { \
__asm__ __volatile__( \
- "movl %0, %%cr4; # turn off PGE " \
+ "mov %0, %%cr4; # turn off PGE " \
:: "r" (mmu_cr4_features)); \
} while (0)
diff --git a/xen/include/asm-x86/string.h b/xen/include/asm-x86/string.h
index 27fbb4d035..fd7ae02a85 100644
--- a/xen/include/asm-x86/string.h
+++ b/xen/include/asm-x86/string.h
@@ -1,485 +1,5 @@
-#ifndef _I386_STRING_H_
-#define _I386_STRING_H_
-
-#include <xen/config.h>
-
-/*
- * This string-include defines all string functions as inline
- * functions. Use gcc. It also assumes ds=es=data space, this should be
- * normal. Most of the string-functions are rather heavily hand-optimized,
- * see especially strtok,strstr,str[c]spn. They should work, but are not
- * very easy to understand. Everything is done entirely within the register
- * set, making the functions fast and clean. String instructions have been
- * used through-out, making for "slightly" unclear code :-)
- *
- * NO Copyright (C) 1991, 1992 Linus Torvalds,
- * consider these trivial functions to be PD.
- */
-
-
-#define __HAVE_ARCH_STRCPY
-static inline char * strcpy(char * dest,const char *src)
-{
-int d0, d1, d2;
-__asm__ __volatile__(
- "1:\tlodsb\n\t"
- "stosb\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b"
- : "=&S" (d0), "=&D" (d1), "=&a" (d2)
- :"0" (src),"1" (dest) : "memory");
-return dest;
-}
-
-#define __HAVE_ARCH_STRNCPY
-static inline char * strncpy(char * dest,const char *src,size_t count)
-{
-int d0, d1, d2, d3;
-__asm__ __volatile__(
- "1:\tdecl %2\n\t"
- "js 2f\n\t"
- "lodsb\n\t"
- "stosb\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b\n\t"
- "rep\n\t"
- "stosb\n"
- "2:"
- : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
- :"0" (src),"1" (dest),"2" (count) : "memory");
-return dest;
-}
-
-#define __HAVE_ARCH_STRCAT
-static inline char * strcat(char * dest,const char * src)
-{
-int d0, d1, d2, d3;
-__asm__ __volatile__(
- "repne\n\t"
- "scasb\n\t"
- "decl %1\n"
- "1:\tlodsb\n\t"
- "stosb\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b"
- : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
- : "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory");
-return dest;
-}
-
-#define __HAVE_ARCH_STRNCAT
-static inline char * strncat(char * dest,const char * src,size_t count)
-{
-int d0, d1, d2, d3;
-__asm__ __volatile__(
- "repne\n\t"
- "scasb\n\t"
- "decl %1\n\t"
- "movl %8,%3\n"
- "1:\tdecl %3\n\t"
- "js 2f\n\t"
- "lodsb\n\t"
- "stosb\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b\n"
- "2:\txorl %2,%2\n\t"
- "stosb"
- : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
- : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
- : "memory");
-return dest;
-}
-
-#define __HAVE_ARCH_STRCMP
-static inline int strcmp(const char * cs,const char * ct)
-{
-int d0, d1;
-register int __res;
-__asm__ __volatile__(
- "1:\tlodsb\n\t"
- "scasb\n\t"
- "jne 2f\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b\n\t"
- "xorl %%eax,%%eax\n\t"
- "jmp 3f\n"
- "2:\tsbbl %%eax,%%eax\n\t"
- "orb $1,%%al\n"
- "3:"
- :"=a" (__res), "=&S" (d0), "=&D" (d1)
- :"1" (cs),"2" (ct));
-return __res;
-}
-
-#define __HAVE_ARCH_STRNCMP
-static inline int strncmp(const char * cs,const char * ct,size_t count)
-{
-register int __res;
-int d0, d1, d2;
-__asm__ __volatile__(
- "1:\tdecl %3\n\t"
- "js 2f\n\t"
- "lodsb\n\t"
- "scasb\n\t"
- "jne 3f\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b\n"
- "2:\txorl %%eax,%%eax\n\t"
- "jmp 4f\n"
- "3:\tsbbl %%eax,%%eax\n\t"
- "orb $1,%%al\n"
- "4:"
- :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
- :"1" (cs),"2" (ct),"3" (count));
-return __res;
-}
-
-#define __HAVE_ARCH_STRCHR
-static inline char * strchr(const char * s, int c)
-{
-int d0;
-register char * __res;
-__asm__ __volatile__(
- "movb %%al,%%ah\n"
- "1:\tlodsb\n\t"
- "cmpb %%ah,%%al\n\t"
- "je 2f\n\t"
- "testb %%al,%%al\n\t"
- "jne 1b\n\t"
- "movl $1,%1\n"
- "2:\tmovl %1,%0\n\t"
- "decl %0"
- :"=a" (__res), "=&S" (d0) : "1" (s),"0" (c));
-return __res;
-}
-
-#define __HAVE_ARCH_STRRCHR
-static inline char * strrchr(const char * s, int c)
-{
-int d0, d1;
-register char * __res;
-__asm__ __volatile__(
- "movb %%al,%%ah\n"
- "1:\tlodsb\n\t"
- "cmpb %%ah,%%al\n\t"
- "jne 2f\n\t"
- "leal -1(%%esi),%0\n"
- "2:\ttestb %%al,%%al\n\t"
- "jne 1b"
- :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
-return __res;
-}
-
-#define __HAVE_ARCH_STRLEN
-static inline size_t strlen(const char * s)
-{
-int d0;
-register int __res;
-__asm__ __volatile__(
- "repne\n\t"
- "scasb\n\t"
- "notl %0\n\t"
- "decl %0"
- :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
-return __res;
-}
-
-static inline void * __memcpy(void * to, const void * from, size_t n)
-{
-int d0, d1, d2;
-__asm__ __volatile__(
- "rep ; movsl\n\t"
- "testb $2,%b4\n\t"
- "je 1f\n\t"
- "movsw\n"
- "1:\ttestb $1,%b4\n\t"
- "je 2f\n\t"
- "movsb\n"
- "2:"
- : "=&c" (d0), "=&D" (d1), "=&S" (d2)
- :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
- : "memory");
-return (to);
-}
-
-/*
- * This looks horribly ugly, but the compiler can optimize it totally,
- * as the count is constant.
- */
-static inline void * __constant_memcpy(void * to, const void * from, size_t n)
-{
- switch (n) {
- case 0:
- return to;
- case 1:
- *(unsigned char *)to = *(const unsigned char *)from;
- return to;
- case 2:
- *(unsigned short *)to = *(const unsigned short *)from;
- return to;
- case 3:
- *(unsigned short *)to = *(const unsigned short *)from;
- *(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
- return to;
- case 4:
- *(unsigned long *)to = *(const unsigned long *)from;
- return to;
- case 6: /* for Ethernet addresses */
- *(unsigned long *)to = *(const unsigned long *)from;
- *(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
- return to;
- case 8:
- *(unsigned long *)to = *(const unsigned long *)from;
- *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
- return to;
- case 12:
- *(unsigned long *)to = *(const unsigned long *)from;
- *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
- *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
- return to;
- case 16:
- *(unsigned long *)to = *(const unsigned long *)from;
- *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
- *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
- *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
- return to;
- case 20:
- *(unsigned long *)to = *(const unsigned long *)from;
- *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
- *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
- *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
- *(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
- return to;
- }
-#define COMMON(x) \
-__asm__ __volatile__( \
- "rep ; movsl" \
- x \
- : "=&c" (d0), "=&D" (d1), "=&S" (d2) \
- : "0" (n/4),"1" ((long) to),"2" ((long) from) \
- : "memory");
-{
- int d0, d1, d2;
- switch (n % 4) {
- case 0: COMMON(""); return to;
- case 1: COMMON("\n\tmovsb"); return to;
- case 2: COMMON("\n\tmovsw"); return to;
- default: COMMON("\n\tmovsw\n\tmovsb"); return to;
- }
-}
-
-#undef COMMON
-}
-
-#define __HAVE_ARCH_MEMCPY
-
-#define memcpy(t, f, n) \
-(__builtin_constant_p(n) ? \
- __constant_memcpy((t),(f),(n)) : \
- __memcpy((t),(f),(n)))
-
-
-/*
- * struct_cpy(x,y), copy structure *x into (matching structure) *y.
- *
- * We get link-time errors if the structure sizes do not match.
- * There is no runtime overhead, it's all optimized away at
- * compile time.
- */
-//extern void __struct_cpy_bug (void);
-
-/*
-#define struct_cpy(x,y) \
-({ \
- if (sizeof(*(x)) != sizeof(*(y))) \
- __struct_cpy_bug; \
- memcpy(x, y, sizeof(*(x))); \
-})
-*/
-
-#define __HAVE_ARCH_MEMMOVE
-static inline void * memmove(void * dest,const void * src, size_t n)
-{
-int d0, d1, d2;
-if (dest<src)
-__asm__ __volatile__(
- "rep\n\t"
- "movsb"
- : "=&c" (d0), "=&S" (d1), "=&D" (d2)
- :"0" (n),"1" (src),"2" (dest)
- : "memory");
-else
-__asm__ __volatile__(
- "std\n\t"
- "rep\n\t"
- "movsb\n\t"
- "cld"
- : "=&c" (d0), "=&S" (d1), "=&D" (d2)
- :"0" (n),
- "1" (n-1+(const char *)src),
- "2" (n-1+(char *)dest)
- :"memory");
-return dest;
-}
-
-#define __HAVE_ARCH_MEMCMP
-#define memcmp __builtin_memcmp
-
-#define __HAVE_ARCH_MEMCHR
-static inline void * memchr(const void * cs,int c,size_t count)
-{
-int d0;
-register void * __res;
-if (!count)
- return NULL;
-__asm__ __volatile__(
- "repne\n\t"
- "scasb\n\t"
- "je 1f\n\t"
- "movl $1,%0\n"
- "1:\tdecl %0"
- :"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count));
-return __res;
-}
-
-static inline void * __memset_generic(void * s, char c,size_t count)
-{
-int d0, d1;
-__asm__ __volatile__(
- "rep\n\t"
- "stosb"
- : "=&c" (d0), "=&D" (d1)
- :"a" (c),"1" (s),"0" (count)
- :"memory");
-return s;
-}
-
-/* we might want to write optimized versions of these later */
-#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
-
-/*
- * memset(x,0,y) is a reasonably common thing to do, so we want to fill
- * things 32 bits at a time even when we don't know the size of the
- * area at compile-time..
- */
-static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
-{
-int d0, d1;
-__asm__ __volatile__(
- "rep ; stosl\n\t"
- "testb $2,%b3\n\t"
- "je 1f\n\t"
- "stosw\n"
- "1:\ttestb $1,%b3\n\t"
- "je 2f\n\t"
- "stosb\n"
- "2:"
- : "=&c" (d0), "=&D" (d1)
- :"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
- :"memory");
-return (s);
-}
-
-/* Added by Gertjan van Wingerde to make minix and sysv module work */
-#define __HAVE_ARCH_STRNLEN
-static inline size_t strnlen(const char * s, size_t count)
-{
-int d0;
-register int __res;
-__asm__ __volatile__(
- "movl %2,%0\n\t"
- "jmp 2f\n"
- "1:\tcmpb $0,(%0)\n\t"
- "je 3f\n\t"
- "incl %0\n"
- "2:\tdecl %1\n\t"
- "cmpl $-1,%1\n\t"
- "jne 1b\n"
- "3:\tsubl %2,%0"
- :"=a" (__res), "=&d" (d0)
- :"c" (s),"1" (count));
-return __res;
-}
-/* end of additional stuff */
-
-//#define __HAVE_ARCH_STRSTR
-
-//extern char *strstr(const char *cs, const char *ct);
-
-/*
- * This looks horribly ugly, but the compiler can optimize it totally,
- * as we by now know that both pattern and count is constant..
- */
-static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
-{
- switch (count) {
- case 0:
- return s;
- case 1:
- *(unsigned char *)s = pattern;
- return s;
- case 2:
- *(unsigned short *)s = pattern;
- return s;
- case 3:
- *(unsigned short *)s = pattern;
- *(2+(unsigned char *)s) = pattern;
- return s;
- case 4:
- *(unsigned long *)s = pattern;
- return s;
- }
-#define COMMON(x) \
-__asm__ __volatile__( \
- "rep ; stosl" \
- x \
- : "=&c" (d0), "=&D" (d1) \
- : "a" (pattern),"0" (count/4),"1" ((long) s) \
- : "memory")
-{
- int d0, d1;
- switch (count % 4) {
- case 0: COMMON(""); return s;
- case 1: COMMON("\n\tstosb"); return s;
- case 2: COMMON("\n\tstosw"); return s;
- default: COMMON("\n\tstosw\n\tstosb"); return s;
- }
-}
-
-#undef COMMON
-}
-
-#define __constant_c_x_memset(s, c, count) \
-(__builtin_constant_p(count) ? \
- __constant_c_and_count_memset((s),(c),(count)) : \
- __constant_c_memset((s),(c),(count)))
-
-#define __memset(s, c, count) \
-(__builtin_constant_p(count) ? \
- __constant_count_memset((s),(c),(count)) : \
- __memset_generic((s),(c),(count)))
-
-#define __HAVE_ARCH_MEMSET
-#define memset(s, c, count) \
-(__builtin_constant_p(c) ? \
- __constant_c_x_memset((s),(0x01010101UL*(unsigned char)(c)),(count)) : \
- __memset((s),(c),(count)))
-
-/*
- * find the first occurrence of byte 'c', or 1 past the area if none
- */
-#define __HAVE_ARCH_MEMSCAN
-static inline void * memscan(void * addr, int c, size_t size)
-{
- if (!size)
- return addr;
- __asm__("repnz; scasb\n\t"
- "jnz 1f\n\t"
- "dec %%edi\n"
- "1:"
- : "=D" (addr), "=c" (size)
- : "0" (addr), "1" (size), "a" (c));
- return addr;
-}
-
+#ifdef __x86_64__
+#include <asm/x86_64/string.h>
+#else
+#include <asm/x86_32/string.h>
#endif
diff --git a/xen/include/asm-x86/types.h b/xen/include/asm-x86/types.h
index 0b4b616b24..e2b229edcf 100644
--- a/xen/include/asm-x86/types.h
+++ b/xen/include/asm-x86/types.h
@@ -3,7 +3,6 @@
typedef unsigned short umode_t;
-typedef unsigned int size_t;
/*
* __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
@@ -44,10 +43,12 @@ typedef unsigned int u32;
typedef signed long long s64;
typedef unsigned long long u64;
#define BITS_PER_LONG 32
+typedef unsigned int size_t;
#elif defined(__x86_64__)
typedef signed long s64;
typedef unsigned long u64;
#define BITS_PER_LONG 64
+typedef unsigned long size_t;
#endif
/* DMA addresses come in generic and 64-bit flavours. */
diff --git a/xen/include/asm-x86/x86_32/string.h b/xen/include/asm-x86/x86_32/string.h
new file mode 100644
index 0000000000..27fbb4d035
--- /dev/null
+++ b/xen/include/asm-x86/x86_32/string.h
@@ -0,0 +1,485 @@
+#ifndef _I386_STRING_H_
+#define _I386_STRING_H_
+
+#include <xen/config.h>
+
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ * NO Copyright (C) 1991, 1992 Linus Torvalds,
+ * consider these trivial functions to be PD.
+ */
+
+
+#define __HAVE_ARCH_STRCPY
+static inline char * strcpy(char * dest,const char *src)
+{
+int d0, d1, d2;
+__asm__ __volatile__(
+ "1:\tlodsb\n\t"
+ "stosb\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b"
+ : "=&S" (d0), "=&D" (d1), "=&a" (d2)
+ :"0" (src),"1" (dest) : "memory");
+return dest;
+}
+
+#define __HAVE_ARCH_STRNCPY
+static inline char * strncpy(char * dest,const char *src,size_t count)
+{
+int d0, d1, d2, d3;
+__asm__ __volatile__(
+ "1:\tdecl %2\n\t"
+ "js 2f\n\t"
+ "lodsb\n\t"
+ "stosb\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n\t"
+ "rep\n\t"
+ "stosb\n"
+ "2:"
+ : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
+ :"0" (src),"1" (dest),"2" (count) : "memory");
+return dest;
+}
+
+#define __HAVE_ARCH_STRCAT
+static inline char * strcat(char * dest,const char * src)
+{
+int d0, d1, d2, d3;
+__asm__ __volatile__(
+ "repne\n\t"
+ "scasb\n\t"
+ "decl %1\n"
+ "1:\tlodsb\n\t"
+ "stosb\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b"
+ : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+ : "0" (src), "1" (dest), "2" (0), "3" (0xffffffff):"memory");
+return dest;
+}
+
+#define __HAVE_ARCH_STRNCAT
+static inline char * strncat(char * dest,const char * src,size_t count)
+{
+int d0, d1, d2, d3;
+__asm__ __volatile__(
+ "repne\n\t"
+ "scasb\n\t"
+ "decl %1\n\t"
+ "movl %8,%3\n"
+ "1:\tdecl %3\n\t"
+ "js 2f\n\t"
+ "lodsb\n\t"
+ "stosb\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n"
+ "2:\txorl %2,%2\n\t"
+ "stosb"
+ : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
+ : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
+ : "memory");
+return dest;
+}
+
+#define __HAVE_ARCH_STRCMP
+static inline int strcmp(const char * cs,const char * ct)
+{
+int d0, d1;
+register int __res;
+__asm__ __volatile__(
+ "1:\tlodsb\n\t"
+ "scasb\n\t"
+ "jne 2f\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n\t"
+ "xorl %%eax,%%eax\n\t"
+ "jmp 3f\n"
+ "2:\tsbbl %%eax,%%eax\n\t"
+ "orb $1,%%al\n"
+ "3:"
+ :"=a" (__res), "=&S" (d0), "=&D" (d1)
+ :"1" (cs),"2" (ct));
+return __res;
+}
+
+#define __HAVE_ARCH_STRNCMP
+static inline int strncmp(const char * cs,const char * ct,size_t count)
+{
+register int __res;
+int d0, d1, d2;
+__asm__ __volatile__(
+ "1:\tdecl %3\n\t"
+ "js 2f\n\t"
+ "lodsb\n\t"
+ "scasb\n\t"
+ "jne 3f\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n"
+ "2:\txorl %%eax,%%eax\n\t"
+ "jmp 4f\n"
+ "3:\tsbbl %%eax,%%eax\n\t"
+ "orb $1,%%al\n"
+ "4:"
+ :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
+ :"1" (cs),"2" (ct),"3" (count));
+return __res;
+}
+
+#define __HAVE_ARCH_STRCHR
+static inline char * strchr(const char * s, int c)
+{
+int d0;
+register char * __res;
+__asm__ __volatile__(
+ "movb %%al,%%ah\n"
+ "1:\tlodsb\n\t"
+ "cmpb %%ah,%%al\n\t"
+ "je 2f\n\t"
+ "testb %%al,%%al\n\t"
+ "jne 1b\n\t"
+ "movl $1,%1\n"
+ "2:\tmovl %1,%0\n\t"
+ "decl %0"
+ :"=a" (__res), "=&S" (d0) : "1" (s),"0" (c));
+return __res;
+}
+
+#define __HAVE_ARCH_STRRCHR
+static inline char * strrchr(const char * s, int c)
+{
+int d0, d1;
+register char * __res;
+__asm__ __volatile__(
+ "movb %%al,%%ah\n"
+ "1:\tlodsb\n\t"
+ "cmpb %%ah,%%al\n\t"
+ "jne 2f\n\t"
+ "leal -1(%%esi),%0\n"
+ "2:\ttestb %%al,%%al\n\t"
+ "jne 1b"
+ :"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
+return __res;
+}
+
+#define __HAVE_ARCH_STRLEN
+static inline size_t strlen(const char * s)
+{
+int d0;
+register int __res;
+__asm__ __volatile__(
+ "repne\n\t"
+ "scasb\n\t"
+ "notl %0\n\t"
+ "decl %0"
+ :"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
+return __res;
+}
+
+static inline void * __memcpy(void * to, const void * from, size_t n)
+{
+int d0, d1, d2;
+__asm__ __volatile__(
+ "rep ; movsl\n\t"
+ "testb $2,%b4\n\t"
+ "je 1f\n\t"
+ "movsw\n"
+ "1:\ttestb $1,%b4\n\t"
+ "je 2f\n\t"
+ "movsb\n"
+ "2:"
+ : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+ :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+ : "memory");
+return (to);
+}
+
+/*
+ * This looks horribly ugly, but the compiler can optimize it totally,
+ * as the count is constant.
+ */
+static inline void * __constant_memcpy(void * to, const void * from, size_t n)
+{
+ switch (n) {
+ case 0:
+ return to;
+ case 1:
+ *(unsigned char *)to = *(const unsigned char *)from;
+ return to;
+ case 2:
+ *(unsigned short *)to = *(const unsigned short *)from;
+ return to;
+ case 3:
+ *(unsigned short *)to = *(const unsigned short *)from;
+ *(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
+ return to;
+ case 4:
+ *(unsigned long *)to = *(const unsigned long *)from;
+ return to;
+ case 6: /* for Ethernet addresses */
+ *(unsigned long *)to = *(const unsigned long *)from;
+ *(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
+ return to;
+ case 8:
+ *(unsigned long *)to = *(const unsigned long *)from;
+ *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+ return to;
+ case 12:
+ *(unsigned long *)to = *(const unsigned long *)from;
+ *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+ *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
+ return to;
+ case 16:
+ *(unsigned long *)to = *(const unsigned long *)from;
+ *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+ *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
+ *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
+ return to;
+ case 20:
+ *(unsigned long *)to = *(const unsigned long *)from;
+ *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+ *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
+ *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
+ *(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
+ return to;
+ }
+#define COMMON(x) \
+__asm__ __volatile__( \
+ "rep ; movsl" \
+ x \
+ : "=&c" (d0), "=&D" (d1), "=&S" (d2) \
+ : "0" (n/4),"1" ((long) to),"2" ((long) from) \
+ : "memory");
+{
+ int d0, d1, d2;
+ switch (n % 4) {
+ case 0: COMMON(""); return to;
+ case 1: COMMON("\n\tmovsb"); return to;
+ case 2: COMMON("\n\tmovsw"); return to;
+ default: COMMON("\n\tmovsw\n\tmovsb"); return to;
+ }
+}
+
+#undef COMMON
+}
+
+#define __HAVE_ARCH_MEMCPY
+
+#define memcpy(t, f, n) \
+(__builtin_constant_p(n) ? \
+ __constant_memcpy((t),(f),(n)) : \
+ __memcpy((t),(f),(n)))
+
+
+/*
+ * struct_cpy(x,y), copy structure *x into (matching structure) *y.
+ *
+ * We get link-time errors if the structure sizes do not match.
+ * There is no runtime overhead, it's all optimized away at
+ * compile time.
+ */
+//extern void __struct_cpy_bug (void);
+
+/*
+#define struct_cpy(x,y) \
+({ \
+ if (sizeof(*(x)) != sizeof(*(y))) \
+ __struct_cpy_bug; \
+ memcpy(x, y, sizeof(*(x))); \
+})
+*/
+
+#define __HAVE_ARCH_MEMMOVE
+static inline void * memmove(void * dest,const void * src, size_t n)
+{
+int d0, d1, d2;
+if (dest<src)
+__asm__ __volatile__(
+ "rep\n\t"
+ "movsb"
+ : "=&c" (d0), "=&S" (d1), "=&D" (d2)
+ :"0" (n),"1" (src),"2" (dest)
+ : "memory");
+else
+__asm__ __volatile__(
+ "std\n\t"
+ "rep\n\t"
+ "movsb\n\t"
+ "cld"
+ : "=&c" (d0), "=&S" (d1), "=&D" (d2)
+ :"0" (n),
+ "1" (n-1+(const char *)src),
+ "2" (n-1+(char *)dest)
+ :"memory");
+return dest;
+}
+
+#define __HAVE_ARCH_MEMCMP
+#define memcmp __builtin_memcmp
+
+#define __HAVE_ARCH_MEMCHR
+static inline void * memchr(const void * cs,int c,size_t count)
+{
+int d0;
+register void * __res;
+if (!count)
+ return NULL;
+__asm__ __volatile__(
+ "repne\n\t"
+ "scasb\n\t"
+ "je 1f\n\t"
+ "movl $1,%0\n"
+ "1:\tdecl %0"
+ :"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count));
+return __res;
+}
+
+static inline void * __memset_generic(void * s, char c,size_t count)
+{
+int d0, d1;
+__asm__ __volatile__(
+ "rep\n\t"
+ "stosb"
+ : "=&c" (d0), "=&D" (d1)
+ :"a" (c),"1" (s),"0" (count)
+ :"memory");
+return s;
+}
+
+/* we might want to write optimized versions of these later */
+#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
+
+/*
+ * memset(x,0,y) is a reasonably common thing to do, so we want to fill
+ * things 32 bits at a time even when we don't know the size of the
+ * area at compile-time..
+ */
+static inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
+{
+int d0, d1;
+__asm__ __volatile__(
+ "rep ; stosl\n\t"
+ "testb $2,%b3\n\t"
+ "je 1f\n\t"
+ "stosw\n"
+ "1:\ttestb $1,%b3\n\t"
+ "je 2f\n\t"
+ "stosb\n"
+ "2:"
+ : "=&c" (d0), "=&D" (d1)
+ :"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
+ :"memory");
+return (s);
+}
+
+/* Added by Gertjan van Wingerde to make minix and sysv module work */
+#define __HAVE_ARCH_STRNLEN
+static inline size_t strnlen(const char * s, size_t count)
+{
+int d0;
+register int __res;
+__asm__ __volatile__(
+ "movl %2,%0\n\t"
+ "jmp 2f\n"
+ "1:\tcmpb $0,(%0)\n\t"
+ "je 3f\n\t"
+ "incl %0\n"
+ "2:\tdecl %1\n\t"
+ "cmpl $-1,%1\n\t"
+ "jne 1b\n"
+ "3:\tsubl %2,%0"
+ :"=a" (__res), "=&d" (d0)
+ :"c" (s),"1" (count));
+return __res;
+}
+/* end of additional stuff */
+
+//#define __HAVE_ARCH_STRSTR
+
+//extern char *strstr(const char *cs, const char *ct);
+
+/*
+ * This looks horribly ugly, but the compiler can optimize it totally,
+ * as we by now know that both pattern and count is constant..
+ */
+static inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
+{
+ switch (count) {
+ case 0:
+ return s;
+ case 1:
+ *(unsigned char *)s = pattern;
+ return s;
+ case 2:
+ *(unsigned short *)s = pattern;
+ return s;
+ case 3:
+ *(unsigned short *)s = pattern;
+ *(2+(unsigned char *)s) = pattern;
+ return s;
+ case 4:
+ *(unsigned long *)s = pattern;
+ return s;
+ }
+#define COMMON(x) \
+__asm__ __volatile__( \
+ "rep ; stosl" \
+ x \
+ : "=&c" (d0), "=&D" (d1) \
+ : "a" (pattern),"0" (count/4),"1" ((long) s) \
+ : "memory")
+{
+ int d0, d1;
+ switch (count % 4) {
+ case 0: COMMON(""); return s;
+ case 1: COMMON("\n\tstosb"); return s;
+ case 2: COMMON("\n\tstosw"); return s;
+ default: COMMON("\n\tstosw\n\tstosb"); return s;
+ }
+}
+
+#undef COMMON
+}
+
+#define __constant_c_x_memset(s, c, count) \
+(__builtin_constant_p(count) ? \
+ __constant_c_and_count_memset((s),(c),(count)) : \
+ __constant_c_memset((s),(c),(count)))
+
+#define __memset(s, c, count) \
+(__builtin_constant_p(count) ? \
+ __constant_count_memset((s),(c),(count)) : \
+ __memset_generic((s),(c),(count)))
+
+#define __HAVE_ARCH_MEMSET
+#define memset(s, c, count) \
+(__builtin_constant_p(c) ? \
+ __constant_c_x_memset((s),(0x01010101UL*(unsigned char)(c)),(count)) : \
+ __memset((s),(c),(count)))
+
+/*
+ * find the first occurrence of byte 'c', or 1 past the area if none
+ */
+#define __HAVE_ARCH_MEMSCAN
+static inline void * memscan(void * addr, int c, size_t size)
+{
+ if (!size)
+ return addr;
+ __asm__("repnz; scasb\n\t"
+ "jnz 1f\n\t"
+ "dec %%edi\n"
+ "1:"
+ : "=D" (addr), "=c" (size)
+ : "0" (addr), "1" (size), "a" (c));
+ return addr;
+}
+
+#endif
diff --git a/xen/include/asm-x86/x86_64/string.h b/xen/include/asm-x86/x86_64/string.h
new file mode 100644
index 0000000000..27876b9da0
--- /dev/null
+++ b/xen/include/asm-x86/x86_64/string.h
@@ -0,0 +1,69 @@
+#ifndef _X86_64_STRING_H_
+#define _X86_64_STRING_H_
+
+#ifdef __KERNEL__
+
+#define struct_cpy(x,y) (*(x)=*(y))
+
+/* Written 2002 by Andi Kleen */
+
+/* Only used for special circumstances. Stolen from i386/string.h */
+static inline void * __inline_memcpy(void * to, const void * from, size_t n)
+{
+unsigned long d0, d1, d2;
+__asm__ __volatile__(
+ "rep ; movsl\n\t"
+ "testb $2,%b4\n\t"
+ "je 1f\n\t"
+ "movsw\n"
+ "1:\ttestb $1,%b4\n\t"
+ "je 2f\n\t"
+ "movsb\n"
+ "2:"
+ : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+ :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+ : "memory");
+return (to);
+}
+
+/* Even with __builtin_ the compiler may decide to use the out of line
+ function. */
+
+#define __HAVE_ARCH_MEMCPY 1
+extern void *__memcpy(void *to, const void *from, size_t len);
+#define memcpy(dst,src,len) \
+ ({ size_t __len = (len); \
+ void *__ret; \
+ if (__builtin_constant_p(len) && __len >= 64) \
+ __ret = __memcpy((dst),(src),__len); \
+ else \
+ __ret = __builtin_memcpy((dst),(src),__len); \
+ __ret; })
+
+
+#define __HAVE_ARCH_MEMSET
+#define memset __builtin_memset
+
+#define __HAVE_ARCH_MEMMOVE
+void * memmove(void * dest,const void *src,size_t count);
+
+/* Use C out of line version for memcmp */
+#define memcmp __builtin_memcmp
+int memcmp(const void * cs,const void * ct,size_t count);
+
+/* out of line string functions use always C versions */
+#define strlen __builtin_strlen
+size_t strlen(const char * s);
+
+#define strcpy __builtin_strcpy
+char * strcpy(char * dest,const char *src);
+
+#define strcat __builtin_strcat
+char * strcat(char * dest, const char * src);
+
+#define strcmp __builtin_strcmp
+int strcmp(const char * cs,const char * ct);
+
+#endif /* __KERNEL__ */
+
+#endif
diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h
index 26721e8240..4688037deb 100644
--- a/xen/include/xen/mm.h
+++ b/xen/include/xen/mm.h
@@ -86,7 +86,7 @@ struct pfn_info
#define PageSetSlab(page) ((void)0)
#define PageClearSlab(page) ((void)0)
-#define IS_XEN_HEAP_FRAME(_pfn) (page_to_phys(_pfn) < MAX_XENHEAP_ADDRESS)
+#define IS_XEN_HEAP_FRAME(_pfn) (page_to_phys(_pfn) < xenheap_phys_end)
#define SHARE_PFN_WITH_DOMAIN(_pfn, _dom) \
do { \
@@ -104,7 +104,7 @@ extern struct list_head free_list;
extern spinlock_t free_list_lock;
extern unsigned int free_pfns;
extern unsigned long max_page;
-void init_frametable(unsigned long nr_pages);
+void init_frametable(void *frametable_vstart, unsigned long nr_pages);
void add_to_domain_alloc_list(unsigned long ps, unsigned long pe);
struct pfn_info *alloc_domain_page(struct domain *p);