]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/PlatformPei/Xen.c
0f75fa798320a4bdd8a81c38ca31d63e5678a1e3
[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
31 #include "Platform.h"
32 #include "Xen.h"
33
34 BOOLEAN mXen = FALSE;
35
36 EFI_XEN_INFO mXenInfo;
37
38 /**
39 Returns E820 map provided by Xen
40
41 @param Entries Pointer to E820 map
42 @param Count Number of entries
43
44 @return EFI_STATUS
45 **/
46 EFI_STATUS
47 XenGetE820Map (
48 EFI_E820_ENTRY64 **Entries,
49 UINT32 *Count
50 )
51 {
52 EFI_XEN_OVMF_INFO *Info =
53 (EFI_XEN_OVMF_INFO *)(UINTN) OVMF_INFO_PHYSICAL_ADDRESS;
54
55 if (AsciiStrCmp ((CHAR8 *) Info->Signature, "XenHVMOVMF")) {
56 return EFI_NOT_FOUND;
57 }
58
59 ASSERT (Info->E820 < MAX_ADDRESS);
60 *Entries = (EFI_E820_ENTRY64 *)(UINTN) Info->E820;
61 *Count = Info->E820EntriesCount;
62
63 return EFI_SUCCESS;
64 }
65
66 /**
67 Connects to the Hypervisor.
68
69 @param XenLeaf CPUID index used to connect.
70
71 @return EFI_STATUS
72
73 **/
74 EFI_STATUS
75 XenConnect (
76 UINT32 XenLeaf
77 )
78 {
79 UINT32 Index;
80 UINT32 TransferReg;
81 UINT32 TransferPages;
82 UINT32 XenVersion;
83
84 AsmCpuid (XenLeaf + 2, &TransferPages, &TransferReg, NULL, NULL);
85 mXenInfo.HyperPages = AllocatePages (TransferPages);
86 if (!mXenInfo.HyperPages) {
87 return EFI_OUT_OF_RESOURCES;
88 }
89
90 for (Index = 0; Index < TransferPages; Index++) {
91 AsmWriteMsr64 (TransferReg,
92 (UINTN) mXenInfo.HyperPages +
93 (Index << EFI_PAGE_SHIFT) + Index);
94 }
95
96 AsmCpuid (XenLeaf + 1, &XenVersion, NULL, NULL, NULL);
97 DEBUG ((EFI_D_ERROR, "Detected Xen version %d.%d\n",
98 XenVersion >> 16, XenVersion & 0xFFFF));
99 mXenInfo.VersionMajor = (UINT16)(XenVersion >> 16);
100 mXenInfo.VersionMinor = (UINT16)(XenVersion & 0xFFFF);
101
102 /* TBD: Locate hvm_info and reserve it away. */
103 mXenInfo.HvmInfo = NULL;
104
105 BuildGuidDataHob (
106 &gEfiXenInfoGuid,
107 &mXenInfo,
108 sizeof(mXenInfo)
109 );
110
111 return EFI_SUCCESS;
112 }
113
114 /**
115 Figures out if we are running inside Xen HVM.
116
117 @return UINT32 CPUID index used to connect to HV.
118
119 **/
120 UINT32
121 XenDetect (
122 VOID
123 )
124 {
125
126 UINT32 XenLeaf;
127 UINT8 Signature[13];
128
129 for (XenLeaf = 0x40000000; XenLeaf < 0x40010000; XenLeaf += 0x100) {
130 AsmCpuid (XenLeaf, NULL, (UINT32 *) &Signature[0],
131 (UINT32 *) &Signature[4],
132 (UINT32 *) &Signature[8]);
133 Signature[12] = '\0';
134
135 if (!AsciiStrCmp ((CHAR8 *) Signature, "XenVMMXenVMM")) {
136 mXen = TRUE;
137 return XenLeaf;
138 }
139 }
140
141 return 0;
142 }
143
144 /**
145 Perform Xen PEI initialization.
146
147 @return EFI_SUCCESS Xen initialized successfully
148 @return EFI_NOT_FOUND Not running under Xen
149
150 **/
151 EFI_STATUS
152 InitializeXen (
153 UINT32 XenLeaf
154 )
155 {
156 XenConnect (XenLeaf);
157
158 //
159 // Reserve away HVMLOADER reserved memory [0xFC000000,0xFD000000).
160 // This needs to match HVMLOADER RESERVED_MEMBASE/RESERVED_MEMSIZE.
161 //
162 AddReservedMemoryBaseSizeHob (0xFC000000, 0x1000000);
163
164 return EFI_SUCCESS;
165 }