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