diff options
author | Keir Fraser <keir@xen.org> | 2011-07-23 09:43:47 +0100 |
---|---|---|
committer | Keir Fraser <keir@xen.org> | 2011-07-23 09:43:47 +0100 |
commit | dc21926aff31c26c2c291fe02ecf7c31e956a921 (patch) | |
tree | 1013e0b0322dbb83b4aa5dd6a01b702b04be2956 /tools/firmware | |
parent | b74ae3bf6395569694e77f98fef5eb9ea31d3229 (diff) | |
download | xen-dc21926aff31c26c2c291fe02ecf7c31e956a921.tar.gz xen-dc21926aff31c26c2c291fe02ecf7c31e956a921.tar.bz2 xen-dc21926aff31c26c2c291fe02ecf7c31e956a921.zip |
hvmloader: New functions mem_hole_alloc() and mem_hole_populate_ram().
These can be used by BIOS-specific handlers to set up memory regions
as required by their firmware payload.
Use mem_hole_alloc() to allocate properly reserved space for the
shared-info-page mapping. The old location conflicts with space
required for the OVMF BIOS (support for which is work in progress).
Signed-off-by: Keir Fraser <keir@xen.org>
Diffstat (limited to 'tools/firmware')
-rw-r--r-- | tools/firmware/hvmloader/util.c | 50 | ||||
-rw-r--r-- | tools/firmware/hvmloader/util.h | 7 |
2 files changed, 39 insertions, 18 deletions
diff --git a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c index 1180cbc566..0801fb6aac 100644 --- a/tools/firmware/hvmloader/util.c +++ b/tools/firmware/hvmloader/util.c @@ -303,29 +303,14 @@ uuid_to_string(char *dest, uint8_t *uuid) *p = '\0'; } -void *mem_alloc(uint32_t size, uint32_t align) +void mem_hole_populate_ram(xen_pfn_t mfn, uint32_t nr_mfns) { - static uint32_t reserve = RESERVED_MEMBASE - 1; static int over_allocated; struct xen_add_to_physmap xatp; struct xen_memory_reservation xmr; - xen_pfn_t mfn; - uint32_t s, e; - - /* Align to at least 16 bytes. */ - if ( align < 16 ) - align = 16; - s = (reserve + align) & ~(align - 1); - e = s + size - 1; - - BUG_ON((e < s) || (e >> PAGE_SHIFT) >= hvm_info->reserved_mem_pgstart); - - while ( (reserve >> PAGE_SHIFT) != (e >> PAGE_SHIFT) ) + for ( ; nr_mfns-- != 0; mfn++ ) { - reserve += PAGE_SIZE; - mfn = reserve >> PAGE_SHIFT; - /* Try to allocate a brand new page in the reserved area. */ if ( !over_allocated ) { @@ -356,6 +341,35 @@ void *mem_alloc(uint32_t size, uint32_t align) if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) BUG(); } +} + +static uint32_t reserve = RESERVED_MEMBASE - 1; + +xen_pfn_t mem_hole_alloc(uint32_t nr_mfns) +{ + hvm_info->reserved_mem_pgstart -= nr_mfns; + BUG_ON(hvm_info->reserved_mem_pgstart <= (reserve >> PAGE_SHIFT)); + return hvm_info->reserved_mem_pgstart; +} + +void *mem_alloc(uint32_t size, uint32_t align) +{ + uint32_t s, e; + + /* Align to at least 16 bytes. */ + if ( align < 16 ) + align = 16; + + s = (reserve + align) & ~(align - 1); + e = s + size - 1; + + BUG_ON((e < s) || (e >> PAGE_SHIFT) >= hvm_info->reserved_mem_pgstart); + + while ( (reserve >> PAGE_SHIFT) != (e >> PAGE_SHIFT) ) + { + reserve += PAGE_SIZE; + mem_hole_populate_ram(reserve >> PAGE_SHIFT, 1); + } reserve = e; @@ -635,7 +649,7 @@ struct shared_info *get_shared_info(void) xatp.domid = DOMID_SELF; xatp.space = XENMAPSPACE_shared_info; xatp.idx = 0; - xatp.gpfn = 0xfffffu; + xatp.gpfn = mem_hole_alloc(1); shared_info = (struct shared_info *)(xatp.gpfn << PAGE_SHIFT); if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) BUG(); diff --git a/tools/firmware/hvmloader/util.h b/tools/firmware/hvmloader/util.h index 5d0798c47f..3c253ea64b 100644 --- a/tools/firmware/hvmloader/util.h +++ b/tools/firmware/hvmloader/util.h @@ -3,6 +3,7 @@ #include <stdarg.h> #include <stdint.h> +#include <xen/xen.h> #include <xen/hvm/hvm_info_table.h> #define __STR(...) #__VA_ARGS__ @@ -164,6 +165,12 @@ void uuid_to_string(char *dest, uint8_t *uuid); int printf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); int vprintf(const char *fmt, va_list ap); +/* Populate specified memory hole with RAM. */ +void mem_hole_populate_ram(xen_pfn_t mfn, uint32_t nr_mfns); + +/* Allocate a memory hole below 4GB. */ +xen_pfn_t mem_hole_alloc(uint32_t nr_mfns); + /* Allocate memory in a reserved region below 4GB. */ void *mem_alloc(uint32_t size, uint32_t align); #define virt_to_phys(v) ((unsigned long)(v)) |