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