summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/XenResetVector/Ia32
diff options
context:
space:
mode:
authorAnthony PERARD <anthony.perard@citrix.com>2019-08-13 12:30:47 +0100
committerLaszlo Ersek <lersek@redhat.com>2019-08-21 18:03:49 +0200
commitc05de360ec614f71716a201760b91ee055a5ff28 (patch)
tree8cd734ceafa20e50f411eb66bb81dc4499246e7e /OvmfPkg/XenResetVector/Ia32
parent75e85e3382b9adb7488a42f885d9cd2b52cdf816 (diff)
downloadedk2-c05de360ec614f71716a201760b91ee055a5ff28.tar.gz
edk2-c05de360ec614f71716a201760b91ee055a5ff28.tar.bz2
edk2-c05de360ec614f71716a201760b91ee055a5ff28.zip
OvmfPkg: Introduce XenResetVector
Introduce XenResetVector, a copy of OvmfPkg/ResetVector, with one changes: - SEC_DEFAULT_CR0: enable cache (bit 30 or CD set to 0) Xen copies the OVMF code to RAM, there is no need to disable cache. This new module will later be modified to add a new entry point, more detail in a following commit "OvmfPkg/XenResetVector: Add new entry point for Xen PVH" Value FILE_GUID of XenResetVector have not changed compare to ResetVector because it is a special value (gEfiFirmwareVolumeTopFileGuid). Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=1689 Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Message-Id: <20190813113119.14804-4-anthony.perard@citrix.com>
Diffstat (limited to 'OvmfPkg/XenResetVector/Ia32')
-rw-r--r--OvmfPkg/XenResetVector/Ia32/PageTables64.asm149
1 files changed, 149 insertions, 0 deletions
diff --git a/OvmfPkg/XenResetVector/Ia32/PageTables64.asm b/OvmfPkg/XenResetVector/Ia32/PageTables64.asm
new file mode 100644
index 0000000000..9f1c0e2259
--- /dev/null
+++ b/OvmfPkg/XenResetVector/Ia32/PageTables64.asm
@@ -0,0 +1,149 @@
+;------------------------------------------------------------------------------
+; @file
+; Sets the CR3 register for 64-bit paging
+;
+; Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
+; Copyright (c) 2019, Citrix Systems, Inc.
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+;------------------------------------------------------------------------------
+
+BITS 32
+
+%define PAGE_PRESENT 0x01
+%define PAGE_READ_WRITE 0x02
+%define PAGE_USER_SUPERVISOR 0x04
+%define PAGE_WRITE_THROUGH 0x08
+%define PAGE_CACHE_DISABLE 0x010
+%define PAGE_ACCESSED 0x020
+%define PAGE_DIRTY 0x040
+%define PAGE_PAT 0x080
+%define PAGE_GLOBAL 0x0100
+%define PAGE_2M_MBO 0x080
+%define PAGE_2M_PAT 0x01000
+
+%define PAGE_2M_PDE_ATTR (PAGE_2M_MBO + \
+ PAGE_ACCESSED + \
+ PAGE_DIRTY + \
+ PAGE_READ_WRITE + \
+ PAGE_PRESENT)
+
+%define PAGE_PDP_ATTR (PAGE_ACCESSED + \
+ PAGE_READ_WRITE + \
+ PAGE_PRESENT)
+
+; Check if Secure Encrypted Virtualization (SEV) feature is enabled
+;
+; If SEV is enabled then EAX will be at least 32
+; If SEV is disabled then EAX will be zero.
+;
+CheckSevFeature:
+ ; Check if we have a valid (0x8000_001F) CPUID leaf
+ mov eax, 0x80000000
+ cpuid
+
+ ; This check should fail on Intel or Non SEV AMD CPUs. In future if
+ ; Intel CPUs supports this CPUID leaf then we are guranteed to have exact
+ ; same bit definition.
+ cmp eax, 0x8000001f
+ jl NoSev
+
+ ; Check for memory encryption feature:
+ ; CPUID Fn8000_001F[EAX] - Bit 1
+ ;
+ mov eax, 0x8000001f
+ cpuid
+ bt eax, 1
+ jnc NoSev
+
+ ; Check if memory encryption is enabled
+ ; MSR_0xC0010131 - Bit 0 (SEV enabled)
+ mov ecx, 0xc0010131
+ rdmsr
+ bt eax, 0
+ jnc NoSev
+
+ ; Get pte bit position to enable memory encryption
+ ; CPUID Fn8000_001F[EBX] - Bits 5:0
+ ;
+ mov eax, ebx
+ and eax, 0x3f
+ jmp SevExit
+
+NoSev:
+ xor eax, eax
+
+SevExit:
+ OneTimeCallRet CheckSevFeature
+
+;
+; Modified: EAX, EBX, ECX, EDX
+;
+SetCr3ForPageTables64:
+
+ OneTimeCall CheckSevFeature
+ xor edx, edx
+ test eax, eax
+ jz SevNotActive
+
+ ; If SEV is enabled, C-bit is always above 31
+ sub eax, 32
+ bts edx, eax
+
+SevNotActive:
+
+ ;
+ ; For OVMF, build some initial page tables at
+ ; PcdOvmfSecPageTablesBase - (PcdOvmfSecPageTablesBase + 0x6000).
+ ;
+ ; This range should match with PcdOvmfSecPageTablesSize which is
+ ; declared in the FDF files.
+ ;
+ ; At the end of PEI, the pages tables will be rebuilt into a
+ ; more permanent location by DxeIpl.
+ ;
+
+ mov ecx, 6 * 0x1000 / 4
+ xor eax, eax
+clearPageTablesMemoryLoop:
+ mov dword[ecx * 4 + PT_ADDR (0) - 4], eax
+ loop clearPageTablesMemoryLoop
+
+ ;
+ ; Top level Page Directory Pointers (1 * 512GB entry)
+ ;
+ mov dword[PT_ADDR (0)], PT_ADDR (0x1000) + PAGE_PDP_ATTR
+ mov dword[PT_ADDR (4)], edx
+
+ ;
+ ; Next level Page Directory Pointers (4 * 1GB entries => 4GB)
+ ;
+ mov dword[PT_ADDR (0x1000)], PT_ADDR (0x2000) + PAGE_PDP_ATTR
+ mov dword[PT_ADDR (0x1004)], edx
+ mov dword[PT_ADDR (0x1008)], PT_ADDR (0x3000) + PAGE_PDP_ATTR
+ mov dword[PT_ADDR (0x100C)], edx
+ mov dword[PT_ADDR (0x1010)], PT_ADDR (0x4000) + PAGE_PDP_ATTR
+ mov dword[PT_ADDR (0x1014)], edx
+ mov dword[PT_ADDR (0x1018)], PT_ADDR (0x5000) + PAGE_PDP_ATTR
+ mov dword[PT_ADDR (0x101C)], edx
+
+ ;
+ ; Page Table Entries (2048 * 2MB entries => 4GB)
+ ;
+ mov ecx, 0x800
+pageTableEntriesLoop:
+ mov eax, ecx
+ dec eax
+ shl eax, 21
+ add eax, PAGE_2M_PDE_ATTR
+ mov [ecx * 8 + PT_ADDR (0x2000 - 8)], eax
+ mov [(ecx * 8 + PT_ADDR (0x2000 - 8)) + 4], edx
+ loop pageTableEntriesLoop
+
+ ;
+ ; Set CR3 now that the paging structures are available
+ ;
+ mov eax, PT_ADDR (0)
+ mov cr3, eax
+
+ OneTimeCallRet SetCr3ForPageTables64