]> git.proxmox.com Git - mirror_edk2.git/blame - IntelSiliconPkg/IntelVTdDxe/DmaProtection.h
IntelSiliconPkg: Fix VS2015 NOOPT IA32 build failure in IntelVTdDxe
[mirror_edk2.git] / IntelSiliconPkg / IntelVTdDxe / DmaProtection.h
CommitLineData
c049fc99
JY
1/** @file\r
2\r
3 Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
4 This program and the accompanying materials\r
5 are licensed and made available under the terms and conditions of the BSD License\r
6 which accompanies this distribution. The full text of the license may be found at\r
7 http://opensource.org/licenses/bsd-license.php.\r
8\r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12**/\r
13\r
14#ifndef _DMAR_PROTECTION_H_\r
15#define _DMAR_PROTECTION_H_\r
16\r
17#include <Uefi.h>\r
18#include <PiDxe.h>\r
19\r
20#include <Library/BaseLib.h>\r
21#include <Library/BaseMemoryLib.h>\r
22#include <Library/MemoryAllocationLib.h>\r
23#include <Library/UefiBootServicesTableLib.h>\r
24#include <Library/IoLib.h>\r
25#include <Library/PciSegmentLib.h>\r
26#include <Library/DebugLib.h>\r
27#include <Library/UefiLib.h>\r
28\r
29#include <Guid/EventGroup.h>\r
30#include <Guid/Acpi.h>\r
31\r
32#include <Protocol/DxeSmmReadyToLock.h>\r
33#include <Protocol/PciRootBridgeIo.h>\r
34#include <Protocol/PciIo.h>\r
35#include <Protocol/PciEnumerationComplete.h>\r
36#include <Protocol/AcpiSystemDescriptionTable.h>\r
37#include <Protocol/PlatformVtdPolicy.h>\r
38#include <Protocol/IoMmu.h>\r
39\r
40#include <IndustryStandard/Pci.h>\r
41#include <IndustryStandard/DmaRemappingReportingTable.h>\r
42#include <IndustryStandard/Vtd.h>\r
43\r
76c6f69c
SZ
44#define VTD_64BITS_ADDRESS(Lo, Hi) (LShiftU64 (Lo, 12) | LShiftU64 (Hi, 32))\r
45\r
c049fc99
JY
46#define ALIGN_VALUE_UP(Value, Alignment) (((Value) + (Alignment) - 1) & (~((Alignment) - 1)))\r
47#define ALIGN_VALUE_LOW(Value, Alignment) ((Value) & (~((Alignment) - 1)))\r
48\r
49//\r
50// This is the initial max PCI descriptor.\r
51// The number may be enlarged later.\r
52//\r
53#define MAX_PCI_DESCRIPTORS 0x100\r
54\r
55typedef struct {\r
56 BOOLEAN IncludeAllFlag;\r
57 UINTN PciDescriptorNumber;\r
58 UINTN PciDescriptorMaxNumber;\r
59 BOOLEAN *IsRealPciDevice;\r
60 VTD_SOURCE_ID *PciDescriptors;\r
61} PCI_DEVICE_INFORMATION;\r
62\r
63typedef struct {\r
64 UINTN VtdUnitBaseAddress;\r
65 UINT16 Segment;\r
66 VTD_CAP_REG CapReg;\r
67 VTD_ECAP_REG ECapReg;\r
68 VTD_ROOT_ENTRY *RootEntryTable;\r
69 VTD_EXT_ROOT_ENTRY *ExtRootEntryTable;\r
70 VTD_SECOND_LEVEL_PAGING_ENTRY *FixedSecondLevelPagingEntry;\r
71 BOOLEAN HasDirtyPages;\r
72 PCI_DEVICE_INFORMATION PciDeviceInfo;\r
73} VTD_UNIT_INFORMATION;\r
74\r
75extern EFI_ACPI_DMAR_HEADER *mAcpiDmarTable;\r
76\r
77extern UINT64 mVtdHostAddressWidthMask;\r
78extern UINTN mVtdUnitNumber;\r
79extern VTD_UNIT_INFORMATION *mVtdUnitInformation;\r
80\r
81extern UINT64 mBelow4GMemoryLimit;\r
82extern UINT64 mAbove4GMemoryLimit;\r
83\r
84extern EDKII_PLATFORM_VTD_POLICY_PROTOCOL *mPlatformVTdPolicy;\r
85\r
86/**\r
87 Prepare VTD configuration.\r
88**/\r
89VOID\r
90PrepareVtdConfig (\r
91 VOID\r
92 );\r
93\r
94/**\r
95 Setup VTd translation table.\r
96\r
97 @retval EFI_SUCCESS Setup translation table successfully.\r
98 @retval EFI_OUT_OF_RESOURCE Setup translation table fail.\r
99**/\r
100EFI_STATUS\r
101SetupTranslationTable (\r
102 VOID\r
103 );\r
104\r
105/**\r
106 Enable DMAR translation.\r
107\r
108 @retval EFI_SUCCESS DMAR translation is enabled.\r
109 @retval EFI_DEVICE_ERROR DMAR translation is not enabled.\r
110**/\r
111EFI_STATUS\r
112EnableDmar (\r
113 VOID\r
114 );\r
115\r
116/**\r
117 Disable DMAR translation.\r
118\r
119 @retval EFI_SUCCESS DMAR translation is disabled.\r
120 @retval EFI_DEVICE_ERROR DMAR translation is not disabled.\r
121**/\r
122EFI_STATUS\r
123DisableDmar (\r
124 VOID\r
125 );\r
126\r
127/**\r
128 Invalid VTd IOTLB page.\r
129\r
130 @param[in] VtdIndex The index of VTd engine.\r
131 @param[in] Address The address of IOTLB page.\r
132 @param[in] AddressMode The address mode of IOTLB page.\r
133 @param[in] DomainIdentifier The domain ID of the source.\r
134\r
135 @retval EFI_SUCCESS VTd IOTLB page is invalidated.\r
136 @retval EFI_DEVICE_ERROR VTd IOTLB page is not invalidated.\r
137**/\r
138EFI_STATUS\r
139InvalidateVtdIOTLBPage (\r
140 IN UINTN VtdIndex,\r
141 IN UINT64 Address,\r
142 IN UINT8 AddressMode,\r
143 IN UINT16 DomainIdentifier\r
144 );\r
145\r
146/**\r
147 Invalid VTd IOTLB domain.\r
148\r
149 @param[in] VtdIndex The index of VTd engine.\r
150 @param[in] DomainIdentifier The domain ID of the source.\r
151\r
152 @retval EFI_SUCCESS VTd IOTLB domain is invalidated.\r
153 @retval EFI_DEVICE_ERROR VTd IOTLB domain is not invalidated.\r
154**/\r
155EFI_STATUS\r
156InvalidateVtdIOTLBDomain (\r
157 IN UINTN VtdIndex,\r
158 IN UINT16 DomainIdentifier\r
159 );\r
160\r
161/**\r
162 Invalid VTd global IOTLB.\r
163\r
164 @param[in] VtdIndex The index of VTd engine.\r
165\r
166 @retval EFI_SUCCESS VTd global IOTLB is invalidated.\r
167 @retval EFI_DEVICE_ERROR VTd global IOTLB is not invalidated.\r
168**/\r
169EFI_STATUS\r
170InvalidateVtdIOTLBGlobal (\r
171 IN UINTN VtdIndex\r
172 );\r
173\r
174/**\r
175 Dump VTd registers.\r
176\r
177 @param[in] VtdIndex The index of VTd engine.\r
178**/\r
179VOID\r
180DumpVtdRegs (\r
181 IN UINTN VtdIndex\r
182 );\r
183\r
184/**\r
185 Dump VTd registers for all VTd engine.\r
186**/\r
187VOID\r
188DumpVtdRegsAll (\r
189 VOID\r
190 );\r
191\r
192/**\r
193 Dump VTd capability registers.\r
194\r
195 @param[in] CapReg The capability register.\r
196**/\r
197VOID\r
198DumpVtdCapRegs (\r
199 IN VTD_CAP_REG *CapReg\r
200 );\r
201\r
202/**\r
203 Dump VTd extended capability registers.\r
204\r
205 @param[in] ECapReg The extended capability register.\r
206**/\r
207VOID\r
208DumpVtdECapRegs (\r
209 IN VTD_ECAP_REG *ECapReg\r
210 );\r
211\r
212/**\r
213 Register PCI device to VTd engine as PCI descriptor.\r
214\r
215 @param[in] VtdIndex The index of VTd engine.\r
216 @param[in] Segment The segment of the source.\r
217 @param[in] SourceId The SourceId of the source.\r
218 @param[in] IsRealPciDevice TRUE: It is a real PCI device.\r
219 FALSE: It is not a real PCI device.\r
220 @param[in] CheckExist TRUE: ERROR will be returned if the PCI device is already registered.\r
221 FALSE: SUCCESS will be returned if the PCI device is registered.\r
222\r
223 @retval EFI_SUCCESS The PCI device is registered.\r
224 @retval EFI_OUT_OF_RESOURCES No enough resource to register a new PCI device.\r
225 @retval EFI_ALREADY_STARTED The device is already registered.\r
226**/\r
227EFI_STATUS\r
228RegisterPciDevice (\r
229 IN UINTN VtdIndex,\r
230 IN UINT16 Segment,\r
231 IN VTD_SOURCE_ID SourceId,\r
232 IN BOOLEAN IsRealPciDevice,\r
233 IN BOOLEAN CheckExist\r
234 );\r
235\r
236/**\r
237 Scan PCI bus and register PCI devices under the bus.\r
238\r
239 @param[in] VtdIndex The index of VTd engine.\r
240 @param[in] Segment The segment of the source.\r
241 @param[in] Bus The bus of the source.\r
242\r
243 @retval EFI_SUCCESS The PCI devices under the bus are registered.\r
244 @retval EFI_OUT_OF_RESOURCES No enough resource to register a new PCI device.\r
245**/\r
246EFI_STATUS\r
247ScanPciBus (\r
248 IN UINTN VtdIndex,\r
249 IN UINT16 Segment,\r
250 IN UINT8 Bus\r
251 );\r
252\r
253/**\r
254 Dump the PCI device information managed by this VTd engine.\r
255\r
256 @param[in] VtdIndex The index of VTd engine.\r
257**/\r
258VOID\r
259DumpPciDeviceInfo (\r
260 IN UINTN VtdIndex\r
261 );\r
262\r
263/**\r
264 Find the VTd index by the Segment and SourceId.\r
265\r
266 @param[in] Segment The segment of the source.\r
267 @param[in] SourceId The SourceId of the source.\r
268 @param[out] ExtContextEntry The ExtContextEntry of the source.\r
269 @param[out] ContextEntry The ContextEntry of the source.\r
270\r
271 @return The index of the PCI descriptor.\r
272 @retval (UINTN)-1 The PCI descriptor is not found.\r
273**/\r
274UINTN\r
275FindVtdIndexByPciDevice (\r
276 IN UINT16 Segment,\r
277 IN VTD_SOURCE_ID SourceId,\r
278 OUT VTD_EXT_CONTEXT_ENTRY **ExtContextEntry,\r
279 OUT VTD_CONTEXT_ENTRY **ContextEntry\r
280 );\r
281\r
282/**\r
283 Get the DMAR ACPI table.\r
284\r
285 @retval EFI_SUCCESS The DMAR ACPI table is got.\r
286 @retval EFI_NOT_FOUND The DMAR ACPI table is not found.\r
287**/\r
288EFI_STATUS\r
289GetDmarAcpiTable (\r
290 VOID\r
291 );\r
292\r
293/**\r
294 Parse DMAR DRHD table.\r
295\r
296 @return EFI_SUCCESS The DMAR DRHD table is parsed.\r
297**/\r
298EFI_STATUS\r
299ParseDmarAcpiTableDrhd (\r
300 VOID\r
301 );\r
302\r
303/**\r
304 Parse DMAR RMRR table.\r
305\r
306 @return EFI_SUCCESS The DMAR RMRR table is parsed.\r
307**/\r
308EFI_STATUS\r
309ParseDmarAcpiTableRmrr (\r
310 VOID\r
311 );\r
312\r
313/**\r
314 Dump DMAR context entry table.\r
315\r
316 @param[in] RootEntry DMAR root entry.\r
317**/\r
318VOID\r
319DumpDmarContextEntryTable (\r
320 IN VTD_ROOT_ENTRY *RootEntry\r
321 );\r
322\r
323/**\r
324 Dump DMAR extended context entry table.\r
325\r
326 @param[in] ExtRootEntry DMAR extended root entry.\r
327**/\r
328VOID\r
329DumpDmarExtContextEntryTable (\r
330 IN VTD_EXT_ROOT_ENTRY *ExtRootEntry\r
331 );\r
332\r
333/**\r
334 Dump DMAR second level paging entry.\r
335\r
336 @param[in] SecondLevelPagingEntry The second level paging entry.\r
337**/\r
338VOID\r
339DumpSecondLevelPagingEntry (\r
340 IN VOID *SecondLevelPagingEntry\r
341 );\r
342\r
343/**\r
344 Set VTd attribute for a system memory.\r
345\r
346 @param[in] VtdIndex The index used to identify a VTd engine.\r
347 @param[in] SecondLevelPagingEntry The second level paging entry in VTd table for the device.\r
348 @param[in] BaseAddress The base of device memory address to be used as the DMA memory.\r
349 @param[in] Length The length of device memory address to be used as the DMA memory.\r
350 @param[in] IoMmuAccess The IOMMU access.\r
351\r
352 @retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by BaseAddress and Length.\r
353 @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.\r
354 @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.\r
355 @retval EFI_INVALID_PARAMETER Length is 0.\r
356 @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.\r
357 @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.\r
358 @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by BaseAddress and Length.\r
359 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.\r
360 @retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.\r
361**/\r
362EFI_STATUS\r
363SetPageAttribute (\r
364 IN UINTN VtdIndex,\r
365 IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry,\r
366 IN UINT64 BaseAddress,\r
367 IN UINT64 Length,\r
368 IN UINT64 IoMmuAccess\r
369 );\r
370\r
371/**\r
372 Set VTd attribute for a system memory.\r
373\r
374 @param[in] Segment The Segment used to identify a VTd engine.\r
375 @param[in] SourceId The SourceId used to identify a VTd engine and table entry.\r
376 @param[in] BaseAddress The base of device memory address to be used as the DMA memory.\r
377 @param[in] Length The length of device memory address to be used as the DMA memory.\r
378 @param[in] IoMmuAccess The IOMMU access.\r
379\r
380 @retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by BaseAddress and Length.\r
381 @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.\r
382 @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.\r
383 @retval EFI_INVALID_PARAMETER Length is 0.\r
384 @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.\r
385 @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.\r
386 @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by BaseAddress and Length.\r
387 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.\r
388 @retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.\r
389**/\r
390EFI_STATUS\r
391SetAccessAttribute (\r
392 IN UINT16 Segment,\r
393 IN VTD_SOURCE_ID SourceId,\r
394 IN UINT64 BaseAddress,\r
395 IN UINT64 Length,\r
396 IN UINT64 IoMmuAccess\r
397 );\r
398\r
399/**\r
400 Return the index of PCI descriptor.\r
401\r
402 @param[in] VtdIndex The index used to identify a VTd engine.\r
403 @param[in] Segment The Segment used to identify a VTd engine.\r
404 @param[in] SourceId The SourceId used to identify a VTd engine and table entry.\r
405\r
406 @return The index of the PCI descriptor.\r
407 @retval (UINTN)-1 The PCI descriptor is not found.\r
408**/\r
409UINTN\r
410GetPciDescriptor (\r
411 IN UINTN VtdIndex,\r
412 IN UINT16 Segment,\r
413 IN VTD_SOURCE_ID SourceId\r
414 );\r
415\r
416/**\r
417 Dump VTd registers if there is error.\r
418**/\r
419VOID\r
420DumpVtdIfError (\r
421 VOID\r
422 );\r
423\r
424/**\r
425 Initialize platform VTd policy.\r
426**/\r
427VOID\r
428InitializePlatformVTdPolicy (\r
429 VOID\r
430 );\r
431\r
432/**\r
433 Always enable the VTd page attribute for the device.\r
434\r
435 @param[in] Segment The Segment used to identify a VTd engine.\r
436 @param[in] SourceId The SourceId used to identify a VTd engine and table entry.\r
437\r
438 @retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device.\r
439**/\r
440EFI_STATUS\r
441AlwaysEnablePageAttribute (\r
442 IN UINT16 Segment,\r
443 IN VTD_SOURCE_ID SourceId\r
444 );\r
445\r
446/**\r
447 Convert the DeviceHandle to SourceId and Segment.\r
448\r
449 @param[in] DeviceHandle The device who initiates the DMA access request.\r
450 @param[out] Segment The Segment used to identify a VTd engine.\r
451 @param[out] SourceId The SourceId used to identify a VTd engine and table entry.\r
452\r
453 @retval EFI_SUCCESS The Segment and SourceId are returned.\r
454 @retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.\r
455 @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.\r
456**/\r
457EFI_STATUS\r
458DeviceHandleToSourceId (\r
459 IN EFI_HANDLE DeviceHandle,\r
460 OUT UINT16 *Segment,\r
461 OUT VTD_SOURCE_ID *SourceId\r
462 );\r
463\r
464/**\r
465 Get device information from mapping.\r
466\r
467 @param[in] Mapping The mapping.\r
468 @param[out] DeviceAddress The device address of the mapping.\r
469 @param[out] NumberOfPages The number of pages of the mapping.\r
470\r
471 @retval EFI_SUCCESS The device information is returned.\r
472 @retval EFI_INVALID_PARAMETER The mapping is invalid.\r
473**/\r
474EFI_STATUS\r
475GetDeviceInfoFromMapping (\r
476 IN VOID *Mapping,\r
477 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
478 OUT UINTN *NumberOfPages\r
479 );\r
480\r
481/**\r
482 Initialize DMA protection.\r
483**/\r
484VOID\r
485InitializeDmaProtection (\r
486 VOID\r
487 );\r
488\r
489/**\r
490 Allocate zero pages.\r
491\r
492 @param[in] Pages the number of pages.\r
493\r
494 @return the page address.\r
495 @retval NULL No resource to allocate pages.\r
496**/\r
497VOID *\r
498EFIAPI\r
499AllocateZeroPages (\r
500 IN UINTN Pages\r
501 );\r
502\r
503#endif\r