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