]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/QemuFwCfgLib/QemuFwCfgPei.c
OvmfPkg/QemuFwCfgLib: Implement SEV internal functions for PEI phase
[mirror_edk2.git] / OvmfPkg / Library / QemuFwCfgLib / QemuFwCfgPei.c
CommitLineData
2ce7e221
LE
1/** @file\r
2\r
3 Stateful and implicitly initialized fw_cfg library implementation.\r
4\r
5 Copyright (C) 2013, Red Hat, Inc.\r
6 Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>\r
5feae253 7 Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>\r
2ce7e221
LE
8\r
9 This program and the accompanying materials are licensed and made available\r
10 under the terms and conditions of the BSD License which accompanies this\r
11 distribution. The full text of the license may be found at\r
12 http://opensource.org/licenses/bsd-license.php\r
13\r
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
15 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16**/\r
17\r
5feae253 18#include <Library/BaseLib.h>\r
2ce7e221
LE
19#include <Library/DebugLib.h>\r
20#include <Library/QemuFwCfgLib.h>\r
5feae253 21#include <Library/MemEncryptSevLib.h>\r
2ce7e221 22\r
5297c0bf
LE
23#include "QemuFwCfgLibInternal.h"\r
24\r
2ce7e221 25STATIC BOOLEAN mQemuFwCfgSupported = FALSE;\r
2c8dcbc6 26STATIC BOOLEAN mQemuFwCfgDmaSupported;\r
2ce7e221
LE
27\r
28\r
29/**\r
30 Returns a boolean indicating if the firmware configuration interface\r
31 is available or not.\r
32\r
33 This function may change fw_cfg state.\r
34\r
35 @retval TRUE The interface is available\r
36 @retval FALSE The interface is not available\r
37\r
38**/\r
39BOOLEAN\r
40EFIAPI\r
41QemuFwCfgIsAvailable (\r
42 VOID\r
43 )\r
44{\r
45 return InternalQemuFwCfgIsAvailable ();\r
46}\r
47\r
48\r
49RETURN_STATUS\r
50EFIAPI\r
51QemuFwCfgInitialize (\r
52 VOID\r
53 )\r
54{\r
55 UINT32 Signature;\r
56 UINT32 Revision;\r
57\r
58 //\r
59 // Enable the access routines while probing to see if it is supported.\r
2c8dcbc6 60 // For probing we always use the IO Port (IoReadFifo8()) access method.\r
2ce7e221
LE
61 //\r
62 mQemuFwCfgSupported = TRUE;\r
2c8dcbc6 63 mQemuFwCfgDmaSupported = FALSE;\r
2ce7e221
LE
64\r
65 QemuFwCfgSelectItem (QemuFwCfgItemSignature);\r
66 Signature = QemuFwCfgRead32 ();\r
67 DEBUG ((EFI_D_INFO, "FW CFG Signature: 0x%x\n", Signature));\r
68 QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);\r
69 Revision = QemuFwCfgRead32 ();\r
70 DEBUG ((EFI_D_INFO, "FW CFG Revision: 0x%x\n", Revision));\r
71 if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) ||\r
72 (Revision < 1)\r
73 ) {\r
74 DEBUG ((EFI_D_INFO, "QemuFwCfg interface not supported.\n"));\r
75 mQemuFwCfgSupported = FALSE;\r
76 return RETURN_SUCCESS;\r
77 }\r
78\r
2c8dcbc6
LE
79 if ((Revision & FW_CFG_F_DMA) == 0) {\r
80 DEBUG ((DEBUG_INFO, "QemuFwCfg interface (IO Port) is supported.\n"));\r
81 } else {\r
5feae253
BS
82 //\r
83 // If SEV is enabled then we do not support DMA operations in PEI phase.\r
84 // This is mainly because DMA in SEV guest requires using bounce buffer\r
85 // (which need to allocate dynamic memory and allocating a PAGE size'd\r
86 // buffer can be challenge in PEI phase)\r
87 //\r
88 if (InternalQemuFwCfgSevIsEnabled ()) {\r
89 DEBUG ((DEBUG_INFO, "SEV: QemuFwCfg fallback to IO Port interface.\n"));\r
90 } else {\r
91 mQemuFwCfgDmaSupported = TRUE;\r
92 DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));\r
93 }\r
2c8dcbc6 94 }\r
2ce7e221
LE
95 return RETURN_SUCCESS;\r
96}\r
97\r
98\r
99/**\r
100 Returns a boolean indicating if the firmware configuration interface is\r
101 available for library-internal purposes.\r
102\r
103 This function never changes fw_cfg state.\r
104\r
105 @retval TRUE The interface is available internally.\r
106 @retval FALSE The interface is not available internally.\r
107**/\r
108BOOLEAN\r
2ce7e221
LE
109InternalQemuFwCfgIsAvailable (\r
110 VOID\r
111 )\r
112{\r
113 return mQemuFwCfgSupported;\r
114}\r
2c8dcbc6
LE
115\r
116/**\r
117 Returns a boolean indicating whether QEMU provides the DMA-like access method\r
118 for fw_cfg.\r
119\r
120 @retval TRUE The DMA-like access method is available.\r
121 @retval FALSE The DMA-like access method is unavailable.\r
122**/\r
123BOOLEAN\r
124InternalQemuFwCfgDmaIsAvailable (\r
125 VOID\r
126 )\r
127{\r
128 return mQemuFwCfgDmaSupported;\r
129}\r
5feae253
BS
130\r
131/**\r
132\r
133 Returns a boolean indicating whether SEV is enabled\r
134\r
135 @retval TRUE SEV is enabled\r
136 @retval FALSE SEV is disabled\r
137**/\r
138BOOLEAN\r
139InternalQemuFwCfgSevIsEnabled (\r
140 VOID\r
141 )\r
142{\r
143 return MemEncryptSevIsEnabled ();\r
144}\r
145\r
146/**\r
147 Allocate a bounce buffer for SEV DMA.\r
148\r
149 @param[in] NumPage Number of pages.\r
150 @param[out] Buffer Allocated DMA Buffer pointer\r
151\r
152**/\r
153VOID\r
154InternalQemuFwCfgSevDmaAllocateBuffer (\r
155 OUT VOID **Buffer,\r
156 IN UINT32 NumPages\r
157 )\r
158{\r
159 //\r
160 // We should never reach here\r
161 //\r
162 ASSERT (FALSE);\r
163 CpuDeadLoop ();\r
164}\r
165\r
166/**\r
167 Free the DMA buffer allocated using InternalQemuFwCfgSevDmaAllocateBuffer\r
168\r
169 @param[in] NumPage Number of pages.\r
170 @param[in] Buffer DMA Buffer pointer\r
171\r
172**/\r
173VOID\r
174InternalQemuFwCfgSevDmaFreeBuffer (\r
175 IN VOID *Buffer,\r
176 IN UINT32 NumPages\r
177 )\r
178{\r
179 //\r
180 // We should never reach here\r
181 //\r
182 ASSERT (FALSE);\r
183 CpuDeadLoop ();\r
184}\r