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