OvmfPkg/XenResetVector: Allow jumpstart from either hvmloader or PVH

This patch allows the ResetVector to be run indenpendently from build
time addresses.

The goal of the patch is to avoid having to create RAM just below 4G
when creating a Xen PVH guest while being compatible with the way
hvmloader currently load OVMF, just below 4G.

Only the new PVH entry point will do the calculation.

The ResetVector will figure out its current running address by creating
a temporary stack, make a call and calculate the difference between the
build time address and the address at run time.

This patch copies and make the necessary modification to some other asm
files:
- copy of UefiCpuPkg/.../Flat32ToFlat64.asm:
  Allow Transition32FlatTo64Flat to be run from anywhere in memory
- copy of UefiCpuPkg/../SearchForBfvBase.asm:
  Add a extra parameter to indicate where to start the search for the
  boot firmware volume.

Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20190813113119.14804-9-anthony.perard@citrix.com>
This commit is contained in:
Anthony PERARD 2019-08-13 12:30:52 +01:00 committed by Laszlo Ersek
parent 93314ae597
commit f198e254f7
4 changed files with 194 additions and 7 deletions

View File

@ -54,6 +54,9 @@ jumpTo32BitAndLandHere:
mov gs, ax mov gs, ax
mov ss, ax mov ss, ax
; parameter for Flat32SearchForBfvBase
xor eax, eax ; Start searching from top of 4GB for BfvBase
OneTimeCallRet TransitionFromReal16To32BitFlat OneTimeCallRet TransitionFromReal16To32BitFlat
ALIGN 2 ALIGN 2

View File

@ -0,0 +1,68 @@
;------------------------------------------------------------------------------
; @file
; Transition from 32 bit flat protected mode into 64 bit flat protected mode
;
; Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
; Copyright (c) 2019, Citrix Systems, Inc.
;
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
;------------------------------------------------------------------------------
BITS 32
;
; Modified: EAX, EBX, ECX, EDX, ESP
;
Transition32FlatTo64Flat:
OneTimeCall SetCr3ForPageTables64
mov eax, cr4
bts eax, 5 ; enable PAE
mov cr4, eax
mov ecx, 0xc0000080
rdmsr
bts eax, 8 ; set LME
wrmsr
mov eax, cr0
bts eax, 31 ; set PG
mov cr0, eax ; enable paging
;
; backup ESP
;
mov ebx, esp
;
; recalculate delta
;
mov esp, PVH_SPACE(16)
call .delta
.delta:
pop edx
sub edx, ADDR_OF(.delta)
;
; push return addr and seg to the stack, then return far
;
push dword LINEAR_CODE64_SEL
mov eax, ADDR_OF(jumpTo64BitAndLandHere)
add eax, edx ; add delta
push eax
retf
BITS 64
jumpTo64BitAndLandHere:
;
; restore ESP
;
mov esp, ebx
debugShowPostCode POSTCODE_64BIT_MODE
OneTimeCallRet Transition32FlatTo64Flat

View File

@ -0,0 +1,87 @@
;------------------------------------------------------------------------------
; @file
; Search for the Boot Firmware Volume (BFV) base address
;
; Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.<BR>
; Copyright (c) 2019, Citrix Systems, Inc.
;
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
;------------------------------------------------------------------------------
;#define EFI_FIRMWARE_FILE_SYSTEM2_GUID \
; { 0x8c8ce578, 0x8a3d, 0x4f1c, { 0x99, 0x35, 0x89, 0x61, 0x85, 0xc3, 0x2d, 0xd3 } }
%define FFS_GUID_DWORD0 0x8c8ce578
%define FFS_GUID_DWORD1 0x4f1c8a3d
%define FFS_GUID_DWORD2 0x61893599
%define FFS_GUID_DWORD3 0xd32dc385
BITS 32
;
; Modified: EAX, EBX, ECX
; Preserved: EDI, ESP
;
; @param[in] EAX Start search from here
; @param[out] EBP Address of Boot Firmware Volume (BFV)
;
Flat32SearchForBfvBase:
mov ecx, eax
searchingForBfvHeaderLoop:
;
; We check for a firmware volume at every 4KB address in the 16MB
; just below where we started, ECX.
;
sub eax, 0x1000
mov ebx, ecx
sub ebx, eax
cmp ebx, 0x01000000
; if ECX-EAX > 16MB; jump notfound
ja searchedForBfvHeaderButNotFound
;
; Check FFS GUID
;
cmp dword [eax + 0x10], FFS_GUID_DWORD0
jne searchingForBfvHeaderLoop
cmp dword [eax + 0x14], FFS_GUID_DWORD1
jne searchingForBfvHeaderLoop
cmp dword [eax + 0x18], FFS_GUID_DWORD2
jne searchingForBfvHeaderLoop
cmp dword [eax + 0x1c], FFS_GUID_DWORD3
jne searchingForBfvHeaderLoop
;
; Check FV Length
;
cmp dword [eax + 0x24], 0
jne searchingForBfvHeaderLoop
mov ebx, eax
add ebx, dword [eax + 0x20]
cmp ebx, ecx
jnz searchingForBfvHeaderLoop
jmp searchedForBfvHeaderAndItWasFound
searchedForBfvHeaderButNotFound:
;
; Hang if the SEC entry point was not found
;
debugShowPostCode POSTCODE_BFV_NOT_FOUND
;
; 0xbfbfbfbf in the EAX & EBP registers helps signal what failed
; for debugging purposes.
;
mov eax, 0xBFBFBFBF
mov ebp, eax
jmp $
searchedForBfvHeaderAndItWasFound:
mov ebp, eax
debugShowPostCode POSTCODE_BFV_FOUND
OneTimeCallRet Flat32SearchForBfvBase

View File

@ -16,25 +16,42 @@ xenPVHMain:
; ;
mov di, 'BP' mov di, 'BP'
;
; ESP will be used as initial value of the EAX register
; in Main.asm
;
xor esp, esp
; ;
; Store "Start of day" struct pointer for later use ; Store "Start of day" struct pointer for later use
; ;
mov dword[PVH_SPACE (0)], ebx mov dword[PVH_SPACE (0)], ebx
mov dword[PVH_SPACE (4)], 'XPVH' mov dword[PVH_SPACE (4)], 'XPVH'
;
; calculate delta between build-addr and run position
;
mov esp, PVH_SPACE(16) ; create a temporary stack
call .delta
.delta:
pop edx ; get addr of .delta
sub edx, ADDR_OF(.delta) ; calculate delta
;
; Find address of GDT and gdtr and fix the later
;
mov ebx, ADDR_OF(gdtr) mov ebx, ADDR_OF(gdtr)
add ebx, edx ; add delta gdtr
mov eax, ADDR_OF(GDT_BASE)
add eax, edx ; add delta to GDT_BASE
mov dword[ebx + 2], eax ; fix GDT_BASE addr in gdtr
lgdt [ebx] lgdt [ebx]
mov eax, SEC_DEFAULT_CR0 mov eax, SEC_DEFAULT_CR0
mov cr0, eax mov cr0, eax
jmp LINEAR_CODE_SEL:ADDR_OF(.jmpToNewCodeSeg) ;
; push return addr to the stack, then return far
;
push dword LINEAR_CODE_SEL ; segment to select
mov eax, ADDR_OF(.jmpToNewCodeSeg) ; return addr
add eax, edx ; add delta to return addr
push eax
retf
.jmpToNewCodeSeg: .jmpToNewCodeSeg:
mov eax, SEC_DEFAULT_CR4 mov eax, SEC_DEFAULT_CR4
@ -47,6 +64,18 @@ xenPVHMain:
mov gs, ax mov gs, ax
mov ss, ax mov ss, ax
;
; ESP will be used as initial value of the EAX register
; in Main.asm
;
xor esp, esp
;
; parameter for Flat32SearchForBfvBase
;
mov eax, ADDR_OF(fourGigabytes)
add eax, edx ; add delta
; ;
; Jump to the main routine of the pre-SEC code ; Jump to the main routine of the pre-SEC code
; skiping the 16-bit part of the routine and ; skiping the 16-bit part of the routine and