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