diff options
author | Jan Beulich <jbeulich@novell.com> | 2011-08-19 09:54:26 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@novell.com> | 2011-08-19 09:54:26 +0100 |
commit | bc4a68f21f43c2e37346cf5a1f37c19a53b540c2 (patch) | |
tree | 3b4af0bd3182a264bbe3b84a65e21a606e4f43ab /xen/arch/x86/efi | |
parent | 2f399b3bb0cae8072ed42856eac6a805728516fe (diff) | |
download | xen-bc4a68f21f43c2e37346cf5a1f37c19a53b540c2.tar.gz xen-bc4a68f21f43c2e37346cf5a1f37c19a53b540c2.tar.bz2 xen-bc4a68f21f43c2e37346cf5a1f37c19a53b540c2.zip |
x86: make run-time part of trampoline relocatable
In order to eliminate an initial hack in the EFI boot code (where
memory for the trampoline was just "claimed" instead of properly
allocated), the trampoline code must no longer make assumption on the
address at which it would be located. For the time being, the fixed
address is being retained for the traditional multiboot path.
As an additional benefit (at least from my pov) it allows confining
the visibility of the BOOT_TRAMPOLINE definition to just the boot
code.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'xen/arch/x86/efi')
-rw-r--r-- | xen/arch/x86/efi/boot.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/xen/arch/x86/efi/boot.c b/xen/arch/x86/efi/boot.c index 2e9d5532be..fcc2db284f 100644 --- a/xen/arch/x86/efi/boot.c +++ b/xen/arch/x86/efi/boot.c @@ -599,6 +599,9 @@ static void __init relocate_image(unsigned long delta) } } +extern const s32 __trampoline_rel_start[], __trampoline_rel_stop[]; +extern const s32 __trampoline_seg_start[], __trampoline_seg_stop[]; + void EFIAPI __init __attribute__((__noreturn__)) efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) { @@ -614,9 +617,10 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *mode_info; EFI_FILE_HANDLE dir_handle; union string section = { NULL }, name; + const s32 *trampoline_ptr; struct e820entry *e; u64 efer; - bool_t base_video = 0, trampoline_okay = 0; + bool_t base_video = 0; efi_ih = ImageHandle; efi_bs = SystemTable->BootServices; @@ -914,15 +918,27 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) dmi_efi_get_table((void *)(long)efi.smbios); /* Allocate space for trampoline (in first Mb). */ - cfg.addr = BOOT_TRAMPOLINE; + cfg.addr = 0x100000; cfg.size = trampoline_end - trampoline_start; - status = efi_bs->AllocatePages(AllocateAddress, EfiLoaderData, + status = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData, PFN_UP(cfg.size), &cfg.addr); if ( EFI_ERROR(status) ) { cfg.addr = 0; - PrintErr(L"Note: Trampoline area is in use\r\n"); + blexit(L"No memory for trampoline\r\n"); } + trampoline_phys = cfg.addr; + /* Apply relocations to trampoline. */ + for ( trampoline_ptr = __trampoline_rel_start; + trampoline_ptr < __trampoline_rel_stop; + ++trampoline_ptr ) + *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) += + trampoline_phys; + for ( trampoline_ptr = __trampoline_seg_start; + trampoline_ptr < __trampoline_seg_stop; + ++trampoline_ptr ) + *(u16 *)(*trampoline_ptr + (long)trampoline_ptr) = + trampoline_phys >> 4; /* Initialise L2 identity-map and xen page table entries (16MB). */ for ( i = 0; i < 8; ++i ) @@ -1096,14 +1112,8 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) e->type = type; ++e820nr; } - if ( type == E820_RAM && e->addr <= BOOT_TRAMPOLINE && - e->addr + e->size >= BOOT_TRAMPOLINE + cfg.size ) - trampoline_okay = 1; } - if ( !trampoline_okay ) - blexit(L"Trampoline area unavailable\r\n"); - status = efi_bs->ExitBootServices(ImageHandle, map_key); if ( EFI_ERROR(status) ) PrintErrMesg(L"Cannot exit boot services", status); @@ -1117,7 +1127,7 @@ efi_start(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) efi_fw_vendor = (void *)efi_fw_vendor + DIRECTMAP_VIRT_START; relocate_image(__XEN_VIRT_START - xen_phys_start); - memcpy((void *)(long)BOOT_TRAMPOLINE, trampoline_start, cfg.size); + memcpy((void *)trampoline_phys, trampoline_start, cfg.size); /* Set system registers and transfer control. */ asm volatile("pushq $0\n\tpopfq"); |