ia64/xen-unstable

changeset 15121:8dbc11034f82

[IA64] memmap: split dom_fw_common.c

Split into dom0 builder, domu builder and utility functions.
Introduce wrapper functions which hide xen internal implementations

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Alex Williamson <alex.williamson@hp.com>
date Mon May 21 13:50:05 2007 -0600 (2007-05-21)
parents 35530f81e638
children 2fb4ab0c174a
files 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_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/xen/arch/ia64/xen/dom_fw_common.c	Mon May 21 13:16:01 2007 -0600
     1.2 +++ b/xen/arch/ia64/xen/dom_fw_common.c	Mon May 21 13:50:05 2007 -0600
     1.3 @@ -9,40 +9,48 @@
     1.4   *                    dom0 vp model support
     1.5   */
     1.6  
     1.7 -#include <xen/config.h>
     1.8 +#ifdef __XEN__
     1.9  #include <asm/system.h>
    1.10 -#include <asm/pgalloc.h>
    1.11 +#include <asm/dom_fw_dom0.h>
    1.12 +#include <asm/dom_fw_utils.h>
    1.13 +#else
    1.14 +#include <string.h>
    1.15 +#include <stdio.h>
    1.16 +#include <stdlib.h>
    1.17 +#include <assert.h>
    1.18 +#include <inttypes.h>
    1.19  
    1.20 -#include <linux/efi.h>
    1.21 -#include <linux/sort.h>
    1.22 -#include <asm/io.h>
    1.23 -#include <asm/pal.h>
    1.24 -#include <asm/sal.h>
    1.25 -#include <asm/meminit.h>
    1.26 -#include <asm/fpswa.h>
    1.27 -#include <xen/version.h>
    1.28 -#include <xen/acpi.h>
    1.29 -#include <xen/errno.h>
    1.30 -
    1.31 -#include <asm/dom_fw.h>
    1.32 +#include <xen/arch-ia64.h>
    1.33  #include <asm/bundle.h>
    1.34  
    1.35 -#define ONE_MB (1UL << 20)
    1.36 +#include "xg_private.h"
    1.37 +#include "xc_dom.h"
    1.38 +#include "ia64/xc_dom_ia64_util.h"
    1.39  
    1.40 -extern unsigned long running_on_sim;
    1.41 +#define ia64_fc(addr)   asm volatile ("fc %0" :: "r"(addr) : "memory")
    1.42 +#endif /* __XEN__ */
    1.43  
    1.44 -#define FW_VENDOR "X\0e\0n\0/\0i\0a\0\066\0\064\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    1.45 +#include <xen/acpi.h>
    1.46 +#include <asm/dom_fw.h>
    1.47 +#include <asm/dom_fw_domu.h>
    1.48  
    1.49 -#define MAKE_MD(typ, attr, start, end) 					\
    1.50 -	do {								\
    1.51 -		md = tables->efi_memmap + i++;				\
    1.52 -		md->type = typ;						\
    1.53 -		md->pad = 0;						\
    1.54 -		md->phys_addr = start;					\
    1.55 -		md->virt_addr = 0;					\
    1.56 -		md->num_pages = (end - start) >> EFI_PAGE_SHIFT;	\
    1.57 -		md->attribute = attr;					\
    1.58 -	} while (0)
    1.59 +void
    1.60 +xen_ia64_efi_make_md(struct fw_tables *tables, int *index,
    1.61 +		     uint32_t type, uint64_t attr, 
    1.62 +		     uint64_t start, uint64_t end)
    1.63 +{
    1.64 +	efi_memory_desc_t *md = &tables->efi_memmap[*index];
    1.65 +	md->type = type;
    1.66 +	md->pad = 0;
    1.67 +	md->phys_addr = start;
    1.68 +	md->virt_addr = 0;
    1.69 +	md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
    1.70 +	md->attribute = attr;
    1.71 +
    1.72 +	(*index)++;
    1.73 +}
    1.74 +#define MAKE_MD(typ, attr, start, end) \
    1.75 +	xen_ia64_efi_make_md((tables), &(i), (typ), (attr), (start), (end))
    1.76  
    1.77  #define EFI_HYPERCALL_PATCH(tgt, call)					\
    1.78  	do {								\
    1.79 @@ -57,22 +65,12 @@ extern unsigned long running_on_sim;
    1.80  		tables->func_ptrs[pfn++] = 0;                     	\
    1.81  	} while (0)
    1.82  
    1.83 -/* allocate a page for fw
    1.84 - * guest_setup() @ libxc/xc_linux_build.c does for domU
    1.85 - */
    1.86 -static inline void
    1.87 -assign_new_domain_page_if_dom0(struct domain *d, unsigned long mpaddr)
    1.88 -{
    1.89 -        if (d == dom0)
    1.90 -            assign_new_domain0_page(d, mpaddr);
    1.91 -}
    1.92 -
    1.93  /**************************************************************************
    1.94  Hypercall bundle creation
    1.95  **************************************************************************/
    1.96  
    1.97  static void
    1.98 -build_hypercall_bundle(u64 *imva, u64 brkimm, u64 hypnum, u64 ret)
    1.99 +build_hypercall_bundle(uint64_t *imva, uint64_t brkimm, uint64_t hypnum, uint64_t ret)
   1.100  {
   1.101  	INST64_A5 slot0;
   1.102  	INST64_I19 slot1;
   1.103 @@ -110,7 +108,7 @@ build_hypercall_bundle(u64 *imva, u64 br
   1.104  }
   1.105  
   1.106  static void
   1.107 -build_pal_hypercall_bundles(u64 *imva, u64 brkimm, u64 hypnum)
   1.108 +build_pal_hypercall_bundles(uint64_t *imva, uint64_t brkimm, uint64_t hypnum)
   1.109  {
   1.110  	extern unsigned long pal_call_stub[];
   1.111  	IA64_BUNDLE bundle;
   1.112 @@ -148,7 +146,7 @@ build_pal_hypercall_bundles(u64 *imva, u
   1.113  
   1.114  // builds a hypercall bundle at domain physical address
   1.115  static void
   1.116 -dom_fpswa_hypercall_patch(u64 brkimm, unsigned long imva)
   1.117 +dom_fpswa_hypercall_patch(uint64_t brkimm, unsigned long imva)
   1.118  {
   1.119  	unsigned long *entry_imva, *patch_imva;
   1.120  	const unsigned long entry_paddr = FW_HYPERCALL_FPSWA_ENTRY_PADDR;
   1.121 @@ -168,27 +166,27 @@ dom_fpswa_hypercall_patch(u64 brkimm, un
   1.122  
   1.123  // builds a hypercall bundle at domain physical address
   1.124  static void
   1.125 -dom_efi_hypercall_patch(u64 brkimm, unsigned long paddr,
   1.126 +dom_efi_hypercall_patch(uint64_t brkimm, unsigned long paddr,
   1.127                          unsigned long hypercall, unsigned long imva)
   1.128  {
   1.129 -	build_hypercall_bundle((u64 *)(imva + paddr - FW_HYPERCALL_BASE_PADDR),
   1.130 +	build_hypercall_bundle((uint64_t *)(imva + paddr - FW_HYPERCALL_BASE_PADDR),
   1.131  	                       brkimm, hypercall, 1);
   1.132  }
   1.133  
   1.134  // builds a hypercall bundle at domain physical address
   1.135  static void
   1.136 -dom_fw_hypercall_patch(u64 brkimm, unsigned long paddr,
   1.137 +dom_fw_hypercall_patch(uint64_t brkimm, unsigned long paddr,
   1.138  		       unsigned long hypercall,unsigned long ret,
   1.139                         unsigned long imva)
   1.140  {
   1.141 -	build_hypercall_bundle((u64 *)(imva + paddr - FW_HYPERCALL_BASE_PADDR),
   1.142 +	build_hypercall_bundle((uint64_t *)(imva + paddr - FW_HYPERCALL_BASE_PADDR),
   1.143  	                       brkimm, hypercall, ret);
   1.144  }
   1.145  
   1.146  static void
   1.147 -dom_fw_pal_hypercall_patch(u64 brkimm, unsigned long paddr, unsigned long imva)
   1.148 +dom_fw_pal_hypercall_patch(uint64_t brkimm, unsigned long paddr, unsigned long imva)
   1.149  {
   1.150 -	build_pal_hypercall_bundles((u64*)(imva + paddr -
   1.151 +	build_pal_hypercall_bundles((uint64_t*)(imva + paddr -
   1.152  	                            FW_HYPERCALL_BASE_PADDR),
   1.153  	                            brkimm, FW_HYPERCALL_PAL_CALL);
   1.154  }
   1.155 @@ -196,7 +194,7 @@ dom_fw_pal_hypercall_patch(u64 brkimm, u
   1.156  static inline void
   1.157  print_md(efi_memory_desc_t *md)
   1.158  {
   1.159 -	u64 size;
   1.160 +	uint64_t size;
   1.161  	
   1.162  	printk(XENLOG_INFO "dom mem: type=%2u, attr=0x%016lx, "
   1.163  	       "range=[0x%016lx-0x%016lx) ",
   1.164 @@ -210,41 +208,10 @@ print_md(efi_memory_desc_t *md)
   1.165  		printk("(%luKB)\n", size >> 10);
   1.166  }
   1.167  
   1.168 -static u32 lsapic_nbr;
   1.169 -
   1.170 -/* Modify lsapic table.  Provides LPs.  */
   1.171 -static int 
   1.172 -acpi_update_lsapic (acpi_table_entry_header *header, const unsigned long end)
   1.173 -{
   1.174 -	struct acpi_table_lsapic *lsapic;
   1.175 -	int enable;
   1.176 -
   1.177 -	lsapic = (struct acpi_table_lsapic *) header;
   1.178 -	if (!lsapic)
   1.179 -		return -EINVAL;
   1.180 -
   1.181 -	if (lsapic_nbr < MAX_VIRT_CPUS && dom0->vcpu[lsapic_nbr] != NULL)
   1.182 -		enable = 1;
   1.183 -	else
   1.184 -		enable = 0;
   1.185 -	if (lsapic->flags.enabled && enable) {
   1.186 -		printk("enable lsapic entry: 0x%lx\n", (u64)lsapic);
   1.187 -		lsapic->id = lsapic_nbr;
   1.188 -		lsapic->eid = 0;
   1.189 -		lsapic_nbr++;
   1.190 -	} else if (lsapic->flags.enabled) {
   1.191 -		printk("DISABLE lsapic entry: 0x%lx\n", (u64)lsapic);
   1.192 -		lsapic->flags.enabled = 0;
   1.193 -		lsapic->id = 0;
   1.194 -		lsapic->eid = 0;
   1.195 -	}
   1.196 -	return 0;
   1.197 -}
   1.198 -
   1.199 -static u8
   1.200 +uint8_t
   1.201  generate_acpi_checksum(void *tbl, unsigned long len)
   1.202  {
   1.203 -	u8 *ptr, sum = 0;
   1.204 +	uint8_t *ptr, sum = 0;
   1.205  
   1.206  	for (ptr = tbl; len > 0 ; len--, ptr++)
   1.207  		sum += *ptr;
   1.208 @@ -252,73 +219,26 @@ generate_acpi_checksum(void *tbl, unsign
   1.209  	return 0 - sum;
   1.210  }
   1.211  
   1.212 -static int __init
   1.213 -acpi_patch_plat_int_src (
   1.214 -	acpi_table_entry_header *header, const unsigned long end)
   1.215 -{
   1.216 -	struct acpi_table_plat_int_src *plintsrc;
   1.217 -
   1.218 -	plintsrc = (struct acpi_table_plat_int_src *)header;
   1.219 -	if (!plintsrc)
   1.220 -		return -EINVAL;
   1.221 -
   1.222 -	if (plintsrc->type == ACPI_INTERRUPT_CPEI) {
   1.223 -		printk("ACPI_INTERRUPT_CPEI disabled for Domain0\n");
   1.224 -		plintsrc->type = -1;
   1.225 -	}
   1.226 -	return 0;
   1.227 -}
   1.228 -
   1.229 -static int
   1.230 -acpi_update_madt_checksum (unsigned long phys_addr, unsigned long size)
   1.231 -{
   1.232 -	struct acpi_table_madt* acpi_madt;
   1.233 -
   1.234 -	if (!phys_addr || !size)
   1.235 -		return -EINVAL;
   1.236 -
   1.237 -	acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
   1.238 -	acpi_madt->header.checksum = 0;
   1.239 -	acpi_madt->header.checksum = generate_acpi_checksum(acpi_madt, size);
   1.240 -
   1.241 -	return 0;
   1.242 -}
   1.243 -
   1.244 -/* base is physical address of acpi table */
   1.245 -static void touch_acpi_table(void)
   1.246 -{
   1.247 -	lsapic_nbr = 0;
   1.248 -	if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_update_lsapic, 0) < 0)
   1.249 -		printk("Error parsing MADT - no LAPIC entries\n");
   1.250 -	if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC,
   1.251 -	                          acpi_patch_plat_int_src, 0) < 0)
   1.252 -		printk("Error parsing MADT - no PLAT_INT_SRC entries\n");
   1.253 -
   1.254 -	acpi_table_parse(ACPI_APIC, acpi_update_madt_checksum);
   1.255 -
   1.256 -	return;
   1.257 -}
   1.258 -
   1.259  struct fake_acpi_tables {
   1.260  	struct acpi20_table_rsdp rsdp;
   1.261  	struct xsdt_descriptor_rev2 xsdt;
   1.262 -	u64 madt_ptr;
   1.263 +	uint64_t madt_ptr;
   1.264  	struct fadt_descriptor_rev2 fadt;
   1.265  	struct facs_descriptor_rev2 facs;
   1.266  	struct acpi_table_header dsdt;
   1.267 -	u8 aml[8 + 11 * MAX_VIRT_CPUS];
   1.268 +	uint8_t aml[8 + 11 * MAX_VIRT_CPUS];
   1.269  	struct acpi_table_madt madt;
   1.270  	struct acpi_table_lsapic lsapic[MAX_VIRT_CPUS];
   1.271 -	u8 pm1a_evt_blk[4];
   1.272 -	u8 pm1a_cnt_blk[1];
   1.273 -	u8 pm_tmr_blk[4];
   1.274 +	uint8_t pm1a_evt_blk[4];
   1.275 +	uint8_t pm1a_cnt_blk[1];
   1.276 +	uint8_t pm_tmr_blk[4];
   1.277  };
   1.278 -#define ACPI_TABLE_MPA(field) \
   1.279 -  FW_ACPI_BASE_PADDR + offsetof(struct fake_acpi_tables, field);
   1.280 +#define ACPI_TABLE_MPA(field)                                       \
   1.281 +    FW_ACPI_BASE_PADDR + offsetof(struct fake_acpi_tables, field);
   1.282  
   1.283  /* Create enough of an ACPI structure to make the guest OS ACPI happy. */
   1.284 -static void
   1.285 -dom_fw_fake_acpi(struct domain *d, struct fake_acpi_tables *tables)
   1.286 +void
   1.287 +dom_fw_fake_acpi(domain_t *d, struct fake_acpi_tables *tables)
   1.288  {
   1.289  	struct acpi20_table_rsdp *rsdp = &tables->rsdp;
   1.290  	struct xsdt_descriptor_rev2 *xsdt = &tables->xsdt;
   1.291 @@ -331,18 +251,20 @@ dom_fw_fake_acpi(struct domain *d, struc
   1.292  	int aml_len;
   1.293  	int nbr_cpus;
   1.294  
   1.295 +	BUILD_BUG_ON(sizeof(struct fake_acpi_tables) >
   1.296 +	             (FW_ACPI_END_PADDR - FW_ACPI_BASE_PADDR));
   1.297 +
   1.298  	memset(tables, 0, sizeof(struct fake_acpi_tables));
   1.299  
   1.300  	/* setup XSDT (64bit version of RSDT) */
   1.301  	memcpy(xsdt->signature, XSDT_SIG, sizeof(xsdt->signature));
   1.302  	/* XSDT points to both the FADT and the MADT, so add one entry */
   1.303 -	xsdt->length = sizeof(struct xsdt_descriptor_rev2) + sizeof(u64);
   1.304 +	xsdt->length = sizeof(struct xsdt_descriptor_rev2) + sizeof(uint64_t);
   1.305  	xsdt->revision = 1;
   1.306  	memcpy(xsdt->oem_id, "XEN", 3);
   1.307  	memcpy(xsdt->oem_table_id, "Xen/ia64", 8);
   1.308  	memcpy(xsdt->asl_compiler_id, "XEN", 3);
   1.309 -	xsdt->asl_compiler_revision = (xen_major_version() << 16) |
   1.310 -		xen_minor_version();
   1.311 +	xsdt->asl_compiler_revision = xen_ia64_version(d);
   1.312  
   1.313  	xsdt->table_offset_entry[0] = ACPI_TABLE_MPA(fadt);
   1.314  	tables->madt_ptr = ACPI_TABLE_MPA(madt);
   1.315 @@ -356,8 +278,7 @@ dom_fw_fake_acpi(struct domain *d, struc
   1.316  	memcpy(fadt->oem_id, "XEN", 3);
   1.317  	memcpy(fadt->oem_table_id, "Xen/ia64", 8);
   1.318  	memcpy(fadt->asl_compiler_id, "XEN", 3);
   1.319 -	fadt->asl_compiler_revision = (xen_major_version() << 16) |
   1.320 -		xen_minor_version();
   1.321 +	fadt->asl_compiler_revision = xen_ia64_version(d);
   1.322  
   1.323  	memcpy(facs->signature, FACS_SIG, sizeof(facs->signature));
   1.324  	facs->version = 1;
   1.325 @@ -403,8 +324,7 @@ dom_fw_fake_acpi(struct domain *d, struc
   1.326  	memcpy(dsdt->oem_id, "XEN", 3);
   1.327  	memcpy(dsdt->oem_table_id, "Xen/ia64", 8);
   1.328  	memcpy(dsdt->asl_compiler_id, "XEN", 3);
   1.329 -	dsdt->asl_compiler_revision = (xen_major_version() << 16) |
   1.330 -		xen_minor_version();
   1.331 +	dsdt->asl_compiler_revision = xen_ia64_version(d);
   1.332  
   1.333  	/* Trivial namespace, avoids ACPI CA complaints */
   1.334  	tables->aml[0] = 0x10; /* Scope */
   1.335 @@ -443,8 +363,7 @@ dom_fw_fake_acpi(struct domain *d, struc
   1.336  	memcpy(madt->header.oem_id, "XEN", 3);
   1.337  	memcpy(madt->header.oem_table_id, "Xen/ia64", 8);
   1.338  	memcpy(madt->header.asl_compiler_id, "XEN", 3);
   1.339 -	madt->header.asl_compiler_revision = (xen_major_version() << 16) |
   1.340 -		xen_minor_version();
   1.341 +	madt->header.asl_compiler_revision = xen_ia64_version(d);
   1.342  
   1.343  	/* An LSAPIC entry describes a CPU.  */
   1.344  	nbr_cpus = 0;
   1.345 @@ -454,8 +373,7 @@ dom_fw_fake_acpi(struct domain *d, struc
   1.346  		lsapic[i].acpi_id = i;
   1.347  		lsapic[i].id = i;
   1.348  		lsapic[i].eid = 0;
   1.349 -		//XXX replace d->vcpu[i] != NULL with XEN_DOMCTL_getvcpuinfo
   1.350 -		if (d->vcpu[i] != NULL) {
   1.351 +		if (xen_ia64_is_vcpu_allocated(d, i)) {
   1.352  			lsapic[i].flags.enabled = 1;
   1.353  			nbr_cpus++;
   1.354  		}
   1.355 @@ -467,7 +385,7 @@ dom_fw_fake_acpi(struct domain *d, struc
   1.356  	return;
   1.357  }
   1.358  
   1.359 -static int
   1.360 +int
   1.361  efi_mdt_cmp(const void *a, const void *b)
   1.362  {
   1.363  	const efi_memory_desc_t *x = a, *y = b;
   1.364 @@ -486,461 +404,19 @@ efi_mdt_cmp(const void *a, const void *b
   1.365  	return 0;
   1.366  }
   1.367  
   1.368 -#define NFUNCPTRS 16
   1.369 -#define NUM_EFI_SYS_TABLES 6
   1.370 -#define NUM_MEM_DESCS 64 //large enough
   1.371 -
   1.372 -struct fw_tables {
   1.373 -	efi_system_table_t efi_systab;
   1.374 -	efi_runtime_services_t efi_runtime;
   1.375 -	efi_config_table_t efi_tables[NUM_EFI_SYS_TABLES];
   1.376 -
   1.377 -	struct ia64_sal_systab sal_systab;
   1.378 -	struct ia64_sal_desc_entry_point sal_ed;
   1.379 -	struct ia64_sal_desc_ap_wakeup sal_wakeup;
   1.380 -	/* End of SAL descriptors.  Do not forget to update checkum bound.  */
   1.381 -
   1.382 -	fpswa_interface_t fpswa_inf;
   1.383 -	efi_memory_desc_t efi_memmap[NUM_MEM_DESCS];
   1.384 -	unsigned long func_ptrs[2*NFUNCPTRS];
   1.385 - 	struct xen_sal_data sal_data;
   1.386 -	unsigned char fw_vendor[sizeof(FW_VENDOR)];
   1.387 -};
   1.388 -#define FW_FIELD_MPA(field) \
   1.389 -   FW_TABLES_BASE_PADDR + offsetof(struct fw_tables, field)
   1.390 -
   1.391 -static void
   1.392 -efi_systable_init_dom0(struct fw_tables *tables)
   1.393 -{
   1.394 -	int i = 1;
   1.395 -	/* Write messages to the console.  */
   1.396 -	touch_acpi_table();
   1.397 -
   1.398 -	printk("Domain0 EFI passthrough:");
   1.399 -	if (efi.mps) {
   1.400 -		tables->efi_tables[i].guid = MPS_TABLE_GUID;
   1.401 -		tables->efi_tables[i].table = __pa(efi.mps);
   1.402 -		printk(" MPS=0x%lx",tables->efi_tables[i].table);
   1.403 -		i++;
   1.404 -	}
   1.405 -
   1.406 -	if (efi.acpi20) {
   1.407 -		tables->efi_tables[i].guid = ACPI_20_TABLE_GUID;
   1.408 -		tables->efi_tables[i].table = __pa(efi.acpi20);
   1.409 -		printk(" ACPI 2.0=0x%lx",tables->efi_tables[i].table);
   1.410 -		i++;
   1.411 -	}
   1.412 -	if (efi.acpi) {
   1.413 -		tables->efi_tables[i].guid = ACPI_TABLE_GUID;
   1.414 -		tables->efi_tables[i].table = __pa(efi.acpi);
   1.415 -		printk(" ACPI=0x%lx",tables->efi_tables[i].table);
   1.416 -		i++;
   1.417 -	}
   1.418 -	if (efi.smbios) {
   1.419 -		tables->efi_tables[i].guid = SMBIOS_TABLE_GUID;
   1.420 -		tables->efi_tables[i].table = __pa(efi.smbios);
   1.421 -		printk(" SMBIOS=0x%lx",tables->efi_tables[i].table);
   1.422 -		i++;
   1.423 -	}
   1.424 -	if (efi.hcdp) {
   1.425 -		tables->efi_tables[i].guid = HCDP_TABLE_GUID;
   1.426 -		tables->efi_tables[i].table = __pa(efi.hcdp);
   1.427 -		printk(" HCDP=0x%lx",tables->efi_tables[i].table);
   1.428 -		i++;
   1.429 -	}
   1.430 -	printk("\n");
   1.431 -	BUG_ON(i > NUM_EFI_SYS_TABLES);
   1.432 -}
   1.433 -
   1.434 -static void
   1.435 -setup_dom0_memmap_info(struct domain *d, struct fw_tables *tables,
   1.436 -		       int *num_mds)
   1.437 -{
   1.438 -	int i;
   1.439 -	efi_memory_desc_t *md;
   1.440 -	efi_memory_desc_t *last_mem_md = NULL;
   1.441 -	xen_ia64_memmap_info_t* memmap_info;
   1.442 -	unsigned long paddr_start;
   1.443 -	unsigned long paddr_end;
   1.444 -
   1.445 -	for (i = *num_mds - 1; i >= 0; i--) {
   1.446 -		md = &tables->efi_memmap[i];
   1.447 -		if (md->attribute == EFI_MEMORY_WB &&
   1.448 -		    md->type == EFI_CONVENTIONAL_MEMORY &&
   1.449 -		    md->num_pages >
   1.450 -		    2 * (1UL << (PAGE_SHIFT - EFI_PAGE_SHIFT))) {
   1.451 -			last_mem_md = md;
   1.452 -			break;
   1.453 -		}
   1.454 -	}
   1.455 -
   1.456 -	if (last_mem_md == NULL) {
   1.457 -		printk("%s: warning: "
   1.458 -		       "no dom0 contiguous memory to hold memory map\n",
   1.459 -		       __func__);
   1.460 -		return;
   1.461 -	}
   1.462 -	paddr_end = last_mem_md->phys_addr +
   1.463 -		(last_mem_md->num_pages << EFI_PAGE_SHIFT);
   1.464 -	paddr_start = (paddr_end - PAGE_SIZE) & PAGE_MASK;
   1.465 -	last_mem_md->num_pages -=
   1.466 -		(paddr_end - paddr_start) / (1UL << EFI_PAGE_SHIFT);
   1.467 -
   1.468 -	md = &tables->efi_memmap[*num_mds];
   1.469 -	(*num_mds)++;
   1.470 -	md->type = EFI_RUNTIME_SERVICES_DATA;
   1.471 -	md->phys_addr = paddr_start;
   1.472 -	md->virt_addr = 0;
   1.473 -	md->num_pages = 1UL << (PAGE_SHIFT - EFI_PAGE_SHIFT);
   1.474 -	md->attribute = EFI_MEMORY_WB;
   1.475 -
   1.476 -	memmap_info = domain_mpa_to_imva(d, md->phys_addr);
   1.477 -	BUG_ON(*num_mds > NUM_MEM_DESCS);
   1.478 -
   1.479 -	memmap_info->efi_memdesc_size = sizeof(md[0]);
   1.480 -	memmap_info->efi_memdesc_version = EFI_MEMORY_DESCRIPTOR_VERSION;
   1.481 -	memmap_info->efi_memmap_size = *num_mds * sizeof(md[0]);
   1.482 -	memcpy(&memmap_info->memdesc, &tables->efi_memmap[0],
   1.483 -	       memmap_info->efi_memmap_size);
   1.484 -	d->shared_info->arch.memmap_info_num_pages = 1;
   1.485 -	d->shared_info->arch.memmap_info_pfn = md->phys_addr >> PAGE_SHIFT;
   1.486 -
   1.487 -	sort(tables->efi_memmap, *num_mds, sizeof(efi_memory_desc_t),
   1.488 -	     efi_mdt_cmp, NULL);
   1.489 -}
   1.490 -
   1.491 -/* Complete the dom0 memmap.  */
   1.492 -static int
   1.493 -complete_dom0_memmap(struct domain *d,
   1.494 -                     struct fw_tables *tables,
   1.495 -                     unsigned long maxmem,
   1.496 -                     int num_mds)
   1.497 -{
   1.498 -	efi_memory_desc_t *md;
   1.499 -	u64 addr;
   1.500 -	void *efi_map_start, *efi_map_end, *p;
   1.501 -	u64 efi_desc_size;
   1.502 -	int i;
   1.503 -	unsigned long dom_mem = maxmem - (d->tot_pages << PAGE_SHIFT);
   1.504 -
   1.505 -	/* Walk through all MDT entries.
   1.506 -	   Copy all interesting entries.  */
   1.507 -	efi_map_start = __va(ia64_boot_param->efi_memmap);
   1.508 -	efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
   1.509 -	efi_desc_size = ia64_boot_param->efi_memdesc_size;
   1.510 -
   1.511 -	for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   1.512 -		const efi_memory_desc_t *md = p;
   1.513 -		efi_memory_desc_t *dom_md = &tables->efi_memmap[num_mds];
   1.514 -		u64 start = md->phys_addr;
   1.515 -		u64 size = md->num_pages << EFI_PAGE_SHIFT;
   1.516 -		u64 end = start + size;
   1.517 -		u64 mpaddr;
   1.518 -		unsigned long flags;
   1.519 -
   1.520 -		switch (md->type) {
   1.521 -		case EFI_RUNTIME_SERVICES_CODE:
   1.522 -		case EFI_RUNTIME_SERVICES_DATA:
   1.523 -		case EFI_ACPI_RECLAIM_MEMORY:
   1.524 -		case EFI_ACPI_MEMORY_NVS:
   1.525 -		case EFI_RESERVED_TYPE:
   1.526 -			/*
   1.527 -			 * Map into dom0 - We must respect protection
   1.528 -			 * and cache attributes.  Not all of these pages
   1.529 -			 * are writable!!!
   1.530 -			 */
   1.531 -			flags = ASSIGN_writable;	/* dummy - zero */
   1.532 -			if (md->attribute & EFI_MEMORY_WP)
   1.533 -				flags |= ASSIGN_readonly;
   1.534 -			if ((md->attribute & EFI_MEMORY_UC) &&
   1.535 -			    !(md->attribute & EFI_MEMORY_WB))
   1.536 -				flags |= ASSIGN_nocache;
   1.537 -
   1.538 -			assign_domain_mach_page(d, start, size, flags);
   1.539 -
   1.540 -			/* Fall-through.  */
   1.541 -		case EFI_MEMORY_MAPPED_IO:
   1.542 -			/* Will be mapped with ioremap.  */
   1.543 -			/* Copy descriptor.  */
   1.544 -			*dom_md = *md;
   1.545 -			dom_md->virt_addr = 0;
   1.546 -			num_mds++;
   1.547 -			break;
   1.548 -
   1.549 -		case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
   1.550 -			flags = ASSIGN_writable;	/* dummy - zero */
   1.551 -			if (md->attribute & EFI_MEMORY_UC)
   1.552 -				flags |= ASSIGN_nocache;
   1.553 -
   1.554 -			if (start > 0x1ffffffff0000000UL) {
   1.555 -				mpaddr = 0x4000000000000UL - size;
   1.556 -				printk(XENLOG_INFO "Remapping IO ports from "
   1.557 -				       "%lx to %lx\n", start, mpaddr);
   1.558 -			} else
   1.559 -				mpaddr = start;
   1.560 -
   1.561 -			/* Map into dom0.  */
   1.562 -			assign_domain_mmio_page(d, mpaddr, start, size, flags);
   1.563 -			/* Copy descriptor.  */
   1.564 -			*dom_md = *md;
   1.565 -			dom_md->phys_addr = mpaddr;
   1.566 -			dom_md->virt_addr = 0;
   1.567 -			num_mds++;
   1.568 -			break;
   1.569 -
   1.570 -		case EFI_CONVENTIONAL_MEMORY:
   1.571 -		case EFI_LOADER_CODE:
   1.572 -		case EFI_LOADER_DATA:
   1.573 -		case EFI_BOOT_SERVICES_CODE:
   1.574 -		case EFI_BOOT_SERVICES_DATA:
   1.575 -			if (!(md->attribute & EFI_MEMORY_WB))
   1.576 -				break;
   1.577 -
   1.578 -			start = max(FW_END_PADDR, start);
   1.579 -			end = min(start + dom_mem, end);
   1.580 -			if (end <= start)
   1.581 -				break;
   1.582 -
   1.583 -			dom_md->type = EFI_CONVENTIONAL_MEMORY;
   1.584 -			dom_md->phys_addr = start;
   1.585 -			dom_md->virt_addr = 0;
   1.586 -			dom_md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
   1.587 -			dom_md->attribute = EFI_MEMORY_WB;
   1.588 -			num_mds++;
   1.589 -
   1.590 -			dom_mem -= dom_md->num_pages << EFI_PAGE_SHIFT;
   1.591 -			break;
   1.592 -
   1.593 -		case EFI_UNUSABLE_MEMORY:
   1.594 -		case EFI_PAL_CODE:
   1.595 -			/*
   1.596 -			 * We don't really need these, but holes in the
   1.597 -			 * memory map may cause Linux to assume there are
   1.598 -			 * uncacheable ranges within a granule.
   1.599 -			 */
   1.600 -			dom_md->type = EFI_UNUSABLE_MEMORY;
   1.601 -			dom_md->phys_addr = start;
   1.602 -			dom_md->virt_addr = 0;
   1.603 -			dom_md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
   1.604 -			dom_md->attribute = EFI_MEMORY_WB;
   1.605 -			num_mds++;
   1.606 -			break;
   1.607 -
   1.608 -		default:
   1.609 -			/* Print a warning but continue.  */
   1.610 -			printk("complete_dom0_memmap: warning: "
   1.611 -			       "unhandled MDT entry type %u\n", md->type);
   1.612 -		}
   1.613 -	}
   1.614 -	BUG_ON(num_mds > NUM_MEM_DESCS);
   1.615 -	
   1.616 -	sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t),
   1.617 -	     efi_mdt_cmp, NULL);
   1.618 -
   1.619 -	/* setup_guest() @ libxc/xc_linux_build() arranges memory for domU.
   1.620 -	 * however no one arranges memory for dom0,
   1.621 -	 * instead we allocate pages manually.
   1.622 -	 */
   1.623 -	for (i = 0; i < num_mds; i++) {
   1.624 -		md = &tables->efi_memmap[i];
   1.625 -
   1.626 -		if (md->type == EFI_LOADER_DATA ||
   1.627 -		    md->type == EFI_PAL_CODE ||
   1.628 -		    md->type == EFI_CONVENTIONAL_MEMORY) {
   1.629 -			unsigned long start = md->phys_addr & PAGE_MASK;
   1.630 -			unsigned long end = md->phys_addr +
   1.631 -				(md->num_pages << EFI_PAGE_SHIFT);
   1.632 -
   1.633 -			if (end == start) {
   1.634 -				/* md->num_pages = 0 is allowed. */
   1.635 -				continue;
   1.636 -			}
   1.637 -			
   1.638 -			for (addr = start; addr < end; addr += PAGE_SIZE)
   1.639 -				assign_new_domain0_page(d, addr);
   1.640 -		}
   1.641 -	}
   1.642 -	// Map low-memory holes & unmapped MMIO for legacy drivers
   1.643 -	for (addr = 0; addr < ONE_MB; addr += PAGE_SIZE) {
   1.644 -		if (domain_page_mapped(d, addr))
   1.645 -			continue;
   1.646 -		
   1.647 -		if (efi_mmio(addr, PAGE_SIZE)) {
   1.648 -			unsigned long flags;
   1.649 -			flags = ASSIGN_writable | ASSIGN_nocache;
   1.650 -			assign_domain_mmio_page(d, addr, addr,
   1.651 -						PAGE_SIZE, flags);
   1.652 -		}
   1.653 -	}
   1.654 -	setup_dom0_memmap_info(d, tables, &num_mds);
   1.655 -	return num_mds;
   1.656 -}
   1.657 -	
   1.658 -static void
   1.659 -efi_systable_init_domu(struct fw_tables *tables)
   1.660 -{
   1.661 -	int i = 1;
   1.662 -	printk(XENLOG_GUEST XENLOG_INFO "DomainU EFI build up:");
   1.663 -
   1.664 -	tables->efi_tables[i].guid = ACPI_20_TABLE_GUID;
   1.665 -	tables->efi_tables[i].table = FW_ACPI_BASE_PADDR;
   1.666 -	printk(" ACPI 2.0=0x%lx",tables->efi_tables[i].table);
   1.667 -	i++;
   1.668 -	printk("\n");
   1.669 -	BUG_ON(i > NUM_EFI_SYS_TABLES);
   1.670 -}
   1.671 -
   1.672 -static int
   1.673 -complete_domu_memmap(struct domain *d,
   1.674 -                     struct fw_tables *tables,
   1.675 -                     unsigned long maxmem,
   1.676 -                     int num_mds,
   1.677 -		     unsigned long memmap_info_pfn,
   1.678 -		     unsigned long reserved_size)
   1.679 -{
   1.680 -	efi_memory_desc_t *md;
   1.681 -	int i = num_mds; /* for MAKE_MD */
   1.682 -	int create_memmap = 0;
   1.683 -	xen_ia64_memmap_info_t* memmap_info;
   1.684 -	unsigned long paddr_start;
   1.685 -	unsigned long paddr_end;
   1.686 -	void *p;
   1.687 -	void *memmap_start;
   1.688 -	void *memmap_end;
   1.689 -
   1.690 -	if (memmap_info_pfn == 0 || reserved_size == 0) {
   1.691 -		/* old domain builder which doesn't setup
   1.692 -		 * memory map. create it for compatibility */
   1.693 -		memmap_info_pfn = (maxmem >> PAGE_SHIFT) - 1;
   1.694 -		/* 4 = memmap info page, start info page, xenstore page and
   1.695 -		   console page */
   1.696 -		reserved_size = 4 << PAGE_SHIFT;
   1.697 -		create_memmap = 1;
   1.698 -	}
   1.699 -	paddr_start = memmap_info_pfn << PAGE_SHIFT;
   1.700 -	paddr_end = paddr_start + reserved_size;
   1.701 -	memmap_info = domain_mpa_to_imva(d, paddr_start);//XXX replace this with xc_map_foreign_map_range()
   1.702 -	if (memmap_info->efi_memmap_size == 0) {
   1.703 -		create_memmap = 1;
   1.704 -	} else if (memmap_info->efi_memdesc_size != sizeof(md[0]) ||
   1.705 -		   memmap_info->efi_memdesc_version !=
   1.706 -		   EFI_MEMORY_DESCRIPTOR_VERSION) {
   1.707 -		printk(XENLOG_WARNING
   1.708 -		       "%s: Warning: unknown memory map "
   1.709 -		       "memmap size %"PRIu64" "
   1.710 -		       "memdesc size %"PRIu64" "
   1.711 -		       "version %"PRIu32"\n",
   1.712 -		       __func__,
   1.713 -		       memmap_info->efi_memmap_size,
   1.714 -		       memmap_info->efi_memdesc_size,
   1.715 -		       memmap_info->efi_memdesc_version);
   1.716 -		create_memmap = 1;
   1.717 -	} else if (reserved_size < memmap_info->efi_memmap_size) {
   1.718 -		printk(XENLOG_WARNING
   1.719 -		       "%s: Warning: too short reserved size %"PRIu64"\n",
   1.720 -		       __func__, reserved_size);
   1.721 -		return -EINVAL;
   1.722 -	} else if (memmap_info->efi_memmap_size >
   1.723 -		   PAGE_SIZE - sizeof(*memmap_info)) {
   1.724 -		/*
   1.725 -		 * curently memmap spanning more than single page isn't
   1.726 -		 * supported.
   1.727 -		 */
   1.728 -		printk(XENLOG_WARNING
   1.729 -		       "%s: Warning: too large reserved_size %"PRIu64"\n",
   1.730 -		       __func__, memmap_info->efi_memmap_size);
   1.731 -		return -ENOSYS;
   1.732 -	}
   1.733 -	
   1.734 -	if (create_memmap) {
   1.735 -		/*
   1.736 -		 * old domain builder which doesn't setup
   1.737 -		 * memory map. create it for compatibility
   1.738 -		 */
   1.739 -		memmap_info->efi_memdesc_size = sizeof(md[0]);
   1.740 -		memmap_info->efi_memdesc_version =
   1.741 -			EFI_MEMORY_DESCRIPTOR_VERSION;
   1.742 -		memmap_info->efi_memmap_size = 1 * sizeof(md[0]);
   1.743 -		md = (efi_memory_desc_t*)&memmap_info->memdesc;
   1.744 -		md[num_mds].type = EFI_CONVENTIONAL_MEMORY;
   1.745 -		md[num_mds].pad = 0;
   1.746 -		md[num_mds].phys_addr = 0;
   1.747 -		md[num_mds].virt_addr = 0;
   1.748 -		md[num_mds].num_pages = maxmem >> EFI_PAGE_SHIFT;
   1.749 -		md[num_mds].attribute = EFI_MEMORY_WB;
   1.750 -	}
   1.751 -
   1.752 -	memmap_start = &memmap_info->memdesc;
   1.753 -	memmap_end = memmap_start + memmap_info->efi_memmap_size;
   1.754 -	/* XXX Currently the table must be in a single page. */
   1.755 -	if ((unsigned long)memmap_end > (unsigned long)memmap_info + PAGE_SIZE)
   1.756 -		return -EINVAL;
   1.757 -
   1.758 -	/* sort it bofore use
   1.759 -	 * XXX: this is created by user space domain builder so that
   1.760 -	 * we should check its integrity */
   1.761 -	sort(&memmap_info->memdesc,
   1.762 -	     memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size,
   1.763 -	     memmap_info->efi_memdesc_size,
   1.764 -	     efi_mdt_cmp, NULL);
   1.765 -
   1.766 -	for (p = memmap_start; p < memmap_end; p += memmap_info->efi_memdesc_size) {
   1.767 -		unsigned long start;
   1.768 -		unsigned long end;
   1.769 -		md = p;
   1.770 -		start = md->phys_addr;
   1.771 -		end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
   1.772 -
   1.773 -		if (start < FW_END_PADDR)
   1.774 -			start = FW_END_PADDR;
   1.775 -		if (end <= start)
   1.776 -			continue;
   1.777 -
   1.778 -		/* exclude [paddr_start, paddr_end) */
   1.779 -		if (paddr_end <= start || end <= paddr_start) {
   1.780 -			MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   1.781 -				start, end);
   1.782 -		} else if (paddr_start <= start && paddr_end < end) {
   1.783 -			MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   1.784 -				paddr_end, end);
   1.785 -		} else if (start < paddr_start && end <= paddr_end) {
   1.786 -			MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   1.787 -				start, paddr_start);
   1.788 -		} else {
   1.789 -			MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   1.790 -				start, paddr_start);
   1.791 -			MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   1.792 -				paddr_end, end);
   1.793 -		}
   1.794 -	}
   1.795 -
   1.796 -	/* memmap info page. */
   1.797 -	MAKE_MD(EFI_RUNTIME_SERVICES_DATA, EFI_MEMORY_WB,
   1.798 -		paddr_start, paddr_end);
   1.799 -
   1.800 -	/* Create an entry for IO ports.  */
   1.801 -	MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE, EFI_MEMORY_UC,
   1.802 -		IO_PORTS_PADDR, IO_PORTS_PADDR + IO_PORTS_SIZE);
   1.803 -
   1.804 -	num_mds = i;
   1.805 -	sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t),
   1.806 -	     efi_mdt_cmp, NULL);
   1.807 -	return num_mds;
   1.808 -}
   1.809 -
   1.810 -static int
   1.811 -dom_fw_init(struct domain *d,
   1.812 -	    u64 brkimm,
   1.813 -            struct ia64_boot_param *bp,
   1.814 +int
   1.815 +dom_fw_init(domain_t *d,
   1.816 +	    uint64_t brkimm,
   1.817 +            struct xen_ia64_boot_param *bp,
   1.818              struct fw_tables *tables,
   1.819              unsigned long hypercalls_imva,
   1.820              unsigned long maxmem)
   1.821  {
   1.822 -	efi_memory_desc_t *md;
   1.823  	unsigned long pfn;
   1.824  	unsigned char checksum;
   1.825  	char *cp;
   1.826  	int num_mds, i;
   1.827 +	int fpswa_supported = 0;
   1.828  
   1.829  	memset(tables, 0, sizeof(struct fw_tables));
   1.830  
   1.831 @@ -982,7 +458,7 @@ dom_fw_init(struct domain *d,
   1.832  		tables->efi_tables[i].guid = NULL_GUID;
   1.833  		tables->efi_tables[i].table = 0;
   1.834  	}
   1.835 -	if (d == dom0) {
   1.836 +	if (xen_ia64_is_dom0(d)) {
   1.837  		efi_systable_init_dom0(tables);
   1.838  	} else {
   1.839  		efi_systable_init_domu(tables);
   1.840 @@ -1027,11 +503,11 @@ dom_fw_init(struct domain *d,
   1.841  	                       FW_HYPERCALL_SAL_RETURN, 0, hypercalls_imva);
   1.842  
   1.843  	/* Fill in the FPSWA interface: */
   1.844 -	if (fpswa_interface) {
   1.845 -		tables->fpswa_inf.revision = fpswa_interface->revision;
   1.846 +	if (!xen_ia64_fpswa_revision(d, &tables->fpswa_inf.revision)) {
   1.847 +		fpswa_supported = 1;
   1.848  		dom_fpswa_hypercall_patch(brkimm, hypercalls_imva);
   1.849  		tables->fpswa_inf.fpswa = 
   1.850 -		                       (void *)FW_HYPERCALL_FPSWA_ENTRY_PADDR;
   1.851 +			(void *)FW_HYPERCALL_FPSWA_ENTRY_PADDR;
   1.852  	}
   1.853  
   1.854  	i = 0; /* Used by MAKE_MD */
   1.855 @@ -1046,7 +522,7 @@ dom_fw_init(struct domain *d,
   1.856  	MAKE_MD(EFI_RUNTIME_SERVICES_DATA, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
   1.857  	        FW_TABLES_BASE_PADDR, FW_TABLES_END_PADDR);
   1.858  
   1.859 -	if (d != dom0 || running_on_sim) {
   1.860 +	if (!xen_ia64_is_dom0(d) || xen_ia64_is_running_on_sim(d)) {
   1.861  		/* DomU (or hp-ski).
   1.862  		   Create a continuous memory area.  */
   1.863  		/* kludge: bp->efi_memmap is used to pass memmap_info
   1.864 @@ -1057,8 +533,8 @@ dom_fw_init(struct domain *d,
   1.865  		 * see ia64_setup_memmap() @ xc_dom_boot.c
   1.866  		 */
   1.867  		num_mds = complete_domu_memmap(d, tables, maxmem, i,
   1.868 -					       bp->efi_memmap,
   1.869 -					       bp->efi_memmap_size);
   1.870 +					       XEN_IA64_MEMMAP_INFO_PFN(bp),
   1.871 +					       XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp));
   1.872  	} else {
   1.873  		/* Dom0.
   1.874  		   We must preserve ACPI data from real machine,
   1.875 @@ -1083,151 +559,7 @@ dom_fw_init(struct domain *d,
   1.876  	bp->console_info.num_rows = 25;
   1.877  	bp->console_info.orig_x = 0;
   1.878  	bp->console_info.orig_y = 24;
   1.879 -	if (fpswa_interface)
   1.880 +	if (fpswa_supported)
   1.881  		bp->fpswa = FW_FIELD_MPA(fpswa_inf);
   1.882  	return 0;
   1.883  }
   1.884 -
   1.885 -static void
   1.886 -dom_fw_domain_init(struct domain *d, struct fw_tables *tables)
   1.887 -{
   1.888 -	/* Initialise for EFI_SET_VIRTUAL_ADDRESS_MAP emulation */
   1.889 -	d->arch.efi_runtime = &tables->efi_runtime;
   1.890 -	d->arch.fpswa_inf   = &tables->fpswa_inf;
   1.891 -	d->arch.sal_data    = &tables->sal_data;
   1.892 -}
   1.893 -
   1.894 -static int
   1.895 -dom_fw_set_convmem_end(struct domain *d)
   1.896 -{
   1.897 -	xen_ia64_memmap_info_t* memmap_info;
   1.898 -	efi_memory_desc_t *md;
   1.899 -	void *p;
   1.900 -	void *memmap_start;
   1.901 -	void *memmap_end;
   1.902 -
   1.903 -	if (d->shared_info->arch.memmap_info_pfn == 0)
   1.904 -		return -EINVAL;
   1.905 -
   1.906 -	memmap_info = domain_mpa_to_imva(d, d->shared_info->arch.memmap_info_pfn << PAGE_SHIFT);
   1.907 -	if (memmap_info->efi_memmap_size == 0 ||
   1.908 -	    memmap_info->efi_memdesc_size != sizeof(*md) ||
   1.909 -	    memmap_info->efi_memdesc_version !=
   1.910 -	    EFI_MEMORY_DESCRIPTOR_VERSION)
   1.911 -		return -EINVAL;
   1.912 -	/* only 1page case is supported */
   1.913 -	if (d->shared_info->arch.memmap_info_num_pages != 1)
   1.914 -		return -ENOSYS;
   1.915 -
   1.916 -	memmap_start = &memmap_info->memdesc;
   1.917 -	memmap_end = memmap_start + memmap_info->efi_memmap_size;
   1.918 -
   1.919 -	/* XXX Currently the table must be in a single page. */
   1.920 -	if ((unsigned long)memmap_end > (unsigned long)memmap_info + PAGE_SIZE)
   1.921 -		return -EINVAL;
   1.922 -
   1.923 -	/* sort it bofore use
   1.924 -	 * XXX: this is created by user space domain builder so that
   1.925 -	 * we should check its integrity */
   1.926 -	sort(&memmap_info->memdesc,
   1.927 -	     memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size,
   1.928 -	     memmap_info->efi_memdesc_size,
   1.929 -	     efi_mdt_cmp, NULL);
   1.930 -
   1.931 -	if (d->arch.convmem_end == 0)
   1.932 -		d->arch.convmem_end = d->max_pages << PAGE_SHIFT;
   1.933 -	for (p = memmap_start; p < memmap_end; p += memmap_info->efi_memdesc_size) {
   1.934 -		unsigned long end;
   1.935 -		md = p;
   1.936 -		end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
   1.937 -		if (md->attribute == EFI_MEMORY_WB &&
   1.938 -		    md->type == EFI_CONVENTIONAL_MEMORY &&
   1.939 -		    md->num_pages > 0 &&
   1.940 -		    d->arch.convmem_end < end)
   1.941 -			d->arch.convmem_end = end;
   1.942 -	}
   1.943 -	return 0;
   1.944 -}
   1.945 -
   1.946 -int
   1.947 -dom_fw_setup(struct domain *d, unsigned long bp_mpa, unsigned long maxmem)
   1.948 -{
   1.949 -	int ret = 0;
   1.950 -	struct ia64_boot_param *bp;
   1.951 -	unsigned long imva_tables_base;
   1.952 -	unsigned long imva_hypercall_base;
   1.953 -
   1.954 -	BUILD_BUG_ON(sizeof(struct fw_tables) >
   1.955 -	             (FW_TABLES_END_PADDR - FW_TABLES_BASE_PADDR));
   1.956 -
   1.957 -	BUILD_BUG_ON(sizeof(struct fake_acpi_tables) >
   1.958 -	             (FW_ACPI_END_PADDR - FW_ACPI_BASE_PADDR));
   1.959 -
   1.960 -	/* Create page for hypercalls.  */
   1.961 -	assign_new_domain_page_if_dom0(d, FW_HYPERCALL_BASE_PADDR);
   1.962 -	imva_hypercall_base = (unsigned long)domain_mpa_to_imva
   1.963 -	                                     (d, FW_HYPERCALL_BASE_PADDR);
   1.964 -
   1.965 -	/* Create page for acpi tables.  */
   1.966 -	if (d != dom0) {
   1.967 -		void *imva;
   1.968 -
   1.969 -		assign_new_domain_page_if_dom0(d, FW_ACPI_BASE_PADDR);
   1.970 -		imva = domain_mpa_to_imva (d, FW_ACPI_BASE_PADDR);
   1.971 -		dom_fw_fake_acpi(d, (struct fake_acpi_tables *)imva);
   1.972 -	}
   1.973 -
   1.974 -	/* Create page for FW tables.  */
   1.975 -	assign_new_domain_page_if_dom0(d, FW_TABLES_BASE_PADDR);
   1.976 -	imva_tables_base = (unsigned long)domain_mpa_to_imva
   1.977 -	                                  (d, FW_TABLES_BASE_PADDR);
   1.978 -
   1.979 -	/* Create page for boot_param.  */
   1.980 -	assign_new_domain_page_if_dom0(d, bp_mpa);
   1.981 -	bp = domain_mpa_to_imva(d, bp_mpa);
   1.982 -	if (d != dom0) {
   1.983 -		/*
   1.984 -		 * XXX kludge.
   1.985 -		 * when XEN_DOMCTL_arch_setup is called, shared_info can't
   1.986 -		 * be accessed by libxc so that memmap_info_pfn isn't
   1.987 -		 * initialized. But dom_fw_set_convmem_end() requires it, 
   1.988 -		 * so here we initialize it.
   1.989 -		 * note:dom_fw_init() overwrites memmap_info_num_pages,
   1.990 -		 *      memmap_info_pfns.
   1.991 -		 */
   1.992 -		if ((bp->efi_memmap_size & ~PAGE_MASK) != 0) {
   1.993 -			printk("%s:%d size 0x%lx 0x%lx 0x%lx\n",
   1.994 -			       __func__, __LINE__,
   1.995 -			       bp->efi_memmap_size,
   1.996 -			       bp->efi_memmap_size & ~PAGE_SIZE,
   1.997 -			       ~PAGE_SIZE);
   1.998 -			return -EINVAL;
   1.999 -		}
  1.1000 -		if (bp->efi_memmap_size == 0) {
  1.1001 -			/* old domain builder compatibility */
  1.1002 -			d->shared_info->arch.memmap_info_num_pages = 1;
  1.1003 -			d->shared_info->arch.memmap_info_pfn =
  1.1004 -				(maxmem >> PAGE_SHIFT) - 1;
  1.1005 -		} else {
  1.1006 -			/*
  1.1007 -			 * 3: start info page, xenstore page and console page
  1.1008 -			 */
  1.1009 -			if (bp->efi_memmap_size < 4 * PAGE_SIZE)
  1.1010 -				return -EINVAL;
  1.1011 -			d->shared_info->arch.memmap_info_num_pages =
  1.1012 -				(bp->efi_memmap_size >> PAGE_SHIFT) - 3;
  1.1013 -			d->shared_info->arch.memmap_info_pfn = bp->efi_memmap;
  1.1014 -			/* currently multi page memmap isn't supported */
  1.1015 -			if (d->shared_info->arch.memmap_info_num_pages != 1)
  1.1016 -				return -ENOSYS;
  1.1017 -		}
  1.1018 -	}
  1.1019 -	ret = dom_fw_init(d, d->arch.breakimm, bp,
  1.1020 -			    (struct fw_tables *)imva_tables_base,
  1.1021 -			    imva_hypercall_base, maxmem);
  1.1022 -	if (ret < 0)
  1.1023 -		return ret;
  1.1024 -
  1.1025 -	dom_fw_domain_init(d, (struct fw_tables *)imva_tables_base);
  1.1026 -	return dom_fw_set_convmem_end(d);
  1.1027 -}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xen/arch/ia64/xen/dom_fw_dom0.c	Mon May 21 13:50:05 2007 -0600
     2.3 @@ -0,0 +1,390 @@
     2.4 +/******************************************************************************
     2.5 + *
     2.6 + * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
     2.7 + *                    VA Linux Systems Japan K.K.
     2.8 + *
     2.9 + * This program is free software; you can redistribute it and/or modify
    2.10 + * it under the terms of the GNU General Public License as published by
    2.11 + * the Free Software Foundation; either version 2 of the License, or
    2.12 + * (at your option) any later version.
    2.13 + *
    2.14 + * This program is distributed in the hope that it will be useful,
    2.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    2.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    2.17 + * GNU General Public License for more details.
    2.18 + *
    2.19 + * You should have received a copy of the GNU General Public License
    2.20 + * along with this program; if not, write to the Free Software
    2.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    2.22 + *
    2.23 + */
    2.24 +/*
    2.25 + *  Xen domain firmware emulation support
    2.26 + *  Copyright (C) 2004 Hewlett-Packard Co.
    2.27 + *       Dan Magenheimer (dan.magenheimer@hp.com)
    2.28 + */
    2.29 +
    2.30 +#include <xen/config.h>
    2.31 +#include <xen/acpi.h>
    2.32 +#include <xen/errno.h>
    2.33 +#include <xen/sched.h>
    2.34 +
    2.35 +#include <asm/dom_fw.h>
    2.36 +#include <asm/dom_fw_common.h>
    2.37 +#include <asm/dom_fw_dom0.h>
    2.38 +
    2.39 +#include <linux/sort.h>
    2.40 +
    2.41 +static u32 lsapic_nbr;
    2.42 +
    2.43 +/* Modify lsapic table.  Provides LPs.  */
    2.44 +static int __init
    2.45 +acpi_update_lsapic(acpi_table_entry_header *header, const unsigned long end)
    2.46 +{
    2.47 +    struct acpi_table_lsapic *lsapic;
    2.48 +    int enable;
    2.49 +
    2.50 +    lsapic = (struct acpi_table_lsapic *) header;
    2.51 +    if (!lsapic)
    2.52 +        return -EINVAL;
    2.53 +
    2.54 +    if (lsapic_nbr < MAX_VIRT_CPUS && dom0->vcpu[lsapic_nbr] != NULL)
    2.55 +        enable = 1;
    2.56 +    else
    2.57 +        enable = 0;
    2.58 +    if (lsapic->flags.enabled && enable) {
    2.59 +        printk("enable lsapic entry: 0x%lx\n", (u64)lsapic);
    2.60 +        lsapic->id = lsapic_nbr;
    2.61 +        lsapic->eid = 0;
    2.62 +        lsapic_nbr++;
    2.63 +    } else if (lsapic->flags.enabled) {
    2.64 +        printk("DISABLE lsapic entry: 0x%lx\n", (u64)lsapic);
    2.65 +        lsapic->flags.enabled = 0;
    2.66 +        lsapic->id = 0;
    2.67 +        lsapic->eid = 0;
    2.68 +    }
    2.69 +    return 0;
    2.70 +}
    2.71 +
    2.72 +static int __init
    2.73 +acpi_patch_plat_int_src(acpi_table_entry_header *header,
    2.74 +                        const unsigned long end)
    2.75 +{
    2.76 +    struct acpi_table_plat_int_src *plintsrc;
    2.77 +
    2.78 +    plintsrc = (struct acpi_table_plat_int_src *)header;
    2.79 +    if (!plintsrc)
    2.80 +        return -EINVAL;
    2.81 +
    2.82 +    if (plintsrc->type == ACPI_INTERRUPT_CPEI) {
    2.83 +        printk("ACPI_INTERRUPT_CPEI disabled for Domain0\n");
    2.84 +        plintsrc->type = -1;
    2.85 +    }
    2.86 +    return 0;
    2.87 +}
    2.88 +
    2.89 +static int __init
    2.90 +acpi_update_madt_checksum(unsigned long phys_addr, unsigned long size)
    2.91 +{
    2.92 +    struct acpi_table_madt* acpi_madt;
    2.93 +
    2.94 +    if (!phys_addr || !size)
    2.95 +        return -EINVAL;
    2.96 +
    2.97 +    acpi_madt = (struct acpi_table_madt *) __va(phys_addr);
    2.98 +    acpi_madt->header.checksum = 0;
    2.99 +    acpi_madt->header.checksum = generate_acpi_checksum(acpi_madt, size);
   2.100 +
   2.101 +    return 0;
   2.102 +}
   2.103 +
   2.104 +/* base is physical address of acpi table */
   2.105 +static void __init
   2.106 +touch_acpi_table(void)
   2.107 +{
   2.108 +    lsapic_nbr = 0;
   2.109 +    if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_update_lsapic, 0) < 0)
   2.110 +        printk("Error parsing MADT - no LAPIC entries\n");
   2.111 +    if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC,
   2.112 +                              acpi_patch_plat_int_src, 0) < 0)
   2.113 +        printk("Error parsing MADT - no PLAT_INT_SRC entries\n");
   2.114 +
   2.115 +    acpi_table_parse(ACPI_APIC, acpi_update_madt_checksum);
   2.116 +
   2.117 +    return;
   2.118 +}
   2.119 +
   2.120 +void __init
   2.121 +efi_systable_init_dom0(struct fw_tables *tables)
   2.122 +{
   2.123 +    int i = 1;
   2.124 +    /* Write messages to the console.  */
   2.125 +    touch_acpi_table();
   2.126 +
   2.127 +    printk("Domain0 EFI passthrough:");
   2.128 +    if (efi.mps) {
   2.129 +        tables->efi_tables[i].guid = MPS_TABLE_GUID;
   2.130 +        tables->efi_tables[i].table = __pa(efi.mps);
   2.131 +        printk(" MPS=0x%lx",tables->efi_tables[i].table);
   2.132 +        i++;
   2.133 +    }
   2.134 +    if (efi.acpi20) {
   2.135 +        tables->efi_tables[i].guid = ACPI_20_TABLE_GUID;
   2.136 +        tables->efi_tables[i].table = __pa(efi.acpi20);
   2.137 +        printk(" ACPI 2.0=0x%lx",tables->efi_tables[i].table);
   2.138 +        i++;
   2.139 +    }
   2.140 +    if (efi.acpi) {
   2.141 +        tables->efi_tables[i].guid = ACPI_TABLE_GUID;
   2.142 +        tables->efi_tables[i].table = __pa(efi.acpi);
   2.143 +        printk(" ACPI=0x%lx",tables->efi_tables[i].table);
   2.144 +        i++;
   2.145 +    }
   2.146 +    if (efi.smbios) {
   2.147 +        tables->efi_tables[i].guid = SMBIOS_TABLE_GUID;
   2.148 +        tables->efi_tables[i].table = __pa(efi.smbios);
   2.149 +        printk(" SMBIOS=0x%lx",tables->efi_tables[i].table);
   2.150 +        i++;
   2.151 +    }
   2.152 +    if (efi.hcdp) {
   2.153 +        tables->efi_tables[i].guid = HCDP_TABLE_GUID;
   2.154 +        tables->efi_tables[i].table = __pa(efi.hcdp);
   2.155 +        printk(" HCDP=0x%lx",tables->efi_tables[i].table);
   2.156 +        i++;
   2.157 +    }
   2.158 +    printk("\n");
   2.159 +    BUG_ON(i > NUM_EFI_SYS_TABLES);
   2.160 +}
   2.161 +
   2.162 +static void __init
   2.163 +setup_dom0_memmap_info(struct domain *d, struct fw_tables *tables,
   2.164 +                       int *num_mds)
   2.165 +{
   2.166 +    int i;
   2.167 +    efi_memory_desc_t *md;
   2.168 +    efi_memory_desc_t *last_mem_md = NULL;
   2.169 +    xen_ia64_memmap_info_t* memmap_info;
   2.170 +    unsigned long paddr_start;
   2.171 +    unsigned long paddr_end;
   2.172 +
   2.173 +    for (i = *num_mds - 1; i >= 0; i--) {
   2.174 +        md = &tables->efi_memmap[i];
   2.175 +        if (md->attribute == EFI_MEMORY_WB &&
   2.176 +            md->type == EFI_CONVENTIONAL_MEMORY &&
   2.177 +            md->num_pages > 2 * (1UL << (PAGE_SHIFT - EFI_PAGE_SHIFT))) {
   2.178 +            last_mem_md = md;
   2.179 +            break;
   2.180 +        }
   2.181 +    }
   2.182 +
   2.183 +    if (last_mem_md == NULL) {
   2.184 +        printk("%s: warning: "
   2.185 +               "no dom0 contiguous memory to hold memory map\n",
   2.186 +               __func__);
   2.187 +        return;
   2.188 +    }
   2.189 +    paddr_end = last_mem_md->phys_addr +
   2.190 +        (last_mem_md->num_pages << EFI_PAGE_SHIFT);
   2.191 +    paddr_start = (paddr_end - PAGE_SIZE) & PAGE_MASK;
   2.192 +    last_mem_md->num_pages -=
   2.193 +        (paddr_end - paddr_start) / (1UL << EFI_PAGE_SHIFT);
   2.194 +
   2.195 +    md = &tables->efi_memmap[*num_mds];
   2.196 +    (*num_mds)++;
   2.197 +    md->type = EFI_RUNTIME_SERVICES_DATA;
   2.198 +    md->phys_addr = paddr_start;
   2.199 +    md->virt_addr = 0;
   2.200 +    md->num_pages = 1UL << (PAGE_SHIFT - EFI_PAGE_SHIFT);
   2.201 +    md->attribute = EFI_MEMORY_WB;
   2.202 +
   2.203 +    memmap_info = domain_mpa_to_imva(d, md->phys_addr);
   2.204 +    BUG_ON(*num_mds > NUM_MEM_DESCS);
   2.205 +
   2.206 +    memmap_info->efi_memdesc_size = sizeof(md[0]);
   2.207 +    memmap_info->efi_memdesc_version = EFI_MEMORY_DESCRIPTOR_VERSION;
   2.208 +    memmap_info->efi_memmap_size = *num_mds * sizeof(md[0]);
   2.209 +    memcpy(&memmap_info->memdesc, &tables->efi_memmap[0],
   2.210 +           memmap_info->efi_memmap_size);
   2.211 +    d->shared_info->arch.memmap_info_num_pages = 1;
   2.212 +    d->shared_info->arch.memmap_info_pfn = md->phys_addr >> PAGE_SHIFT;
   2.213 +
   2.214 +    sort(tables->efi_memmap, *num_mds, sizeof(efi_memory_desc_t),
   2.215 +         efi_mdt_cmp, NULL);
   2.216 +}
   2.217 +
   2.218 +/* Complete the dom0 memmap.  */
   2.219 +int __init
   2.220 +complete_dom0_memmap(struct domain *d,
   2.221 +                     struct fw_tables *tables,
   2.222 +                     unsigned long maxmem,
   2.223 +                     int num_mds)
   2.224 +{
   2.225 +    efi_memory_desc_t *md;
   2.226 +    u64 addr;
   2.227 +    void *efi_map_start, *efi_map_end, *p;
   2.228 +    u64 efi_desc_size;
   2.229 +    int i;
   2.230 +    unsigned long dom_mem = maxmem - (d->tot_pages << PAGE_SHIFT);
   2.231 +
   2.232 +    /* Walk through all MDT entries.
   2.233 +       Copy all interesting entries.  */
   2.234 +    efi_map_start = __va(ia64_boot_param->efi_memmap);
   2.235 +    efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size;
   2.236 +    efi_desc_size = ia64_boot_param->efi_memdesc_size;
   2.237 +
   2.238 +    for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) {
   2.239 +        const efi_memory_desc_t *md = p;
   2.240 +        efi_memory_desc_t *dom_md = &tables->efi_memmap[num_mds];
   2.241 +        u64 start = md->phys_addr;
   2.242 +        u64 size = md->num_pages << EFI_PAGE_SHIFT;
   2.243 +        u64 end = start + size;
   2.244 +        u64 mpaddr;
   2.245 +        unsigned long flags;
   2.246 +
   2.247 +        switch (md->type) {
   2.248 +        case EFI_RUNTIME_SERVICES_CODE:
   2.249 +        case EFI_RUNTIME_SERVICES_DATA:
   2.250 +        case EFI_ACPI_RECLAIM_MEMORY:
   2.251 +        case EFI_ACPI_MEMORY_NVS:
   2.252 +        case EFI_RESERVED_TYPE:
   2.253 +            /*
   2.254 +             * Map into dom0 - We must respect protection
   2.255 +             * and cache attributes.  Not all of these pages
   2.256 +             * are writable!!!
   2.257 +             */
   2.258 +            flags = ASSIGN_writable;    /* dummy - zero */
   2.259 +            if (md->attribute & EFI_MEMORY_WP)
   2.260 +                flags |= ASSIGN_readonly;
   2.261 +            if ((md->attribute & EFI_MEMORY_UC) &&
   2.262 +                !(md->attribute & EFI_MEMORY_WB))
   2.263 +                flags |= ASSIGN_nocache;
   2.264 +
   2.265 +            assign_domain_mach_page(d, start, size, flags);
   2.266 +
   2.267 +            /* Fall-through.  */
   2.268 +        case EFI_MEMORY_MAPPED_IO:
   2.269 +            /* Will be mapped with ioremap.  */
   2.270 +            /* Copy descriptor.  */
   2.271 +            *dom_md = *md;
   2.272 +            dom_md->virt_addr = 0;
   2.273 +            num_mds++;
   2.274 +            break;
   2.275 +
   2.276 +        case EFI_MEMORY_MAPPED_IO_PORT_SPACE:
   2.277 +            flags = ASSIGN_writable;    /* dummy - zero */
   2.278 +            if (md->attribute & EFI_MEMORY_UC)
   2.279 +                flags |= ASSIGN_nocache;
   2.280 +
   2.281 +            if (start > 0x1ffffffff0000000UL) {
   2.282 +                mpaddr = 0x4000000000000UL - size;
   2.283 +                printk(XENLOG_INFO "Remapping IO ports from "
   2.284 +                       "%lx to %lx\n", start, mpaddr);
   2.285 +            } else
   2.286 +                mpaddr = start;
   2.287 +
   2.288 +            /* Map into dom0.  */
   2.289 +            assign_domain_mmio_page(d, mpaddr, start, size, flags);
   2.290 +            /* Copy descriptor.  */
   2.291 +            *dom_md = *md;
   2.292 +            dom_md->phys_addr = mpaddr;
   2.293 +            dom_md->virt_addr = 0;
   2.294 +            num_mds++;
   2.295 +            break;
   2.296 +
   2.297 +        case EFI_CONVENTIONAL_MEMORY:
   2.298 +        case EFI_LOADER_CODE:
   2.299 +        case EFI_LOADER_DATA:
   2.300 +        case EFI_BOOT_SERVICES_CODE:
   2.301 +        case EFI_BOOT_SERVICES_DATA:
   2.302 +            if (!(md->attribute & EFI_MEMORY_WB))
   2.303 +                break;
   2.304 +
   2.305 +            start = max(FW_END_PADDR, start);
   2.306 +            end = min(start + dom_mem, end);
   2.307 +            if (end <= start)
   2.308 +                break;
   2.309 +
   2.310 +            dom_md->type = EFI_CONVENTIONAL_MEMORY;
   2.311 +            dom_md->phys_addr = start;
   2.312 +            dom_md->virt_addr = 0;
   2.313 +            dom_md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
   2.314 +            dom_md->attribute = EFI_MEMORY_WB;
   2.315 +            num_mds++;
   2.316 +
   2.317 +            dom_mem -= dom_md->num_pages << EFI_PAGE_SHIFT;
   2.318 +            break;
   2.319 +
   2.320 +        case EFI_UNUSABLE_MEMORY:
   2.321 +        case EFI_PAL_CODE:
   2.322 +            /*
   2.323 +             * We don't really need these, but holes in the
   2.324 +             * memory map may cause Linux to assume there are
   2.325 +             * uncacheable ranges within a granule.
   2.326 +             */
   2.327 +            dom_md->type = EFI_UNUSABLE_MEMORY;
   2.328 +            dom_md->phys_addr = start;
   2.329 +            dom_md->virt_addr = 0;
   2.330 +            dom_md->num_pages = (end - start) >> EFI_PAGE_SHIFT;
   2.331 +            dom_md->attribute = EFI_MEMORY_WB;
   2.332 +            num_mds++;
   2.333 +            break;
   2.334 +
   2.335 +        default:
   2.336 +            /* Print a warning but continue.  */
   2.337 +            printk("complete_dom0_memmap: warning: "
   2.338 +                   "unhandled MDT entry type %u\n", md->type);
   2.339 +        }
   2.340 +    }
   2.341 +    BUG_ON(num_mds > NUM_MEM_DESCS);
   2.342 +    
   2.343 +    sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t),
   2.344 +         efi_mdt_cmp, NULL);
   2.345 +
   2.346 +    /* setup_guest() @ libxc/xc_linux_build() arranges memory for domU.
   2.347 +     * however no one arranges memory for dom0,
   2.348 +     * instead we allocate pages manually.
   2.349 +     */
   2.350 +    for (i = 0; i < num_mds; i++) {
   2.351 +        md = &tables->efi_memmap[i];
   2.352 +
   2.353 +        if (md->type == EFI_LOADER_DATA ||
   2.354 +            md->type == EFI_PAL_CODE ||
   2.355 +            md->type == EFI_CONVENTIONAL_MEMORY) {
   2.356 +            unsigned long start = md->phys_addr & PAGE_MASK;
   2.357 +            unsigned long end = md->phys_addr +
   2.358 +                (md->num_pages << EFI_PAGE_SHIFT);
   2.359 +
   2.360 +            if (end == start) {
   2.361 +                /* md->num_pages = 0 is allowed. */
   2.362 +                continue;
   2.363 +            }
   2.364 +            
   2.365 +            for (addr = start; addr < end; addr += PAGE_SIZE)
   2.366 +                assign_new_domain0_page(d, addr);
   2.367 +        }
   2.368 +    }
   2.369 +    // Map low-memory holes & unmapped MMIO for legacy drivers
   2.370 +    for (addr = 0; addr < ONE_MB; addr += PAGE_SIZE) {
   2.371 +        if (domain_page_mapped(d, addr))
   2.372 +            continue;
   2.373 +        
   2.374 +        if (efi_mmio(addr, PAGE_SIZE)) {
   2.375 +            unsigned long flags;
   2.376 +            flags = ASSIGN_writable | ASSIGN_nocache;
   2.377 +            assign_domain_mmio_page(d, addr, addr,
   2.378 +                        PAGE_SIZE, flags);
   2.379 +        }
   2.380 +    }
   2.381 +    setup_dom0_memmap_info(d, tables, &num_mds);
   2.382 +    return num_mds;
   2.383 +}
   2.384 +
   2.385 +/*
   2.386 + * Local variables:
   2.387 + * mode: C
   2.388 + * c-set-style: "BSD"
   2.389 + * c-basic-offset: 4
   2.390 + * tab-width: 4
   2.391 + * indent-tabs-mode: nil
   2.392 + * End:
   2.393 + */
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen/arch/ia64/xen/dom_fw_domu.c	Mon May 21 13:50:05 2007 -0600
     3.3 @@ -0,0 +1,221 @@
     3.4 +/******************************************************************************
     3.5 + *
     3.6 + * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
     3.7 + *                    VA Linux Systems Japan K.K.
     3.8 + *
     3.9 + * This program is free software; you can redistribute it and/or modify
    3.10 + * it under the terms of the GNU General Public License as published by
    3.11 + * the Free Software Foundation; either version 2 of the License, or
    3.12 + * (at your option) any later version.
    3.13 + *
    3.14 + * This program is distributed in the hope that it will be useful,
    3.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    3.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    3.17 + * GNU General Public License for more details.
    3.18 + *
    3.19 + * You should have received a copy of the GNU General Public License
    3.20 + * along with this program; if not, write to the Free Software
    3.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    3.22 + *
    3.23 + */
    3.24 +/*
    3.25 + *  Xen domain firmware emulation support
    3.26 + *  Copyright (C) 2004 Hewlett-Packard Co.
    3.27 + *       Dan Magenheimer (dan.magenheimer@hp.com)
    3.28 + */
    3.29 +
    3.30 +#ifdef __XEN__
    3.31 +#include <xen/sched.h>
    3.32 +#include <asm/dom_fw_utils.h>
    3.33 +#include <linux/sort.h>
    3.34 +#define xen_ia64_dom_fw_map(d, mpaddr)  domain_mpa_to_imva((d), (mpaddr))
    3.35 +#define xen_ia64_dom_fw_unmap(d, vaddr)  do { } while (0)
    3.36 +#else
    3.37 +#include <stdio.h>
    3.38 +#include <stdlib.h>
    3.39 +#include <assert.h>
    3.40 +#include <errno.h>
    3.41 +#include <inttypes.h>
    3.42 +
    3.43 +#include <xen/arch-ia64.h>
    3.44 +
    3.45 +#include "xg_private.h"
    3.46 +#include "xc_dom.h"
    3.47 +#include "ia64/xc_dom_ia64_util.h"
    3.48 +#endif
    3.49 +
    3.50 +#include <asm/dom_fw.h>
    3.51 +#include <asm/dom_fw_domu.h>
    3.52 +
    3.53 +void
    3.54 +efi_systable_init_domu(struct fw_tables *tables)
    3.55 +{
    3.56 +    int i = 1;
    3.57 +    printk(XENLOG_GUEST XENLOG_INFO "DomainU EFI build up:");
    3.58 +
    3.59 +    tables->efi_tables[i].guid = ACPI_20_TABLE_GUID;
    3.60 +    tables->efi_tables[i].table = FW_ACPI_BASE_PADDR;
    3.61 +    printk(" ACPI 2.0=0x%lx",tables->efi_tables[i].table);
    3.62 +    i++;
    3.63 +    printk("\n");
    3.64 +    BUG_ON(i > NUM_EFI_SYS_TABLES);
    3.65 +}
    3.66 +
    3.67 +#define MAKE_MD(typ, attr, start, end) \
    3.68 +	xen_ia64_efi_make_md((tables), &(i), (typ), (attr), (start), (end))
    3.69 +
    3.70 +int
    3.71 +complete_domu_memmap(domain_t *d,
    3.72 +                     struct fw_tables *tables,
    3.73 +                     unsigned long maxmem,
    3.74 +                     int num_mds,
    3.75 +                     unsigned long memmap_info_pfn,
    3.76 +                     unsigned long memmap_info_num_pages)
    3.77 +{
    3.78 +    efi_memory_desc_t *md;
    3.79 +    int i = num_mds; /* for MAKE_MD */
    3.80 +    int create_memmap = 0;
    3.81 +    xen_ia64_memmap_info_t* memmap_info;
    3.82 +    unsigned long memmap_info_size;
    3.83 +    unsigned long paddr_start;
    3.84 +    unsigned long paddr_end;
    3.85 +    void *p;
    3.86 +    void *memmap_start;
    3.87 +    void *memmap_end;
    3.88 +
    3.89 +    if (memmap_info_pfn == 0 || memmap_info_num_pages == 0) {
    3.90 +        /* old domain builder which doesn't setup
    3.91 +         * memory map. create it for compatibility */
    3.92 +        memmap_info_pfn = (maxmem >> PAGE_SHIFT) - 1;
    3.93 +        memmap_info_num_pages = 1;
    3.94 +        create_memmap = 1;
    3.95 +    }
    3.96 +
    3.97 +    memmap_info_size = memmap_info_num_pages << PAGE_SHIFT;
    3.98 +    paddr_start = memmap_info_pfn << PAGE_SHIFT;
    3.99 +    /* 3 = start info page, xenstore page and console page */
   3.100 +    paddr_end = paddr_start + memmap_info_size + 3 * PAGE_SIZE;
   3.101 +    memmap_info = xen_ia64_dom_fw_map(d, paddr_start);
   3.102 +    if (memmap_info->efi_memmap_size == 0) {
   3.103 +        create_memmap = 1;
   3.104 +    } else if (memmap_info->efi_memdesc_size != sizeof(md[0]) ||
   3.105 +               memmap_info->efi_memdesc_version !=
   3.106 +               EFI_MEMORY_DESCRIPTOR_VERSION) {
   3.107 +        printk(XENLOG_WARNING
   3.108 +               "%s: Warning: unknown memory map "
   3.109 +               "memmap size %"PRIu64" "
   3.110 +               "memdesc size %"PRIu64" "
   3.111 +               "version %"PRIu32"\n",
   3.112 +               __func__,
   3.113 +               memmap_info->efi_memmap_size,
   3.114 +               memmap_info->efi_memdesc_size,
   3.115 +               memmap_info->efi_memdesc_version);
   3.116 +        create_memmap = 1;
   3.117 +    } else if (memmap_info_size < memmap_info->efi_memmap_size) {
   3.118 +        printk(XENLOG_WARNING
   3.119 +               "%s: Warning: too short memmap info size %"PRIu64"\n",
   3.120 +               __func__, memmap_info_size);
   3.121 +        xen_ia64_dom_fw_unmap(d, memmap_info);
   3.122 +        return -EINVAL;
   3.123 +    } else if (memmap_info->efi_memmap_size >
   3.124 +           PAGE_SIZE - sizeof(*memmap_info)) {
   3.125 +        /*
   3.126 +         * curently memmap spanning more than single page isn't
   3.127 +         * supported.
   3.128 +         */
   3.129 +        printk(XENLOG_WARNING
   3.130 +               "%s: Warning: too large efi_memmap_size %"PRIu64"\n",
   3.131 +               __func__, memmap_info->efi_memmap_size);
   3.132 +        xen_ia64_dom_fw_unmap(d, memmap_info);
   3.133 +        return -ENOSYS;
   3.134 +    }
   3.135 +    
   3.136 +    if (create_memmap) {
   3.137 +        /*
   3.138 +         * old domain builder which doesn't setup
   3.139 +         * memory map. create it for compatibility
   3.140 +         */
   3.141 +        memmap_info->efi_memdesc_size = sizeof(md[0]);
   3.142 +        memmap_info->efi_memdesc_version =
   3.143 +            EFI_MEMORY_DESCRIPTOR_VERSION;
   3.144 +        memmap_info->efi_memmap_size = 1 * sizeof(md[0]);
   3.145 +        md = (efi_memory_desc_t*)&memmap_info->memdesc;
   3.146 +        md[num_mds].type = EFI_CONVENTIONAL_MEMORY;
   3.147 +        md[num_mds].pad = 0;
   3.148 +        md[num_mds].phys_addr = 0;
   3.149 +        md[num_mds].virt_addr = 0;
   3.150 +        md[num_mds].num_pages = maxmem >> EFI_PAGE_SHIFT;
   3.151 +        md[num_mds].attribute = EFI_MEMORY_WB;
   3.152 +    }
   3.153 +
   3.154 +    memmap_start = &memmap_info->memdesc;
   3.155 +    memmap_end = memmap_start + memmap_info->efi_memmap_size;
   3.156 +    /* XXX Currently the table must be in a single page. */
   3.157 +    if ((unsigned long)memmap_end > (unsigned long)memmap_info + PAGE_SIZE) {
   3.158 +        xen_ia64_dom_fw_unmap(d, memmap_info);
   3.159 +        return -EINVAL;
   3.160 +    }
   3.161 +
   3.162 +    /* sort it bofore use
   3.163 +     * XXX: this is created by user space domain builder so that
   3.164 +     * we should check its integrity */
   3.165 +    sort(&memmap_info->memdesc,
   3.166 +         memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size,
   3.167 +         memmap_info->efi_memdesc_size,
   3.168 +         efi_mdt_cmp, NULL);
   3.169 +
   3.170 +    for (p = memmap_start; p < memmap_end; p += memmap_info->efi_memdesc_size) {
   3.171 +        unsigned long start;
   3.172 +        unsigned long end;
   3.173 +        md = p;
   3.174 +        start = md->phys_addr;
   3.175 +        end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
   3.176 +
   3.177 +        if (start < FW_END_PADDR)
   3.178 +            start = FW_END_PADDR;
   3.179 +        if (end <= start)
   3.180 +            continue;
   3.181 +
   3.182 +        /* exclude [paddr_start, paddr_end) */
   3.183 +        if (paddr_end <= start || end <= paddr_start) {
   3.184 +            MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   3.185 +                start, end);
   3.186 +        } else if (paddr_start <= start && paddr_end < end) {
   3.187 +            MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   3.188 +                paddr_end, end);
   3.189 +        } else if (start < paddr_start && end <= paddr_end) {
   3.190 +            MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   3.191 +                start, paddr_start);
   3.192 +        } else {
   3.193 +            MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   3.194 +                start, paddr_start);
   3.195 +            MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   3.196 +                paddr_end, end);
   3.197 +        }
   3.198 +    }
   3.199 +
   3.200 +    /* memmap info page. */
   3.201 +    MAKE_MD(EFI_RUNTIME_SERVICES_DATA, EFI_MEMORY_WB,
   3.202 +        paddr_start, paddr_end);
   3.203 +
   3.204 +    /* Create an entry for IO ports.  */
   3.205 +    MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE, EFI_MEMORY_UC,
   3.206 +        IO_PORTS_PADDR, IO_PORTS_PADDR + IO_PORTS_SIZE);
   3.207 +
   3.208 +    num_mds = i;
   3.209 +    sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t),
   3.210 +         efi_mdt_cmp, NULL);
   3.211 +
   3.212 +    xen_ia64_dom_fw_unmap(d, memmap_info);
   3.213 +    return num_mds;
   3.214 +}
   3.215 +
   3.216 +/*
   3.217 + * Local variables:
   3.218 + * mode: C
   3.219 + * c-set-style: "BSD"
   3.220 + * c-basic-offset: 4
   3.221 + * tab-width: 4
   3.222 + * indent-tabs-mode: nil
   3.223 + * End:
   3.224 + */
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/arch/ia64/xen/dom_fw_utils.c	Mon May 21 13:50:05 2007 -0600
     4.3 @@ -0,0 +1,215 @@
     4.4 +/******************************************************************************
     4.5 + *
     4.6 + * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
     4.7 + *                    VA Linux Systems Japan K.K.
     4.8 + *
     4.9 + * This program is free software; you can redistribute it and/or modify
    4.10 + * it under the terms of the GNU General Public License as published by
    4.11 + * the Free Software Foundation; either version 2 of the License, or
    4.12 + * (at your option) any later version.
    4.13 + *
    4.14 + * This program is distributed in the hope that it will be useful,
    4.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    4.17 + * GNU General Public License for more details.
    4.18 + *
    4.19 + * You should have received a copy of the GNU General Public License
    4.20 + * along with this program; if not, write to the Free Software
    4.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    4.22 + *
    4.23 + */
    4.24 +
    4.25 +#include <xen/types.h>
    4.26 +#include <xen/version.h>
    4.27 +#include <xen/errno.h>
    4.28 +#include <xen/sched.h>
    4.29 +
    4.30 +#include <asm/fpswa.h>
    4.31 +#include <asm/dom_fw.h>
    4.32 +#include <asm/dom_fw_common.h>
    4.33 +
    4.34 +#include <linux/sort.h>
    4.35 +
    4.36 +uint32_t
    4.37 +xen_ia64_version(struct domain *unused)
    4.38 +{
    4.39 +    return (xen_major_version() << 16) | xen_minor_version();
    4.40 +}
    4.41 +
    4.42 +int
    4.43 +xen_ia64_fpswa_revision(struct domain *d, unsigned int *revision)
    4.44 +{
    4.45 +    if (fpswa_interface == NULL)
    4.46 +        return -ENOSYS;
    4.47 +    *revision = fpswa_interface->revision;
    4.48 +    return 0;
    4.49 +}
    4.50 +
    4.51 +int
    4.52 +xen_ia64_is_vcpu_allocated(struct domain *d, uint32_t vcpu)
    4.53 +{
    4.54 +    return d->vcpu[vcpu] != NULL;
    4.55 +}
    4.56 +
    4.57 +int xen_ia64_is_running_on_sim(struct domain *unused)
    4.58 +{
    4.59 +    extern unsigned long running_on_sim;
    4.60 +    return running_on_sim;
    4.61 +}
    4.62 +
    4.63 +int
    4.64 +xen_ia64_is_dom0(struct domain *d)
    4.65 +{
    4.66 +    return d == dom0;
    4.67 +}
    4.68 +
    4.69 +static void
    4.70 +dom_fw_domain_init(struct domain *d, struct fw_tables *tables)
    4.71 +{
    4.72 +    /* Initialise for EFI_SET_VIRTUAL_ADDRESS_MAP emulation */
    4.73 +    d->arch.efi_runtime = &tables->efi_runtime;
    4.74 +    d->arch.fpswa_inf   = &tables->fpswa_inf;
    4.75 +    d->arch.sal_data    = &tables->sal_data;
    4.76 +}
    4.77 +
    4.78 +static int
    4.79 +dom_fw_set_convmem_end(struct domain *d)
    4.80 +{
    4.81 +    xen_ia64_memmap_info_t* memmap_info;
    4.82 +    efi_memory_desc_t *md;
    4.83 +    void *p;
    4.84 +    void *memmap_start;
    4.85 +    void *memmap_end;
    4.86 +
    4.87 +    if (d->shared_info->arch.memmap_info_pfn == 0)
    4.88 +        return -EINVAL;
    4.89 +
    4.90 +    memmap_info = domain_mpa_to_imva(d, d->shared_info->arch.memmap_info_pfn << PAGE_SHIFT);
    4.91 +    if (memmap_info->efi_memmap_size == 0 ||
    4.92 +        memmap_info->efi_memdesc_size != sizeof(*md) ||
    4.93 +        memmap_info->efi_memdesc_version !=
    4.94 +        EFI_MEMORY_DESCRIPTOR_VERSION)
    4.95 +        return -EINVAL;
    4.96 +    /* only 1page case is supported */
    4.97 +    if (d->shared_info->arch.memmap_info_num_pages != 1)
    4.98 +        return -ENOSYS;
    4.99 +
   4.100 +    memmap_start = &memmap_info->memdesc;
   4.101 +    memmap_end = memmap_start + memmap_info->efi_memmap_size;
   4.102 +
   4.103 +    /* XXX Currently the table must be in a single page. */
   4.104 +    if ((unsigned long)memmap_end > (unsigned long)memmap_info + PAGE_SIZE)
   4.105 +        return -EINVAL;
   4.106 +
   4.107 +    /* sort it bofore use
   4.108 +     * XXX: this is created by user space domain builder so that
   4.109 +     * we should check its integrity */
   4.110 +    sort(&memmap_info->memdesc,
   4.111 +         memmap_info->efi_memmap_size / memmap_info->efi_memdesc_size,
   4.112 +         memmap_info->efi_memdesc_size,
   4.113 +         efi_mdt_cmp, NULL);
   4.114 +
   4.115 +    if (d->arch.convmem_end == 0)
   4.116 +        d->arch.convmem_end = d->max_pages << PAGE_SHIFT;
   4.117 +    for (p = memmap_start; p < memmap_end; p += memmap_info->efi_memdesc_size) {
   4.118 +        unsigned long end;
   4.119 +        md = p;
   4.120 +        end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
   4.121 +        if (md->attribute == EFI_MEMORY_WB &&
   4.122 +            md->type == EFI_CONVENTIONAL_MEMORY &&
   4.123 +            md->num_pages > 0 &&
   4.124 +            d->arch.convmem_end < end)
   4.125 +            d->arch.convmem_end = end;
   4.126 +    }
   4.127 +    return 0;
   4.128 +}
   4.129 +
   4.130 +/* allocate a page for fw
   4.131 + * guest_setup() @ libxc/xc_linux_build.c does for domU
   4.132 + */
   4.133 +static inline void
   4.134 +assign_new_domain_page_if_dom0(struct domain *d, unsigned long mpaddr)
   4.135 +{
   4.136 +        if (d == dom0)
   4.137 +            assign_new_domain0_page(d, mpaddr);
   4.138 +}
   4.139 +
   4.140 +int
   4.141 +dom_fw_setup(domain_t *d, unsigned long bp_mpa, unsigned long maxmem)
   4.142 +{
   4.143 +    int old_domu_builder = 0;
   4.144 +    struct xen_ia64_boot_param *bp;
   4.145 +    struct fw_tables *imva_tables_base;
   4.146 +
   4.147 +    BUILD_BUG_ON(sizeof(struct fw_tables) >
   4.148 +                 (FW_TABLES_END_PADDR - FW_TABLES_BASE_PADDR));
   4.149 +
   4.150 +    /* Create page for boot_param.  */
   4.151 +    assign_new_domain_page_if_dom0(d, bp_mpa);
   4.152 +    bp = domain_mpa_to_imva(d, bp_mpa);
   4.153 +    if (d != dom0) {
   4.154 +        /*
   4.155 +         * XXX kludge.
   4.156 +         * when XEN_DOMCTL_arch_setup is called, shared_info can't
   4.157 +         * be accessed by libxc so that memmap_info_pfn isn't
   4.158 +         * initialized. But dom_fw_set_convmem_end() requires it, 
   4.159 +         * so here we initialize it.
   4.160 +         * note: domain builder may overwrite memmap_info_num_pages,
   4.161 +         *       memmap_info_pfns later.
   4.162 +         */
   4.163 +        if (bp->efi_memmap_size == 0 || 
   4.164 +            XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp) == 0 ||
   4.165 +            XEN_IA64_MEMMAP_INFO_PFN(bp) == 0) {
   4.166 +            /* old domain builder compatibility */
   4.167 +            d->shared_info->arch.memmap_info_num_pages = 1;
   4.168 +            d->shared_info->arch.memmap_info_pfn = (maxmem >> PAGE_SHIFT) - 1;
   4.169 +            old_domu_builder = 1;
   4.170 +        } else {
   4.171 +            d->shared_info->arch.memmap_info_num_pages =
   4.172 +                XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp);
   4.173 +            d->shared_info->arch.memmap_info_pfn =
   4.174 +                XEN_IA64_MEMMAP_INFO_PFN(bp);
   4.175 +            /* currently multi page memmap isn't supported */
   4.176 +            if (d->shared_info->arch.memmap_info_num_pages != 1)
   4.177 +                return -ENOSYS;
   4.178 +        }
   4.179 +    }
   4.180 +
   4.181 +    /* Create page for FW tables.  */
   4.182 +    assign_new_domain_page_if_dom0(d, FW_TABLES_BASE_PADDR);
   4.183 +    imva_tables_base = (struct fw_tables *)domain_mpa_to_imva
   4.184 +                                      (d, FW_TABLES_BASE_PADDR);
   4.185 +    /* Create page for acpi tables.  */
   4.186 +    if (d != dom0 && old_domu_builder) {
   4.187 +        struct fake_acpi_tables *imva;
   4.188 +        imva = domain_mpa_to_imva(d, FW_ACPI_BASE_PADDR);
   4.189 +        dom_fw_fake_acpi(d, imva);
   4.190 +    }
   4.191 +    if (d == dom0 || old_domu_builder) {
   4.192 +        int ret;
   4.193 +        unsigned long imva_hypercall_base;
   4.194 +
   4.195 +        /* Create page for hypercalls.  */
   4.196 +        assign_new_domain_page_if_dom0(d, FW_HYPERCALL_BASE_PADDR);
   4.197 +        imva_hypercall_base = (unsigned long)domain_mpa_to_imva
   4.198 +            (d, FW_HYPERCALL_BASE_PADDR);
   4.199 +
   4.200 +        ret = dom_fw_init(d, d->arch.breakimm, bp,
   4.201 +                          imva_tables_base, imva_hypercall_base, maxmem);
   4.202 +        if (ret < 0)
   4.203 +            return ret;
   4.204 +    }
   4.205 +
   4.206 +    dom_fw_domain_init(d, imva_tables_base);
   4.207 +    return dom_fw_set_convmem_end(d);
   4.208 +}
   4.209 +
   4.210 +/*
   4.211 + * Local variables:
   4.212 + * mode: C
   4.213 + * c-set-style: "BSD"
   4.214 + * c-basic-offset: 4
   4.215 + * tab-width: 4
   4.216 + * indent-tabs-mode: nil
   4.217 + * End:
   4.218 + */
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/xen/include/asm-ia64/dom_fw_common.h	Mon May 21 13:50:05 2007 -0600
     5.3 @@ -0,0 +1,107 @@
     5.4 +/******************************************************************************
     5.5 + *
     5.6 + * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
     5.7 + *                    VA Linux Systems Japan K.K.
     5.8 + *
     5.9 + * This program is free software; you can redistribute it and/or modify
    5.10 + * it under the terms of the GNU General Public License as published by
    5.11 + * the Free Software Foundation; either version 2 of the License, or
    5.12 + * (at your option) any later version.
    5.13 + *
    5.14 + * This program is distributed in the hope that it will be useful,
    5.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    5.17 + * GNU General Public License for more details.
    5.18 + *
    5.19 + * You should have received a copy of the GNU General Public License
    5.20 + * along with this program; if not, write to the Free Software
    5.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    5.22 + *
    5.23 + */
    5.24 +#ifndef __ASM_IA64_DOM_FW_COMMON_H__
    5.25 +#define __ASM_IA64_DOM_FW_COMMON_H__
    5.26 +
    5.27 +#ifdef __XEN__
    5.28 +#include <linux/efi.h>
    5.29 +#include <asm/sal.h>
    5.30 +#include <xen/sched.h>
    5.31 +typedef struct domain domain_t;
    5.32 +#else
    5.33 +#include "xc_efi.h"
    5.34 +#include "ia64/sal.h"
    5.35 +#include "xg_private.h"
    5.36 +typedef struct xc_dom_image domain_t;
    5.37 +
    5.38 +#define XENLOG_INFO     "info:"
    5.39 +#define XENLOG_WARNING	"Warning:"
    5.40 +#define XENLOG_GUEST	""
    5.41 +#define printk(fmt, args ...)	xc_dom_printf(fmt, ## args)
    5.42 +
    5.43 +#define BUG_ON(p)	assert(!(p))
    5.44 +#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
    5.45 +
    5.46 +//for sort in linux/sort.h.
    5.47 +#define sort(base, num, size, cmp, swap) qsort((base), (num), (size), (cmp))
    5.48 +#endif
    5.49 +
    5.50 +#include <asm/fpswa.h>
    5.51 +
    5.52 +#define ONE_MB          (1UL << 20)
    5.53 +#define FW_VENDOR       "X\0e\0n\0/\0i\0a\0\066\0\064\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
    5.54 +
    5.55 +#define NFUNCPTRS               16
    5.56 +#define NUM_EFI_SYS_TABLES      6
    5.57 +#define NUM_MEM_DESCS           64 //large enough
    5.58 +
    5.59 +struct fw_tables {
    5.60 +    efi_system_table_t                  efi_systab;
    5.61 +    efi_runtime_services_t              efi_runtime;
    5.62 +    efi_config_table_t                  efi_tables[NUM_EFI_SYS_TABLES];
    5.63 +
    5.64 +    struct ia64_sal_systab              sal_systab;
    5.65 +    struct ia64_sal_desc_entry_point    sal_ed;
    5.66 +    struct ia64_sal_desc_ap_wakeup      sal_wakeup;
    5.67 +    /* End of SAL descriptors.  Do not forget to update checkum bound.  */
    5.68 +
    5.69 +    fpswa_interface_t                   fpswa_inf;
    5.70 +    efi_memory_desc_t                   efi_memmap[NUM_MEM_DESCS];
    5.71 +    unsigned long                       func_ptrs[2*NFUNCPTRS];
    5.72 +    struct xen_sal_data                 sal_data;
    5.73 +    unsigned char                       fw_vendor[sizeof(FW_VENDOR)];
    5.74 +};
    5.75 +#define FW_FIELD_MPA(field)                                     \
    5.76 +    FW_TABLES_BASE_PADDR + offsetof(struct fw_tables, field)
    5.77 +
    5.78 +void
    5.79 +xen_ia64_efi_make_md(struct fw_tables *tables, int *index,
    5.80 +                     uint32_t type, uint64_t attr, 
    5.81 +                     uint64_t start, uint64_t end);
    5.82 +uint8_t generate_acpi_checksum(void *tbl, unsigned long len);
    5.83 +struct fake_acpi_tables;
    5.84 +void dom_fw_fake_acpi(domain_t *d, struct fake_acpi_tables *tables);
    5.85 +int efi_mdt_cmp(const void *a, const void *b); 
    5.86 +
    5.87 +struct ia64_boot_param;
    5.88 +int dom_fw_init(domain_t *d, uint64_t brkimm, struct xen_ia64_boot_param *bp,
    5.89 +                struct fw_tables *tables, unsigned long hypercalls_imva,
    5.90 +                unsigned long maxmem);
    5.91 +
    5.92 +// XEN_DOMCTL_arch_setup hypercall abuse
    5.93 +// struct ia64_boot_param::domain_{start, size} 
    5.94 +// to pass memmap_pfn and memmap_size.
    5.95 +// This imposes arch_setup hypercall must be done before
    5.96 +// setting bp->domain_{size, start} and the domain builder must clean it later.
    5.97 +#define XEN_IA64_MEMMAP_INFO_NUM_PAGES(bp)      (bp)->domain_size
    5.98 +#define XEN_IA64_MEMMAP_INFO_PFN(bp)            (bp)->domain_start
    5.99 +
   5.100 +#endif /* __ASM_IA64_DOM_FW_COMMON_H__ */
   5.101 +
   5.102 +/*
   5.103 + * Local variables:
   5.104 + * mode: C
   5.105 + * c-set-style: "BSD"
   5.106 + * c-basic-offset: 4
   5.107 + * tab-width: 4
   5.108 + * indent-tabs-mode: nil
   5.109 + * End:
   5.110 + */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/xen/include/asm-ia64/dom_fw_dom0.h	Mon May 21 13:50:05 2007 -0600
     6.3 @@ -0,0 +1,44 @@
     6.4 +/******************************************************************************
     6.5 + *
     6.6 + * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
     6.7 + *                    VA Linux Systems Japan K.K.
     6.8 + *
     6.9 + * This program is free software; you can redistribute it and/or modify
    6.10 + * it under the terms of the GNU General Public License as published by
    6.11 + * the Free Software Foundation; either version 2 of the License, or
    6.12 + * (at your option) any later version.
    6.13 + *
    6.14 + * This program is distributed in the hope that it will be useful,
    6.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.17 + * GNU General Public License for more details.
    6.18 + *
    6.19 + * You should have received a copy of the GNU General Public License
    6.20 + * along with this program; if not, write to the Free Software
    6.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    6.22 + *
    6.23 + */
    6.24 +#ifndef __ASM_IA64_DOM_FW_DOM0_H__
    6.25 +#define __ASM_IA64_DOM_FW_DOM0_H__
    6.26 +
    6.27 +struct fw_tables;
    6.28 +struct domain;
    6.29 +
    6.30 +void efi_systable_init_dom0(struct fw_tables *tables);
    6.31 +int
    6.32 +complete_dom0_memmap(struct domain *d,
    6.33 +                     struct fw_tables *tables,
    6.34 +                     unsigned long maxmem,
    6.35 +                     int num_mds);
    6.36 +
    6.37 +#endif /* __ASM_IA64_DOM_FW_DOM0_H__ */
    6.38 +/*
    6.39 + * Local variables:
    6.40 + * mode: C
    6.41 + * c-set-style: "BSD"
    6.42 + * c-basic-offset: 4
    6.43 + * tab-width: 4
    6.44 + * indent-tabs-mode: nil
    6.45 + * End:
    6.46 + */
    6.47 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/xen/include/asm-ia64/dom_fw_domu.h	Mon May 21 13:50:05 2007 -0600
     7.3 @@ -0,0 +1,45 @@
     7.4 +/******************************************************************************
     7.5 + *
     7.6 + * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
     7.7 + *                    VA Linux Systems Japan K.K.
     7.8 + *
     7.9 + * This program is free software; you can redistribute it and/or modify
    7.10 + * it under the terms of the GNU General Public License as published by
    7.11 + * the Free Software Foundation; either version 2 of the License, or
    7.12 + * (at your option) any later version.
    7.13 + *
    7.14 + * This program is distributed in the hope that it will be useful,
    7.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.17 + * GNU General Public License for more details.
    7.18 + *
    7.19 + * You should have received a copy of the GNU General Public License
    7.20 + * along with this program; if not, write to the Free Software
    7.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    7.22 + *
    7.23 + */
    7.24 +#ifndef __ASM_IA64_DOM_FW_DOMU_H__
    7.25 +#define __ASM_IA64_DOM_FW_DOMU_H__
    7.26 +
    7.27 +#include <asm/dom_fw_common.h>
    7.28 +
    7.29 +void efi_systable_init_domu(struct fw_tables *tables);
    7.30 +
    7.31 +int
    7.32 +complete_domu_memmap(domain_t *d,
    7.33 +                     struct fw_tables *tables,
    7.34 +                     unsigned long maxmem,
    7.35 +                     int num_mds,
    7.36 +                     unsigned long memmap_info_pfn,
    7.37 +                     unsigned long reserved_size);
    7.38 +#endif /* __ASM_IA64_DOM_FW_DOMU_H__ */
    7.39 +/*
    7.40 + * Local variables:
    7.41 + * mode: C
    7.42 + * c-set-style: "BSD"
    7.43 + * c-basic-offset: 4
    7.44 + * tab-width: 4
    7.45 + * indent-tabs-mode: nil
    7.46 + * End:
    7.47 + */
    7.48 +
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xen/include/asm-ia64/dom_fw_utils.h	Mon May 21 13:50:05 2007 -0600
     8.3 @@ -0,0 +1,40 @@
     8.4 +/******************************************************************************
     8.5 + *
     8.6 + * Copyright (c) 2007 Isaku Yamahata <yamahata at valinux co jp>
     8.7 + *                    VA Linux Systems Japan K.K.
     8.8 + *
     8.9 + * This program is free software; you can redistribute it and/or modify
    8.10 + * it under the terms of the GNU General Public License as published by
    8.11 + * the Free Software Foundation; either version 2 of the License, or
    8.12 + * (at your option) any later version.
    8.13 + *
    8.14 + * This program is distributed in the hope that it will be useful,
    8.15 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.17 + * GNU General Public License for more details.
    8.18 + *
    8.19 + * You should have received a copy of the GNU General Public License
    8.20 + * along with this program; if not, write to the Free Software
    8.21 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    8.22 + *
    8.23 + */
    8.24 +#ifndef __ASM_XEN_IA64_DOM_FW_UTILS_H__
    8.25 +#define __ASM_XEN_IA64_DOM_FW_UTILS_H__
    8.26 +
    8.27 +uint32_t xen_ia64_version(struct domain *unused); 
    8.28 +int xen_ia64_fpswa_revision(struct domain *d, unsigned int *revision); 
    8.29 +int xen_ia64_is_vcpu_allocated(struct domain *d, uint32_t vcpu); 
    8.30 +int xen_ia64_is_running_on_sim(struct domain *unused);
    8.31 +int xen_ia64_is_dom0(struct domain *d);
    8.32 +
    8.33 +#endif /* __ASM_XEN_IA64_DOM_FW_UTILS_H__ */
    8.34 +
    8.35 +/*
    8.36 + * Local variables:
    8.37 + * mode: C
    8.38 + * c-set-style: "BSD"
    8.39 + * c-basic-offset: 4
    8.40 + * tab-width: 4
    8.41 + * indent-tabs-mode: nil
    8.42 + * End:
    8.43 + */