]> git.proxmox.com Git - mirror_edk2.git/blame - IntelSiliconPkg/Feature/VTd/IntelVTdDxe/DmaProtection.h
PcAtChipsetPkg/IsaAcpiDxe: Fix VS2012 build failure
[mirror_edk2.git] / IntelSiliconPkg / Feature / VTd / 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
4ad5f597
JY
28#include <Library/CacheMaintenanceLib.h>\r
29#include <Library/PerformanceLib.h>\r
30#include <Library/PrintLib.h>\r
c049fc99
JY
31\r
32#include <Guid/EventGroup.h>\r
33#include <Guid/Acpi.h>\r
34\r
35#include <Protocol/DxeSmmReadyToLock.h>\r
36#include <Protocol/PciRootBridgeIo.h>\r
37#include <Protocol/PciIo.h>\r
38#include <Protocol/PciEnumerationComplete.h>\r
c049fc99
JY
39#include <Protocol/PlatformVtdPolicy.h>\r
40#include <Protocol/IoMmu.h>\r
41\r
42#include <IndustryStandard/Pci.h>\r
43#include <IndustryStandard/DmaRemappingReportingTable.h>\r
44#include <IndustryStandard/Vtd.h>\r
45\r
76c6f69c
SZ
46#define VTD_64BITS_ADDRESS(Lo, Hi) (LShiftU64 (Lo, 12) | LShiftU64 (Hi, 32))\r
47\r
c049fc99
JY
48#define ALIGN_VALUE_UP(Value, Alignment) (((Value) + (Alignment) - 1) & (~((Alignment) - 1)))\r
49#define ALIGN_VALUE_LOW(Value, Alignment) ((Value) & (~((Alignment) - 1)))\r
50\r
51//\r
f77d35c7 52// This is the initial max PCI DATA number.\r
c049fc99
JY
53// The number may be enlarged later.\r
54//\r
f77d35c7 55#define MAX_VTD_PCI_DATA_NUMBER 0x100\r
c049fc99
JY
56\r
57typedef struct {\r
f77d35c7
JY
58 UINT8 DeviceType;\r
59 VTD_SOURCE_ID PciSourceId;\r
60 EDKII_PLATFORM_VTD_PCI_DEVICE_ID PciDeviceId;\r
4ad5f597 61 // for statistic analysis\r
f77d35c7
JY
62 UINTN AccessCount;\r
63} PCI_DEVICE_DATA;\r
64\r
65typedef struct {\r
66 BOOLEAN IncludeAllFlag;\r
67 UINTN PciDeviceDataNumber;\r
68 UINTN PciDeviceDataMaxNumber;\r
69 PCI_DEVICE_DATA *PciDeviceData;\r
c049fc99
JY
70} PCI_DEVICE_INFORMATION;\r
71\r
72typedef struct {\r
73 UINTN VtdUnitBaseAddress;\r
74 UINT16 Segment;\r
75 VTD_CAP_REG CapReg;\r
76 VTD_ECAP_REG ECapReg;\r
77 VTD_ROOT_ENTRY *RootEntryTable;\r
78 VTD_EXT_ROOT_ENTRY *ExtRootEntryTable;\r
79 VTD_SECOND_LEVEL_PAGING_ENTRY *FixedSecondLevelPagingEntry;\r
4ad5f597 80 BOOLEAN HasDirtyContext;\r
c049fc99
JY
81 BOOLEAN HasDirtyPages;\r
82 PCI_DEVICE_INFORMATION PciDeviceInfo;\r
83} VTD_UNIT_INFORMATION;\r
84\r
f77d35c7
JY
85/**\r
86 The scan bus callback function.\r
87\r
88 It is called in PCI bus scan for each PCI device under the bus.\r
89\r
90 @param[in] Context The context of the callback.\r
91 @param[in] Segment The segment of the source.\r
92 @param[in] Bus The bus of the source.\r
93 @param[in] Device The device of the source.\r
94 @param[in] Function The function of the source.\r
95\r
96 @retval EFI_SUCCESS The specific PCI device is processed in the callback.\r
97**/\r
98typedef\r
99EFI_STATUS\r
100(EFIAPI *SCAN_BUS_FUNC_CALLBACK_FUNC) (\r
101 IN VOID *Context,\r
102 IN UINT16 Segment,\r
103 IN UINT8 Bus,\r
104 IN UINT8 Device,\r
105 IN UINT8 Function\r
106 );\r
107\r
c049fc99
JY
108extern EFI_ACPI_DMAR_HEADER *mAcpiDmarTable;\r
109\r
110extern UINT64 mVtdHostAddressWidthMask;\r
111extern UINTN mVtdUnitNumber;\r
112extern VTD_UNIT_INFORMATION *mVtdUnitInformation;\r
113\r
114extern UINT64 mBelow4GMemoryLimit;\r
115extern UINT64 mAbove4GMemoryLimit;\r
116\r
117extern EDKII_PLATFORM_VTD_POLICY_PROTOCOL *mPlatformVTdPolicy;\r
118\r
119/**\r
120 Prepare VTD configuration.\r
121**/\r
122VOID\r
123PrepareVtdConfig (\r
124 VOID\r
125 );\r
126\r
127/**\r
128 Setup VTd translation table.\r
129\r
130 @retval EFI_SUCCESS Setup translation table successfully.\r
131 @retval EFI_OUT_OF_RESOURCE Setup translation table fail.\r
132**/\r
133EFI_STATUS\r
134SetupTranslationTable (\r
135 VOID\r
136 );\r
137\r
138/**\r
139 Enable DMAR translation.\r
140\r
141 @retval EFI_SUCCESS DMAR translation is enabled.\r
142 @retval EFI_DEVICE_ERROR DMAR translation is not enabled.\r
143**/\r
144EFI_STATUS\r
145EnableDmar (\r
146 VOID\r
147 );\r
148\r
149/**\r
150 Disable DMAR translation.\r
151\r
152 @retval EFI_SUCCESS DMAR translation is disabled.\r
153 @retval EFI_DEVICE_ERROR DMAR translation is not disabled.\r
154**/\r
155EFI_STATUS\r
156DisableDmar (\r
157 VOID\r
158 );\r
159\r
c049fc99
JY
160/**\r
161 Invalid VTd global IOTLB.\r
162\r
163 @param[in] VtdIndex The index of VTd engine.\r
164\r
165 @retval EFI_SUCCESS VTd global IOTLB is invalidated.\r
166 @retval EFI_DEVICE_ERROR VTd global IOTLB is not invalidated.\r
167**/\r
168EFI_STATUS\r
169InvalidateVtdIOTLBGlobal (\r
170 IN UINTN VtdIndex\r
171 );\r
172\r
173/**\r
174 Dump VTd registers.\r
175\r
176 @param[in] VtdIndex The index of VTd engine.\r
177**/\r
178VOID\r
179DumpVtdRegs (\r
180 IN UINTN VtdIndex\r
181 );\r
182\r
183/**\r
184 Dump VTd registers for all VTd engine.\r
185**/\r
186VOID\r
187DumpVtdRegsAll (\r
188 VOID\r
189 );\r
190\r
191/**\r
192 Dump VTd capability registers.\r
193\r
194 @param[in] CapReg The capability register.\r
195**/\r
196VOID\r
197DumpVtdCapRegs (\r
198 IN VTD_CAP_REG *CapReg\r
199 );\r
200\r
201/**\r
202 Dump VTd extended capability registers.\r
203\r
204 @param[in] ECapReg The extended capability register.\r
205**/\r
206VOID\r
207DumpVtdECapRegs (\r
208 IN VTD_ECAP_REG *ECapReg\r
209 );\r
210\r
211/**\r
f77d35c7 212 Register PCI device to VTd engine.\r
c049fc99
JY
213\r
214 @param[in] VtdIndex The index of VTd engine.\r
215 @param[in] Segment The segment of the source.\r
216 @param[in] SourceId The SourceId of the source.\r
f77d35c7 217 @param[in] DeviceType The DMAR device scope type.\r
c049fc99
JY
218 @param[in] CheckExist TRUE: ERROR will be returned if the PCI device is already registered.\r
219 FALSE: SUCCESS will be returned if the PCI device is registered.\r
220\r
221 @retval EFI_SUCCESS The PCI device is registered.\r
222 @retval EFI_OUT_OF_RESOURCES No enough resource to register a new PCI device.\r
223 @retval EFI_ALREADY_STARTED The device is already registered.\r
224**/\r
225EFI_STATUS\r
226RegisterPciDevice (\r
227 IN UINTN VtdIndex,\r
228 IN UINT16 Segment,\r
229 IN VTD_SOURCE_ID SourceId,\r
f77d35c7 230 IN UINT8 DeviceType,\r
c049fc99
JY
231 IN BOOLEAN CheckExist\r
232 );\r
233\r
234/**\r
f77d35c7 235 The scan bus callback function to always enable page attribute.\r
c049fc99 236\r
f77d35c7 237 @param[in] Context The context of the callback.\r
c049fc99
JY
238 @param[in] Segment The segment of the source.\r
239 @param[in] Bus The bus of the source.\r
f77d35c7
JY
240 @param[in] Device The device of the source.\r
241 @param[in] Function The function of the source.\r
c049fc99 242\r
f77d35c7 243 @retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device.\r
c049fc99
JY
244**/\r
245EFI_STATUS\r
f77d35c7
JY
246EFIAPI\r
247ScanBusCallbackRegisterPciDevice (\r
248 IN VOID *Context,\r
c049fc99 249 IN UINT16 Segment,\r
f77d35c7
JY
250 IN UINT8 Bus,\r
251 IN UINT8 Device,\r
252 IN UINT8 Function\r
253 );\r
254\r
255/**\r
256 Scan PCI bus and invoke callback function for each PCI devices under the bus.\r
257\r
258 @param[in] Context The context of the callback function.\r
259 @param[in] Segment The segment of the source.\r
260 @param[in] Bus The bus of the source.\r
261 @param[in] Callback The callback function in PCI scan.\r
262\r
263 @retval EFI_SUCCESS The PCI devices under the bus are scaned.\r
264**/\r
265EFI_STATUS\r
266ScanPciBus (\r
267 IN VOID *Context,\r
268 IN UINT16 Segment,\r
269 IN UINT8 Bus,\r
270 IN SCAN_BUS_FUNC_CALLBACK_FUNC Callback\r
c049fc99
JY
271 );\r
272\r
273/**\r
274 Dump the PCI device information managed by this VTd engine.\r
275\r
276 @param[in] VtdIndex The index of VTd engine.\r
277**/\r
278VOID\r
279DumpPciDeviceInfo (\r
280 IN UINTN VtdIndex\r
281 );\r
282\r
283/**\r
284 Find the VTd index by the Segment and SourceId.\r
285\r
286 @param[in] Segment The segment of the source.\r
287 @param[in] SourceId The SourceId of the source.\r
288 @param[out] ExtContextEntry The ExtContextEntry of the source.\r
289 @param[out] ContextEntry The ContextEntry of the source.\r
290\r
f77d35c7
JY
291 @return The index of the VTd engine.\r
292 @retval (UINTN)-1 The VTd engine is not found.\r
c049fc99
JY
293**/\r
294UINTN\r
295FindVtdIndexByPciDevice (\r
296 IN UINT16 Segment,\r
297 IN VTD_SOURCE_ID SourceId,\r
298 OUT VTD_EXT_CONTEXT_ENTRY **ExtContextEntry,\r
299 OUT VTD_CONTEXT_ENTRY **ContextEntry\r
300 );\r
301\r
302/**\r
303 Get the DMAR ACPI table.\r
304\r
305 @retval EFI_SUCCESS The DMAR ACPI table is got.\r
306 @retval EFI_NOT_FOUND The DMAR ACPI table is not found.\r
307**/\r
308EFI_STATUS\r
309GetDmarAcpiTable (\r
310 VOID\r
311 );\r
312\r
313/**\r
314 Parse DMAR DRHD table.\r
315\r
316 @return EFI_SUCCESS The DMAR DRHD table is parsed.\r
317**/\r
318EFI_STATUS\r
319ParseDmarAcpiTableDrhd (\r
320 VOID\r
321 );\r
322\r
323/**\r
324 Parse DMAR RMRR table.\r
325\r
326 @return EFI_SUCCESS The DMAR RMRR table is parsed.\r
327**/\r
328EFI_STATUS\r
329ParseDmarAcpiTableRmrr (\r
330 VOID\r
331 );\r
332\r
333/**\r
334 Dump DMAR context entry table.\r
335\r
336 @param[in] RootEntry DMAR root entry.\r
337**/\r
338VOID\r
339DumpDmarContextEntryTable (\r
340 IN VTD_ROOT_ENTRY *RootEntry\r
341 );\r
342\r
343/**\r
344 Dump DMAR extended context entry table.\r
345\r
346 @param[in] ExtRootEntry DMAR extended root entry.\r
347**/\r
348VOID\r
349DumpDmarExtContextEntryTable (\r
350 IN VTD_EXT_ROOT_ENTRY *ExtRootEntry\r
351 );\r
352\r
353/**\r
354 Dump DMAR second level paging entry.\r
355\r
356 @param[in] SecondLevelPagingEntry The second level paging entry.\r
357**/\r
358VOID\r
359DumpSecondLevelPagingEntry (\r
360 IN VOID *SecondLevelPagingEntry\r
361 );\r
362\r
363/**\r
364 Set VTd attribute for a system memory.\r
365\r
366 @param[in] VtdIndex The index used to identify a VTd engine.\r
d654bf85 367 @param[in] DomainIdentifier The domain ID of the source.\r
c049fc99
JY
368 @param[in] SecondLevelPagingEntry The second level paging entry in VTd table for the device.\r
369 @param[in] BaseAddress The base of device memory address to be used as the DMA memory.\r
370 @param[in] Length The length of device memory address to be used as the DMA memory.\r
371 @param[in] IoMmuAccess The IOMMU access.\r
372\r
373 @retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by BaseAddress and Length.\r
374 @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.\r
375 @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.\r
376 @retval EFI_INVALID_PARAMETER Length is 0.\r
377 @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.\r
378 @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.\r
379 @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by BaseAddress and Length.\r
380 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.\r
381 @retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.\r
382**/\r
383EFI_STATUS\r
384SetPageAttribute (\r
385 IN UINTN VtdIndex,\r
4ad5f597 386 IN UINT16 DomainIdentifier,\r
c049fc99
JY
387 IN VTD_SECOND_LEVEL_PAGING_ENTRY *SecondLevelPagingEntry,\r
388 IN UINT64 BaseAddress,\r
389 IN UINT64 Length,\r
390 IN UINT64 IoMmuAccess\r
391 );\r
392\r
393/**\r
394 Set VTd attribute for a system memory.\r
395\r
396 @param[in] Segment The Segment used to identify a VTd engine.\r
397 @param[in] SourceId The SourceId used to identify a VTd engine and table entry.\r
398 @param[in] BaseAddress The base of device memory address to be used as the DMA memory.\r
399 @param[in] Length The length of device memory address to be used as the DMA memory.\r
400 @param[in] IoMmuAccess The IOMMU access.\r
401\r
402 @retval EFI_SUCCESS The IoMmuAccess is set for the memory range specified by BaseAddress and Length.\r
403 @retval EFI_INVALID_PARAMETER BaseAddress is not IoMmu Page size aligned.\r
404 @retval EFI_INVALID_PARAMETER Length is not IoMmu Page size aligned.\r
405 @retval EFI_INVALID_PARAMETER Length is 0.\r
406 @retval EFI_INVALID_PARAMETER IoMmuAccess specified an illegal combination of access.\r
407 @retval EFI_UNSUPPORTED The bit mask of IoMmuAccess is not supported by the IOMMU.\r
408 @retval EFI_UNSUPPORTED The IOMMU does not support the memory range specified by BaseAddress and Length.\r
409 @retval EFI_OUT_OF_RESOURCES There are not enough resources available to modify the IOMMU access.\r
410 @retval EFI_DEVICE_ERROR The IOMMU device reported an error while attempting the operation.\r
411**/\r
412EFI_STATUS\r
413SetAccessAttribute (\r
414 IN UINT16 Segment,\r
415 IN VTD_SOURCE_ID SourceId,\r
416 IN UINT64 BaseAddress,\r
417 IN UINT64 Length,\r
418 IN UINT64 IoMmuAccess\r
419 );\r
420\r
421/**\r
f77d35c7 422 Return the index of PCI data.\r
c049fc99
JY
423\r
424 @param[in] VtdIndex The index used to identify a VTd engine.\r
425 @param[in] Segment The Segment used to identify a VTd engine.\r
426 @param[in] SourceId The SourceId used to identify a VTd engine and table entry.\r
427\r
f77d35c7
JY
428 @return The index of the PCI data.\r
429 @retval (UINTN)-1 The PCI data is not found.\r
c049fc99
JY
430**/\r
431UINTN\r
f77d35c7 432GetPciDataIndex (\r
c049fc99
JY
433 IN UINTN VtdIndex,\r
434 IN UINT16 Segment,\r
435 IN VTD_SOURCE_ID SourceId\r
436 );\r
437\r
438/**\r
439 Dump VTd registers if there is error.\r
440**/\r
441VOID\r
442DumpVtdIfError (\r
443 VOID\r
444 );\r
445\r
446/**\r
447 Initialize platform VTd policy.\r
448**/\r
449VOID\r
450InitializePlatformVTdPolicy (\r
451 VOID\r
452 );\r
453\r
454/**\r
455 Always enable the VTd page attribute for the device.\r
456\r
457 @param[in] Segment The Segment used to identify a VTd engine.\r
458 @param[in] SourceId The SourceId used to identify a VTd engine and table entry.\r
459\r
460 @retval EFI_SUCCESS The VTd entry is updated to always enable all DMA access for the specific device.\r
461**/\r
462EFI_STATUS\r
463AlwaysEnablePageAttribute (\r
464 IN UINT16 Segment,\r
465 IN VTD_SOURCE_ID SourceId\r
466 );\r
467\r
468/**\r
469 Convert the DeviceHandle to SourceId and Segment.\r
470\r
471 @param[in] DeviceHandle The device who initiates the DMA access request.\r
472 @param[out] Segment The Segment used to identify a VTd engine.\r
473 @param[out] SourceId The SourceId used to identify a VTd engine and table entry.\r
474\r
475 @retval EFI_SUCCESS The Segment and SourceId are returned.\r
476 @retval EFI_INVALID_PARAMETER DeviceHandle is an invalid handle.\r
477 @retval EFI_UNSUPPORTED DeviceHandle is unknown by the IOMMU.\r
478**/\r
479EFI_STATUS\r
480DeviceHandleToSourceId (\r
481 IN EFI_HANDLE DeviceHandle,\r
482 OUT UINT16 *Segment,\r
483 OUT VTD_SOURCE_ID *SourceId\r
484 );\r
485\r
486/**\r
487 Get device information from mapping.\r
488\r
489 @param[in] Mapping The mapping.\r
490 @param[out] DeviceAddress The device address of the mapping.\r
491 @param[out] NumberOfPages The number of pages of the mapping.\r
492\r
493 @retval EFI_SUCCESS The device information is returned.\r
494 @retval EFI_INVALID_PARAMETER The mapping is invalid.\r
495**/\r
496EFI_STATUS\r
497GetDeviceInfoFromMapping (\r
498 IN VOID *Mapping,\r
499 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,\r
500 OUT UINTN *NumberOfPages\r
501 );\r
502\r
503/**\r
504 Initialize DMA protection.\r
505**/\r
506VOID\r
507InitializeDmaProtection (\r
508 VOID\r
509 );\r
510\r
511/**\r
512 Allocate zero pages.\r
513\r
514 @param[in] Pages the number of pages.\r
515\r
516 @return the page address.\r
517 @retval NULL No resource to allocate pages.\r
518**/\r
519VOID *\r
520EFIAPI\r
521AllocateZeroPages (\r
522 IN UINTN Pages\r
523 );\r
524\r
4ad5f597
JY
525/**\r
526 Flush VTD page table and context table memory.\r
527\r
528 This action is to make sure the IOMMU engine can get final data in memory.\r
529\r
530 @param[in] VtdIndex The index used to identify a VTd engine.\r
531 @param[in] Base The base address of memory to be flushed.\r
532 @param[in] Size The size of memory in bytes to be flushed.\r
533**/\r
534VOID\r
535FlushPageTableMemory (\r
536 IN UINTN VtdIndex,\r
537 IN UINTN Base,\r
538 IN UINTN Size\r
539 );\r
540\r
f77d35c7
JY
541/**\r
542 Get PCI device information from DMAR DevScopeEntry.\r
543\r
544 @param[in] Segment The segment number.\r
545 @param[in] DmarDevScopeEntry DMAR DevScopeEntry\r
546 @param[out] Bus The bus number.\r
547 @param[out] Device The device number.\r
548 @param[out] Function The function number.\r
549\r
550 @retval EFI_SUCCESS The PCI device information is returned.\r
551**/\r
552EFI_STATUS\r
553GetPciBusDeviceFunction (\r
554 IN UINT16 Segment,\r
555 IN EFI_ACPI_DMAR_DEVICE_SCOPE_STRUCTURE_HEADER *DmarDevScopeEntry,\r
556 OUT UINT8 *Bus,\r
557 OUT UINT8 *Device,\r
558 OUT UINT8 *Function\r
559 );\r
560\r
c049fc99 561#endif\r