ia64/xen-unstable

changeset 15155:c0cdcebc0377

[IA64] Allow dynamic allocation of dom0 fw_tables

This address Xensource bugzilla #980

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Alex Williamson <alex.williamson@hp.com>
date Mon Jun 04 13:57:08 2007 -0600 (2007-06-04)
parents b46c2ff6dfb0
children 249446c52deb
files tools/libxc/ia64/xc_dom_ia64_util.c tools/libxc/ia64/xc_dom_ia64_util.h xen/arch/ia64/xen/dom_fw_common.c xen/arch/ia64/xen/dom_fw_dom0.c xen/arch/ia64/xen/dom_fw_domu.c xen/arch/ia64/xen/dom_fw_utils.c xen/include/asm-ia64/dom_fw.h xen/include/asm-ia64/dom_fw_common.h xen/include/asm-ia64/dom_fw_dom0.h xen/include/asm-ia64/dom_fw_domu.h xen/include/asm-ia64/dom_fw_utils.h
line diff
     1.1 --- a/tools/libxc/ia64/xc_dom_ia64_util.c	Thu May 31 14:47:08 2007 -0600
     1.2 +++ b/tools/libxc/ia64/xc_dom_ia64_util.c	Mon Jun 04 13:57:08 2007 -0600
     1.3 @@ -18,6 +18,7 @@
     1.4   *
     1.5   */
     1.6  
     1.7 +#include <assert.h>
     1.8  #include "xg_private.h"
     1.9  #include "xc_dom.h"
    1.10  #include "asm/dom_fw.h"
    1.11 @@ -114,12 +115,12 @@ xen_ia64_dom_fw_setup(struct xc_dom_imag
    1.12  {
    1.13      int rc = 0;
    1.14      void *imva_hypercall_base = NULL;
    1.15 -    void *imva_tables_base = NULL;
    1.16 +    struct fw_tables *fw_tables = NULL;
    1.17      struct fake_acpi_tables *imva = NULL;
    1.18      struct xen_ia64_boot_param *bp = NULL;
    1.19  
    1.20      BUILD_BUG_ON(sizeof(struct fw_tables) >
    1.21 -                 (FW_TABLES_END_PADDR - FW_TABLES_BASE_PADDR));
    1.22 +                 (FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR));
    1.23  
    1.24      /* Create page for hypercalls.  */
    1.25      imva_hypercall_base = xen_ia64_dom_fw_map(d, FW_HYPERCALL_BASE_PADDR);
    1.26 @@ -129,11 +130,17 @@ xen_ia64_dom_fw_setup(struct xc_dom_imag
    1.27      }
    1.28  
    1.29      /* Create page for FW tables.  */
    1.30 -    imva_tables_base = xen_ia64_dom_fw_map(d, FW_TABLES_BASE_PADDR);
    1.31 -    if (imva_tables_base == NULL) {
    1.32 +    fw_tables = (struct fw_tables*)xen_ia64_dom_fw_map(d, FW_TABLES_BASE_PADDR);
    1.33 +    if (fw_tables == NULL) {
    1.34          rc = -errno;
    1.35          goto out;
    1.36      }
    1.37 +    memset(fw_tables, 0, FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR);
    1.38 +    BUILD_BUG_ON(FW_END_PADDR_MIN != FW_TABLES_END_PADDR_MIN);
    1.39 +    fw_tables->fw_tables_size = FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR;
    1.40 +    fw_tables->fw_end_paddr = FW_END_PADDR_MIN;
    1.41 +    fw_tables->fw_tables_end_paddr = FW_TABLES_END_PADDR_MIN;
    1.42 +    fw_tables->num_mds = 0;
    1.43          
    1.44      /* Create page for acpi tables.  */
    1.45      imva = (struct fake_acpi_tables *)
    1.46 @@ -150,14 +157,22 @@ xen_ia64_dom_fw_setup(struct xc_dom_imag
    1.47          rc = -errno;
    1.48          goto out;
    1.49      }
    1.50 -    rc = dom_fw_init(d, brkimm, bp, imva_tables_base,
    1.51 +    rc = dom_fw_init(d, brkimm, bp, fw_tables,
    1.52                       (unsigned long)imva_hypercall_base, maxmem);
    1.53 +    BUG_ON(fw_tables->fw_tables_size < sizeof(*fw_tables) +
    1.54 +           sizeof(fw_tables->efi_memmap[0]) * fw_tables->num_mds);
    1.55  
    1.56 +    /* clear domain builder internal use member */
    1.57 +    fw_tables->fw_tables_size = 0;
    1.58 +    fw_tables->fw_end_paddr = 0;
    1.59 +    fw_tables->fw_tables_end_paddr = 0;
    1.60 +    fw_tables->num_mds = 0;
    1.61 +    
    1.62   out:
    1.63      if (imva_hypercall_base != NULL)
    1.64          xen_ia64_dom_fw_unmap(d, imva_hypercall_base);
    1.65 -    if (imva_tables_base != NULL)
    1.66 -        xen_ia64_dom_fw_unmap(d, imva_tables_base);
    1.67 +    if (fw_tables != NULL)
    1.68 +        xen_ia64_dom_fw_unmap(d, fw_tables);
    1.69      if (imva != NULL)
    1.70          xen_ia64_dom_fw_unmap(d, imva);
    1.71      if (bp != NULL)
     2.1 --- a/tools/libxc/ia64/xc_dom_ia64_util.h	Thu May 31 14:47:08 2007 -0600
     2.2 +++ b/tools/libxc/ia64/xc_dom_ia64_util.h	Mon Jun 04 13:57:08 2007 -0600
     2.3 @@ -14,6 +14,6 @@ int
     2.4  xen_ia64_dom_fw_setup(struct xc_dom_image *d, uint64_t brkimm,
     2.5                        unsigned long bp_mpa, unsigned long maxmem);
     2.6  #define efi_systable_init_dom0(tables)	assert(0)
     2.7 -#define complete_dom0_memmap(d, tables, maxmem, num_mds) ({assert(0);0;})
     2.8 +#define complete_dom0_memmap(d, tables) ({assert(0);0;})
     2.9  
    2.10  #endif /* XC_IA64_DOM_IA64_UTIL_H */
     3.1 --- a/xen/arch/ia64/xen/dom_fw_common.c	Thu May 31 14:47:08 2007 -0600
     3.2 +++ b/xen/arch/ia64/xen/dom_fw_common.c	Mon Jun 04 13:57:08 2007 -0600
     3.3 @@ -35,22 +35,17 @@
     3.4  #include <asm/dom_fw_domu.h>
     3.5  
     3.6  void
     3.7 -xen_ia64_efi_make_md(struct fw_tables *tables, int *index,
     3.8 +xen_ia64_efi_make_md(efi_memory_desc_t *md,
     3.9  		     uint32_t type, uint64_t attr, 
    3.10  		     uint64_t start, uint64_t end)
    3.11  {
    3.12 -	efi_memory_desc_t *md = &tables->efi_memmap[*index];
    3.13  	md->type = type;
    3.14  	md->pad = 0;
    3.15  	md->phys_addr = start;
    3.16  	md->virt_addr = 0;
    3.17  	md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
    3.18  	md->attribute = attr;
    3.19 -
    3.20 -	(*index)++;
    3.21  }
    3.22 -#define MAKE_MD(typ, attr, start, end) \
    3.23 -	xen_ia64_efi_make_md((tables), &(i), (typ), (attr), (start), (end))
    3.24  
    3.25  #define EFI_HYPERCALL_PATCH(tgt, call)					\
    3.26  	do {								\
    3.27 @@ -422,7 +417,7 @@ dom_fw_init(domain_t *d,
    3.28  	int num_mds, i;
    3.29  	int fpswa_supported = 0;
    3.30  
    3.31 -	memset(tables, 0, sizeof(struct fw_tables));
    3.32 +	/* Caller must zero-clear fw_tables */
    3.33  
    3.34  	/* EFI systab.  */
    3.35  	tables->efi_systab.hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
    3.36 @@ -514,17 +509,25 @@ dom_fw_init(domain_t *d,
    3.37  			(void *)FW_HYPERCALL_FPSWA_ENTRY_PADDR;
    3.38  	}
    3.39  
    3.40 -	i = 0; /* Used by MAKE_MD */
    3.41 -
    3.42 +	tables->num_mds = 0;
    3.43  	/* hypercall patches live here, masquerade as reserved PAL memory */
    3.44 -	MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,
    3.45 -	        FW_HYPERCALL_BASE_PADDR, FW_HYPERCALL_END_PADDR);
    3.46 +	xen_ia64_efi_make_md(&tables->efi_memmap[tables->num_mds],
    3.47 +			     EFI_PAL_CODE, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
    3.48 +			     FW_HYPERCALL_BASE_PADDR, FW_HYPERCALL_END_PADDR);
    3.49 +	tables->num_mds++;
    3.50  
    3.51  	/* Create dom0/domu md entry for fw and cpi tables area.  */
    3.52 -	MAKE_MD(EFI_ACPI_MEMORY_NVS, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
    3.53 -	        FW_ACPI_BASE_PADDR, FW_ACPI_END_PADDR);
    3.54 -	MAKE_MD(EFI_RUNTIME_SERVICES_DATA, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
    3.55 -	        FW_TABLES_BASE_PADDR, FW_TABLES_END_PADDR);
    3.56 +	xen_ia64_efi_make_md(&tables->efi_memmap[tables->num_mds],
    3.57 +			     EFI_ACPI_MEMORY_NVS,
    3.58 +			     EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
    3.59 +			     FW_ACPI_BASE_PADDR, FW_ACPI_END_PADDR);
    3.60 +	tables->num_mds++;
    3.61 +	xen_ia64_efi_make_md(&tables->efi_memmap[tables->num_mds],
    3.62 +			     EFI_RUNTIME_SERVICES_DATA,
    3.63 +			     EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
    3.64 +			     FW_TABLES_BASE_PADDR,
    3.65 +			     tables->fw_tables_end_paddr);
    3.66 +	tables->num_mds++;
    3.67  
    3.68  	if (!xen_ia64_is_dom0(d) || xen_ia64_is_running_on_sim(d)) {
    3.69  		/* DomU (or hp-ski).
    3.70 @@ -536,26 +539,27 @@ dom_fw_init(domain_t *d,
    3.71  		 * and console page.
    3.72  		 * see ia64_setup_memmap() @ xc_dom_boot.c
    3.73  		 */
    3.74 -		num_mds = complete_domu_memmap(d, tables, maxmem, i,
    3.75 +		num_mds = complete_domu_memmap(d, tables, maxmem,
    3.76  					       XEN_IA64_MEMMAP_INFO_PFN(bp),
    3.77  					       XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp));
    3.78  	} else {
    3.79  		/* Dom0.
    3.80  		   We must preserve ACPI data from real machine,
    3.81  		   as well as IO areas.  */
    3.82 -		num_mds = complete_dom0_memmap(d, tables, maxmem, i);
    3.83 +		num_mds = complete_dom0_memmap(d, tables);
    3.84  	}
    3.85  	if (num_mds < 0)
    3.86  		return num_mds;
    3.87 +	BUG_ON(num_mds != tables->num_mds);
    3.88  
    3.89  	/* Display memmap.  */
    3.90 -	for (i = 0 ; i < num_mds; i++)
    3.91 +	for (i = 0 ; i < tables->num_mds; i++)
    3.92  		print_md(&tables->efi_memmap[i]);
    3.93  
    3.94  	/* Fill boot_param  */
    3.95  	bp->efi_systab = FW_FIELD_MPA(efi_systab);
    3.96  	bp->efi_memmap = FW_FIELD_MPA(efi_memmap);
    3.97 -	bp->efi_memmap_size = num_mds * sizeof(efi_memory_desc_t);
    3.98 +	bp->efi_memmap_size = tables->num_mds * sizeof(efi_memory_desc_t);
    3.99  	bp->efi_memdesc_size = sizeof(efi_memory_desc_t);
   3.100  	bp->efi_memdesc_version = EFI_MEMDESC_VERSION;
   3.101  	bp->command_line = 0;
     4.1 --- a/xen/arch/ia64/xen/dom_fw_dom0.c	Thu May 31 14:47:08 2007 -0600
     4.2 +++ b/xen/arch/ia64/xen/dom_fw_dom0.c	Mon Jun 04 13:57:08 2007 -0600
     4.3 @@ -32,6 +32,7 @@
     4.4  #include <asm/dom_fw.h>
     4.5  #include <asm/dom_fw_common.h>
     4.6  #include <asm/dom_fw_dom0.h>
     4.7 +#include <asm/dom_fw_utils.h>
     4.8  
     4.9  #include <linux/sort.h>
    4.10  
    4.11 @@ -158,21 +159,26 @@ void __init efi_systable_init_dom0(struc
    4.12  }
    4.13  
    4.14  static void __init
    4.15 -setup_dom0_memmap_info(struct domain *d, struct fw_tables *tables, int *num_mds)
    4.16 +setup_dom0_memmap_info(struct domain *d, struct fw_tables *tables)
    4.17  {
    4.18  	int i;
    4.19 +	size_t size;
    4.20 +	unsigned int num_pages;
    4.21  	efi_memory_desc_t *md;
    4.22  	efi_memory_desc_t *last_mem_md = NULL;
    4.23  	xen_ia64_memmap_info_t *memmap_info;
    4.24  	unsigned long paddr_start;
    4.25  	unsigned long paddr_end;
    4.26  
    4.27 -	for (i = *num_mds - 1; i >= 0; i--) {
    4.28 +	size = sizeof(*memmap_info) +
    4.29 +		(tables->num_mds + 1) * sizeof(tables->efi_memmap[0]);
    4.30 +	num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
    4.31 +	for (i = tables->num_mds - 1; i >= 0; i--) {
    4.32  		md = &tables->efi_memmap[i];
    4.33  		if (md->attribute == EFI_MEMORY_WB &&
    4.34  		    md->type == EFI_CONVENTIONAL_MEMORY &&
    4.35  		    md->num_pages >
    4.36 -		    2 * (1UL << (PAGE_SHIFT - EFI_PAGE_SHIFT))) {
    4.37 +		    ((num_pages + 1) << (PAGE_SHIFT - EFI_PAGE_SHIFT))) {
    4.38  			last_mem_md = md;
    4.39  			break;
    4.40  		}
    4.41 @@ -186,45 +192,71 @@ setup_dom0_memmap_info(struct domain *d,
    4.42  	}
    4.43  	paddr_end = last_mem_md->phys_addr +
    4.44  	    (last_mem_md->num_pages << EFI_PAGE_SHIFT);
    4.45 -	paddr_start = (paddr_end - PAGE_SIZE) & PAGE_MASK;
    4.46 -	last_mem_md->num_pages -=
    4.47 -	    (paddr_end - paddr_start) / (1UL << EFI_PAGE_SHIFT);
    4.48 +	paddr_start = (paddr_end - (num_pages << PAGE_SHIFT)) & PAGE_MASK;
    4.49 +	last_mem_md->num_pages -= (paddr_end - paddr_start) >> EFI_PAGE_SHIFT;
    4.50  
    4.51 -	md = &tables->efi_memmap[*num_mds];
    4.52 -	(*num_mds)++;
    4.53 +	md = &tables->efi_memmap[tables->num_mds];
    4.54 +	tables->num_mds++;
    4.55  	md->type = EFI_RUNTIME_SERVICES_DATA;
    4.56  	md->phys_addr = paddr_start;
    4.57  	md->virt_addr = 0;
    4.58 -	md->num_pages = 1UL << (PAGE_SHIFT - EFI_PAGE_SHIFT);
    4.59 +	md->num_pages = num_pages << (PAGE_SHIFT - EFI_PAGE_SHIFT);
    4.60  	md->attribute = EFI_MEMORY_WB;
    4.61  
    4.62 -	memmap_info = domain_mpa_to_imva(d, md->phys_addr);
    4.63 -	BUG_ON(*num_mds > NUM_MEM_DESCS);
    4.64 +	BUG_ON(tables->fw_tables_size <
    4.65 +	       sizeof(*tables) +
    4.66 +	       sizeof(tables->efi_memmap[0]) * tables->num_mds);
    4.67 +	/* with this sort, md doesn't point memmap table */
    4.68 +	sort(tables->efi_memmap, tables->num_mds,
    4.69 +	     sizeof(efi_memory_desc_t), efi_mdt_cmp, NULL);
    4.70  
    4.71 +	memmap_info = domain_mpa_to_imva(d, paddr_start);
    4.72  	memmap_info->efi_memdesc_size = sizeof(md[0]);
    4.73  	memmap_info->efi_memdesc_version = EFI_MEMORY_DESCRIPTOR_VERSION;
    4.74 -	memmap_info->efi_memmap_size = *num_mds * sizeof(md[0]);
    4.75 -	memcpy(&memmap_info->memdesc, &tables->efi_memmap[0],
    4.76 -	       memmap_info->efi_memmap_size);
    4.77 -	d->shared_info->arch.memmap_info_num_pages = 1;
    4.78 -	d->shared_info->arch.memmap_info_pfn = md->phys_addr >> PAGE_SHIFT;
    4.79 +	memmap_info->efi_memmap_size = tables->num_mds * sizeof(md[0]);
    4.80 +	dom_fw_copy_to(d,
    4.81 +		       paddr_start + offsetof(xen_ia64_memmap_info_t, memdesc),
    4.82 +		       &tables->efi_memmap[0], memmap_info->efi_memmap_size);
    4.83 +	d->shared_info->arch.memmap_info_num_pages = num_pages;
    4.84 +	d->shared_info->arch.memmap_info_pfn = paddr_start >> PAGE_SHIFT;
    4.85 +}
    4.86  
    4.87 -	sort(tables->efi_memmap, *num_mds, sizeof(efi_memory_desc_t),
    4.88 -	     efi_mdt_cmp, NULL);
    4.89 +/* setup_guest() @ libxc/xc_linux_build() arranges memory for domU.
    4.90 + * however no one arranges memory for dom0,
    4.91 + * instead we allocate pages manually.
    4.92 + */
    4.93 +static void
    4.94 +assign_new_domain0_range(struct domain *d, const efi_memory_desc_t * md)
    4.95 +{
    4.96 +	if (md->type == EFI_PAL_CODE ||
    4.97 +	    md->type == EFI_RUNTIME_SERVICES_DATA ||
    4.98 +	    md->type == EFI_CONVENTIONAL_MEMORY) {
    4.99 +		unsigned long start = md->phys_addr & PAGE_MASK;
   4.100 +		unsigned long end =
   4.101 +			md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
   4.102 +		unsigned long addr;
   4.103 +
   4.104 +		if (end == start) {
   4.105 +			/* md->num_pages = 0 is allowed. */
   4.106 +			return;
   4.107 +		}
   4.108 +
   4.109 +		for (addr = start; addr < end; addr += PAGE_SIZE)
   4.110 +			assign_new_domain0_page(d, addr);
   4.111 +	}
   4.112  }
   4.113  
   4.114  /* Complete the dom0 memmap.  */
   4.115  int __init
   4.116 -complete_dom0_memmap(struct domain *d,
   4.117 -		     struct fw_tables *tables,
   4.118 -		     unsigned long maxmem, int num_mds)
   4.119 +complete_dom0_memmap(struct domain *d, struct fw_tables *tables)
   4.120  {
   4.121 -	efi_memory_desc_t *md;
   4.122  	u64 addr;
   4.123  	void *efi_map_start, *efi_map_end, *p;
   4.124  	u64 efi_desc_size;
   4.125  	int i;
   4.126 -	unsigned long dom_mem = maxmem - (d->tot_pages << PAGE_SHIFT);
   4.127 +
   4.128 +	for (i = 0; i < tables->num_mds; i++)
   4.129 +		assign_new_domain0_range(d, &tables->efi_memmap[i]);
   4.130  
   4.131  	/* Walk through all MDT entries.
   4.132  	   Copy all interesting entries.  */
   4.133 @@ -234,7 +266,7 @@ complete_dom0_memmap(struct domain *d,
   4.134  
   4.135  	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   4.136  		const efi_memory_desc_t *md = p;
   4.137 -		efi_memory_desc_t *dom_md = &tables->efi_memmap[num_mds];
   4.138 +		efi_memory_desc_t *dom_md = &tables->efi_memmap[tables->num_mds];
   4.139  		u64 start = md->phys_addr;
   4.140  		u64 size = md->num_pages << EFI_PAGE_SHIFT;
   4.141  		u64 end = start + size;
   4.142 @@ -267,7 +299,7 @@ complete_dom0_memmap(struct domain *d,
   4.143  			/* Copy descriptor.  */
   4.144  			*dom_md = *md;
   4.145  			dom_md->virt_addr = 0;
   4.146 -			num_mds++;
   4.147 +			tables->num_mds++;
   4.148  			break;
   4.149  
   4.150  		case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
   4.151 @@ -288,31 +320,55 @@ complete_dom0_memmap(struct domain *d,
   4.152  			*dom_md = *md;
   4.153  			dom_md->phys_addr = mpaddr;
   4.154  			dom_md->virt_addr = 0;
   4.155 -			num_mds++;
   4.156 +			tables->num_mds++;
   4.157  			break;
   4.158  
   4.159  		case EFI_CONVENTIONAL_MEMORY:
   4.160  		case EFI_LOADER_CODE:
   4.161  		case EFI_LOADER_DATA:
   4.162  		case EFI_BOOT_SERVICES_CODE:
   4.163 -		case EFI_BOOT_SERVICES_DATA:
   4.164 +		case EFI_BOOT_SERVICES_DATA: {
   4.165 +			u64 dom_md_start;
   4.166 +			u64 dom_md_end;
   4.167 +			unsigned long left_mem =
   4.168 +				(unsigned long)(d->max_pages - d->tot_pages) <<
   4.169 +				PAGE_SHIFT;
   4.170 +
   4.171  			if (!(md->attribute & EFI_MEMORY_WB))
   4.172  				break;
   4.173  
   4.174 -			start = max(FW_END_PADDR, start);
   4.175 -			end = min(start + dom_mem, end);
   4.176 -			if (end <= start)
   4.177 -				break;
   4.178 +			dom_md_start = max(tables->fw_end_paddr, start);
   4.179 +			dom_md_end = dom_md_start;
   4.180 +			do {
   4.181 +				dom_md_end = min(dom_md_end + left_mem, end);
   4.182 +				if (dom_md_end < dom_md_start + PAGE_SIZE)
   4.183 +					break;
   4.184 +
   4.185 +				dom_md->type = EFI_CONVENTIONAL_MEMORY;
   4.186 +				dom_md->phys_addr = dom_md_start;
   4.187 +				dom_md->virt_addr = 0;
   4.188 +				dom_md->num_pages =
   4.189 +					(dom_md_end - dom_md_start) >>
   4.190 +					EFI_PAGE_SHIFT;
   4.191 +				dom_md->attribute = EFI_MEMORY_WB;
   4.192  
   4.193 -			dom_md->type = EFI_CONVENTIONAL_MEMORY;
   4.194 -			dom_md->phys_addr = start;
   4.195 -			dom_md->virt_addr = 0;
   4.196 -			dom_md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
   4.197 -			dom_md->attribute = EFI_MEMORY_WB;
   4.198 -			num_mds++;
   4.199 +				assign_new_domain0_range(d, dom_md);
   4.200 +				/*
   4.201 +				 * recalculate left_mem.
   4.202 +				 * we might already allocated memory in
   4.203 +				 * this region because of kernel loader.
   4.204 +				 * So we might consumed less than
   4.205 +				 * (dom_md_end - dom_md_start) above.
   4.206 +				 */
   4.207 +				left_mem = (unsigned long)
   4.208 +					(d->max_pages - d->tot_pages) <<
   4.209 +					PAGE_SHIFT;
   4.210 +			} while (left_mem > 0 && dom_md_end < end);
   4.211  
   4.212 -			dom_mem -= dom_md->num_pages << EFI_PAGE_SHIFT;
   4.213 +			if (!(dom_md_end < dom_md_start + PAGE_SIZE))
   4.214 +				tables->num_mds++;
   4.215  			break;
   4.216 +		}
   4.217  
   4.218  		case EFI_UNUSABLE_MEMORY:
   4.219  		case EFI_PAL_CODE:
   4.220 @@ -326,7 +382,7 @@ complete_dom0_memmap(struct domain *d,
   4.221  			dom_md->virt_addr = 0;
   4.222  			dom_md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
   4.223  			dom_md->attribute = EFI_MEMORY_WB;
   4.224 -			num_mds++;
   4.225 +			tables->num_mds++;
   4.226  			break;
   4.227  
   4.228  		default:
   4.229 @@ -335,34 +391,13 @@ complete_dom0_memmap(struct domain *d,
   4.230  			       "unhandled MDT entry type %u\n", md->type);
   4.231  		}
   4.232  	}
   4.233 -	BUG_ON(num_mds > NUM_MEM_DESCS);
   4.234 +	BUG_ON(tables->fw_tables_size <
   4.235 +	       sizeof(*tables) +
   4.236 +	       sizeof(tables->efi_memmap[0]) * tables->num_mds);
   4.237  
   4.238 -	sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t),
   4.239 +	sort(tables->efi_memmap, tables->num_mds, sizeof(efi_memory_desc_t),
   4.240  	     efi_mdt_cmp, NULL);
   4.241  
   4.242 -	/* setup_guest() @ libxc/xc_linux_build() arranges memory for domU.
   4.243 -	 * however no one arranges memory for dom0,
   4.244 -	 * instead we allocate pages manually.
   4.245 -	 */
   4.246 -	for (i = 0; i < num_mds; i++) {
   4.247 -		md = &tables->efi_memmap[i];
   4.248 -
   4.249 -		if (md->type == EFI_LOADER_DATA ||
   4.250 -		    md->type == EFI_PAL_CODE ||
   4.251 -		    md->type == EFI_CONVENTIONAL_MEMORY) {
   4.252 -			unsigned long start = md->phys_addr & PAGE_MASK;
   4.253 -			unsigned long end = md->phys_addr +
   4.254 -			    (md->num_pages << EFI_PAGE_SHIFT);
   4.255 -
   4.256 -			if (end == start) {
   4.257 -				/* md->num_pages = 0 is allowed. */
   4.258 -				continue;
   4.259 -			}
   4.260 -
   4.261 -			for (addr = start; addr < end; addr += PAGE_SIZE)
   4.262 -				assign_new_domain0_page(d, addr);
   4.263 -		}
   4.264 -	}
   4.265  	// Map low-memory holes & unmapped MMIO for legacy drivers
   4.266  	for (addr = 0; addr < ONE_MB; addr += PAGE_SIZE) {
   4.267  		if (domain_page_mapped(d, addr))
   4.268 @@ -375,8 +410,8 @@ complete_dom0_memmap(struct domain *d,
   4.269  						flags);
   4.270  		}
   4.271  	}
   4.272 -	setup_dom0_memmap_info(d, tables, &num_mds);
   4.273 -	return num_mds;
   4.274 +	setup_dom0_memmap_info(d, tables);
   4.275 +	return tables->num_mds;
   4.276  }
   4.277  
   4.278  /*
     5.1 --- a/xen/arch/ia64/xen/dom_fw_domu.c	Thu May 31 14:47:08 2007 -0600
     5.2 +++ b/xen/arch/ia64/xen/dom_fw_domu.c	Mon Jun 04 13:57:08 2007 -0600
     5.3 @@ -61,19 +61,14 @@ void efi_systable_init_domu(struct fw_ta
     5.4  	BUG_ON(i > NUM_EFI_SYS_TABLES);
     5.5  }
     5.6  
     5.7 -#define MAKE_MD(typ, attr, start, end) \
     5.8 -	xen_ia64_efi_make_md((tables), &(i), (typ), (attr), (start), (end))
     5.9 -
    5.10  int
    5.11  complete_domu_memmap(domain_t * d,
    5.12  		     struct fw_tables *tables,
    5.13  		     unsigned long maxmem,
    5.14 -		     int num_mds,
    5.15  		     unsigned long memmap_info_pfn,
    5.16  		     unsigned long memmap_info_num_pages)
    5.17  {
    5.18  	efi_memory_desc_t *md;
    5.19 -	int i = num_mds;	/* for MAKE_MD */
    5.20  	int create_memmap = 0;
    5.21  	xen_ia64_memmap_info_t *memmap_info;
    5.22  	unsigned long memmap_info_size;
    5.23 @@ -142,12 +137,12 @@ complete_domu_memmap(domain_t * d,
    5.24  		memmap_info->efi_memmap_size = 1 * sizeof(md[0]);
    5.25  
    5.26  		md = (efi_memory_desc_t *) & memmap_info->memdesc;
    5.27 -		md[num_mds].type = EFI_CONVENTIONAL_MEMORY;
    5.28 -		md[num_mds].pad = 0;
    5.29 -		md[num_mds].phys_addr = 0;
    5.30 -		md[num_mds].virt_addr = 0;
    5.31 -		md[num_mds].num_pages = maxmem >> EFI_PAGE_SHIFT;
    5.32 -		md[num_mds].attribute = EFI_MEMORY_WB;
    5.33 +		md->type = EFI_CONVENTIONAL_MEMORY;
    5.34 +		md->pad = 0;
    5.35 +		md->phys_addr = 0;
    5.36 +		md->virt_addr = 0;
    5.37 +		md->num_pages = maxmem >> EFI_PAGE_SHIFT;
    5.38 +		md->attribute = EFI_MEMORY_WB;
    5.39  	}
    5.40  
    5.41  	memmap_start = &memmap_info->memdesc;
    5.42 @@ -175,43 +170,61 @@ complete_domu_memmap(domain_t * d,
    5.43  		start = md->phys_addr;
    5.44  		end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
    5.45  
    5.46 -		if (start < FW_END_PADDR)
    5.47 -			start = FW_END_PADDR;
    5.48 +		if (start < tables->fw_end_paddr)
    5.49 +			start = tables->fw_end_paddr;
    5.50  		if (end <= start)
    5.51  			continue;
    5.52  
    5.53  		/* exclude [paddr_start, paddr_end) */
    5.54  		if (paddr_end <= start || end <= paddr_start) {
    5.55 -			MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB, start,
    5.56 -				end);
    5.57 +			xen_ia64_efi_make_md(&tables->
    5.58 +					     efi_memmap[tables->num_mds],
    5.59 +					     EFI_CONVENTIONAL_MEMORY,
    5.60 +					     EFI_MEMORY_WB, start, end);
    5.61 +			tables->num_mds++;
    5.62  		} else if (paddr_start <= start && paddr_end < end) {
    5.63 -			MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
    5.64 -				paddr_end, end);
    5.65 +			xen_ia64_efi_make_md(&tables->
    5.66 +					     efi_memmap[tables->num_mds],
    5.67 +					     EFI_CONVENTIONAL_MEMORY,
    5.68 +					     EFI_MEMORY_WB, paddr_end, end);
    5.69 +			tables->num_mds++;
    5.70  		} else if (start < paddr_start && end <= paddr_end) {
    5.71 -			MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB, start,
    5.72 -				paddr_start);
    5.73 +			xen_ia64_efi_make_md(&tables->
    5.74 +					     efi_memmap[tables->num_mds],
    5.75 +					     EFI_CONVENTIONAL_MEMORY,
    5.76 +					     EFI_MEMORY_WB, start, paddr_start);
    5.77 +			tables->num_mds++;
    5.78  		} else {
    5.79 -			MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB, start,
    5.80 -				paddr_start);
    5.81 -			MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
    5.82 -				paddr_end, end);
    5.83 +			xen_ia64_efi_make_md(&tables->
    5.84 +					     efi_memmap[tables->num_mds],
    5.85 +					     EFI_CONVENTIONAL_MEMORY,
    5.86 +					     EFI_MEMORY_WB, start, paddr_start);
    5.87 +			tables->num_mds++;
    5.88 +			xen_ia64_efi_make_md(&tables->
    5.89 +					     efi_memmap[tables->num_mds],
    5.90 +					     EFI_CONVENTIONAL_MEMORY,
    5.91 +					     EFI_MEMORY_WB, paddr_end, end);
    5.92 +			tables->num_mds++;
    5.93  		}
    5.94  	}
    5.95  
    5.96  	/* memmap info page. */
    5.97 -	MAKE_MD(EFI_RUNTIME_SERVICES_DATA, EFI_MEMORY_WB, paddr_start,
    5.98 -		paddr_end);
    5.99 +	xen_ia64_efi_make_md(&tables->efi_memmap[tables->num_mds],
   5.100 +			     EFI_RUNTIME_SERVICES_DATA, EFI_MEMORY_WB,
   5.101 +			     paddr_start, paddr_end);
   5.102 +	tables->num_mds++;
   5.103  
   5.104  	/* Create an entry for IO ports.  */
   5.105 -	MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE, EFI_MEMORY_UC,
   5.106 -		IO_PORTS_PADDR, IO_PORTS_PADDR + IO_PORTS_SIZE);
   5.107 +	xen_ia64_efi_make_md(&tables->efi_memmap[tables->num_mds],
   5.108 +			     EFI_MEMORY_MAPPED_IO_PORT_SPACE, EFI_MEMORY_UC,
   5.109 +			     IO_PORTS_PADDR, IO_PORTS_PADDR + IO_PORTS_SIZE);
   5.110 +	tables->num_mds++;
   5.111  
   5.112 -	num_mds = i;
   5.113 -	sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t),
   5.114 +	sort(tables->efi_memmap, tables->num_mds, sizeof(efi_memory_desc_t),
   5.115  	     efi_mdt_cmp, NULL);
   5.116  
   5.117  	xen_ia64_dom_fw_unmap(d, memmap_info);
   5.118 -	return num_mds;
   5.119 +	return tables->num_mds;
   5.120  }
   5.121  
   5.122  /*
     6.1 --- a/xen/arch/ia64/xen/dom_fw_utils.c	Thu May 31 14:47:08 2007 -0600
     6.2 +++ b/xen/arch/ia64/xen/dom_fw_utils.c	Mon Jun 04 13:57:08 2007 -0600
     6.3 @@ -27,6 +27,7 @@
     6.4  #include <asm/fpswa.h>
     6.5  #include <asm/dom_fw.h>
     6.6  #include <asm/dom_fw_common.h>
     6.7 +#include <asm/dom_fw_utils.h>
     6.8  
     6.9  #include <linux/sort.h>
    6.10  
    6.11 @@ -70,6 +71,8 @@ static void dom_fw_domain_init(struct do
    6.12  
    6.13  static int dom_fw_set_convmem_end(struct domain *d)
    6.14  {
    6.15 +	unsigned long gpaddr;
    6.16 +	size_t size;
    6.17  	xen_ia64_memmap_info_t *memmap_info;
    6.18  	efi_memory_desc_t *md;
    6.19  	void *p;
    6.20 @@ -79,27 +82,24 @@ static int dom_fw_set_convmem_end(struct
    6.21  	if (d->shared_info->arch.memmap_info_pfn == 0)
    6.22  		return -EINVAL;
    6.23  
    6.24 -	memmap_info =
    6.25 -	    domain_mpa_to_imva(d,
    6.26 -			       d->shared_info->arch.
    6.27 -			       memmap_info_pfn << PAGE_SHIFT);
    6.28 -	if (memmap_info->efi_memmap_size == 0
    6.29 -	    || memmap_info->efi_memdesc_size != sizeof(*md)
    6.30 -	    || memmap_info->efi_memdesc_version !=
    6.31 -	    EFI_MEMORY_DESCRIPTOR_VERSION)
    6.32 +	gpaddr = d->shared_info->arch.memmap_info_pfn << PAGE_SHIFT;
    6.33 +	size = d->shared_info->arch.memmap_info_num_pages << PAGE_SHIFT;
    6.34 +	memmap_info = _xmalloc(size, __alignof__(*memmap_info));
    6.35 +	if (memmap_info == NULL)
    6.36 +		return -ENOMEM;
    6.37 +	dom_fw_copy_from(memmap_info, d, gpaddr, size);
    6.38 +	if (memmap_info->efi_memmap_size == 0 ||
    6.39 +	    memmap_info->efi_memdesc_size != sizeof(*md) ||
    6.40 +	    memmap_info->efi_memdesc_version != EFI_MEMORY_DESCRIPTOR_VERSION ||
    6.41 +	    sizeof(*memmap_info) + memmap_info->efi_memmap_size > size ||
    6.42 +	    memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size == 0) {
    6.43 +		xfree(memmap_info);
    6.44  		return -EINVAL;
    6.45 -
    6.46 -	/* only 1page case is supported */
    6.47 -	if (d->shared_info->arch.memmap_info_num_pages != 1)
    6.48 -		return -ENOSYS;
    6.49 +	}
    6.50  
    6.51  	memmap_start = &memmap_info->memdesc;
    6.52  	memmap_end = memmap_start + memmap_info->efi_memmap_size;
    6.53  
    6.54 -	/* XXX Currently the table must be in a single page. */
    6.55 -	if ((unsigned long)memmap_end > (unsigned long)memmap_info + PAGE_SIZE)
    6.56 -		return -EINVAL;
    6.57 -
    6.58  	/* sort it bofore use
    6.59  	 * XXX: this is created by user space domain builder so that
    6.60  	 * we should check its integrity */
    6.61 @@ -122,6 +122,9 @@ static int dom_fw_set_convmem_end(struct
    6.62  		    md->num_pages > 0 && d->arch.convmem_end < end)
    6.63  			d->arch.convmem_end = end;
    6.64  	}
    6.65 +
    6.66 +	dom_fw_copy_to(d, gpaddr, memmap_info, size);
    6.67 +	xfree(memmap_info);
    6.68  	return 0;
    6.69  }
    6.70  
    6.71 @@ -135,22 +138,62 @@ assign_new_domain_page_if_dom0(struct do
    6.72  		assign_new_domain0_page(d, mpaddr);
    6.73  }
    6.74  
    6.75 -static void
    6.76 -dom_fw_setup_for_domain_restore(domain_t *d, unsigned long maxmem)
    6.77 +static void dom_fw_setup_for_domain_restore(domain_t * d, unsigned long maxmem)
    6.78  {
    6.79  	assign_new_domain_page(d, FW_HYPERCALL_BASE_PADDR);
    6.80  	dom_fw_domain_init(d, domain_mpa_to_imva(d, FW_TABLES_BASE_PADDR));
    6.81  	d->arch.convmem_end = maxmem;
    6.82  }
    6.83  
    6.84 +/* copy memory range to domain pseudo physical address space */
    6.85 +void
    6.86 +dom_fw_copy_to(struct domain *d, unsigned long dest_gpaddr,
    6.87 +	       void *src, size_t size)
    6.88 +{
    6.89 +	while (size > 0) {
    6.90 +		unsigned long page_offset = dest_gpaddr & ~PAGE_MASK;
    6.91 +		size_t copy_size = size;
    6.92 +		void *dest;
    6.93 +
    6.94 +		if (page_offset + copy_size > PAGE_SIZE)
    6.95 +			copy_size = PAGE_SIZE - page_offset;
    6.96 +		dest = domain_mpa_to_imva(d, dest_gpaddr);
    6.97 +		memcpy(dest, src, copy_size);
    6.98 +
    6.99 +		src += copy_size;
   6.100 +		dest_gpaddr += copy_size;
   6.101 +		size -= copy_size;
   6.102 +	}
   6.103 +}
   6.104 +
   6.105 +/* copy memory range from domain pseudo physical address space */
   6.106 +void
   6.107 +dom_fw_copy_from(void *dest, struct domain *d, unsigned long src_gpaddr,
   6.108 +		 size_t size)
   6.109 +{
   6.110 +	while (size > 0) {
   6.111 +		unsigned long page_offset = src_gpaddr & ~PAGE_MASK;
   6.112 +		size_t copy_size = size;
   6.113 +		void *src;
   6.114 +
   6.115 +		if (page_offset + copy_size > PAGE_SIZE)
   6.116 +			copy_size = PAGE_SIZE - page_offset;
   6.117 +		src = domain_mpa_to_imva(d, src_gpaddr);
   6.118 +		memcpy(dest, src, copy_size);
   6.119 +
   6.120 +		dest += copy_size;
   6.121 +		src_gpaddr += copy_size;
   6.122 +		size -= copy_size;
   6.123 +	}
   6.124 +}
   6.125 +
   6.126  int dom_fw_setup(domain_t * d, unsigned long bp_mpa, unsigned long maxmem)
   6.127  {
   6.128  	int old_domu_builder = 0;
   6.129  	struct xen_ia64_boot_param *bp;
   6.130 -	struct fw_tables *imva_tables_base;
   6.131  
   6.132  	BUILD_BUG_ON(sizeof(struct fw_tables) >
   6.133 -		     (FW_TABLES_END_PADDR - FW_TABLES_BASE_PADDR));
   6.134 +		     (FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR));
   6.135  
   6.136  	if (bp_mpa == 0) {
   6.137  		/* bp_mpa == 0 means this is domain restore case. */
   6.138 @@ -190,10 +233,6 @@ int dom_fw_setup(domain_t * d, unsigned 
   6.139  		}
   6.140  	}
   6.141  
   6.142 -	/* Create page for FW tables.  */
   6.143 -	assign_new_domain_page_if_dom0(d, FW_TABLES_BASE_PADDR);
   6.144 -	imva_tables_base = (struct fw_tables *)domain_mpa_to_imva
   6.145 -	    (d, FW_TABLES_BASE_PADDR);
   6.146  	/* Create page for acpi tables.  */
   6.147  	if (d != dom0 && old_domu_builder) {
   6.148  		struct fake_acpi_tables *imva;
   6.149 @@ -203,20 +242,81 @@ int dom_fw_setup(domain_t * d, unsigned 
   6.150  	if (d == dom0 || old_domu_builder) {
   6.151  		int ret;
   6.152  		unsigned long imva_hypercall_base;
   6.153 +		size_t fw_tables_size;
   6.154 +		struct fw_tables *fw_tables;
   6.155 +		unsigned long gpaddr;
   6.156  
   6.157  		/* Create page for hypercalls.  */
   6.158  		assign_new_domain_page_if_dom0(d, FW_HYPERCALL_BASE_PADDR);
   6.159  		imva_hypercall_base = (unsigned long)domain_mpa_to_imva
   6.160  		    (d, FW_HYPERCALL_BASE_PADDR);
   6.161  
   6.162 +		/* Estimate necessary efi memmap size and allocate memory */
   6.163 +		fw_tables_size = sizeof(*fw_tables) +
   6.164 +			(ia64_boot_param->efi_memmap_size /
   6.165 +			 ia64_boot_param->efi_memdesc_size + NUM_MEM_DESCS) *
   6.166 +			sizeof(fw_tables->efi_memmap[0]);
   6.167 +		if (fw_tables_size <
   6.168 +		    FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR)
   6.169 +			fw_tables_size =
   6.170 +			    FW_TABLES_END_PADDR_MIN - FW_TABLES_BASE_PADDR;
   6.171 +		fw_tables_size = (fw_tables_size + ((1UL << EFI_PAGE_SHIFT) - 1))
   6.172 +			& ~((1UL << EFI_PAGE_SHIFT) - 1);
   6.173 +		fw_tables =
   6.174 +		    (struct fw_tables *)_xmalloc(fw_tables_size,
   6.175 +						 __alignof__(*fw_tables));
   6.176 +		if (fw_tables == NULL) {
   6.177 +			dprintk(XENLOG_INFO,
   6.178 +				"can't allocate fw_tables memory size = %ld\n",
   6.179 +				fw_tables_size);
   6.180 +			return -ENOMEM;
   6.181 +		}
   6.182 +		memset(fw_tables, 0, fw_tables_size);
   6.183 +		BUILD_BUG_ON(FW_END_PADDR_MIN != FW_TABLES_END_PADDR_MIN);
   6.184 +		fw_tables->fw_tables_size = fw_tables_size;
   6.185 +		fw_tables->fw_end_paddr = FW_TABLES_BASE_PADDR + fw_tables_size;
   6.186 +		fw_tables->fw_tables_end_paddr =
   6.187 +			FW_TABLES_BASE_PADDR + fw_tables_size;
   6.188 +		fw_tables->num_mds = 0;
   6.189 +
   6.190 +		/* It is necessary to allocate pages before dom_fw_init()
   6.191 +		 * dom_fw_init() uses up page to d->max_pages.
   6.192 +		 */
   6.193 +		for (gpaddr = FW_TABLES_BASE_PADDR;
   6.194 +		     gpaddr < fw_tables->fw_end_paddr; gpaddr += PAGE_SIZE)
   6.195 +			assign_new_domain_page_if_dom0(d, gpaddr);
   6.196 +
   6.197  		ret = dom_fw_init(d, d->arch.breakimm, bp,
   6.198 -				  imva_tables_base, imva_hypercall_base,
   6.199 -				  maxmem);
   6.200 -		if (ret < 0)
   6.201 +				  fw_tables, imva_hypercall_base, maxmem);
   6.202 +		if (ret < 0) {
   6.203 +			xfree(fw_tables);
   6.204  			return ret;
   6.205 +		}
   6.206 +		if (sizeof(*fw_tables) +
   6.207 +		    fw_tables->num_mds * sizeof(fw_tables->efi_memmap[0]) >
   6.208 +		    fw_tables_size) {
   6.209 +			panic("EFI memmap too large. Increase NUM_MEM_DESCS.\n"
   6.210 +			      "fw_table_size %ld > %ld num_mds %ld "
   6.211 +			      "NUM_MEM_DESCS %d.\n",
   6.212 +			      fw_tables_size, fw_tables->fw_tables_size,
   6.213 +			      fw_tables->num_mds, NUM_MEM_DESCS);
   6.214 +		}
   6.215 +		fw_tables_size = sizeof(*fw_tables) +
   6.216 +			fw_tables->num_mds * sizeof(fw_tables->efi_memmap[0]);
   6.217 +
   6.218 +		/* clear domain builder internal use member */
   6.219 +		fw_tables->fw_tables_size = 0;
   6.220 +		fw_tables->fw_end_paddr = 0;
   6.221 +		fw_tables->fw_tables_end_paddr = 0;
   6.222 +		fw_tables->num_mds = 0;
   6.223 +
   6.224 +		/* copy fw_tables into domain pseudo physical address space */
   6.225 +		dom_fw_copy_to(d, FW_TABLES_BASE_PADDR, fw_tables,
   6.226 +			       fw_tables_size);
   6.227 +		xfree(fw_tables);
   6.228  	}
   6.229  
   6.230 -	dom_fw_domain_init(d, imva_tables_base);
   6.231 +	dom_fw_domain_init(d, domain_mpa_to_imva(d, FW_TABLES_BASE_PADDR));
   6.232  	return dom_fw_set_convmem_end(d);
   6.233  }
   6.234  
     7.1 --- a/xen/include/asm-ia64/dom_fw.h	Thu May 31 14:47:08 2007 -0600
     7.2 +++ b/xen/include/asm-ia64/dom_fw.h	Mon Jun 04 13:57:08 2007 -0600
     7.3 @@ -8,7 +8,8 @@
     7.4  /* Portion of guest physical memory space reserved for PAL/SAL/EFI/ACPI
     7.5     data and code.  */
     7.6  #define FW_BASE_PADDR		0x0000UL
     7.7 -#define FW_END_PADDR		0x3000UL
     7.8 +/* It is assumed that FW_END_PADDR_MIN = FW_TABLES_END_PADDR_MIN */
     7.9 +#define FW_END_PADDR_MIN	0x3000UL
    7.10  
    7.11  /* This is used to determined the portion of a domain's metaphysical memory
    7.12     space reserved for the hypercall patch table. */
    7.13 @@ -29,7 +30,7 @@
    7.14  
    7.15  /* Base and end guest physical address of EFI and SAL (non-ACPI) tables.  */
    7.16  #define FW_TABLES_BASE_PADDR	0x2000UL
    7.17 -#define FW_TABLES_END_PADDR	0x3000UL
    7.18 +#define FW_TABLES_END_PADDR_MIN	0x3000UL
    7.19  
    7.20  
    7.21  /* Hypercalls number have a low part and a high part.
     8.1 --- a/xen/include/asm-ia64/dom_fw_common.h	Thu May 31 14:47:08 2007 -0600
     8.2 +++ b/xen/include/asm-ia64/dom_fw_common.h	Mon Jun 04 13:57:08 2007 -0600
     8.3 @@ -64,16 +64,26 @@ struct fw_tables {
     8.4      /* End of SAL descriptors.  Do not forget to update checkum bound.  */
     8.5  
     8.6      fpswa_interface_t                   fpswa_inf;
     8.7 -    efi_memory_desc_t                   efi_memmap[NUM_MEM_DESCS];
     8.8      unsigned long                       func_ptrs[2*NFUNCPTRS];
     8.9      struct xen_sal_data                 sal_data;
    8.10      unsigned char                       fw_vendor[sizeof(FW_VENDOR)];
    8.11 +
    8.12 +    /*
    8.13 +     * These four member for domain builder internal use at virtualized
    8.14 +     * efi memmap creation. They should be zero-cleared after use.
    8.15 +     */
    8.16 +    unsigned long                       fw_tables_size;
    8.17 +    unsigned long                       fw_end_paddr;   
    8.18 +    unsigned long                       fw_tables_end_paddr;
    8.19 +    unsigned long                       num_mds;
    8.20 +
    8.21 +    efi_memory_desc_t                   efi_memmap[0];
    8.22  };
    8.23  #define FW_FIELD_MPA(field)                                     \
    8.24      FW_TABLES_BASE_PADDR + offsetof(struct fw_tables, field)
    8.25  
    8.26  void
    8.27 -xen_ia64_efi_make_md(struct fw_tables *tables, int *index,
    8.28 +xen_ia64_efi_make_md(efi_memory_desc_t *md,
    8.29                       uint32_t type, uint64_t attr, 
    8.30                       uint64_t start, uint64_t end);
    8.31  uint8_t generate_acpi_checksum(void *tbl, unsigned long len);
     9.1 --- a/xen/include/asm-ia64/dom_fw_dom0.h	Thu May 31 14:47:08 2007 -0600
     9.2 +++ b/xen/include/asm-ia64/dom_fw_dom0.h	Mon Jun 04 13:57:08 2007 -0600
     9.3 @@ -25,11 +25,7 @@ struct fw_tables;
     9.4  struct domain;
     9.5  
     9.6  void efi_systable_init_dom0(struct fw_tables *tables);
     9.7 -int
     9.8 -complete_dom0_memmap(struct domain *d,
     9.9 -                     struct fw_tables *tables,
    9.10 -                     unsigned long maxmem,
    9.11 -                     int num_mds);
    9.12 +int complete_dom0_memmap(struct domain *d, struct fw_tables *tables);
    9.13  
    9.14  #endif /* __ASM_IA64_DOM_FW_DOM0_H__ */
    9.15  /*
    10.1 --- a/xen/include/asm-ia64/dom_fw_domu.h	Thu May 31 14:47:08 2007 -0600
    10.2 +++ b/xen/include/asm-ia64/dom_fw_domu.h	Mon Jun 04 13:57:08 2007 -0600
    10.3 @@ -29,9 +29,9 @@ int
    10.4  complete_domu_memmap(domain_t *d,
    10.5                       struct fw_tables *tables,
    10.6                       unsigned long maxmem,
    10.7 -                     int num_mds,
    10.8                       unsigned long memmap_info_pfn,
    10.9                       unsigned long reserved_size);
   10.10 +
   10.11  #endif /* __ASM_IA64_DOM_FW_DOMU_H__ */
   10.12  /*
   10.13   * Local variables:
    11.1 --- a/xen/include/asm-ia64/dom_fw_utils.h	Thu May 31 14:47:08 2007 -0600
    11.2 +++ b/xen/include/asm-ia64/dom_fw_utils.h	Mon Jun 04 13:57:08 2007 -0600
    11.3 @@ -26,6 +26,10 @@ int xen_ia64_fpswa_revision(struct domai
    11.4  int xen_ia64_is_vcpu_allocated(struct domain *d, uint32_t vcpu); 
    11.5  int xen_ia64_is_running_on_sim(struct domain *unused);
    11.6  int xen_ia64_is_dom0(struct domain *d);
    11.7 +void dom_fw_copy_to(struct domain *d, unsigned long dest_gpaddr,
    11.8 +                    void *src, size_t size); 
    11.9 +void dom_fw_copy_from(void* dest, struct domain *d, unsigned long src_gpaddr,
   11.10 +                      size_t size); 
   11.11  
   11.12  #endif /* __ASM_XEN_IA64_DOM_FW_UTILS_H__ */
   11.13