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