OvmfPkg/MemEncryptSevLib: find pages of initial SMRAM save state map
[mirror_edk2.git] / OvmfPkg / Library / BaseMemEncryptSevLib / MemEncryptSevLibInternal.c
CommitLineData
a1f22614
BS
1/** @file\r
2\r
3 Secure Encrypted Virtualization (SEV) library helper function\r
4\r
5 Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
6\r
4bd6bf31
LE
7 This program and the accompanying materials are licensed and made available\r
8 under the terms and conditions of the BSD License which accompanies this\r
9 distribution. The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php\r
a1f22614
BS
11\r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include <Library/BaseLib.h>\r
18#include <Library/DebugLib.h>\r
bd13ecf3 19#include <Library/MemEncryptSevLib.h>\r
61a044c6 20#include <Library/PcdLib.h>\r
a1f22614
BS
21#include <Register/Amd/Cpuid.h>\r
22#include <Register/Amd/Msr.h>\r
bd13ecf3 23#include <Register/Cpuid.h>\r
61a044c6
LE
24#include <Register/QemuSmramSaveStateMap.h>\r
25#include <Register/SmramSaveStateMap.h>\r
26#include <Uefi/UefiBaseType.h>\r
a1f22614
BS
27\r
28STATIC BOOLEAN mSevStatus = FALSE;\r
29STATIC BOOLEAN mSevStatusChecked = FALSE;\r
30\r
31/**\r
32\r
33 Returns a boolean to indicate whether SEV is enabled\r
34\r
35 @retval TRUE SEV is enabled\r
36 @retval FALSE SEV is not enabled\r
37 **/\r
38STATIC\r
39BOOLEAN\r
40EFIAPI\r
41InternalMemEncryptSevIsEnabled (\r
42 VOID\r
43 )\r
44{\r
45 UINT32 RegEax;\r
46 MSR_SEV_STATUS_REGISTER Msr;\r
47 CPUID_MEMORY_ENCRYPTION_INFO_EAX Eax;\r
48\r
49 //\r
50 // Check if memory encryption leaf exist\r
51 //\r
52 AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);\r
53 if (RegEax >= CPUID_MEMORY_ENCRYPTION_INFO) {\r
54 //\r
55 // CPUID Fn8000_001F[EAX] Bit 1 (Sev supported)\r
56 //\r
57 AsmCpuid (CPUID_MEMORY_ENCRYPTION_INFO, &Eax.Uint32, NULL, NULL, NULL);\r
58\r
59 if (Eax.Bits.SevBit) {\r
60 //\r
61 // Check MSR_0xC0010131 Bit 0 (Sev Enabled)\r
62 //\r
63 Msr.Uint32 = AsmReadMsr32 (MSR_SEV_STATUS);\r
64 if (Msr.Bits.SevBit) {\r
65 return TRUE;\r
66 }\r
67 }\r
68 }\r
69\r
70 return FALSE;\r
71}\r
72\r
73/**\r
a1f22614
BS
74 Returns a boolean to indicate whether SEV is enabled\r
75\r
76 @retval TRUE SEV is enabled\r
77 @retval FALSE SEV is not enabled\r
d4dd22c7 78**/\r
a1f22614
BS
79BOOLEAN\r
80EFIAPI\r
81MemEncryptSevIsEnabled (\r
82 VOID\r
83 )\r
84{\r
85 if (mSevStatusChecked) {\r
86 return mSevStatus;\r
87 }\r
88\r
89 mSevStatus = InternalMemEncryptSevIsEnabled();\r
90 mSevStatusChecked = TRUE;\r
91\r
92 return mSevStatus;\r
93}\r
61a044c6
LE
94\r
95\r
96/**\r
97 Locate the page range that covers the initial (pre-SMBASE-relocation) SMRAM\r
98 Save State Map.\r
99\r
100 @param[out] BaseAddress The base address of the lowest-address page that\r
101 covers the initial SMRAM Save State Map.\r
102\r
103 @param[out] NumberOfPages The number of pages in the page range that covers\r
104 the initial SMRAM Save State Map.\r
105\r
106 @retval RETURN_SUCCESS BaseAddress and NumberOfPages have been set on\r
107 output.\r
108\r
109 @retval RETURN_UNSUPPORTED SMM is unavailable.\r
110**/\r
111RETURN_STATUS\r
112EFIAPI\r
113MemEncryptSevLocateInitialSmramSaveStateMapPages (\r
114 OUT UINTN *BaseAddress,\r
115 OUT UINTN *NumberOfPages\r
116 )\r
117{\r
118 UINTN MapStart;\r
119 UINTN MapEnd;\r
120 UINTN MapPagesStart; // MapStart rounded down to page boundary\r
121 UINTN MapPagesEnd; // MapEnd rounded up to page boundary\r
122 UINTN MapPagesSize; // difference between MapPagesStart and MapPagesEnd\r
123\r
124 if (!FeaturePcdGet (PcdSmmSmramRequire)) {\r
125 return RETURN_UNSUPPORTED;\r
126 }\r
127\r
128 MapStart = SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET;\r
129 MapEnd = MapStart + sizeof (QEMU_SMRAM_SAVE_STATE_MAP);\r
130 MapPagesStart = MapStart & ~(UINTN)EFI_PAGE_MASK;\r
131 MapPagesEnd = ALIGN_VALUE (MapEnd, EFI_PAGE_SIZE);\r
132 MapPagesSize = MapPagesEnd - MapPagesStart;\r
133\r
134 ASSERT ((MapPagesSize & EFI_PAGE_MASK) == 0);\r
135\r
136 *BaseAddress = MapPagesStart;\r
137 *NumberOfPages = MapPagesSize >> EFI_PAGE_SHIFT;\r
138\r
139 return RETURN_SUCCESS;\r
140}\r