Skip to content

Commit

Permalink
x86/boot: Refactor BIOS/PVH start
Browse files Browse the repository at this point in the history
The 2 code paths were sharing quite some common code, reuse it instead
of having duplications.

Signed-off-by: Frediano Ziglio <[email protected]>
Reviewed-by: Andrew Cooper <[email protected]>
  • Loading branch information
freddy77 authored and andyhhp committed Sep 26, 2024
1 parent a184ac7 commit 0857c75
Showing 1 changed file with 37 additions and 67 deletions.
104 changes: 37 additions & 67 deletions xen/arch/x86/boot/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#define MB2_HT(name) (MULTIBOOT2_HEADER_TAG_##name)
#define MB2_TT(name) (MULTIBOOT2_TAG_TYPE_##name)

#define XEN_HVM_START_MAGIC_VALUE 0x336ec578

.macro mb2ht_args arg:req, args:vararg
.long \arg
.ifnb \args
Expand Down Expand Up @@ -409,13 +411,27 @@ cs32_switch:
ELFNOTE(Xen, XEN_ELFNOTE_PHYS32_ENTRY, .long sym_offs(__pvh_start))

__pvh_start:
cld
mov $XEN_HVM_START_MAGIC_VALUE, %eax
/*
* Fall through into BIOS code.
* We will use %eax to distinguish we came from PVH entry point.
*/
#endif /* CONFIG_PVH_GUEST */

__start:
cli
cld

/*
* We need one call (i.e. push) to determine the load address. See
* __start for a discussion on how to do this safely using the PVH
* info structure.
* Multiboot (both 1 and 2) and PVH specify the stack pointer as
* undefined. This is unhelpful for relocatable images, where one
* call (i.e. push) is required to calculate the image's load address.
*
* During BIOS boot, there is one area of memory we know about with
* reasonable confidence that it isn't overlapped by Xen, and that's
* the Multiboot info structure in %ebx. Use it as a temporary stack.
*
* During PVH boot use info structure in %ebx.
*/

/* Preserve the field we're about to clobber. */
Expand All @@ -433,34 +449,17 @@ __pvh_start:
/* Set up stack. */
lea STACK_SIZE - CPUINFO_sizeof + sym_esi(cpu0_stack), %esp

call .Linitialise_bss

mov %ebx, sym_esi(pvh_start_info_pa)

/* Force xen console. Will revert to user choice in init code. */
movb $-1, sym_esi(opt_console_xen)

/* Prepare gdt and segments */
/* Initialize GDTR and basic data segments. */
add %esi, sym_esi(gdt_boot_base)
lgdt sym_esi(gdt_boot_descr)

mov $BOOT_DS, %ecx
mov %ecx, %ds
mov %ecx, %es
mov %ecx, %ss
mov %ecx, %fs
mov %ecx, %gs

/* Skip bootloader setup and bios setup, go straight to trampoline */
movb $1, sym_esi(pvh_boot)
movb $1, sym_esi(skip_realmode)

/* Set trampoline_phys to use mfn 1 to avoid having a mapping at VA 0 */
movw $0x1000, sym_esi(trampoline_phys)
mov (%ebx), %eax /* mov $XEN_HVM_START_MAGIC_VALUE, %eax */
jmp trampoline_setup

#endif /* CONFIG_PVH_GUEST */

.Linitialise_bss:
/* Initialise the BSS. Preserve %eax (BOOTLOADER_MAGIC). */
mov %eax, %ebp

Expand All @@ -472,39 +471,25 @@ __pvh_start:
rep stosl

mov %ebp, %eax
ret

__start:
cld
cli

/*
* Multiboot (both 1 and 2) specify the stack pointer as undefined
* when entering in BIOS circumstances. This is unhelpful for
* relocatable images, where one call (i.e. push) is required to
* calculate the image's load address.
*
* This early in boot, there is one area of memory we know about with
* reasonable confidence that it isn't overlapped by Xen, and that's
* the Multiboot info structure in %ebx. Use it as a temporary stack.
*/

/* Preserve the field we're about to clobber. */
mov (%ebx), %edx
lea 4(%ebx), %esp
#ifdef CONFIG_PVH_GUEST
cmp $XEN_HVM_START_MAGIC_VALUE, %eax
jne 1f

/* Calculate the load base address. */
call 1f
1: pop %esi
sub $sym_offs(1b), %esi
mov %ebx, sym_esi(pvh_start_info_pa)

/* Restore the clobbered field. */
mov %edx, (%ebx)
/* Force xen console. Will revert to user choice in init code. */
movb $-1, sym_esi(opt_console_xen)

/* Set up stack. */
lea STACK_SIZE - CPUINFO_sizeof + sym_esi(cpu0_stack), %esp
/* Skip bootloader setup and bios setup, go straight to trampoline */
movb $1, sym_esi(pvh_boot)
movb $1, sym_esi(skip_realmode)

call .Linitialise_bss
/* Set trampoline_phys to use mfn 1 to avoid having a mapping at VA 0 */
movl $PAGE_SIZE, sym_esi(trampoline_phys)
jmp trampoline_setup
1:
#endif /* CONFIG_PVH_GUEST */

/* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value. */
xor %edx,%edx
Expand Down Expand Up @@ -563,22 +548,7 @@ __start:
trampoline_bios_setup:
/*
* Called on legacy BIOS platforms only.
*
* Initialize GDTR and basic data segments.
*/
add %esi,sym_esi(gdt_boot_base)
lgdt sym_esi(gdt_boot_descr)

mov $BOOT_DS,%ecx
mov %ecx,%ds
mov %ecx,%es
mov %ecx,%ss
/* %esp is initialized later. */

/* Load null descriptor to unused segment registers. */
xor %ecx,%ecx
mov %ecx,%fs
mov %ecx,%gs

/* Set up trampoline segment 64k below EBDA */
movzwl 0x40e,%ecx /* EBDA segment */
Expand Down

0 comments on commit 0857c75

Please sign in to comment.