]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/PlatformPei/Xen.c
BaseTools: Library hashing fix and optimization for --hash feature
[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
67 \r
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
101 /* TBD: Locate hvm_info and reserve it away. */\r
102 mXenInfo.HvmInfo = NULL;\r
103\r
104 BuildGuidDataHob (\r
105 &gEfiXenInfoGuid,\r
106 &mXenInfo,\r
107 sizeof(mXenInfo)\r
108 );\r
109\r
110 return EFI_SUCCESS;\r
111}\r
112\r
113/**\r
114 Figures out if we are running inside Xen HVM.\r
115\r
b98b4941
JJ
116 @retval TRUE Xen was detected\r
117 @retval FALSE Xen was not detected\r
eec7d420 118\r
119**/\r
b98b4941 120BOOLEAN\r
eec7d420 121XenDetect (\r
122 VOID\r
123 )\r
124{\r
eec7d420 125 UINT8 Signature[13];\r
126\r
b98b4941
JJ
127 if (mXenLeaf != 0) {\r
128 return TRUE;\r
129 }\r
130\r
131 Signature[12] = '\0';\r
132 for (mXenLeaf = 0x40000000; mXenLeaf < 0x40010000; mXenLeaf += 0x100) {\r
133 AsmCpuid (mXenLeaf,\r
134 NULL,\r
135 (UINT32 *) &Signature[0],\r
eec7d420 136 (UINT32 *) &Signature[4],\r
137 (UINT32 *) &Signature[8]);\r
eec7d420 138\r
139 if (!AsciiStrCmp ((CHAR8 *) Signature, "XenVMMXenVMM")) {\r
b621bb0a 140 mXen = TRUE;\r
b98b4941 141 return TRUE;\r
eec7d420 142 }\r
143 }\r
144\r
b98b4941
JJ
145 mXenLeaf = 0;\r
146 return FALSE;\r
eec7d420 147}\r
148\r
18f31ada
JJ
149\r
150VOID\r
151XenPublishRamRegions (\r
152 VOID\r
153 )\r
154{\r
155 EFI_E820_ENTRY64 *E820Map;\r
156 UINT32 E820EntriesCount;\r
157 EFI_STATUS Status;\r
158\r
159 if (!mXen) {\r
160 return;\r
161 }\r
162\r
163 DEBUG ((EFI_D_INFO, "Using memory map provided by Xen\n"));\r
164\r
165 //\r
166 // Parse RAM in E820 map\r
167 //\r
7ffced92 168 E820EntriesCount = 0;\r
18f31ada
JJ
169 Status = XenGetE820Map (&E820Map, &E820EntriesCount);\r
170\r
171 ASSERT_EFI_ERROR (Status);\r
172\r
173 if (E820EntriesCount > 0) {\r
174 EFI_E820_ENTRY64 *Entry;\r
175 UINT32 Loop;\r
176\r
177 for (Loop = 0; Loop < E820EntriesCount; Loop++) {\r
178 Entry = E820Map + Loop;\r
179\r
180 //\r
181 // Only care about RAM\r
182 //\r
183 if (Entry->Type != EfiAcpiAddressRangeMemory) {\r
184 continue;\r
185 }\r
186\r
035ce3b3 187 AddMemoryBaseSizeHob (Entry->BaseAddr, Entry->Length);\r
18f31ada
JJ
188\r
189 MtrrSetMemoryAttribute (Entry->BaseAddr, Entry->Length, CacheWriteBack);\r
190 }\r
191 }\r
192}\r
193\r
194\r
eec7d420 195/**\r
196 Perform Xen PEI initialization.\r
197\r
198 @return EFI_SUCCESS Xen initialized successfully\r
199 @return EFI_NOT_FOUND Not running under Xen\r
200\r
201**/\r
202EFI_STATUS\r
203InitializeXen (\r
b98b4941 204 VOID\r
eec7d420 205 )\r
206{\r
32e083c7
LE
207 RETURN_STATUS PcdStatus;\r
208\r
b98b4941
JJ
209 if (mXenLeaf == 0) {\r
210 return EFI_NOT_FOUND;\r
211 }\r
212\r
213 XenConnect (mXenLeaf);\r
eec7d420 214\r
215 //\r
216 // Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000).\r
217 // This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE.\r
218 //\r
cdef34ec 219 AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000, FALSE);\r
eec7d420 220\r
32e083c7
LE
221 PcdStatus = PcdSetBoolS (PcdPciDisableBusEnumeration, TRUE);\r
222 ASSERT_RETURN_ERROR (PcdStatus);\r
c191a58f 223\r
eec7d420 224 return EFI_SUCCESS;\r
225}\r