]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/PlatformPei/Xen.c
ShellPkg/SmbiosView: SMBIOS 3.3.0 Update "Intel persistent memory"
[mirror_edk2.git] / OvmfPkg / PlatformPei / Xen.c
CommitLineData
eec7d420 1/**@file\r
2 Xen Platform PEI support\r
3\r
035ce3b3 4 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
eec7d420 5 Copyright (c) 2011, Andrei Warkentin <andreiw@motorola.com>\r
6\r
b26f0cf9 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
eec7d420 8\r
9**/\r
10\r
11//\r
12// The package level header files this module uses\r
13//\r
14#include <PiPei.h>\r
15\r
16//\r
17// The Library classes this module consumes\r
18//\r
19#include <Library/DebugLib.h>\r
20#include <Library/HobLib.h>\r
21#include <Library/MemoryAllocationLib.h>\r
22#include <Library/PcdLib.h>\r
23#include <Guid/XenInfo.h>\r
18f31ada
JJ
24#include <IndustryStandard/E820.h>\r
25#include <Library/ResourcePublicationLib.h>\r
26#include <Library/MtrrLib.h>\r
eec7d420 27\r
28#include "Platform.h"\r
bb6a9a93 29#include "Xen.h"\r
eec7d420 30\r
b621bb0a
JJ
31BOOLEAN mXen = FALSE;\r
32\r
b98b4941
JJ
33STATIC UINT32 mXenLeaf = 0;\r
34\r
eec7d420 35EFI_XEN_INFO mXenInfo;\r
36\r
bb6a9a93
WL
37/**\r
38 Returns E820 map provided by Xen\r
39\r
40 @param Entries Pointer to E820 map\r
41 @param Count Number of entries\r
42\r
43 @return EFI_STATUS\r
44**/\r
45EFI_STATUS\r
46XenGetE820Map (\r
47 EFI_E820_ENTRY64 **Entries,\r
48 UINT32 *Count\r
49 )\r
50{\r
51 EFI_XEN_OVMF_INFO *Info =\r
52 (EFI_XEN_OVMF_INFO *)(UINTN) OVMF_INFO_PHYSICAL_ADDRESS;\r
53\r
54 if (AsciiStrCmp ((CHAR8 *) Info->Signature, "XenHVMOVMF")) {\r
55 return EFI_NOT_FOUND;\r
56 }\r
57\r
58 ASSERT (Info->E820 < MAX_ADDRESS);\r
59 *Entries = (EFI_E820_ENTRY64 *)(UINTN) Info->E820;\r
60 *Count = Info->E820EntriesCount;\r
61\r
62 return EFI_SUCCESS;\r
63}\r
eec7d420 64\r
65/**\r
66 Connects to the Hypervisor.\r
4040754d 67\r
eec7d420 68 @param XenLeaf CPUID index used to connect.\r
69\r
70 @return EFI_STATUS\r
71\r
72**/\r
73EFI_STATUS\r
74XenConnect (\r
75 UINT32 XenLeaf\r
76 )\r
77{\r
78 UINT32 Index;\r
79 UINT32 TransferReg;\r
80 UINT32 TransferPages;\r
81 UINT32 XenVersion;\r
82\r
83 AsmCpuid (XenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL);\r
84 mXenInfo.HyperPages = AllocatePages (TransferPages);\r
85 if (!mXenInfo.HyperPages) {\r
86 return EFI_OUT_OF_RESOURCES;\r
87 }\r
88\r
89 for (Index = 0; Index < TransferPages; Index++) {\r
90 AsmWriteMsr64 (TransferReg,\r
91 (UINTN) mXenInfo.HyperPages +\r
92 (Index << EFI_PAGE_SHIFT) + Index);\r
93 }\r
94\r
95 AsmCpuid (XenLeaf + 1, &XenVersion, NULL, NULL, NULL);\r
96 DEBUG ((EFI_D_ERROR, "Detected Xen version %d.%d\n",\r
97 XenVersion >> 16, XenVersion & 0xFFFF));\r
670a64e7 98 mXenInfo.VersionMajor = (UINT16)(XenVersion >> 16);\r
99 mXenInfo.VersionMinor = (UINT16)(XenVersion & 0xFFFF);\r
eec7d420 100\r
eec7d420 101 BuildGuidDataHob (\r
102 &gEfiXenInfoGuid,\r
103 &mXenInfo,\r
104 sizeof(mXenInfo)\r
105 );\r
106\r
107 return EFI_SUCCESS;\r
108}\r
109\r
110/**\r
111 Figures out if we are running inside Xen HVM.\r
112\r
b98b4941
JJ
113 @retval TRUE Xen was detected\r
114 @retval FALSE Xen was not detected\r
eec7d420 115\r
116**/\r
b98b4941 117BOOLEAN\r
eec7d420 118XenDetect (\r
119 VOID\r
120 )\r
121{\r
eec7d420 122 UINT8 Signature[13];\r
123\r
b98b4941
JJ
124 if (mXenLeaf != 0) {\r
125 return TRUE;\r
126 }\r
127\r
128 Signature[12] = '\0';\r
129 for (mXenLeaf = 0x40000000; mXenLeaf < 0x40010000; mXenLeaf += 0x100) {\r
130 AsmCpuid (mXenLeaf,\r
131 NULL,\r
132 (UINT32 *) &Signature[0],\r
eec7d420 133 (UINT32 *) &Signature[4],\r
134 (UINT32 *) &Signature[8]);\r
eec7d420 135\r
136 if (!AsciiStrCmp ((CHAR8 *) Signature, "XenVMMXenVMM")) {\r
b621bb0a 137 mXen = TRUE;\r
b98b4941 138 return TRUE;\r
eec7d420 139 }\r
140 }\r
141\r
b98b4941
JJ
142 mXenLeaf = 0;\r
143 return FALSE;\r
eec7d420 144}\r
145\r
18f31ada
JJ
146\r
147VOID\r
148XenPublishRamRegions (\r
149 VOID\r
150 )\r
151{\r
152 EFI_E820_ENTRY64 *E820Map;\r
153 UINT32 E820EntriesCount;\r
154 EFI_STATUS Status;\r
155\r
156 if (!mXen) {\r
157 return;\r
158 }\r
159\r
160 DEBUG ((EFI_D_INFO, "Using memory map provided by Xen\n"));\r
161\r
162 //\r
163 // Parse RAM in E820 map\r
164 //\r
7ffced92 165 E820EntriesCount = 0;\r
18f31ada
JJ
166 Status = XenGetE820Map (&E820Map, &E820EntriesCount);\r
167\r
168 ASSERT_EFI_ERROR (Status);\r
169\r
170 if (E820EntriesCount > 0) {\r
171 EFI_E820_ENTRY64 *Entry;\r
172 UINT32 Loop;\r
173\r
174 for (Loop = 0; Loop < E820EntriesCount; Loop++) {\r
175 Entry = E820Map + Loop;\r
176\r
177 //\r
178 // Only care about RAM\r
179 //\r
180 if (Entry->Type != EfiAcpiAddressRangeMemory) {\r
181 continue;\r
182 }\r
183\r
035ce3b3 184 AddMemoryBaseSizeHob (Entry->BaseAddr, Entry->Length);\r
18f31ada
JJ
185\r
186 MtrrSetMemoryAttribute (Entry->BaseAddr, Entry->Length, CacheWriteBack);\r
187 }\r
188 }\r
189}\r
190\r
191\r
eec7d420 192/**\r
193 Perform Xen PEI initialization.\r
194\r
195 @return EFI_SUCCESS Xen initialized successfully\r
196 @return EFI_NOT_FOUND Not running under Xen\r
197\r
198**/\r
199EFI_STATUS\r
200InitializeXen (\r
b98b4941 201 VOID\r
eec7d420 202 )\r
203{\r
32e083c7
LE
204 RETURN_STATUS PcdStatus;\r
205\r
b98b4941
JJ
206 if (mXenLeaf == 0) {\r
207 return EFI_NOT_FOUND;\r
208 }\r
209\r
210 XenConnect (mXenLeaf);\r
eec7d420 211\r
212 //\r
213 // Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000).\r
214 // This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE.\r
215 //\r
cdef34ec 216 AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000, FALSE);\r
eec7d420 217\r
32e083c7
LE
218 PcdStatus = PcdSetBoolS (PcdPciDisableBusEnumeration, TRUE);\r
219 ASSERT_RETURN_ERROR (PcdStatus);\r
c191a58f 220\r
eec7d420 221 return EFI_SUCCESS;\r
222}\r