# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 9031316e52030ef5065cd424d117f88abb0106b9
# Parent 8314141cfe543d0e83b15a6eca9569df4b82a0b2
[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@xxxxxx>
---
xen/arch/ia64/xen/dom_fw.c | 195 ++++++++++++++++++++++++------------------
xen/include/asm-ia64/dom_fw.h | 4
2 files changed, 114 insertions(+), 85 deletions(-)
diff -r 8314141cfe54 -r 9031316e5203 xen/arch/ia64/xen/dom_fw.c
--- a/xen/arch/ia64/xen/dom_fw.c Tue Jun 20 17:02:22 2006 -0600
+++ b/xen/arch/ia64/xen/dom_fw.c Wed Jun 21 10:15:46 2006 -0600
@@ -30,9 +30,30 @@ extern unsigned long dom0_start;
extern unsigned long running_on_sim;
-
unsigned long dom_fw_base_mpa = -1;
unsigned long imva_fw_base = -1;
+
+#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"
+
+#define MAKE_MD(typ, attr, start, end, abs) \
+ do { \
+ md = efi_memmap + i++; \
+ md->type = typ; \
+ md->pad = 0; \
+ md->phys_addr = abs ? start : start_mpaddr + start; \
+ md->virt_addr = 0; \
+ md->num_pages = (end - start) >> EFI_PAGE_SHIFT; \
+ md->attribute = attr; \
+ } while (0)
+
+#define EFI_HYPERCALL_PATCH(tgt, call) \
+ do { \
+ dom_efi_hypercall_patch(d, FW_HYPERCALL_##call##_PADDR, \
+ FW_HYPERCALL_##call); \
+ tgt = dom_pa((unsigned long) pfn); \
+ *pfn++ = FW_HYPERCALL_##call##_PADDR + start_mpaddr; \
+ *pfn++ = 0; \
+ } while (0)
// return domain (meta)physical address for a given imva
// this function is a call-back from dom_fw_init
@@ -139,14 +160,13 @@ unsigned long dom_fw_setup(struct domain
#define NFUNCPTRS 20
-static void print_md(efi_memory_desc_t *md)
-{
-#if 1
+static inline void
+print_md(efi_memory_desc_t *md)
+{
printk("domain mem: type=%2u, attr=0x%016lx, range=[0x%016lx-0x%016lx)
(%luMB)\n",
md->type, md->attribute, md->phys_addr,
md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT),
md->num_pages >> (20 - EFI_PAGE_SHIFT));
-#endif
}
static u32 lsapic_nbr;
@@ -424,7 +444,6 @@ dom_fw_dom0_passthrough(efi_memory_desc_
arg->md->virt_addr = 0;
arg->md->num_pages = md->num_pages;
arg->md->attribute = md->attribute;
- print_md(arg->md);
(*arg->i)++;
arg->md++;
@@ -440,15 +459,23 @@ dom_fw_dom0_lowmem(efi_memory_desc_t *md
dom_fw_dom0_lowmem(efi_memory_desc_t *md, void *arg__)
{
struct dom0_passthrough_arg* arg = (struct dom0_passthrough_arg*)arg__;
- u64 end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+ u64 end = min(HYPERCALL_START,
+ md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
BUG_ON(md->type != EFI_CONVENTIONAL_MEMORY);
- if (md->phys_addr >= 1*MB)
+ /* avoid hypercall area */
+ if (md->phys_addr >= HYPERCALL_START)
return 0;
- if (end > 1*MB)
- end = 1*MB;
+ /* avoid firmware base area */
+ if (md->phys_addr < dom_pa(imva_fw_base))
+ end = min(end, dom_pa(imva_fw_base));
+ else if (md->phys_addr < dom_pa(imva_fw_base + PAGE_SIZE)) {
+ if (end < dom_pa(imva_fw_base + PAGE_SIZE))
+ return 0;
+ md->phys_addr = dom_pa(imva_fw_base + PAGE_SIZE);
+ }
arg->md->type = md->type;
arg->md->pad = 0;
@@ -456,10 +483,26 @@ dom_fw_dom0_lowmem(efi_memory_desc_t *md
arg->md->virt_addr = 0;
arg->md->num_pages = (end - md->phys_addr) >> EFI_PAGE_SHIFT;
arg->md->attribute = md->attribute;
- print_md(arg->md);
(*arg->i)++;
arg->md++;
+
+ /* if firmware area spliced the md, add the upper part here */
+ if (end == dom_pa(imva_fw_base)) {
+ end = min(HYPERCALL_START,
+ md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT));
+ if (end > dom_pa(imva_fw_base + PAGE_SIZE)) {
+ arg->md->type = md->type;
+ arg->md->pad = 0;
+ arg->md->phys_addr = dom_pa(imva_fw_base + PAGE_SIZE);
+ arg->md->virt_addr = 0;
+ arg->md->num_pages = (end - arg->md->phys_addr) >> EFI_PAGE_SHIFT;
+ arg->md->attribute = md->attribute;
+
+ (*arg->i)++;
+ arg->md++;
+ }
+ }
return 0;
}
@@ -497,25 +540,13 @@ dom_fw_init (struct domain *d, const cha
unsigned long *pfn;
unsigned char checksum = 0;
char *cp, *cmd_line, *fw_vendor;
- int i = 0;
+ int num_mds, j, i = 0;
unsigned long maxmem = (d->max_pages - d->arch.sys_pgnr) * PAGE_SIZE;
#ifdef CONFIG_XEN_IA64_DOM0_VP
const unsigned long start_mpaddr = 0;
#else
const unsigned long start_mpaddr = ((d==dom0)?dom0_start:0);
#endif
-
-# define MAKE_MD(typ, attr, start, end, abs) \
- do { \
- md = efi_memmap + i++; \
- md->type = typ; \
- md->pad = 0; \
- md->phys_addr = abs ? start : start_mpaddr + start; \
- md->virt_addr = 0; \
- md->num_pages = (end - start) >> 12; \
- md->attribute = attr; \
- print_md(md); \
- } while (0)
/* FIXME: should check size but for now we have a whole MB to play with.
And if stealing code from fw-emu.c, watch out for new fw_vendor on the end!
@@ -557,7 +588,6 @@ dom_fw_init (struct domain *d, const cha
efi_systab->hdr.revision = EFI_SYSTEM_TABLE_REVISION;
efi_systab->hdr.headersize = sizeof(efi_systab->hdr);
cp = fw_vendor = &cmd_line[arglen] + (2-(arglen&1)); // round to 16-bit
boundary
-#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"
cp += sizeof(FW_VENDOR) + (8-((unsigned long)cp & 7)); // round to
64-bit boundary
memcpy(fw_vendor,FW_VENDOR,sizeof(FW_VENDOR));
@@ -571,12 +601,6 @@ dom_fw_init (struct domain *d, const cha
efi_runtime->hdr.signature = EFI_RUNTIME_SERVICES_SIGNATURE;
efi_runtime->hdr.revision = EFI_RUNTIME_SERVICES_REVISION;
efi_runtime->hdr.headersize = sizeof(efi_runtime->hdr);
-#define EFI_HYPERCALL_PATCH(tgt,call) do { \
-
dom_efi_hypercall_patch(d,FW_HYPERCALL_##call##_PADDR,FW_HYPERCALL_##call); \
- tgt = dom_pa((unsigned long) pfn); \
- *pfn++ = FW_HYPERCALL_##call##_PADDR + start_mpaddr; \
- *pfn++ = 0; \
- } while (0)
EFI_HYPERCALL_PATCH(efi_runtime->get_time,EFI_GET_TIME);
EFI_HYPERCALL_PATCH(efi_runtime->set_time,EFI_SET_TIME);
@@ -690,7 +714,13 @@ dom_fw_init (struct domain *d, const cha
dom_fpswa_hypercall_patch(d);
fpswa_inf->fpswa = (void *) FW_HYPERCALL_FPSWA_ENTRY_PADDR +
start_mpaddr;
- i = 0;
+ i = 0; /* Used by MAKE_MD */
+
+ /* Create dom0/domu md entry for fw_mem area */
+ MAKE_MD(EFI_ACPI_RECLAIM_MEMORY, EFI_MEMORY_WB | EFI_MEMORY_RUNTIME,
+ dom_pa((unsigned long)fw_mem),
+ dom_pa((unsigned long)fw_mem + fw_mem_size), 1);
+
if (d == dom0) {
#ifndef CONFIG_XEN_IA64_DOM0_VP
/*
@@ -708,9 +738,6 @@ dom_fw_init (struct domain *d, const cha
/* simulate 1MB free memory at physical address zero */
MAKE_MD(EFI_LOADER_DATA,EFI_MEMORY_WB,0*MB,1*MB, 0);//XXX
-#else
- int num_mds;
- int j;
#endif
/* hypercall patches live here, masquerade as reserved PAL
memory */
MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,HYPERCALL_START,HYPERCALL_END,
0);
@@ -755,59 +782,13 @@ dom_fw_init (struct domain *d, const cha
dom_fw_dom0_lowmem, &arg);
}
else MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
-
-#ifdef CONFIG_XEN_IA64_DOM0_VP
- // simple
- // MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
- // HYPERCALL_END, maxmem, 0);
- // is not good. Check overlap.
- sort(efi_memmap, i, sizeof(efi_memory_desc_t),
- efi_mdt_cmp, NULL);
-
- // find gap and fill it with conventional memory
- num_mds = i;
- for (j = 0; j < num_mds; j++) {
- unsigned long end;
- unsigned long next_start;
-
- md = &efi_memmap[j];
- end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
-
- next_start = maxmem;
- if (j + 1 < num_mds) {
- efi_memory_desc_t* next_md = &efi_memmap[j + 1];
- next_start = next_md->phys_addr;
- BUG_ON(end > next_start);
- if (end == next_md->phys_addr)
- continue;
- }
-
- // clip the range and align to PAGE_SIZE
- // Avoid "legacy" low memory addresses and the
- // HYPERCALL patch area.
- if (end < HYPERCALL_END)
- end = HYPERCALL_END;
- if (next_start > maxmem)
- next_start = maxmem;
- end = PAGE_ALIGN(end);
- next_start = next_start & PAGE_MASK;
- if (end >= next_start)
- continue;
-
- MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
- end, next_start, 0);
- if (next_start >= maxmem)
- break;
- }
-#endif
- }
- else {
+ } else {
#ifndef CONFIG_XEN_IA64_DOM0_VP
MAKE_MD(EFI_LOADER_DATA,EFI_MEMORY_WB,0*MB,1*MB, 1);
+
MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem, 1);
#endif
/* hypercall patches live here, masquerade as reserved PAL
memory */
MAKE_MD(EFI_PAL_CODE,EFI_MEMORY_WB|EFI_MEMORY_RUNTIME,HYPERCALL_START,HYPERCALL_END,
1);
-
MAKE_MD(EFI_CONVENTIONAL_MEMORY,EFI_MEMORY_WB,HYPERCALL_END,maxmem, 1);
/* Create a dummy entry for IO ports, so that IO accesses are
trapped by Xen. */
MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE,EFI_MEMORY_UC,
@@ -815,6 +796,50 @@ dom_fw_init (struct domain *d, const cha
MAKE_MD(EFI_RESERVED_TYPE,0,0,0,0);
}
+#ifdef CONFIG_XEN_IA64_DOM0_VP
+ // simple
+ // MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
+ // HYPERCALL_END, maxmem, 0);
+ // is not good. Check overlap.
+ sort(efi_memmap, i, sizeof(efi_memory_desc_t),
+ efi_mdt_cmp, NULL);
+
+ // find gap and fill it with conventional memory
+ num_mds = i;
+ for (j = 0; j < num_mds; j++) {
+ unsigned long end;
+ unsigned long next_start;
+
+ md = &efi_memmap[j];
+ end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
+
+ next_start = maxmem;
+ if (j + 1 < num_mds) {
+ efi_memory_desc_t* next_md = &efi_memmap[j + 1];
+ next_start = next_md->phys_addr;
+ BUG_ON(end > next_start);
+ if (end == next_md->phys_addr)
+ continue;
+ }
+
+ // clip the range and align to PAGE_SIZE
+ // Avoid "legacy" low memory addresses and the
+ // HYPERCALL patch area.
+ if (end < HYPERCALL_END)
+ end = HYPERCALL_END;
+ if (next_start > maxmem)
+ next_start = maxmem;
+ end = PAGE_ALIGN(end);
+ next_start = next_start & PAGE_MASK;
+ if (end >= next_start)
+ continue;
+
+ MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB,
+ end, next_start, 0);
+ if (next_start >= maxmem)
+ break;
+ }
+#endif
sort(efi_memmap, i, sizeof(efi_memory_desc_t), efi_mdt_cmp, NULL);
bp->efi_systab = dom_pa((unsigned long) fw_mem);
@@ -880,6 +905,10 @@ dom_fw_init (struct domain *d, const cha
bp->initrd_start = d->arch.initrd_start;
bp->initrd_size = d->arch.initrd_len;
}
+ for (i = 0 ; i < bp->efi_memmap_size/sizeof(efi_memory_desc_t) ; i++) {
+ md = efi_memmap + i;
+ print_md(md);
+ }
printf(" initrd start 0x%lx", bp->initrd_start);
printf(" initrd size 0x%lx\n", bp->initrd_size);
return bp;
diff -r 8314141cfe54 -r 9031316e5203 xen/include/asm-ia64/dom_fw.h
--- a/xen/include/asm-ia64/dom_fw.h Tue Jun 20 17:02:22 2006 -0600
+++ b/xen/include/asm-ia64/dom_fw.h Wed Jun 21 10:15:46 2006 -0600
@@ -14,8 +14,8 @@
/* This is used to determined the portion of a domain's metaphysical memory
space reserved for the hypercall patch table. */
//FIXME: experiment with smaller sizes
-#define HYPERCALL_START 1*MB
-#define HYPERCALL_END 2*MB
+#define HYPERCALL_START 1UL*MB
+#define HYPERCALL_END 2UL*MB
#define FW_HYPERCALL_BASE_PADDR HYPERCALL_START
#define FW_HYPERCALL_END_PADDR HYPERCALL_END
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|