mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
x86: add multiboot2 protocol support for EFI platforms
This way Xen can be loaded on EFI platforms using GRUB2 and other boot loaders which support multiboot2 protocol. Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com> Acked-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
c5b9805bc1
commit
9180f53655
9 files changed
+405
-22
No files matched your search
+293
-18
@@ -88,6 +88,13 @@ multiboot2_header_start:
|
||||
0, /* Number of the lines - no preference. */ \
|
||||
0 /* Number of bits per pixel - no preference. */
|
||||
|
||||
/* Request that ExitBootServices() not be called. */
|
||||
mb2ht_init MB2_HT(EFI_BS), MB2_HT(OPTIONAL)
|
||||
|
||||
/* EFI64 Multiboot2 entry point. */
|
||||
mb2ht_init MB2_HT(ENTRY_ADDRESS_EFI64), MB2_HT(OPTIONAL), \
|
||||
sym_phys(__efi64_mb2_start)
|
||||
|
||||
/* Multiboot2 header end tag. */
|
||||
mb2ht_init MB2_HT(END), MB2_HT(REQUIRED)
|
||||
.Lmultiboot2_header_end:
|
||||
@@ -99,20 +106,64 @@ multiboot2_header_start:
|
||||
gdt_boot_descr:
|
||||
.word 6*8-1
|
||||
.long sym_phys(trampoline_gdt)
|
||||
.long 0 /* Needed for 64-bit lgdt */
|
||||
|
||||
.Lbad_cpu_msg: .asciz "ERR: Not a 64-bit CPU!"
|
||||
.Lbad_ldr_msg: .asciz "ERR: Not a Multiboot bootloader!"
|
||||
.Lbad_ldr_nbs: .asciz "ERR: Bootloader shutdown EFI x64 boot services!"
|
||||
.Lbad_ldr_nst: .asciz "ERR: EFI SystemTable is not provided by bootloader!"
|
||||
.Lbad_ldr_nih: .asciz "ERR: EFI ImageHandle is not provided by bootloader!"
|
||||
.Lbad_efi_msg: .asciz "ERR: EFI IA-32 platforms are not supported!"
|
||||
|
||||
.section .init.data, "aw", @progbits
|
||||
.align 4
|
||||
|
||||
vga_text_buffer:
|
||||
.long 0xb8000
|
||||
|
||||
efi_platform:
|
||||
.byte 0
|
||||
|
||||
.section .init.text, "ax", @progbits
|
||||
|
||||
bad_cpu:
|
||||
mov $(sym_phys(.Lbad_cpu_msg)),%esi # Error message
|
||||
jmp print_err
|
||||
jmp .Lget_vtb
|
||||
not_multiboot:
|
||||
mov $(sym_phys(.Lbad_ldr_msg)),%esi # Error message
|
||||
print_err:
|
||||
mov $0xB8000,%edi # VGA framebuffer
|
||||
1: mov (%esi),%bl
|
||||
jmp .Lget_vtb
|
||||
.Lmb2_no_st:
|
||||
/*
|
||||
* Here we are on EFI platform. vga_text_buffer was zapped earlier
|
||||
* because there is pretty good chance that VGA is unavailable.
|
||||
*/
|
||||
mov $(sym_phys(.Lbad_ldr_nst)),%esi # Error message
|
||||
jmp .Lget_vtb
|
||||
.Lmb2_no_ih:
|
||||
/* Ditto. */
|
||||
mov $(sym_phys(.Lbad_ldr_nih)),%esi # Error message
|
||||
jmp .Lget_vtb
|
||||
.Lmb2_no_bs:
|
||||
/*
|
||||
* Ditto. Additionally, here there is a chance that Xen was started
|
||||
* via start label. Then reliable vga_text_buffer zap is impossible
|
||||
* in Multiboot2 scanning loop and we have to zero %edi below.
|
||||
*/
|
||||
mov $(sym_phys(.Lbad_ldr_nbs)),%esi # Error message
|
||||
xor %edi,%edi # No VGA text buffer
|
||||
jmp .Lsend_chr
|
||||
.Lmb2_efi_ia_32:
|
||||
/*
|
||||
* Here we are on EFI IA-32 platform. Then reliable vga_text_buffer zap is
|
||||
* impossible in Multiboot2 scanning loop and we have to zero %edi below.
|
||||
*/
|
||||
mov $(sym_phys(.Lbad_efi_msg)),%esi # Error message
|
||||
xor %edi,%edi # No VGA text buffer
|
||||
jmp .Lsend_chr
|
||||
.Lget_vtb:
|
||||
mov sym_phys(vga_text_buffer),%edi
|
||||
.Lsend_chr:
|
||||
mov (%esi),%bl
|
||||
test %bl,%bl # Terminate on '\0' sentinel
|
||||
je .Lhalt
|
||||
mov $0x3f8+5,%dx # UART Line Status Register
|
||||
@@ -122,13 +173,192 @@ print_err:
|
||||
mov $0x3f8+0,%dx # UART Transmit Holding Register
|
||||
mov %bl,%al
|
||||
out %al,%dx # Send a character over the serial line
|
||||
movsb # Write a character to the VGA framebuffer
|
||||
test %edi,%edi # Is the VGA text buffer available?
|
||||
jz .Lsend_chr
|
||||
movsb # Write a character to the VGA text buffer
|
||||
mov $7,%al
|
||||
stosb # Write an attribute to the VGA framebuffer
|
||||
jmp 1b
|
||||
stosb # Write an attribute to the VGA text buffer
|
||||
jmp .Lsend_chr
|
||||
.Lhalt: hlt
|
||||
jmp .Lhalt
|
||||
|
||||
.code64
|
||||
|
||||
__efi64_mb2_start:
|
||||
/*
|
||||
* Multiboot2 spec says that here CPU is in 64-bit mode. However,
|
||||
* there is also guarantee that all code and data is always put
|
||||
* by the bootloader below 4 GiB. Hence, we can safely truncate
|
||||
* addresses to 32-bits in most cases below.
|
||||
*/
|
||||
|
||||
cld
|
||||
|
||||
/* VGA is not available on EFI platforms. */
|
||||
movl $0,vga_text_buffer(%rip)
|
||||
|
||||
/* Check for Multiboot2 bootloader. */
|
||||
cmp $MULTIBOOT2_BOOTLOADER_MAGIC,%eax
|
||||
je .Lefi_multiboot2_proto
|
||||
|
||||
/* Jump to not_multiboot after switching CPU to x86_32 mode. */
|
||||
lea not_multiboot(%rip),%r15
|
||||
jmp x86_32_switch
|
||||
|
||||
.Lefi_multiboot2_proto:
|
||||
/* Zero EFI SystemTable and EFI ImageHandle addresses. */
|
||||
xor %esi,%esi
|
||||
xor %edi,%edi
|
||||
|
||||
/* Skip Multiboot2 information fixed part. */
|
||||
lea (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%rbx),%ecx
|
||||
and $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
|
||||
|
||||
.Lefi_mb2_tsize:
|
||||
/* Check Multiboot2 information total size. */
|
||||
mov %ecx,%r8d
|
||||
sub %ebx,%r8d
|
||||
cmp %r8d,MB2_fixed_total_size(%rbx)
|
||||
jbe .Lrun_bs
|
||||
|
||||
/* Are EFI boot services available? */
|
||||
cmpl $MULTIBOOT2_TAG_TYPE_EFI_BS,MB2_tag_type(%rcx)
|
||||
jne .Lefi_mb2_st
|
||||
|
||||
/* We are on EFI platform and EFI boot services are available. */
|
||||
incb efi_platform(%rip)
|
||||
|
||||
/*
|
||||
* Disable real mode and other legacy stuff which should not
|
||||
* be run on EFI platforms.
|
||||
*/
|
||||
incb skip_realmode(%rip)
|
||||
jmp .Lefi_mb2_next_tag
|
||||
|
||||
.Lefi_mb2_st:
|
||||
/* Get EFI SystemTable address from Multiboot2 information. */
|
||||
cmpl $MULTIBOOT2_TAG_TYPE_EFI64,MB2_tag_type(%rcx)
|
||||
cmove MB2_efi64_st(%rcx),%rsi
|
||||
je .Lefi_mb2_next_tag
|
||||
|
||||
/* Get EFI ImageHandle address from Multiboot2 information. */
|
||||
cmpl $MULTIBOOT2_TAG_TYPE_EFI64_IH,MB2_tag_type(%rcx)
|
||||
cmove MB2_efi64_ih(%rcx),%rdi
|
||||
je .Lefi_mb2_next_tag
|
||||
|
||||
/* Is it the end of Multiboot2 information? */
|
||||
cmpl $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%rcx)
|
||||
je .Lrun_bs
|
||||
|
||||
.Lefi_mb2_next_tag:
|
||||
/* Go to next Multiboot2 information tag. */
|
||||
add MB2_tag_size(%rcx),%ecx
|
||||
add $(MULTIBOOT2_TAG_ALIGN-1),%ecx
|
||||
and $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
|
||||
jmp .Lefi_mb2_tsize
|
||||
|
||||
.Lrun_bs:
|
||||
/* Are EFI boot services available? */
|
||||
cmpb $0,efi_platform(%rip)
|
||||
|
||||
/* Jump to .Lmb2_no_bs after switching CPU to x86_32 mode. */
|
||||
lea .Lmb2_no_bs(%rip),%r15
|
||||
jz x86_32_switch
|
||||
|
||||
/* Is EFI SystemTable address provided by boot loader? */
|
||||
test %rsi,%rsi
|
||||
|
||||
/* Jump to .Lmb2_no_st after switching CPU to x86_32 mode. */
|
||||
lea .Lmb2_no_st(%rip),%r15
|
||||
jz x86_32_switch
|
||||
|
||||
/* Is EFI ImageHandle address provided by boot loader? */
|
||||
test %rdi,%rdi
|
||||
|
||||
/* Jump to .Lmb2_no_ih after switching CPU to x86_32 mode. */
|
||||
lea .Lmb2_no_ih(%rip),%r15
|
||||
jz x86_32_switch
|
||||
|
||||
/*
|
||||
* Align the stack as UEFI spec requires. Keep it aligned
|
||||
* before efi_multiboot2() call by pushing/popping even
|
||||
* numbers of items on it.
|
||||
*/
|
||||
and $~15,%rsp
|
||||
|
||||
/* Save Multiboot2 magic on the stack. */
|
||||
push %rax
|
||||
|
||||
/* Save EFI ImageHandle on the stack. */
|
||||
push %rdi
|
||||
|
||||
/*
|
||||
* Initialize BSS (no nasty surprises!).
|
||||
* It must be done earlier than in BIOS case
|
||||
* because efi_multiboot2() touches it.
|
||||
*/
|
||||
lea __bss_start(%rip),%edi
|
||||
lea __bss_end(%rip),%ecx
|
||||
sub %edi,%ecx
|
||||
shr $3,%ecx
|
||||
xor %eax,%eax
|
||||
rep stosq
|
||||
|
||||
/* Keep the stack aligned. Do not pop a single item off it. */
|
||||
mov (%rsp),%rdi
|
||||
|
||||
/*
|
||||
* efi_multiboot2() is called according to System V AMD64 ABI:
|
||||
* - IN: %rdi - EFI ImageHandle, %rsi - EFI SystemTable.
|
||||
*/
|
||||
call efi_multiboot2
|
||||
|
||||
/* Just pop an item from the stack. */
|
||||
pop %rax
|
||||
|
||||
/* Restore Multiboot2 magic. */
|
||||
pop %rax
|
||||
|
||||
/* Jump to trampoline_setup after switching CPU to x86_32 mode. */
|
||||
lea trampoline_setup(%rip),%r15
|
||||
|
||||
x86_32_switch:
|
||||
mov %r15,%rdi
|
||||
|
||||
cli
|
||||
|
||||
/* Initialize GDTR. */
|
||||
lgdt gdt_boot_descr(%rip)
|
||||
|
||||
/* Reload code selector. */
|
||||
pushq $BOOT_CS32
|
||||
lea cs32_switch(%rip),%edx
|
||||
push %rdx
|
||||
lretq
|
||||
|
||||
.code32
|
||||
|
||||
cs32_switch:
|
||||
/* Initialize basic data segments. */
|
||||
mov $BOOT_DS,%edx
|
||||
mov %edx,%ds
|
||||
mov %edx,%es
|
||||
mov %edx,%ss
|
||||
/* %esp is initialized later. */
|
||||
|
||||
/* Load null descriptor to unused segment registers. */
|
||||
xor %edx,%edx
|
||||
mov %edx,%fs
|
||||
mov %edx,%gs
|
||||
|
||||
/* Disable paging. */
|
||||
mov %cr0,%edx
|
||||
and $(~X86_CR0_PG),%edx
|
||||
mov %edx,%cr0
|
||||
|
||||
/* Jump to earlier loaded address. */
|
||||
jmp *%edi
|
||||
|
||||
__start:
|
||||
cld
|
||||
cli
|
||||
@@ -156,7 +386,7 @@ __start:
|
||||
|
||||
/* Not available? BDA value will be fine. */
|
||||
cmovnz MB_mem_lower(%ebx),%edx
|
||||
jmp trampoline_setup
|
||||
jmp trampoline_bios_setup
|
||||
|
||||
.Lmultiboot2_proto:
|
||||
/* Skip Multiboot2 information fixed part. */
|
||||
@@ -168,24 +398,33 @@ __start:
|
||||
mov %ecx,%edi
|
||||
sub %ebx,%edi
|
||||
cmp %edi,MB2_fixed_total_size(%ebx)
|
||||
jbe trampoline_setup
|
||||
jbe trampoline_bios_setup
|
||||
|
||||
/* Get mem_lower from Multiboot2 information. */
|
||||
cmpl $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,MB2_tag_type(%ecx)
|
||||
cmove MB2_mem_lower(%ecx),%edx
|
||||
je trampoline_setup
|
||||
je .Lmb2_next_tag
|
||||
|
||||
/* EFI IA-32 platforms are not supported. */
|
||||
cmpl $MULTIBOOT2_TAG_TYPE_EFI32,MB2_tag_type(%ecx)
|
||||
je .Lmb2_efi_ia_32
|
||||
|
||||
/* Bootloader shutdown EFI x64 boot services. */
|
||||
cmpl $MULTIBOOT2_TAG_TYPE_EFI64,MB2_tag_type(%ecx)
|
||||
je .Lmb2_no_bs
|
||||
|
||||
/* Is it the end of Multiboot2 information? */
|
||||
cmpl $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%ecx)
|
||||
je trampoline_setup
|
||||
je trampoline_bios_setup
|
||||
|
||||
.Lmb2_next_tag:
|
||||
/* Go to next Multiboot2 information tag. */
|
||||
add MB2_tag_size(%ecx),%ecx
|
||||
add $(MULTIBOOT2_TAG_ALIGN-1),%ecx
|
||||
and $~(MULTIBOOT2_TAG_ALIGN-1),%ecx
|
||||
jmp .Lmb2_tsize
|
||||
|
||||
trampoline_setup:
|
||||
trampoline_bios_setup:
|
||||
/* Set up trampoline segment 64k below EBDA */
|
||||
movzwl 0x40e,%ecx /* EBDA segment */
|
||||
cmp $0xa000,%ecx /* sanity check (high) */
|
||||
@@ -206,23 +445,54 @@ trampoline_setup:
|
||||
cmp %ecx,%edx /* compare with BDA value */
|
||||
cmovb %edx,%ecx /* and use the smaller */
|
||||
|
||||
2: /* Reserve 64kb for the trampoline */
|
||||
sub $0x1000,%ecx
|
||||
2:
|
||||
/* Reserve memory for the trampoline and the low-memory stack. */
|
||||
sub $((TRAMPOLINE_SPACE+TRAMPOLINE_STACK_SPACE)>>4),%ecx
|
||||
|
||||
/* From arch/x86/smpboot.c: start_eip had better be page-aligned! */
|
||||
xor %cl, %cl
|
||||
shl $4, %ecx
|
||||
mov %ecx,sym_phys(trampoline_phys)
|
||||
|
||||
trampoline_setup:
|
||||
mov sym_phys(trampoline_phys),%ecx
|
||||
|
||||
/* Get bottom-most low-memory stack address. */
|
||||
add $TRAMPOLINE_SPACE,%ecx
|
||||
|
||||
/* Save the Multiboot info struct (after relocation) for later use. */
|
||||
mov $sym_phys(cpu0_stack)+1024,%esp
|
||||
push %ecx /* Boot trampoline address. */
|
||||
push %ecx /* Bottom-most low-memory stack address. */
|
||||
push %ebx /* Multiboot information address. */
|
||||
push %eax /* Multiboot magic. */
|
||||
call reloc
|
||||
mov %eax,sym_phys(multiboot_ptr)
|
||||
|
||||
/* Initialize BSS (no nasty surprises!) */
|
||||
/*
|
||||
* Now trampoline_phys points to the following structure (lowest address
|
||||
* is at the bottom):
|
||||
*
|
||||
* +------------------------+
|
||||
* | TRAMPOLINE_STACK_SPACE |
|
||||
* +------------------------+
|
||||
* | mbi data |
|
||||
* +- - - - - - - - - - - - +
|
||||
* | TRAMPOLINE_SPACE |
|
||||
* +------------------------+
|
||||
*
|
||||
* mbi data grows downwards from the highest address of TRAMPOLINE_SPACE
|
||||
* region to the end of the trampoline. The rest of TRAMPOLINE_SPACE is
|
||||
* reserved for trampoline code and data.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Do not zero BSS on EFI platform here.
|
||||
* It was initialized earlier.
|
||||
*/
|
||||
cmpb $0,sym_phys(efi_platform)
|
||||
jnz 1f
|
||||
|
||||
/* Initialize BSS (no nasty surprises!). */
|
||||
mov $sym_phys(__bss_start),%edi
|
||||
mov $sym_phys(__bss_end),%ecx
|
||||
sub %edi,%ecx
|
||||
@@ -230,6 +500,7 @@ trampoline_setup:
|
||||
shr $2,%ecx
|
||||
rep stosl
|
||||
|
||||
1:
|
||||
/* Interrogate CPU extended features via CPUID. */
|
||||
mov $0x80000000,%eax
|
||||
cpuid
|
||||
@@ -281,6 +552,10 @@ trampoline_setup:
|
||||
cmp $sym_phys(__trampoline_seg_stop),%edi
|
||||
jb 1b
|
||||
|
||||
/* Do not parse command line on EFI platform here. */
|
||||
cmpb $0,sym_phys(efi_platform)
|
||||
jnz 1f
|
||||
|
||||
/* Bail if there is no command line to parse. */
|
||||
mov sym_phys(multiboot_ptr),%ebx
|
||||
testl $MBI_CMDLINE,MB_flags(%ebx)
|
||||
@@ -291,9 +566,9 @@ trampoline_setup:
|
||||
call cmdline_parse_early
|
||||
|
||||
1:
|
||||
/* Switch to low-memory stack. */
|
||||
/* Switch to low-memory stack which lives at the end of trampoline region. */
|
||||
mov sym_phys(trampoline_phys),%edi
|
||||
lea 0x10000(%edi),%esp
|
||||
lea TRAMPOLINE_SPACE+TRAMPOLINE_STACK_SPACE(%edi),%esp
|
||||
lea trampoline_boot_cpu_entry-trampoline_start(%edi),%eax
|
||||
pushl $BOOT_CS32
|
||||
push %eax
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
* This entry point is entered from xen/arch/x86/boot/head.S with:
|
||||
* - 0x4(%esp) = MULTIBOOT_MAGIC,
|
||||
* - 0x8(%esp) = MULTIBOOT_INFORMATION_ADDRESS,
|
||||
* - 0xc(%esp) = BOOT_TRAMPOLINE_ADDRESS.
|
||||
* - 0xc(%esp) = TOPMOST_LOW_MEMORY_STACK_ADDRESS.
|
||||
*/
|
||||
asm (
|
||||
" .text \n"
|
||||
|
||||
@@ -101,6 +101,10 @@ static void __init relocate_trampoline(unsigned long phys)
|
||||
const s32 *trampoline_ptr;
|
||||
|
||||
trampoline_phys = phys;
|
||||
|
||||
if ( !efi_enabled(EFI_LOADER) )
|
||||
return;
|
||||
|
||||
/* Apply relocations to trampoline. */
|
||||
for ( trampoline_ptr = __trampoline_rel_start;
|
||||
trampoline_ptr < __trampoline_rel_stop;
|
||||
@@ -550,7 +554,12 @@ static void __init efi_arch_memory_setup(void)
|
||||
|
||||
/* Allocate space for trampoline (in first Mb). */
|
||||
cfg.addr = 0x100000;
|
||||
cfg.size = trampoline_end - trampoline_start;
|
||||
|
||||
if ( efi_enabled(EFI_LOADER) )
|
||||
cfg.size = trampoline_end - trampoline_start;
|
||||
else
|
||||
cfg.size = TRAMPOLINE_SPACE + TRAMPOLINE_STACK_SPACE;
|
||||
|
||||
status = efi_bs->AllocatePages(AllocateMaxAddress, EfiLoaderData,
|
||||
PFN_UP(cfg.size), &cfg.addr);
|
||||
if ( status == EFI_SUCCESS )
|
||||
@@ -561,6 +570,9 @@ static void __init efi_arch_memory_setup(void)
|
||||
PrintStr(L"Trampoline space cannot be allocated; will try fallback.\r\n");
|
||||
}
|
||||
|
||||
if ( !efi_enabled(EFI_LOADER) )
|
||||
return;
|
||||
|
||||
/* Initialise L2 identity-map and boot-map page table entries (16MB). */
|
||||
for ( i = 0; i < 8; ++i )
|
||||
{
|
||||
@@ -653,6 +665,41 @@ static bool_t __init efi_arch_use_config_file(EFI_SYSTEM_TABLE *SystemTable)
|
||||
|
||||
static void efi_arch_flush_dcache_area(const void *vaddr, UINTN size) { }
|
||||
|
||||
void __init efi_multiboot2(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
||||
{
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
|
||||
UINTN cols, gop_mode = ~0, rows;
|
||||
|
||||
__set_bit(EFI_BOOT, &efi_flags);
|
||||
__set_bit(EFI_RS, &efi_flags);
|
||||
|
||||
efi_init(ImageHandle, SystemTable);
|
||||
|
||||
efi_console_set_mode();
|
||||
|
||||
if ( StdOut->QueryMode(StdOut, StdOut->Mode->Mode,
|
||||
&cols, &rows) == EFI_SUCCESS )
|
||||
efi_arch_console_init(cols, rows);
|
||||
|
||||
gop = efi_get_gop();
|
||||
|
||||
if ( gop )
|
||||
gop_mode = efi_find_gop_mode(gop, 0, 0, 0);
|
||||
|
||||
efi_arch_edd();
|
||||
efi_arch_cpu();
|
||||
|
||||
efi_tables();
|
||||
setup_efi_pci();
|
||||
efi_variables();
|
||||
efi_arch_memory_setup();
|
||||
|
||||
if ( gop )
|
||||
efi_set_gop_mode(gop, gop_mode);
|
||||
|
||||
efi_exit_boot(ImageHandle, SystemTable);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* mode: C
|
||||
|
||||
@@ -3,6 +3,45 @@
|
||||
#include <xen/init.h>
|
||||
#include <xen/lib.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/efibind.h>
|
||||
#include <efi/efidef.h>
|
||||
#include <efi/eficapsule.h>
|
||||
#include <efi/eficon.h>
|
||||
#include <efi/efidevp.h>
|
||||
#include <efi/efiapi.h>
|
||||
|
||||
/*
|
||||
* Here we are in EFI stub. EFI calls are not supported due to lack
|
||||
* of relevant functionality in compiler and/or linker.
|
||||
*
|
||||
* efi_multiboot2() is an exception. Please look below for more details.
|
||||
*/
|
||||
|
||||
void __init noreturn efi_multiboot2(EFI_HANDLE ImageHandle,
|
||||
EFI_SYSTEM_TABLE *SystemTable)
|
||||
{
|
||||
static const CHAR16 __initconst err[] =
|
||||
L"Xen does not have EFI code build in!\r\nSystem halted!\r\n";
|
||||
SIMPLE_TEXT_OUTPUT_INTERFACE *StdErr;
|
||||
|
||||
StdErr = SystemTable->StdErr ? SystemTable->StdErr : SystemTable->ConOut;
|
||||
|
||||
/*
|
||||
* Print error message and halt the system.
|
||||
*
|
||||
* We have to open code MS x64 calling convention
|
||||
* in assembly because here this convention may
|
||||
* not be directly supported by C compiler.
|
||||
*/
|
||||
asm volatile(
|
||||
" call *%3 \n"
|
||||
"0: hlt \n"
|
||||
" jmp 0b \n"
|
||||
: "+c" (StdErr), "=d" (StdErr) : "1" (err), "rm" (StdErr->OutputString)
|
||||
: "rax", "r8", "r9", "r10", "r11", "memory");
|
||||
|
||||
unreachable();
|
||||
}
|
||||
|
||||
bool efi_enabled(unsigned int feature)
|
||||
{
|
||||
|
||||
@@ -174,6 +174,8 @@ void __dummy__(void)
|
||||
OFFSET(MB2_tag_type, multiboot2_tag_t, type);
|
||||
OFFSET(MB2_tag_size, multiboot2_tag_t, size);
|
||||
OFFSET(MB2_mem_lower, multiboot2_tag_basic_meminfo_t, mem_lower);
|
||||
OFFSET(MB2_efi64_st, multiboot2_tag_efi64_t, pointer);
|
||||
OFFSET(MB2_efi64_ih, multiboot2_tag_efi64_ih_t, pointer);
|
||||
BLANK();
|
||||
|
||||
OFFSET(DOMAIN_vm_assist, struct domain, vm_assist);
|
||||
|
||||
@@ -330,5 +330,8 @@ ASSERT(IS_ALIGNED(__init_end, PAGE_SIZE), "__init_end misaligned")
|
||||
|
||||
ASSERT(IS_ALIGNED(trampoline_start, 4), "trampoline_start misaligned")
|
||||
ASSERT(IS_ALIGNED(trampoline_end, 4), "trampoline_end misaligned")
|
||||
ASSERT(IS_ALIGNED(__bss_start, 4), "__bss_start misaligned")
|
||||
ASSERT(IS_ALIGNED(__bss_end, 4), "__bss_end misaligned")
|
||||
ASSERT(IS_ALIGNED(__bss_start, 8), "__bss_start misaligned")
|
||||
ASSERT(IS_ALIGNED(__bss_end, 8), "__bss_end misaligned")
|
||||
|
||||
ASSERT((trampoline_end - trampoline_start) < TRAMPOLINE_SPACE - MBI_SPACE_MIN,
|
||||
"not enough room for trampoline and mbi data")
|
||||
@@ -79,6 +79,17 @@ static size_t wstrlen(const CHAR16 * s);
|
||||
static int set_color(u32 mask, int bpp, u8 *pos, u8 *sz);
|
||||
static bool_t match_guid(const EFI_GUID *guid1, const EFI_GUID *guid2);
|
||||
|
||||
static void efi_init(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable);
|
||||
static void efi_console_set_mode(void);
|
||||
static EFI_GRAPHICS_OUTPUT_PROTOCOL *efi_get_gop(void);
|
||||
static UINTN efi_find_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop,
|
||||
UINTN cols, UINTN rows, UINTN depth);
|
||||
static void efi_tables(void);
|
||||
static void setup_efi_pci(void);
|
||||
static void efi_variables(void);
|
||||
static void efi_set_gop_mode(EFI_GRAPHICS_OUTPUT_PROTOCOL *gop, UINTN gop_mode);
|
||||
static void efi_exit_boot(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable);
|
||||
|
||||
static const EFI_BOOT_SERVICES *__initdata efi_bs;
|
||||
static UINT32 __initdata efi_bs_revision;
|
||||
static EFI_HANDLE __initdata efi_ih;
|
||||
|
||||
@@ -73,6 +73,11 @@
|
||||
#define STACK_ORDER 3
|
||||
#define STACK_SIZE (PAGE_SIZE << STACK_ORDER)
|
||||
|
||||
#define TRAMPOLINE_STACK_SPACE PAGE_SIZE
|
||||
#define TRAMPOLINE_SPACE (KB(64) - TRAMPOLINE_STACK_SPACE)
|
||||
|
||||
#define MBI_SPACE_MIN (2 * PAGE_SIZE)
|
||||
|
||||
/* Primary stack is restricted to 8kB by guard pages. */
|
||||
#define PRIMARY_STACK_SIZE 8192
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
#define __force
|
||||
#define __bitwise
|
||||
|
||||
#define KB(_kb) (_AC(_kb, ULL) << 10)
|
||||
#define MB(_mb) (_AC(_mb, ULL) << 20)
|
||||
#define GB(_gb) (_AC(_gb, ULL) << 30)
|
||||
|
||||
|
||||