mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-02 02:03:20 +00:00
hv: EFI can load Hypervisor to address other than COMNFIG_RAM_START
- UEFI: change __emalloc() function to allocate from any available memory under 4G - Define CONFIG_RAM_START to the lowest possible address 1M, making sure HV can only be relocated to higher address Signed-off-by: Zheng Gen <gen.zheng@intel.com> Signed-off-by: Zide Chen <zide.chen@intel.com> Reviewed-by: Yin fengwei <fengwei.yin@intel.com>
This commit is contained in:
parent
84d9da1d6a
commit
6c9e451b41
@ -94,7 +94,7 @@ config LOW_RAM_SIZE
|
||||
config RAM_START
|
||||
hex "Address of the RAM region assigned to the hypervisor"
|
||||
default 0x6e000000 if PLATFORM_SBL
|
||||
default 0x20000000 if PLATFORM_UEFI
|
||||
default 0x00100000 if PLATFORM_UEFI
|
||||
|
||||
config RAM_SIZE
|
||||
hex "Size of the RAM region assigned to the hypervisor"
|
||||
|
@ -41,6 +41,7 @@ EFI_SYSTEM_TABLE *sys_table;
|
||||
EFI_BOOT_SERVICES *boot;
|
||||
char *cmdline = NULL;
|
||||
extern const uint64_t guest_entry;
|
||||
static UINT64 hv_hpa;
|
||||
|
||||
static inline void hv_jump(EFI_PHYSICAL_ADDRESS hv_start,
|
||||
struct multiboot_info *mbi, struct efi_ctx *efi_ctx)
|
||||
@ -185,7 +186,7 @@ again:
|
||||
/* switch hv memory region(0x20000000 ~ 0x22000000) to
|
||||
* available RAM in e820 table
|
||||
*/
|
||||
mmap[j].mm_base_addr = CONFIG_RAM_START;
|
||||
mmap[j].mm_base_addr = hv_hpa;
|
||||
mmap[j].mm_length = CONFIG_RAM_SIZE;
|
||||
mmap[j].mm_type = E820_RAM;
|
||||
j++;
|
||||
@ -307,7 +308,7 @@ switch_to_guest_mode(EFI_HANDLE image)
|
||||
asm volatile ("movq %%r14, %0" : "=r"(efi_ctx->r14));
|
||||
asm volatile ("movq %%r15, %0" : "=r"(efi_ctx->r15));
|
||||
|
||||
hv_jump(CONFIG_RAM_START, mbi, efi_ctx);
|
||||
hv_jump(hv_hpa, mbi, efi_ctx);
|
||||
asm volatile (".global guest_entry\n\t"
|
||||
"guest_entry:\n\t");
|
||||
|
||||
@ -331,7 +332,6 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table)
|
||||
WCHAR *error_buf;
|
||||
EFI_STATUS err;
|
||||
EFI_LOADED_IMAGE *info;
|
||||
EFI_PHYSICAL_ADDRESS addr;
|
||||
UINTN sec_addr;
|
||||
UINTN sec_size;
|
||||
char *section;
|
||||
@ -393,13 +393,12 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *_table)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
err = __emalloc(CONFIG_RAM_SIZE, CONFIG_RAM_START, &addr,
|
||||
EfiReservedMemoryType);
|
||||
err = __emalloc(CONFIG_RAM_SIZE, CONFIG_RAM_START, &hv_hpa,
|
||||
EfiReservedMemoryType);
|
||||
if (err != EFI_SUCCESS)
|
||||
goto failed;
|
||||
|
||||
/* Copy ACRNHV binary to fixed phys addr. LoadImage and StartImage ?? */
|
||||
memcpy((char*)addr, info->ImageBase + sec_addr, sec_size);
|
||||
memcpy((char *)hv_hpa, info->ImageBase + sec_addr, sec_size);
|
||||
|
||||
/* load hypervisor and begin to run on it */
|
||||
err = switch_to_guest_mode(image);
|
||||
|
@ -223,11 +223,7 @@ fail:
|
||||
return err;
|
||||
}
|
||||
|
||||
/* FIXME: This function cannot guarantee to return address under 4G,
|
||||
* and the hypervisor cannot handle params, which address is above 4G,
|
||||
* delivered from efi stub.
|
||||
*/
|
||||
EFI_STATUS __emalloc(UINTN size, UINTN align, EFI_PHYSICAL_ADDRESS *addr,
|
||||
EFI_STATUS __emalloc(UINTN size, UINTN min_addr, EFI_PHYSICAL_ADDRESS *addr,
|
||||
EFI_MEMORY_TYPE mem_type)
|
||||
{
|
||||
UINTN map_size, map_key, desc_size;
|
||||
@ -244,48 +240,46 @@ EFI_STATUS __emalloc(UINTN size, UINTN align, EFI_PHYSICAL_ADDRESS *addr,
|
||||
|
||||
d = (UINTN)map_buf;
|
||||
map_end = (UINTN)map_buf + map_size;
|
||||
size = nr_pages << EFI_PAGE_SHIFT;
|
||||
|
||||
for (; d < map_end; d += desc_size) {
|
||||
EFI_MEMORY_DESCRIPTOR *desc;
|
||||
EFI_PHYSICAL_ADDRESS start, end, aligned;
|
||||
|
||||
desc = (EFI_MEMORY_DESCRIPTOR *)d;
|
||||
if (desc->Type != EfiConventionalMemory)
|
||||
continue;
|
||||
|
||||
if (desc->NumberOfPages < nr_pages)
|
||||
continue;
|
||||
|
||||
start = desc->PhysicalStart;
|
||||
end = start + (desc->NumberOfPages << EFI_PAGE_SHIFT);
|
||||
|
||||
/* Low-memory is super-precious! */
|
||||
if (end <= 1 << 20)
|
||||
continue;
|
||||
if (start < 1 << 20) {
|
||||
size -= (1 << 20) - start;
|
||||
start = (1 << 20);
|
||||
if ((min_addr > start) && (min_addr < end)) {
|
||||
start = min_addr;
|
||||
}
|
||||
|
||||
aligned = align;//(start + align -1) & ~(align -1);
|
||||
start = (start + EFI_PAGE_SIZE - 1) & ~(EFI_PAGE_SIZE - 1);
|
||||
|
||||
/*
|
||||
* Low-memory is super-precious!
|
||||
* Also we don't allocate from address over 4G
|
||||
*/
|
||||
if ((desc->Type != EfiConventionalMemory) ||
|
||||
(desc->NumberOfPages < nr_pages) ||
|
||||
(start < (1ULL << 20)) ||
|
||||
((start + size) > end) ||
|
||||
((start + size) >= (1UL << 32))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((aligned + size) <= end) {
|
||||
//Print(L"trying to allocate memory at %0x!\n", aligned);
|
||||
err = allocate_pages(AllocateAddress, mem_type,
|
||||
nr_pages, &aligned);
|
||||
if (err == EFI_SUCCESS) {
|
||||
//Print(L"trying to allocate memory at %0x, success!\n", aligned);
|
||||
*addr = aligned;
|
||||
break;
|
||||
} {
|
||||
//Print(L"trying to allocate memory at %0x, failure!\n", aligned);
|
||||
}
|
||||
aligned = start;
|
||||
err = allocate_pages(AllocateAddress, mem_type,
|
||||
nr_pages, &aligned);
|
||||
if (err == EFI_SUCCESS) {
|
||||
*addr = aligned;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (d == map_end)
|
||||
if (d == map_end) {
|
||||
err = EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
free_pool(map_buf);
|
||||
fail:
|
||||
|
@ -18,7 +18,12 @@
|
||||
#define CONSOLE_LOGLEVEL_DEFAULT 3
|
||||
#define MEM_LOGLEVEL_DEFAULT 5
|
||||
#define CONFIG_LOW_RAM_SIZE 0x00010000
|
||||
#define CONFIG_RAM_START 0x20000000
|
||||
|
||||
/*
|
||||
* By default build the hypervisor in low address
|
||||
* so that it can only relocate to higher address
|
||||
*/
|
||||
#define CONFIG_RAM_START 0x00100000
|
||||
#define CONFIG_RAM_SIZE 0x02000000 /* 32M */
|
||||
#define CONFIG_DMAR_PARSE_ENABLED 1
|
||||
#define CONFIG_GPU_SBDF 0x00000010 /* 0000:00:02.0 */
|
||||
|
Loading…
Reference in New Issue
Block a user