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