Hi Anthony,
On 08/13/19 13:30, Anthony PERARD wrote:
> 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>
> ---
>
> Notes:
> v3:
> - rebased, SPDX
> - fix commit message
>
> .../XenResetVector/Ia16/Real16ToFlat32.asm | 3 +
> .../XenResetVector/Ia32/Flat32ToFlat64.asm | 68 +++++++++++++++
> .../XenResetVector/Ia32/SearchForBfvBase.asm | 87 +++++++++++++++++++
> OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm | 43 +++++++--
> 4 files changed, 194 insertions(+), 7 deletions(-)
> create mode 100644 OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm
> create mode 100644 OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm
>
> diff --git a/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
> index 5c329bfaea..36ea74f7fe 100644
> --- a/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
> +++ b/OvmfPkg/XenResetVector/Ia16/Real16ToFlat32.asm
> @@ -54,6 +54,9 @@ jumpTo32BitAndLandHere:
> mov gs, ax
> mov ss, ax
>
> + ; parameter for Flat32SearchForBfvBase
> + xor eax, eax ; Start searching from top of 4GB for BfvBase
> +
> OneTimeCallRet TransitionFromReal16To32BitFlat
>
> ALIGN 2
> diff --git a/OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm b/OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm
> new file mode 100644
> index 0000000000..661a8e7028
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia32/Flat32ToFlat64.asm
> @@ -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
> +
> diff --git a/OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm b/OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm
> new file mode 100644
> index 0000000000..190389c46f
> --- /dev/null
> +++ b/OvmfPkg/XenResetVector/Ia32/SearchForBfvBase.asm
> @@ -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
> +
> diff --git a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> index f42df3dba2..2df0f12e18 100644
> --- a/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> +++ b/OvmfPkg/XenResetVector/Ia32/XenPVHMain.asm
> @@ -16,25 +16,42 @@ xenPVHMain:
> ;
> 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
> ;
> mov dword[PVH_SPACE (0)], ebx
> 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)
> + 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]
>
> mov eax, SEC_DEFAULT_CR0
> 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:
>
> mov eax, SEC_DEFAULT_CR4
> @@ -47,6 +64,18 @@ xenPVHMain:
> mov gs, 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)
I've just noticed that the line above triggers the following NASM warning:
Ia32/XenPVHMain.asm:76: warning: dword data exceeds bounds
The warning does not stop the build.
The macro comes from "UefiCpuPkg/ResetVector/Vtf0/CommonMacros.inc":
%define ADDR_OF(x) (0x100000000 - fourGigabytes + x)
So I believe we effectively store 0 to EAX. If that's the intent (I
think it *could* be), please submit a cleanup in the next development
cycle -- we could store a 0 explicitly and add a comment, just to shut
up the warning. If, on the other hand, this is a bug, please submit a
fix soon (for the upcoming release).
Thanks
Laszlo
> + add eax, edx ; add delta
> +
> ;
> ; Jump to the main routine of the pre-SEC code
> ; skiping the 16-bit part of the routine and
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#46167): https://edk2.groups.io/g/devel/message/46167
Mute This Topic: https://groups.io/mt/32851503/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-