ia64/xen-unstable

changeset 10438:9031316e5203

[IA64] create MDT entry to cover fw_mem area in dom_fw_init()

- create MDT entry for fw_mem area on dom0 & domU
- leave a hole for this region in dom_fw_dom0_lowmem()
- move inline macros definitions out of function
- consolidate to single conventional memory adding routine for dom0/domU

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author awilliam@xenbuild.aw
date Wed Jun 21 10:15:46 2006 -0600 (2006-06-21)
parents 8314141cfe54
children be0a536b70cc
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	Tue Jun 20 17:02:22 2006 -0600
     1.2 +++ b/xen/arch/ia64/xen/dom_fw.c	Wed Jun 21 10:15:46 2006 -0600
     1.3 @@ -30,10 +30,31 @@ extern unsigned long dom0_start;
     1.4  
     1.5  extern unsigned long running_on_sim;
     1.6  
     1.7 -
     1.8  unsigned long dom_fw_base_mpa = -1;
     1.9  unsigned long imva_fw_base = -1;
    1.10  
    1.11 +#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.12 +
    1.13 +#define MAKE_MD(typ, attr, start, end, abs) 				\
    1.14 +	do {								\
    1.15 +		md = efi_memmap + i++;					\
    1.16 +		md->type = typ;						\
    1.17 +		md->pad = 0;						\
    1.18 +		md->phys_addr = abs ? start : start_mpaddr + start;	\
    1.19 +		md->virt_addr = 0;					\
    1.20 +		md->num_pages = (end - start) >> EFI_PAGE_SHIFT;	\
    1.21 +		md->attribute = attr;					\
    1.22 +	} while (0)
    1.23 +
    1.24 +#define EFI_HYPERCALL_PATCH(tgt, call)					\
    1.25 +	do {								\
    1.26 +		dom_efi_hypercall_patch(d, FW_HYPERCALL_##call##_PADDR,	\
    1.27 +		                        FW_HYPERCALL_##call);		\
    1.28 +		tgt = dom_pa((unsigned long) pfn);			\
    1.29 +		*pfn++ = FW_HYPERCALL_##call##_PADDR + start_mpaddr;	\
    1.30 +		*pfn++ = 0;						\
    1.31 +	} while (0)
    1.32 +
    1.33  // return domain (meta)physical address for a given imva
    1.34  // this function is a call-back from dom_fw_init
    1.35  static unsigned long
    1.36 @@ -139,14 +160,13 @@ unsigned long dom_fw_setup(struct domain
    1.37  
    1.38  #define NFUNCPTRS 20
    1.39  
    1.40 -static void print_md(efi_memory_desc_t *md)
    1.41 +static inline void
    1.42 +print_md(efi_memory_desc_t *md)
    1.43  {
    1.44 -#if 1
    1.45  	printk("domain mem: type=%2u, attr=0x%016lx, range=[0x%016lx-0x%016lx) (%luMB)\n",
    1.46  		md->type, md->attribute, md->phys_addr,
    1.47  		md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
    1.48  		md->num_pages >> (20 - EFI_PAGE_SHIFT));
    1.49 -#endif
    1.50  }
    1.51  
    1.52  static u32 lsapic_nbr;
    1.53 @@ -424,7 +444,6 @@ dom_fw_dom0_passthrough(efi_memory_desc_
    1.54      arg->md->virt_addr = 0;
    1.55      arg->md->num_pages = md->num_pages;
    1.56      arg->md->attribute = md->attribute;
    1.57 -    print_md(arg->md);
    1.58  
    1.59      (*arg->i)++;
    1.60      arg->md++;
    1.61 @@ -440,15 +459,23 @@ static int
    1.62  dom_fw_dom0_lowmem(efi_memory_desc_t *md, void *arg__)
    1.63  {
    1.64      struct dom0_passthrough_arg* arg = (struct dom0_passthrough_arg*)arg__;
    1.65 -    u64 end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
    1.66 +    u64 end = min(HYPERCALL_START,
    1.67 +                  md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
    1.68  
    1.69      BUG_ON(md->type != EFI_CONVENTIONAL_MEMORY);
    1.70  
    1.71 -    if (md->phys_addr >= 1*MB)
    1.72 +    /* avoid hypercall area */
    1.73 +    if (md->phys_addr >= HYPERCALL_START)
    1.74          return 0;
    1.75  
    1.76 -    if (end > 1*MB)
    1.77 -        end = 1*MB;
    1.78 +    /* avoid firmware base area */
    1.79 +    if (md->phys_addr < dom_pa(imva_fw_base))
    1.80 +        end = min(end, dom_pa(imva_fw_base));
    1.81 +    else if (md->phys_addr < dom_pa(imva_fw_base + PAGE_SIZE)) {
    1.82 +        if (end < dom_pa(imva_fw_base + PAGE_SIZE))
    1.83 +            return 0;
    1.84 +        md->phys_addr = dom_pa(imva_fw_base + PAGE_SIZE);
    1.85 +    }
    1.86  
    1.87      arg->md->type = md->type;
    1.88      arg->md->pad = 0;
    1.89 @@ -456,10 +483,26 @@ dom_fw_dom0_lowmem(efi_memory_desc_t *md
    1.90      arg->md->virt_addr = 0;
    1.91      arg->md->num_pages = (end - md->phys_addr) >> EFI_PAGE_SHIFT;
    1.92      arg->md->attribute = md->attribute;
    1.93 -    print_md(arg->md);
    1.94  
    1.95      (*arg->i)++;
    1.96      arg->md++;
    1.97 +
    1.98 +    /* if firmware area spliced the md, add the upper part here */
    1.99 +    if (end == dom_pa(imva_fw_base)) {
   1.100 +        end = min(HYPERCALL_START,
   1.101 +                  md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
   1.102 +	if (end > dom_pa(imva_fw_base + PAGE_SIZE)) {
   1.103 +            arg->md->type = md->type;
   1.104 +            arg->md->pad = 0;
   1.105 +            arg->md->phys_addr = dom_pa(imva_fw_base + PAGE_SIZE);
   1.106 +            arg->md->virt_addr = 0;
   1.107 +            arg->md->num_pages = (end - arg->md->phys_addr) >> EFI_PAGE_SHIFT;
   1.108 +            arg->md->attribute = md->attribute;
   1.109 +
   1.110 +            (*arg->i)++;
   1.111 +            arg->md++;
   1.112 +        }
   1.113 +    }
   1.114      return 0;
   1.115  }
   1.116  
   1.117 @@ -497,7 +540,7 @@ dom_fw_init (struct domain *d, const cha
   1.118  	unsigned long *pfn;
   1.119  	unsigned char checksum = 0;
   1.120  	char *cp, *cmd_line, *fw_vendor;
   1.121 -	int i = 0;
   1.122 +	int num_mds, j, i = 0;
   1.123  	unsigned long maxmem = (d->max_pages - d->arch.sys_pgnr) * PAGE_SIZE;
   1.124  #ifdef CONFIG_XEN_IA64_DOM0_VP
   1.125  	const unsigned long start_mpaddr = 0;
   1.126 @@ -505,18 +548,6 @@ dom_fw_init (struct domain *d, const cha
   1.127  	const unsigned long start_mpaddr = ((d==dom0)?dom0_start:0);
   1.128  #endif
   1.129  
   1.130 -#	define MAKE_MD(typ, attr, start, end, abs) 	\
   1.131 -	do {						\
   1.132 -		md = efi_memmap + i++;			\
   1.133 -		md->type = typ;				\
   1.134 -		md->pad = 0;				\
   1.135 -		md->phys_addr = abs ? start : start_mpaddr + start;	\
   1.136 -		md->virt_addr = 0;			\
   1.137 -		md->num_pages = (end - start) >> 12;	\
   1.138 -		md->attribute = attr;			\
   1.139 -		print_md(md);				\
   1.140 -	} while (0)
   1.141 -
   1.142  /* FIXME: should check size but for now we have a whole MB to play with.
   1.143     And if stealing code from fw-emu.c, watch out for new fw_vendor on the end!
   1.144  	if (fw_mem_size < sizeof(fw_mem_proto)) {
   1.145 @@ -557,7 +588,6 @@ dom_fw_init (struct domain *d, const cha
   1.146  	efi_systab->hdr.revision  = EFI_SYSTEM_TABLE_REVISION;
   1.147  	efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
   1.148  	cp = fw_vendor = &cmd_line[arglen] + (2-(arglen&1)); // round to 16-bit boundary
   1.149 -#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.150  	cp += sizeof(FW_VENDOR) + (8-((unsigned long)cp & 7)); // round to 64-bit boundary
   1.151  
   1.152  	memcpy(fw_vendor,FW_VENDOR,sizeof(FW_VENDOR));
   1.153 @@ -571,12 +601,6 @@ dom_fw_init (struct domain *d, const cha
   1.154  	efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
   1.155  	efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
   1.156  	efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
   1.157 -#define EFI_HYPERCALL_PATCH(tgt,call) do { \
   1.158 -    dom_efi_hypercall_patch(d,FW_HYPERCALL_##call##_PADDR,FW_HYPERCALL_##call); \
   1.159 -    tgt = dom_pa((unsigned long) pfn); \
   1.160 -    *pfn++ = FW_HYPERCALL_##call##_PADDR + start_mpaddr; \
   1.161 -    *pfn++ = 0; \
   1.162 -    } while (0)
   1.163  
   1.164  	EFI_HYPERCALL_PATCH(efi_runtime->get_time,EFI_GET_TIME);
   1.165  	EFI_HYPERCALL_PATCH(efi_runtime->set_time,EFI_SET_TIME);
   1.166 @@ -690,7 +714,13 @@ dom_fw_init (struct domain *d, const cha
   1.167  	dom_fpswa_hypercall_patch(d);
   1.168  	fpswa_inf->fpswa = (void *) FW_HYPERCALL_FPSWA_ENTRY_PADDR + start_mpaddr;
   1.169  
   1.170 -	i = 0;
   1.171 +	i = 0; /* Used by MAKE_MD */
   1.172 +
   1.173 +	/* Create dom0/domu md entry for fw_mem area */
   1.174 +	MAKE_MD(EFI_ACPI_RECLAIM_MEMORY, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
   1.175 +	        dom_pa((unsigned long)fw_mem),
   1.176 +	        dom_pa((unsigned long)fw_mem + fw_mem_size), 1);
   1.177 +
   1.178  	if (d == dom0) {
   1.179  #ifndef CONFIG_XEN_IA64_DOM0_VP
   1.180  		/*
   1.181 @@ -708,9 +738,6 @@ dom_fw_init (struct domain *d, const cha
   1.182  
   1.183  		/* simulate 1MB free memory at physical address zero */
   1.184  		MAKE_MD(EFI_LOADER_DATA,EFI_MEMORY_WB,0*MB,1*MB, 0);//XXX
   1.185 -#else
   1.186 -		int num_mds;
   1.187 -		int j;
   1.188  #endif
   1.189  		/* hypercall patches live here, masquerade as reserved PAL memory */
   1.190  		MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,HYPERCALL_START,HYPERCALL_END, 0);
   1.191 @@ -755,59 +782,13 @@ dom_fw_init (struct domain *d, const cha
   1.192  			                     dom_fw_dom0_lowmem, &arg);
   1.193  		}
   1.194  		else MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
   1.195 -
   1.196 -#ifdef CONFIG_XEN_IA64_DOM0_VP
   1.197 -		// simple
   1.198 -		// MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   1.199 -		//         HYPERCALL_END, maxmem, 0);
   1.200 -		// is not good. Check overlap.
   1.201 -		sort(efi_memmap, i, sizeof(efi_memory_desc_t),
   1.202 -		     efi_mdt_cmp, NULL);
   1.203 -
   1.204 -		// find gap and fill it with conventional memory
   1.205 -		num_mds = i;
   1.206 -		for (j = 0; j < num_mds; j++) {
   1.207 -			unsigned long end;
   1.208 -			unsigned long next_start;
   1.209 -
   1.210 -			md = &efi_memmap[j];
   1.211 -			end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
   1.212 -
   1.213 -			next_start = maxmem;
   1.214 -			if (j + 1 < num_mds) {
   1.215 -				efi_memory_desc_t* next_md = &efi_memmap[j + 1];
   1.216 -				next_start = next_md->phys_addr;
   1.217 -				BUG_ON(end > next_start);
   1.218 -				if (end == next_md->phys_addr)
   1.219 -					continue;
   1.220 -			}
   1.221 -
   1.222 -			// clip the range and align to PAGE_SIZE
   1.223 -			// Avoid "legacy" low memory addresses and the
   1.224 -			// HYPERCALL patch area.      
   1.225 -			if (end < HYPERCALL_END)
   1.226 -				end = HYPERCALL_END;
   1.227 -			if (next_start > maxmem)
   1.228 -				next_start = maxmem;
   1.229 -			end = PAGE_ALIGN(end);
   1.230 -			next_start = next_start & PAGE_MASK;
   1.231 -			if (end >= next_start)
   1.232 -				continue;
   1.233 -
   1.234 -			MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   1.235 -			        end, next_start, 0);
   1.236 -			if (next_start >= maxmem)
   1.237 -				break;
   1.238 -		}
   1.239 -#endif        
   1.240 -	}
   1.241 -	else {
   1.242 +	} else {
   1.243  #ifndef CONFIG_XEN_IA64_DOM0_VP
   1.244  		MAKE_MD(EFI_LOADER_DATA,EFI_MEMORY_WB,0*MB,1*MB, 1);
   1.245 +		MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem, 1);
   1.246  #endif
   1.247  		/* hypercall patches live here, masquerade as reserved PAL memory */
   1.248  		MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,HYPERCALL_START,HYPERCALL_END, 1);
   1.249 -		MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem, 1);
   1.250  		/* Create a dummy entry for IO ports, so that IO accesses are
   1.251  		   trapped by Xen.  */
   1.252  		MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE,EFI_MEMORY_UC,
   1.253 @@ -815,6 +796,50 @@ dom_fw_init (struct domain *d, const cha
   1.254  		MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
   1.255  	}
   1.256  
   1.257 +#ifdef CONFIG_XEN_IA64_DOM0_VP
   1.258 +	// simple
   1.259 +	// MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   1.260 +	//         HYPERCALL_END, maxmem, 0);
   1.261 +	// is not good. Check overlap.
   1.262 +	sort(efi_memmap, i, sizeof(efi_memory_desc_t),
   1.263 +	     efi_mdt_cmp, NULL);
   1.264 +
   1.265 +	// find gap and fill it with conventional memory
   1.266 +	num_mds = i;
   1.267 +	for (j = 0; j < num_mds; j++) {
   1.268 +		unsigned long end;
   1.269 +		unsigned long next_start;
   1.270 +
   1.271 +		md = &efi_memmap[j];
   1.272 +		end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
   1.273 +
   1.274 +		next_start = maxmem;
   1.275 +		if (j + 1 < num_mds) {
   1.276 +			efi_memory_desc_t* next_md = &efi_memmap[j + 1];
   1.277 +			next_start = next_md->phys_addr;
   1.278 +			BUG_ON(end > next_start);
   1.279 +			if (end == next_md->phys_addr)
   1.280 +				continue;
   1.281 +		}
   1.282 +
   1.283 +		// clip the range and align to PAGE_SIZE
   1.284 +		// Avoid "legacy" low memory addresses and the
   1.285 +		// HYPERCALL patch area.      
   1.286 +		if (end < HYPERCALL_END)
   1.287 +			end = HYPERCALL_END;
   1.288 +		if (next_start > maxmem)
   1.289 +			next_start = maxmem;
   1.290 +		end = PAGE_ALIGN(end);
   1.291 +		next_start = next_start & PAGE_MASK;
   1.292 +		if (end >= next_start)
   1.293 +			continue;
   1.294 +
   1.295 +		MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
   1.296 +		        end, next_start, 0);
   1.297 +		if (next_start >= maxmem)
   1.298 +			break;
   1.299 +	}
   1.300 +#endif        
   1.301  	sort(efi_memmap, i, sizeof(efi_memory_desc_t), efi_mdt_cmp, NULL);
   1.302  
   1.303  	bp->efi_systab = dom_pa((unsigned long) fw_mem);
   1.304 @@ -880,6 +905,10 @@ dom_fw_init (struct domain *d, const cha
   1.305  		bp->initrd_start = d->arch.initrd_start;
   1.306  		bp->initrd_size  = d->arch.initrd_len;
   1.307  	}
   1.308 +	for (i = 0 ; i < bp->efi_memmap_size/sizeof(efi_memory_desc_t) ; i++) {
   1.309 +		md = efi_memmap + i;
   1.310 +		print_md(md);
   1.311 +	}
   1.312  	printf(" initrd start 0x%lx", bp->initrd_start);
   1.313  	printf(" initrd size 0x%lx\n", bp->initrd_size);
   1.314  	return bp;
     2.1 --- a/xen/include/asm-ia64/dom_fw.h	Tue Jun 20 17:02:22 2006 -0600
     2.2 +++ b/xen/include/asm-ia64/dom_fw.h	Wed Jun 21 10:15:46 2006 -0600
     2.3 @@ -14,8 +14,8 @@
     2.4  /* This is used to determined the portion of a domain's metaphysical memory
     2.5     space reserved for the hypercall patch table. */
     2.6  //FIXME: experiment with smaller sizes
     2.7 -#define HYPERCALL_START	1*MB
     2.8 -#define HYPERCALL_END	2*MB
     2.9 +#define HYPERCALL_START	1UL*MB
    2.10 +#define HYPERCALL_END	2UL*MB
    2.11  
    2.12  #define FW_HYPERCALL_BASE_PADDR HYPERCALL_START
    2.13  #define	FW_HYPERCALL_END_PADDR HYPERCALL_END