direct-io.hg

changeset 11337:d188c51ea883

[IA64] dom_fw.c cleaned up.

Only use one page for stubs and tables instead of 2MB.
Create struct fw_tables to make code more understandable.
Many comments added.
Correctly compute sal systab checksum.

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author awilliam@xenbuild.aw
date Fri Aug 25 15:52:31 2006 -0600 (2006-08-25)
parents c232365128cf
children 3e0685ecfe64
files xen/arch/ia64/xen/dom_fw.c xen/include/asm-ia64/dom_fw.h
line diff
     1.1 --- a/xen/arch/ia64/xen/dom_fw.c	Fri Aug 25 15:06:18 2006 -0600
     1.2 +++ b/xen/arch/ia64/xen/dom_fw.c	Fri Aug 25 15:52:31 2006 -0600
     1.3 @@ -26,24 +26,25 @@
     1.4  #include <asm/dom_fw.h>
     1.5  #include <asm/bundle.h>
     1.6  
     1.7 -static void dom_fw_init (struct domain *d, struct ia64_boot_param *bp, char *fw_mem, int fw_mem_size, unsigned long maxmem);
     1.8 -
     1.9 -extern struct domain *dom0;
    1.10 +#define ONE_MB (1UL << 20)
    1.11  
    1.12  extern unsigned long running_on_sim;
    1.13  
    1.14 +/* Base of FW tables.  */
    1.15 +static const unsigned long dom_fw_base_mpa = FW_HYPERCALL_END_PADDR;
    1.16 +static unsigned long dom_fw_end_mpa;
    1.17 +
    1.18  /* Note: two domains cannot be created simulteanously!  */
    1.19 -static unsigned long dom_fw_base_mpa = -1;
    1.20  static unsigned long imva_fw_base = -1;
    1.21  
    1.22  #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.23  
    1.24 -#define MAKE_MD(typ, attr, start, end, abs) 				\
    1.25 +#define MAKE_MD(typ, attr, start, end) 					\
    1.26  	do {								\
    1.27 -		md = efi_memmap + i++;					\
    1.28 +		md = tables->efi_memmap + i++;				\
    1.29  		md->type = typ;						\
    1.30  		md->pad = 0;						\
    1.31 -		md->phys_addr = abs ? start : start_mpaddr + start;	\
    1.32 +		md->phys_addr = start;					\
    1.33  		md->virt_addr = 0;					\
    1.34  		md->num_pages = (end - start) >> EFI_PAGE_SHIFT;	\
    1.35  		md->attribute = attr;					\
    1.36 @@ -53,8 +54,8 @@ static unsigned long imva_fw_base = -1;
    1.37  	do {								\
    1.38  		dom_efi_hypercall_patch(d, FW_HYPERCALL_##call##_PADDR,	\
    1.39  		                        FW_HYPERCALL_##call);		\
    1.40 -		tgt = dom_pa((unsigned long) pfn);			\
    1.41 -		*pfn++ = FW_HYPERCALL_##call##_PADDR + start_mpaddr;	\
    1.42 +		tables->efi_runtime.tgt = dom_pa((unsigned long) pfn);  \
    1.43 +		*pfn++ = FW_HYPERCALL_##call##_PADDR;			\
    1.44  		*pfn++ = 0;						\
    1.45  	} while (0)
    1.46  
    1.47 @@ -63,7 +64,7 @@ static unsigned long imva_fw_base = -1;
    1.48  static unsigned long
    1.49  dom_pa(unsigned long imva)
    1.50  {
    1.51 -	if (dom_fw_base_mpa == -1 || imva_fw_base == -1) {
    1.52 +	if (imva_fw_base == -1) {
    1.53  		printf("dom_pa: uninitialized! (spinning...)\n");
    1.54  		while(1);
    1.55  	}
    1.56 @@ -78,12 +79,12 @@ dom_pa(unsigned long imva)
    1.57  // allocate a page for fw
    1.58  // build_physmap_table() which is called by new_thread()
    1.59  // does for domU.
    1.60 -#define ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, mpaddr)   \
    1.61 -    do {                                            \
    1.62 -        if ((d) == dom0) {                          \
    1.63 -            assign_new_domain0_page((d), (mpaddr)); \
    1.64 -        }                                           \
    1.65 -    } while (0)
    1.66 +static inline void
    1.67 +assign_new_domain_page_if_dom0(struct domain *d, unsigned long mpaddr)
    1.68 +{
    1.69 +        if (d == dom0)
    1.70 +            assign_new_domain0_page(d, mpaddr);
    1.71 +}
    1.72  
    1.73  /**************************************************************************
    1.74  Hypercall bundle creation
    1.75 @@ -105,8 +106,8 @@ static void build_hypercall_bundle(UINT6
    1.76  	slot1.inst = 0;
    1.77  	slot1.qp = 0; slot1.x6 = 0; slot1.x3 = 0; slot1.major = 0x0;
    1.78  	slot1.imm20 = brkimm; slot1.i = brkimm >> 20;
    1.79 -	// if ret slot2: br.ret.sptk.many rp
    1.80 -	// else slot2: br.cond.sptk.many rp
    1.81 +	// if ret slot2:  br.ret.sptk.many rp
    1.82 +	// else   slot2:  br.cond.sptk.many rp
    1.83  	slot2.inst = 0; slot2.qp = 0; slot2.p = 1; slot2.b2 = 0;
    1.84  	slot2.wh = 0; slot2.d = 0; slot2.major = 0x0;
    1.85  	if (ret) {
    1.86 @@ -169,14 +170,15 @@ static void dom_fpswa_hypercall_patch(st
    1.87  	unsigned long entry_paddr = FW_HYPERCALL_FPSWA_ENTRY_PADDR;
    1.88  	unsigned long patch_paddr = FW_HYPERCALL_FPSWA_PATCH_PADDR;
    1.89  
    1.90 -	ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, entry_paddr);
    1.91 -	ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, patch_paddr);
    1.92 +	assign_new_domain_page_if_dom0(d, entry_paddr);
    1.93 +	assign_new_domain_page_if_dom0(d, patch_paddr);
    1.94  	entry_imva = domain_mpa_to_imva(d, entry_paddr);
    1.95  	patch_imva = domain_mpa_to_imva(d, patch_paddr);
    1.96  
    1.97  	*entry_imva++ = patch_paddr;
    1.98  	*entry_imva   = 0;
    1.99 -	build_hypercall_bundle(patch_imva, d->arch.breakimm, FW_HYPERCALL_FPSWA, 1);
   1.100 +	build_hypercall_bundle(patch_imva, d->arch.breakimm,
   1.101 +	                       FW_HYPERCALL_FPSWA, 1);
   1.102  }
   1.103  
   1.104  // builds a hypercall bundle at domain physical address
   1.105 @@ -184,7 +186,7 @@ static void dom_efi_hypercall_patch(stru
   1.106  {
   1.107  	unsigned long *imva;
   1.108  
   1.109 -	ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, paddr);
   1.110 +	assign_new_domain_page_if_dom0(d, paddr);
   1.111  	imva = domain_mpa_to_imva(d, paddr);
   1.112  	build_hypercall_bundle(imva, d->arch.breakimm, hypercall, 1);
   1.113  }
   1.114 @@ -194,7 +196,7 @@ static void dom_fw_hypercall_patch(struc
   1.115  {
   1.116  	unsigned long *imva;
   1.117  
   1.118 -	ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, paddr);
   1.119 +	assign_new_domain_page_if_dom0(d, paddr);
   1.120  	imva = domain_mpa_to_imva(d, paddr);
   1.121  	build_hypercall_bundle(imva, d->arch.breakimm, hypercall, ret);
   1.122  }
   1.123 @@ -203,36 +205,28 @@ static void dom_fw_pal_hypercall_patch(s
   1.124  {
   1.125  	unsigned long *imva;
   1.126  
   1.127 -	ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, paddr);
   1.128 +	assign_new_domain_page_if_dom0(d, paddr);
   1.129  	imva = domain_mpa_to_imva(d, paddr);
   1.130 -	build_pal_hypercall_bundles(imva, d->arch.breakimm, FW_HYPERCALL_PAL_CALL);
   1.131 +	build_pal_hypercall_bundles(imva, d->arch.breakimm,
   1.132 +	                            FW_HYPERCALL_PAL_CALL);
   1.133  }
   1.134  
   1.135 -
   1.136 -void dom_fw_setup(struct domain *d, unsigned long bp_mpa, unsigned long maxmem)
   1.137 -{
   1.138 -	struct ia64_boot_param *bp;
   1.139 -
   1.140 -	dom_fw_base_mpa = 0;
   1.141 -	ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, dom_fw_base_mpa);
   1.142 -	imva_fw_base = (unsigned long) domain_mpa_to_imva(d, dom_fw_base_mpa);
   1.143 -	ASSIGN_NEW_DOMAIN_PAGE_IF_DOM0(d, bp_mpa);
   1.144 -	bp = domain_mpa_to_imva(d, bp_mpa);
   1.145 -	dom_fw_init(d, bp, (char *) imva_fw_base, PAGE_SIZE, maxmem);
   1.146 -}
   1.147 -
   1.148 -
   1.149  /* the following heavily leveraged from linux/arch/ia64/hp/sim/fw-emu.c */
   1.150  
   1.151 -#define NFUNCPTRS 20
   1.152 -
   1.153  static inline void
   1.154  print_md(efi_memory_desc_t *md)
   1.155  {
   1.156 -	printk("domain mem: type=%2u, attr=0x%016lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
   1.157 -		md->type, md->attribute, md->phys_addr,
   1.158 -		md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
   1.159 -		md->num_pages >> (20 - EFI_PAGE_SHIFT));
   1.160 +	u64 size;
   1.161 +	
   1.162 +	printk("dom mem: type=%2u, attr=0x%016lx, range=[0x%016lx-0x%016lx) ",
   1.163 +	       md->type, md->attribute, md->phys_addr,
   1.164 +	       md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
   1.165 +
   1.166 +	size = md->num_pages << EFI_PAGE_SHIFT;
   1.167 +	if (size > ONE_MB)
   1.168 +		printf ("(%luMB)\n", size >> 20);
   1.169 +	else
   1.170 +		printf ("(%luKB)\n", size >> 10);
   1.171  }
   1.172  
   1.173  static u32 lsapic_nbr;
   1.174 @@ -468,9 +462,6 @@ dom_fw_fake_acpi(struct domain *d, struc
   1.175  	return;
   1.176  }
   1.177  
   1.178 -#define NUM_EFI_SYS_TABLES 6
   1.179 -#define NUM_MEM_DESCS	64 //large enough
   1.180 -
   1.181  struct dom0_passthrough_arg {
   1.182      struct domain*      d;
   1.183      int                 flags;
   1.184 @@ -530,23 +521,16 @@ static int
   1.185  dom_fw_dom0_lowmem(efi_memory_desc_t *md, void *arg__)
   1.186  {
   1.187      struct dom0_passthrough_arg* arg = (struct dom0_passthrough_arg*)arg__;
   1.188 -    u64 end = min(HYPERCALL_START,
   1.189 -                  md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
   1.190 +    u64 end = min(ONE_MB, md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
   1.191  
   1.192      BUG_ON(md->type != EFI_CONVENTIONAL_MEMORY);
   1.193  
   1.194 -    /* avoid hypercall area */
   1.195 -    if (md->phys_addr >= HYPERCALL_START)
   1.196 -        return 0;
   1.197 -
   1.198 -    /* avoid firmware base area */
   1.199 -    if (md->phys_addr < dom_pa(imva_fw_base))
   1.200 -        end = min(end, dom_pa(imva_fw_base));
   1.201 -    else if (md->phys_addr < dom_pa(imva_fw_base + PAGE_SIZE)) {
   1.202 -        if (end < dom_pa(imva_fw_base + PAGE_SIZE))
   1.203 -            return 0;
   1.204 -        md->phys_addr = dom_pa(imva_fw_base + PAGE_SIZE);
   1.205 -    }
   1.206 +    /* Avoid firmware and hypercall area.
   1.207 +       We know they are 0-based.  */
   1.208 +    if (end < dom_fw_end_mpa || md->phys_addr >= ONE_MB)
   1.209 +	return 0;
   1.210 +    if (md->phys_addr < dom_fw_end_mpa)
   1.211 +        md->phys_addr = dom_fw_end_mpa;
   1.212  
   1.213      arg->md->type = md->type;
   1.214      arg->md->pad = 0;
   1.215 @@ -558,22 +542,6 @@ dom_fw_dom0_lowmem(efi_memory_desc_t *md
   1.216      (*arg->i)++;
   1.217      arg->md++;
   1.218  
   1.219 -    /* if firmware area spliced the md, add the upper part here */
   1.220 -    if (end == dom_pa(imva_fw_base)) {
   1.221 -        end = min(HYPERCALL_START,
   1.222 -                  md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
   1.223 -	if (end > dom_pa(imva_fw_base + PAGE_SIZE)) {
   1.224 -            arg->md->type = md->type;
   1.225 -            arg->md->pad = 0;
   1.226 -            arg->md->phys_addr = dom_pa(imva_fw_base + PAGE_SIZE);
   1.227 -            arg->md->virt_addr = 0;
   1.228 -            arg->md->num_pages = (end - arg->md->phys_addr) >> EFI_PAGE_SHIFT;
   1.229 -            arg->md->attribute = md->attribute;
   1.230 -
   1.231 -            (*arg->i)++;
   1.232 -            arg->md++;
   1.233 -        }
   1.234 -    }
   1.235      return 0;
   1.236  }
   1.237  
   1.238 @@ -596,296 +564,291 @@ efi_mdt_cmp(const void *a, const void *b
   1.239  	return 0;
   1.240  }
   1.241  
   1.242 -static void
   1.243 -dom_fw_init (struct domain *d, struct ia64_boot_param *bp, char *fw_mem, int fw_mem_size, unsigned long maxmem)
   1.244 -{
   1.245 -	efi_system_table_t *efi_systab;
   1.246 -	efi_runtime_services_t *efi_runtime;
   1.247 -	efi_config_table_t *efi_tables;
   1.248 -	struct ia64_sal_systab *sal_systab;
   1.249 -	struct ia64_sal_desc_entry_point *sal_ed;
   1.250 -	struct ia64_sal_desc_ap_wakeup *sal_wakeup;
   1.251 -	fpswa_interface_t *fpswa_inf;
   1.252 -	efi_memory_desc_t *efi_memmap, *md;
   1.253 - 	struct xen_sal_data *sal_data;
   1.254 -	unsigned long *pfn;
   1.255 -	unsigned char checksum = 0;
   1.256 -	char *cp, *fw_vendor;
   1.257 -	int num_mds, j, i = 0;
   1.258 -	const unsigned long start_mpaddr = 0;
   1.259 +#define NFUNCPTRS 16
   1.260 +#define NUM_EFI_SYS_TABLES 6
   1.261 +#define NUM_MEM_DESCS 64 //large enough
   1.262  
   1.263 -/* FIXME: should check size but for now we have a whole MB to play with.
   1.264 -   And if stealing code from fw-emu.c, watch out for new fw_vendor on the end!
   1.265 -	if (fw_mem_size < sizeof(fw_mem_proto)) {
   1.266 -		printf("sys_fw_init: insufficient space for fw_mem\n");
   1.267 -		return 0;
   1.268 -	}
   1.269 -*/
   1.270 -	memset(fw_mem, 0, fw_mem_size);
   1.271 +struct fw_tables {
   1.272 +	efi_system_table_t efi_systab;
   1.273 +	efi_runtime_services_t efi_runtime;
   1.274 +	efi_config_table_t efi_tables[NUM_EFI_SYS_TABLES];
   1.275  
   1.276 -	cp = fw_mem;
   1.277 -	efi_systab  = (void *) cp; cp += sizeof(*efi_systab);
   1.278 -	efi_runtime = (void *) cp; cp += sizeof(*efi_runtime);
   1.279 -	efi_tables  = (void *) cp; cp += NUM_EFI_SYS_TABLES * sizeof(*efi_tables);
   1.280 -	sal_systab  = (void *) cp; cp += sizeof(*sal_systab);
   1.281 -	sal_ed      = (void *) cp; cp += sizeof(*sal_ed);
   1.282 -	sal_wakeup  = (void *) cp; cp += sizeof(*sal_wakeup);
   1.283 -	fpswa_inf   = (void *) cp; cp += sizeof(*fpswa_inf);
   1.284 -	efi_memmap  = (void *) cp; cp += NUM_MEM_DESCS*sizeof(*efi_memmap);
   1.285 -	pfn         = (void *) cp; cp += NFUNCPTRS * 2 * sizeof(pfn);
   1.286 -	sal_data    = (void *) cp; cp += sizeof(*sal_data);
   1.287 +	struct ia64_sal_systab sal_systab;
   1.288 +	struct ia64_sal_desc_entry_point sal_ed;
   1.289 +	struct ia64_sal_desc_ap_wakeup sal_wakeup;
   1.290 +	/* End of SAL descriptors.  Do not forget to update checkum bound.  */
   1.291 +
   1.292 +	fpswa_interface_t fpswa_inf;
   1.293 +	efi_memory_desc_t efi_memmap[NUM_MEM_DESCS];
   1.294 +	unsigned long func_ptrs[2*NFUNCPTRS];
   1.295 + 	struct xen_sal_data sal_data;
   1.296 +	unsigned char fw_vendor[sizeof(FW_VENDOR)];
   1.297 +
   1.298 +	struct fake_acpi_tables acpi_tables;
   1.299 +};
   1.300 +	
   1.301 +static void
   1.302 +dom_fw_init(struct domain *d,
   1.303 +            struct ia64_boot_param *bp,
   1.304 +            struct fw_tables *tables,
   1.305 +            unsigned long maxmem)
   1.306 +{
   1.307 +	efi_memory_desc_t *md;
   1.308 +	unsigned long *pfn;
   1.309 +	unsigned char checksum;
   1.310 +	char *cp;
   1.311 +	int num_mds, i;
   1.312 +
   1.313 +	memset(tables, 0, sizeof(struct fw_tables));
   1.314  
   1.315  	/* Initialise for EFI_SET_VIRTUAL_ADDRESS_MAP emulation */
   1.316 -	d->arch.efi_runtime = efi_runtime;
   1.317 -	d->arch.fpswa_inf   = fpswa_inf;
   1.318 -	d->arch.sal_data    = sal_data;
   1.319 -
   1.320 -	memset(efi_systab, 0, sizeof(efi_systab));
   1.321 -	efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
   1.322 -	efi_systab->hdr.revision  = EFI_SYSTEM_TABLE_REVISION;
   1.323 -	efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
   1.324 -	fw_vendor = cp;
   1.325 -	cp += sizeof(FW_VENDOR) + (8-((unsigned long)cp & 7)); // round to 64-bit boundary
   1.326 -
   1.327 -	memcpy(fw_vendor,FW_VENDOR,sizeof(FW_VENDOR));
   1.328 -	efi_systab->fw_vendor = dom_pa((unsigned long) fw_vendor);
   1.329 -	efi_systab->fw_revision = 1;
   1.330 -	efi_systab->runtime = (void *) dom_pa((unsigned long) efi_runtime);
   1.331 -	efi_systab->nr_tables = NUM_EFI_SYS_TABLES;
   1.332 -	efi_systab->tables = dom_pa((unsigned long) efi_tables);
   1.333 +	d->arch.efi_runtime = &tables->efi_runtime;
   1.334 +	d->arch.fpswa_inf   = &tables->fpswa_inf;
   1.335 +	d->arch.sal_data    = &tables->sal_data;
   1.336  
   1.337 -	efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
   1.338 -	efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
   1.339 -	efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
   1.340 +	/* EFI systab.  */
   1.341 +	tables->efi_systab.hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
   1.342 +	tables->efi_systab.hdr.revision  = EFI_SYSTEM_TABLE_REVISION;
   1.343 +	tables->efi_systab.hdr.headersize = sizeof(tables->efi_systab.hdr);
   1.344  
   1.345 -	EFI_HYPERCALL_PATCH(efi_runtime->get_time,EFI_GET_TIME);
   1.346 -	EFI_HYPERCALL_PATCH(efi_runtime->set_time,EFI_SET_TIME);
   1.347 -	EFI_HYPERCALL_PATCH(efi_runtime->get_wakeup_time,EFI_GET_WAKEUP_TIME);
   1.348 -	EFI_HYPERCALL_PATCH(efi_runtime->set_wakeup_time,EFI_SET_WAKEUP_TIME);
   1.349 -	EFI_HYPERCALL_PATCH(efi_runtime->set_virtual_address_map,EFI_SET_VIRTUAL_ADDRESS_MAP);
   1.350 -	EFI_HYPERCALL_PATCH(efi_runtime->get_variable,EFI_GET_VARIABLE);
   1.351 -	EFI_HYPERCALL_PATCH(efi_runtime->get_next_variable,EFI_GET_NEXT_VARIABLE);
   1.352 -	EFI_HYPERCALL_PATCH(efi_runtime->set_variable,EFI_SET_VARIABLE);
   1.353 -	EFI_HYPERCALL_PATCH(efi_runtime->get_next_high_mono_count,EFI_GET_NEXT_HIGH_MONO_COUNT);
   1.354 -	EFI_HYPERCALL_PATCH(efi_runtime->reset_system,EFI_RESET_SYSTEM);
   1.355 +	memcpy(tables->fw_vendor,FW_VENDOR,sizeof(FW_VENDOR));
   1.356 +	tables->efi_systab.fw_vendor =
   1.357 +	                             dom_pa((unsigned long)tables->fw_vendor);
   1.358 +	tables->efi_systab.fw_revision = 1;
   1.359 +	tables->efi_systab.runtime =
   1.360 +	                 (void *)dom_pa((unsigned long)&tables->efi_runtime);
   1.361 +	tables->efi_systab.nr_tables = NUM_EFI_SYS_TABLES;
   1.362 +	tables->efi_systab.tables = dom_pa((unsigned long)tables->efi_tables);
   1.363  
   1.364 -	efi_tables[0].guid = SAL_SYSTEM_TABLE_GUID;
   1.365 -	efi_tables[0].table = dom_pa((unsigned long) sal_systab);
   1.366 +	/* EFI runtime.  */
   1.367 +	tables->efi_runtime.hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
   1.368 +	tables->efi_runtime.hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
   1.369 +	tables->efi_runtime.hdr.headersize = sizeof(tables->efi_runtime.hdr);
   1.370 +
   1.371 +	pfn = tables->func_ptrs;
   1.372 +	EFI_HYPERCALL_PATCH(get_time,EFI_GET_TIME);
   1.373 +	EFI_HYPERCALL_PATCH(set_time,EFI_SET_TIME);
   1.374 +	EFI_HYPERCALL_PATCH(get_wakeup_time,EFI_GET_WAKEUP_TIME);
   1.375 +	EFI_HYPERCALL_PATCH(set_wakeup_time,EFI_SET_WAKEUP_TIME);
   1.376 +	EFI_HYPERCALL_PATCH(set_virtual_address_map,
   1.377 +	                    EFI_SET_VIRTUAL_ADDRESS_MAP);
   1.378 +	EFI_HYPERCALL_PATCH(get_variable,EFI_GET_VARIABLE);
   1.379 +	EFI_HYPERCALL_PATCH(get_next_variable,EFI_GET_NEXT_VARIABLE);
   1.380 +	EFI_HYPERCALL_PATCH(set_variable,EFI_SET_VARIABLE);
   1.381 +	EFI_HYPERCALL_PATCH(get_next_high_mono_count,
   1.382 +	                    EFI_GET_NEXT_HIGH_MONO_COUNT);
   1.383 +	EFI_HYPERCALL_PATCH(reset_system,EFI_RESET_SYSTEM);
   1.384 +
   1.385 +	/* System tables.  */
   1.386 +	tables->efi_tables[0].guid = SAL_SYSTEM_TABLE_GUID;
   1.387 +	tables->efi_tables[0].table =
   1.388 +	                           dom_pa((unsigned long)&tables->sal_systab);
   1.389  	for (i = 1; i < NUM_EFI_SYS_TABLES; i++) {
   1.390 -		efi_tables[i].guid = NULL_GUID;
   1.391 -		efi_tables[i].table = 0;
   1.392 +		tables->efi_tables[i].guid = NULL_GUID;
   1.393 +		tables->efi_tables[i].table = 0;
   1.394  	}
   1.395 +	i = 1;
   1.396  	if (d == dom0) {
   1.397  		printf("Domain0 EFI passthrough:");
   1.398 -		i = 1;
   1.399  		if (efi.mps) {
   1.400 -			efi_tables[i].guid = MPS_TABLE_GUID;
   1.401 -			efi_tables[i].table = __pa(efi.mps);
   1.402 -			printf(" MPS=0x%lx",efi_tables[i].table);
   1.403 +			tables->efi_tables[i].guid = MPS_TABLE_GUID;
   1.404 +			tables->efi_tables[i].table = __pa(efi.mps);
   1.405 +			printf(" MPS=0x%lx",tables->efi_tables[i].table);
   1.406  			i++;
   1.407  		}
   1.408  
   1.409  		touch_acpi_table();
   1.410  
   1.411  		if (efi.acpi20) {
   1.412 -			efi_tables[i].guid = ACPI_20_TABLE_GUID;
   1.413 -			efi_tables[i].table = __pa(efi.acpi20);
   1.414 -			printf(" ACPI 2.0=0x%lx",efi_tables[i].table);
   1.415 +			tables->efi_tables[i].guid = ACPI_20_TABLE_GUID;
   1.416 +			tables->efi_tables[i].table = __pa(efi.acpi20);
   1.417 +			printf(" ACPI 2.0=0x%lx",tables->efi_tables[i].table);
   1.418  			i++;
   1.419  		}
   1.420  		if (efi.acpi) {
   1.421 -			efi_tables[i].guid = ACPI_TABLE_GUID;
   1.422 -			efi_tables[i].table = __pa(efi.acpi);
   1.423 -			printf(" ACPI=0x%lx",efi_tables[i].table);
   1.424 +			tables->efi_tables[i].guid = ACPI_TABLE_GUID;
   1.425 +			tables->efi_tables[i].table = __pa(efi.acpi);
   1.426 +			printf(" ACPI=0x%lx",tables->efi_tables[i].table);
   1.427  			i++;
   1.428  		}
   1.429  		if (efi.smbios) {
   1.430 -			efi_tables[i].guid = SMBIOS_TABLE_GUID;
   1.431 -			efi_tables[i].table = __pa(efi.smbios);
   1.432 -			printf(" SMBIOS=0x%lx",efi_tables[i].table);
   1.433 +			tables->efi_tables[i].guid = SMBIOS_TABLE_GUID;
   1.434 +			tables->efi_tables[i].table = __pa(efi.smbios);
   1.435 +			printf(" SMBIOS=0x%lx",tables->efi_tables[i].table);
   1.436  			i++;
   1.437  		}
   1.438  		if (efi.hcdp) {
   1.439 -			efi_tables[i].guid = HCDP_TABLE_GUID;
   1.440 -			efi_tables[i].table = __pa(efi.hcdp);
   1.441 -			printf(" HCDP=0x%lx",efi_tables[i].table);
   1.442 +			tables->efi_tables[i].guid = HCDP_TABLE_GUID;
   1.443 +			tables->efi_tables[i].table = __pa(efi.hcdp);
   1.444 +			printf(" HCDP=0x%lx",tables->efi_tables[i].table);
   1.445  			i++;
   1.446  		}
   1.447  		printf("\n");
   1.448  	} else {
   1.449  		printf("DomainU EFI build up:");
   1.450 -		i = 1;
   1.451 -
   1.452 -		if ((unsigned long)fw_mem + fw_mem_size - (unsigned long)cp >=
   1.453 -		    sizeof(struct fake_acpi_tables)) {
   1.454 -			struct fake_acpi_tables *acpi_tables;
   1.455  
   1.456 -			acpi_tables = (void *)cp;
   1.457 -			cp += sizeof(struct fake_acpi_tables);
   1.458 -			dom_fw_fake_acpi(d, acpi_tables);
   1.459 +		dom_fw_fake_acpi(d, &tables->acpi_tables);
   1.460  
   1.461 -			efi_tables[i].guid = ACPI_20_TABLE_GUID;
   1.462 -			efi_tables[i].table = dom_pa((unsigned long) acpi_tables);
   1.463 -			printf(" ACPI 2.0=0x%lx",efi_tables[i].table);
   1.464 -			i++;
   1.465 -		}
   1.466 +		tables->efi_tables[i].guid = ACPI_20_TABLE_GUID;
   1.467 +		tables->efi_tables[i].table =
   1.468 +		                  dom_pa((unsigned long) &tables->acpi_tables);
   1.469 +		printf(" ACPI 2.0=0x%lx",tables->efi_tables[i].table);
   1.470 +		i++;
   1.471  		printf("\n");
   1.472  	}
   1.473  
   1.474  	/* fill in the SAL system table: */
   1.475 -	memcpy(sal_systab->signature, "SST_", 4);
   1.476 -	sal_systab->size = sizeof(*sal_systab);
   1.477 -	sal_systab->sal_rev_minor = 1;
   1.478 -	sal_systab->sal_rev_major = 0;
   1.479 -	sal_systab->entry_count = 2;
   1.480 +	memcpy(tables->sal_systab.signature, "SST_", 4);
   1.481 +	tables->sal_systab.size = sizeof(tables->sal_systab);
   1.482 +	tables->sal_systab.sal_rev_minor = 1;
   1.483 +	tables->sal_systab.sal_rev_major = 0;
   1.484 +	tables->sal_systab.entry_count = 2;
   1.485  
   1.486 -	strcpy((char *)sal_systab->oem_id, "Xen/ia64");
   1.487 -	strcpy((char *)sal_systab->product_id, "Xen/ia64");
   1.488 +	strcpy((char *)tables->sal_systab.oem_id, "Xen/ia64");
   1.489 +	strcpy((char *)tables->sal_systab.product_id, "Xen/ia64");
   1.490  
   1.491  	/* fill in an entry point: */
   1.492 -	sal_ed->type = SAL_DESC_ENTRY_POINT;
   1.493 -	sal_ed->pal_proc = FW_HYPERCALL_PAL_CALL_PADDR + start_mpaddr;
   1.494 -	dom_fw_pal_hypercall_patch (d, sal_ed->pal_proc);
   1.495 -	sal_ed->sal_proc = FW_HYPERCALL_SAL_CALL_PADDR + start_mpaddr;
   1.496 -	dom_fw_hypercall_patch (d, sal_ed->sal_proc, FW_HYPERCALL_SAL_CALL, 1);
   1.497 -	sal_ed->gp = 0;  // will be ignored
   1.498 +	tables->sal_ed.type = SAL_DESC_ENTRY_POINT;
   1.499 +	tables->sal_ed.pal_proc = FW_HYPERCALL_PAL_CALL_PADDR;
   1.500 +	dom_fw_pal_hypercall_patch(d, tables->sal_ed.pal_proc);
   1.501 +	tables->sal_ed.sal_proc = FW_HYPERCALL_SAL_CALL_PADDR;
   1.502 +	dom_fw_hypercall_patch(d, tables->sal_ed.sal_proc,
   1.503 +	                       FW_HYPERCALL_SAL_CALL, 1);
   1.504 +	tables->sal_ed.gp = 0;  /* will be ignored */
   1.505  
   1.506  	/* Fill an AP wakeup descriptor.  */
   1.507 -	sal_wakeup->type = SAL_DESC_AP_WAKEUP;
   1.508 -	sal_wakeup->mechanism = IA64_SAL_AP_EXTERNAL_INT;
   1.509 -	sal_wakeup->vector = XEN_SAL_BOOT_RENDEZ_VEC;
   1.510 +	tables->sal_wakeup.type = SAL_DESC_AP_WAKEUP;
   1.511 +	tables->sal_wakeup.mechanism = IA64_SAL_AP_EXTERNAL_INT;
   1.512 +	tables->sal_wakeup.vector = XEN_SAL_BOOT_RENDEZ_VEC;
   1.513  
   1.514  	/* Compute checksum.  */
   1.515 -	for (cp = (char *) sal_systab; cp < (char *) efi_memmap; ++cp)
   1.516 +	checksum = 0;
   1.517 +	for (cp = (char *)&tables->sal_systab;
   1.518 +	     cp < (char *)&tables->fpswa_inf;
   1.519 +	     ++cp)
   1.520  		checksum += *cp;
   1.521 -	sal_systab->checksum = -checksum;
   1.522 +	tables->sal_systab.checksum = -checksum;
   1.523  
   1.524  	/* SAL return point.  */
   1.525 -	d->arch.sal_return_addr = FW_HYPERCALL_SAL_RETURN_PADDR + start_mpaddr;
   1.526 +	d->arch.sal_return_addr = FW_HYPERCALL_SAL_RETURN_PADDR;
   1.527  	dom_fw_hypercall_patch (d, d->arch.sal_return_addr,
   1.528  				FW_HYPERCALL_SAL_RETURN, 0);
   1.529  
   1.530  	/* Fill in the FPSWA interface: */
   1.531 -	fpswa_inf->revision = fpswa_interface->revision;
   1.532 +	tables->fpswa_inf.revision = fpswa_interface->revision;
   1.533  	dom_fpswa_hypercall_patch(d);
   1.534 -	fpswa_inf->fpswa = (void *) FW_HYPERCALL_FPSWA_ENTRY_PADDR + start_mpaddr;
   1.535 +	tables->fpswa_inf.fpswa = (void *)FW_HYPERCALL_FPSWA_ENTRY_PADDR;
   1.536  
   1.537  	i = 0; /* Used by MAKE_MD */
   1.538  
   1.539 -	/* Create dom0/domu md entry for fw_mem area */
   1.540 -	MAKE_MD(EFI_ACPI_RECLAIM_MEMORY, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
   1.541 -	        dom_pa((unsigned long)fw_mem),
   1.542 -	        dom_pa((unsigned long)fw_mem + fw_mem_size), 1);
   1.543 -
   1.544 -	if (d == dom0) {
   1.545 -		/* hypercall patches live here, masquerade as reserved PAL memory */
   1.546 -		MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,HYPERCALL_START,HYPERCALL_END, 0);
   1.547 +	/* hypercall patches live here, masquerade as reserved PAL memory */
   1.548 +	MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,
   1.549 +	        FW_HYPERCALL_BASE_PADDR, FW_HYPERCALL_END_PADDR);
   1.550  
   1.551 -		/* pass through the I/O port space */
   1.552 -		if (!running_on_sim) {
   1.553 -			struct dom0_passthrough_arg arg;
   1.554 -			arg.md = &efi_memmap[i];
   1.555 -			arg.i = &i;
   1.556 -			arg.d = d;
   1.557 -			arg.flags = ASSIGN_writable;
   1.558 -			//XXX Is this needed?
   1.559 -			efi_memmap_walk_type(EFI_RUNTIME_SERVICES_CODE,
   1.560 -			                     dom_fw_dom0_passthrough, &arg);
   1.561 -			// for ACPI table.
   1.562 -			arg.flags = ASSIGN_readonly;
   1.563 -			efi_memmap_walk_type(EFI_RUNTIME_SERVICES_DATA,
   1.564 -			                     dom_fw_dom0_passthrough, &arg);
   1.565 -			arg.flags = ASSIGN_writable;
   1.566 -			efi_memmap_walk_type(EFI_ACPI_RECLAIM_MEMORY,
   1.567 -			                     dom_fw_dom0_passthrough, &arg);
   1.568 -			efi_memmap_walk_type(EFI_ACPI_MEMORY_NVS,
   1.569 -			                     dom_fw_dom0_passthrough, &arg);
   1.570 -			efi_memmap_walk_type(EFI_RESERVED_TYPE,
   1.571 -			                     dom_fw_dom0_passthrough, &arg);
   1.572 -			efi_memmap_walk_type(EFI_MEMORY_MAPPED_IO,
   1.573 -			                     dom_fw_dom0_passthrough, &arg);
   1.574 -			efi_memmap_walk_type(EFI_MEMORY_MAPPED_IO_PORT_SPACE,
   1.575 -			                     dom_fw_dom0_passthrough, &arg);
   1.576 -			efi_memmap_walk_type(EFI_CONVENTIONAL_MEMORY,
   1.577 -			                     dom_fw_dom0_lowmem, &arg);
   1.578 -		}
   1.579 -		else MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
   1.580 -	} else {
   1.581 -		/* hypercall patches live here, masquerade as reserved
   1.582 -		   PAL memory */
   1.583 -		MAKE_MD(EFI_PAL_CODE, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
   1.584 -			HYPERCALL_START, HYPERCALL_END, 1);
   1.585 +	/* Create dom0/domu md entry for fw tables area */
   1.586 +	MAKE_MD(EFI_RUNTIME_SERVICES_DATA, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
   1.587 +	        dom_fw_base_mpa, dom_fw_end_mpa);
   1.588 +
   1.589 +	if (d != dom0 || running_on_sim) {
   1.590 +		/* Memory.  */
   1.591 +		MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   1.592 +		        dom_fw_end_mpa, maxmem);
   1.593 +		
   1.594  		/* Create an entry for IO ports.  */
   1.595  		MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE, EFI_MEMORY_UC,
   1.596 -			IO_PORTS_PADDR, IO_PORTS_PADDR + IO_PORTS_SIZE, 1);
   1.597 -		MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
   1.598 -	}
   1.599 -
   1.600 -	// simple
   1.601 -	// MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   1.602 -	//         HYPERCALL_END, maxmem, 0);
   1.603 -	// is not good. Check overlap.
   1.604 -	sort(efi_memmap, i, sizeof(efi_memory_desc_t),
   1.605 -	     efi_mdt_cmp, NULL);
   1.606 -
   1.607 -	// find gap and fill it with conventional memory
   1.608 -	num_mds = i;
   1.609 -	for (j = 0; j < num_mds; j++) {
   1.610 -		unsigned long end;
   1.611 -		unsigned long next_start;
   1.612 -
   1.613 -		md = &efi_memmap[j];
   1.614 -		end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
   1.615 -
   1.616 -		next_start = maxmem;
   1.617 -		if (j + 1 < num_mds) {
   1.618 -			efi_memory_desc_t* next_md = &efi_memmap[j + 1];
   1.619 -			next_start = next_md->phys_addr;
   1.620 -			BUG_ON(end > next_start);
   1.621 -			if (end == next_md->phys_addr)
   1.622 -				continue;
   1.623 -		}
   1.624 +		        IO_PORTS_PADDR, IO_PORTS_PADDR + IO_PORTS_SIZE);
   1.625  
   1.626 -		// clip the range and align to PAGE_SIZE
   1.627 -		// Avoid "legacy" low memory addresses and the
   1.628 -		// HYPERCALL patch area.      
   1.629 -		if (end < HYPERCALL_END)
   1.630 -			end = HYPERCALL_END;
   1.631 -		if (next_start > maxmem)
   1.632 -			next_start = maxmem;
   1.633 -		end = PAGE_ALIGN(end);
   1.634 -		next_start = next_start & PAGE_MASK;
   1.635 -		if (end >= next_start)
   1.636 -			continue;
   1.637 -
   1.638 -		MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   1.639 -		        end, next_start, 0);
   1.640 -		if (next_start >= maxmem)
   1.641 -			break;
   1.642 +		num_mds = i;
   1.643  	}
   1.644 -	sort(efi_memmap, i, sizeof(efi_memory_desc_t), efi_mdt_cmp, NULL);
   1.645 +	else {
   1.646 +		/* pass through the I/O port space */
   1.647 +		struct dom0_passthrough_arg arg;
   1.648 +		u64 addr;
   1.649 +		int j;
   1.650  
   1.651 -	bp->efi_systab = dom_pa((unsigned long) fw_mem);
   1.652 -	bp->efi_memmap = dom_pa((unsigned long) efi_memmap);
   1.653 -	BUG_ON(i > NUM_MEM_DESCS);
   1.654 -	bp->efi_memmap_size = i * sizeof(efi_memory_desc_t);
   1.655 -	bp->efi_memdesc_size = sizeof(efi_memory_desc_t);
   1.656 -	bp->efi_memdesc_version = EFI_MEMDESC_VERSION;
   1.657 -	bp->command_line = 0;
   1.658 -	bp->console_info.num_cols = 80;
   1.659 -	bp->console_info.num_rows = 25;
   1.660 -	bp->console_info.orig_x = 0;
   1.661 -	bp->console_info.orig_y = 24;
   1.662 -	bp->fpswa = dom_pa((unsigned long) fpswa_inf);
   1.663 -	if (d == dom0) {
   1.664 -		int j;
   1.665 -		u64 addr;
   1.666 +		/* Fill from real entries.  */
   1.667 +		arg.md = &tables->efi_memmap[i];
   1.668 +		arg.i = &i;
   1.669 +		arg.d = d;
   1.670 +		arg.flags = ASSIGN_writable;
   1.671 +		//XXX Is this needed?
   1.672 +		efi_memmap_walk_type(EFI_RUNTIME_SERVICES_CODE,
   1.673 +		                     dom_fw_dom0_passthrough, &arg);
   1.674 +		// for ACPI table.
   1.675 +		arg.flags = ASSIGN_readonly;
   1.676 +		efi_memmap_walk_type(EFI_RUNTIME_SERVICES_DATA,
   1.677 +		                     dom_fw_dom0_passthrough, &arg);
   1.678 +		arg.flags = ASSIGN_writable;
   1.679 +		efi_memmap_walk_type(EFI_ACPI_RECLAIM_MEMORY,
   1.680 +		                     dom_fw_dom0_passthrough, &arg);
   1.681 +		efi_memmap_walk_type(EFI_ACPI_MEMORY_NVS,
   1.682 +		                     dom_fw_dom0_passthrough, &arg);
   1.683 +		efi_memmap_walk_type(EFI_MEMORY_MAPPED_IO,
   1.684 +		                     dom_fw_dom0_passthrough, &arg);
   1.685 +		efi_memmap_walk_type(EFI_MEMORY_MAPPED_IO_PORT_SPACE,
   1.686 +		                     dom_fw_dom0_passthrough, &arg);
   1.687 +		efi_memmap_walk_type(EFI_CONVENTIONAL_MEMORY,
   1.688 +		                     dom_fw_dom0_lowmem, &arg);
   1.689 +		num_mds = i;
   1.690 +
   1.691 +		sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t),
   1.692 +		     efi_mdt_cmp, NULL);
   1.693 +
   1.694 +		// find gaps and fill them with conventional memory
   1.695 +		for (j = 0; j < num_mds; j++) {
   1.696 +			unsigned long end;
   1.697 +			unsigned long next_start;
   1.698 +
   1.699 +			md = &tables->efi_memmap[j];
   1.700 +			end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
   1.701 +
   1.702 +			if (j + 1 < num_mds) {
   1.703 +				efi_memory_desc_t* next_md;
   1.704 +				next_md = &tables->efi_memmap[j+1];
   1.705 +				next_start = next_md->phys_addr;
   1.706 +				
   1.707 +				/* Have just been sorted.  */
   1.708 +				BUG_ON(end > next_start);
   1.709 +				
   1.710 +				/* No room for memory!  */
   1.711 +				if (end == next_start)
   1.712 +					continue;
   1.713 +				
   1.714 +				if (next_start > maxmem)
   1.715 +					next_start = maxmem;
   1.716 +			}
   1.717 +			else
   1.718 +				next_start = maxmem;
   1.719 +			
   1.720 +			/* Avoid "legacy" low memory addresses and
   1.721 +			   the HYPERCALL area.  */
   1.722 +			if (end < ONE_MB)
   1.723 +				end = ONE_MB;
   1.724 +						      
   1.725 +			// clip the range and align to PAGE_SIZE
   1.726 +			next_start = next_start & PAGE_MASK;
   1.727 +			end = PAGE_ALIGN(end);
   1.728 +			
   1.729 +			/* No room for memory.  */
   1.730 +			if (end >= next_start)
   1.731 +				continue;
   1.732 +
   1.733 +			MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   1.734 +			        end, next_start);
   1.735 +
   1.736 +			if (next_start >= maxmem)
   1.737 +				break;
   1.738 +		}
   1.739 +		num_mds = i;
   1.740 +		BUG_ON(num_mds > NUM_MEM_DESCS);
   1.741 +		sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t),
   1.742 +		     efi_mdt_cmp, NULL);
   1.743  
   1.744  		// dom0 doesn't need build_physmap_table()
   1.745  		// see arch_set_info_guest()
   1.746  		// instead we allocate pages manually.
   1.747 -		for (j = 0; j < i; j++) {
   1.748 -			md = &efi_memmap[j];
   1.749 +		for (i = 0; i < num_mds; i++) {
   1.750 +			md = &tables->efi_memmap[i];
   1.751  			if (md->phys_addr > maxmem)
   1.752  				break;
   1.753  
   1.754 @@ -898,18 +861,20 @@ dom_fw_init (struct domain *d, struct ia
   1.755  
   1.756  				if (end == start) {
   1.757  					// md->num_pages = 0 is allowed.
   1.758 -					end += PAGE_SIZE;
   1.759 +					continue;
   1.760  				}
   1.761  				if (end > (max_page << PAGE_SHIFT))
   1.762  					end = (max_page << PAGE_SHIFT);
   1.763  
   1.764 -				for (addr = start; addr < end; addr += PAGE_SIZE) {
   1.765 +				for (addr = start;
   1.766 +				     addr < end;
   1.767 +				     addr += PAGE_SIZE) {
   1.768  					assign_new_domain0_page(d, addr);
   1.769  				}
   1.770  			}
   1.771  		}
   1.772  		// Map low-memory holes & unmapped MMIO for legacy drivers
   1.773 -		for (addr = 0; addr < 1*MB; addr += PAGE_SIZE) {
   1.774 +		for (addr = 0; addr < ONE_MB; addr += PAGE_SIZE) {
   1.775  			if (domain_page_mapped(d, addr))
   1.776  				continue;
   1.777  					
   1.778 @@ -917,8 +882,41 @@ dom_fw_init (struct domain *d, struct ia
   1.779  				assign_domain_mmio_page(d, addr, PAGE_SIZE);
   1.780  		}
   1.781  	}
   1.782 -	for (i = 0 ; i < bp->efi_memmap_size/sizeof(efi_memory_desc_t) ; i++) {
   1.783 -		md = efi_memmap + i;
   1.784 -		print_md(md);
   1.785 -	}
   1.786 +
   1.787 +	/* Display memmap.  */
   1.788 +	for (i = 0 ; i < num_mds; i++)
   1.789 +		print_md(&tables->efi_memmap[i]);
   1.790 +
   1.791 +	/* Fill boot_param  */
   1.792 +	bp->efi_systab = dom_pa((unsigned long)&tables->efi_systab);
   1.793 +	bp->efi_memmap = dom_pa((unsigned long)tables->efi_memmap);
   1.794 +	bp->efi_memmap_size = num_mds * sizeof(efi_memory_desc_t);
   1.795 +	bp->efi_memdesc_size = sizeof(efi_memory_desc_t);
   1.796 +	bp->efi_memdesc_version = EFI_MEMDESC_VERSION;
   1.797 +	bp->command_line = 0;
   1.798 +	bp->console_info.num_cols = 80;
   1.799 +	bp->console_info.num_rows = 25;
   1.800 +	bp->console_info.orig_x = 0;
   1.801 +	bp->console_info.orig_y = 24;
   1.802 +	bp->fpswa = dom_pa((unsigned long) &tables->fpswa_inf);
   1.803  }
   1.804 +
   1.805 +void dom_fw_setup(struct domain *d, unsigned long bp_mpa, unsigned long maxmem)
   1.806 +{
   1.807 +	struct ia64_boot_param *bp;
   1.808 +
   1.809 +	/* Note: 4KB < size < 8KB.  */
   1.810 +	BUILD_BUG_ON(sizeof(struct fw_tables) > PAGE_SIZE);
   1.811 +
   1.812 +	dom_fw_end_mpa = PAGE_ALIGN(dom_fw_base_mpa + sizeof(struct fw_tables));
   1.813 +
   1.814 +	/* Create page for hypercalls.  */
   1.815 +	assign_new_domain_page_if_dom0(d, dom_fw_base_mpa);
   1.816 +	imva_fw_base = (unsigned long)domain_mpa_to_imva(d, dom_fw_base_mpa);
   1.817 +
   1.818 +	/* Create page for boot_param.  */
   1.819 +	assign_new_domain_page_if_dom0(d, bp_mpa);
   1.820 +	bp = domain_mpa_to_imva(d, bp_mpa);
   1.821 +
   1.822 +	dom_fw_init(d, bp, (struct fw_tables *)imva_fw_base, maxmem);
   1.823 +}
     2.1 --- a/xen/include/asm-ia64/dom_fw.h	Fri Aug 25 15:06:18 2006 -0600
     2.2 +++ b/xen/include/asm-ia64/dom_fw.h	Fri Aug 25 15:52:31 2006 -0600
     2.3 @@ -7,18 +7,17 @@
     2.4  
     2.5  #include <linux/efi.h>
     2.6  
     2.7 -#ifndef MB
     2.8 -#define MB (1024*1024)
     2.9 -#endif
    2.10 -
    2.11  /* This is used to determined the portion of a domain's metaphysical memory
    2.12     space reserved for the hypercall patch table. */
    2.13 -//FIXME: experiment with smaller sizes
    2.14 -#define HYPERCALL_START	1UL*MB
    2.15 -#define HYPERCALL_END	2UL*MB
    2.16 -
    2.17 -#define FW_HYPERCALL_BASE_PADDR HYPERCALL_START
    2.18 -#define	FW_HYPERCALL_END_PADDR HYPERCALL_END
    2.19 +/* Map:
    2.20 +   Index           Addr
    2.21 +   0x0000-0x000f   0x0000-0x00ff  : unused
    2.22 +   0x0010-0x001f   0x0100-0x01ff  : EFI
    2.23 +   0x0080-0x008f   0x0800-0x08ff  : PAL/SAL
    2.24 +   0x0090-0x009f   0x0900-0x09ff  : FPSWA
    2.25 +*/
    2.26 +#define	FW_HYPERCALL_BASE_PADDR 0x0000UL
    2.27 +#define	FW_HYPERCALL_END_PADDR  0X1000UL
    2.28  #define	FW_HYPERCALL_PADDR(index) (FW_HYPERCALL_BASE_PADDR + (16UL * index))
    2.29  
    2.30  /* Hypercalls number have a low part and a high part.
    2.31 @@ -91,16 +90,16 @@
    2.32   */
    2.33  
    2.34  /* these are indexes into the runtime services table */
    2.35 -#define FW_HYPERCALL_EFI_GET_TIME_INDEX			0UL
    2.36 -#define FW_HYPERCALL_EFI_SET_TIME_INDEX			1UL
    2.37 -#define FW_HYPERCALL_EFI_GET_WAKEUP_TIME_INDEX		2UL
    2.38 -#define FW_HYPERCALL_EFI_SET_WAKEUP_TIME_INDEX		3UL
    2.39 -#define FW_HYPERCALL_EFI_SET_VIRTUAL_ADDRESS_MAP_INDEX	4UL
    2.40 -#define FW_HYPERCALL_EFI_GET_VARIABLE_INDEX		5UL
    2.41 -#define FW_HYPERCALL_EFI_GET_NEXT_VARIABLE_INDEX	6UL
    2.42 -#define FW_HYPERCALL_EFI_SET_VARIABLE_INDEX		7UL
    2.43 -#define FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_INDEX	8UL
    2.44 -#define FW_HYPERCALL_EFI_RESET_SYSTEM_INDEX		9UL
    2.45 +#define FW_HYPERCALL_EFI_GET_TIME_INDEX			0x10UL
    2.46 +#define FW_HYPERCALL_EFI_SET_TIME_INDEX			0x11UL
    2.47 +#define FW_HYPERCALL_EFI_GET_WAKEUP_TIME_INDEX		0x12UL
    2.48 +#define FW_HYPERCALL_EFI_SET_WAKEUP_TIME_INDEX		0x13UL
    2.49 +#define FW_HYPERCALL_EFI_SET_VIRTUAL_ADDRESS_MAP_INDEX	0x14UL
    2.50 +#define FW_HYPERCALL_EFI_GET_VARIABLE_INDEX		0x15UL
    2.51 +#define FW_HYPERCALL_EFI_GET_NEXT_VARIABLE_INDEX	0x16UL
    2.52 +#define FW_HYPERCALL_EFI_SET_VARIABLE_INDEX		0x17UL
    2.53 +#define FW_HYPERCALL_EFI_GET_NEXT_HIGH_MONO_COUNT_INDEX	0x18UL
    2.54 +#define FW_HYPERCALL_EFI_RESET_SYSTEM_INDEX		0x19UL
    2.55  
    2.56  /* these are hypercall numbers */
    2.57  #define FW_HYPERCALL_EFI_CALL				0x300UL