@@ -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
@@ -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. */
@@ -433,14 +449,7 @@ __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)
@@ -448,19 +457,9 @@ __pvh_start:
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
@@ -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
@@ -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 */
The 2 code paths were sharing quite some common code, reuse it instead of having duplications. Signed-off-by: Frediano Ziglio <frediano.ziglio@cloud.com> --- Changes since v1: - use %dl instead of %ebp to reduce code size; - fold cli instruction; - update some comments. Changes since v3: - dropped %dl and constant, distinguish entry by magic. Changes since v4: - remove old sentence from commit message; - fixed a typo; - load XEN_HVM_START_MAGIC_VALUE constant directly; - set %fs and %gs as other segment registers; - remove some spurious line changes. Changes since v5: - fixed a typo. --- xen/arch/x86/boot/head.S | 104 ++++++++++++++------------------------- 1 file changed, 37 insertions(+), 67 deletions(-)