]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelSiliconPkg/IntelVTdDxe/DmaProtection.c
IntelSiliconPkg/IntelVTdDxe: Move to feature dir.
[mirror_edk2.git] / IntelSiliconPkg / IntelVTdDxe / DmaProtection.c
diff --git a/IntelSiliconPkg/IntelVTdDxe/DmaProtection.c b/IntelSiliconPkg/IntelVTdDxe/DmaProtection.c
deleted file mode 100644 (file)
index f5de01f..0000000
+++ /dev/null
@@ -1,503 +0,0 @@
-/** @file\r
-\r
-  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>\r
-  This program and the accompanying materials\r
-  are licensed and made available under the terms and conditions of the BSD License\r
-  which accompanies this distribution.  The full text of the license may be found at\r
-  http://opensource.org/licenses/bsd-license.php.\r
-\r
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "DmaProtection.h"\r
-\r
-EFI_ACPI_SDT_PROTOCOL                   *mAcpiSdt;\r
-UINT64                                  mBelow4GMemoryLimit;\r
-UINT64                                  mAbove4GMemoryLimit;\r
-\r
-EDKII_PLATFORM_VTD_POLICY_PROTOCOL      *mPlatformVTdPolicy;\r
-\r
-/**\r
-  return the UEFI memory information.\r
-\r
-  @param[out] Below4GMemoryLimit  The below 4GiB memory limit\r
-  @param[out] Above4GMemoryLimit  The above 4GiB memory limit\r
-**/\r
-VOID\r
-ReturnUefiMemoryMap (\r
-  OUT UINT64   *Below4GMemoryLimit,\r
-  OUT UINT64   *Above4GMemoryLimit\r
-  )\r
-{\r
-  EFI_STATUS                  Status;\r
-  EFI_MEMORY_DESCRIPTOR       *EfiMemoryMap;\r
-  EFI_MEMORY_DESCRIPTOR       *EfiMemoryMapEnd;\r
-  EFI_MEMORY_DESCRIPTOR       *EfiEntry;\r
-  EFI_MEMORY_DESCRIPTOR       *NextEfiEntry;\r
-  EFI_MEMORY_DESCRIPTOR       TempEfiEntry;\r
-  UINTN                       EfiMemoryMapSize;\r
-  UINTN                       EfiMapKey;\r
-  UINTN                       EfiDescriptorSize;\r
-  UINT32                      EfiDescriptorVersion;\r
-  UINT64                      MemoryBlockLength;\r
-\r
-  *Below4GMemoryLimit = 0;\r
-  *Above4GMemoryLimit = 0;\r
-\r
-  //\r
-  // Get the EFI memory map.\r
-  //\r
-  EfiMemoryMapSize  = 0;\r
-  EfiMemoryMap      = NULL;\r
-  Status = gBS->GetMemoryMap (\r
-                  &EfiMemoryMapSize,\r
-                  EfiMemoryMap,\r
-                  &EfiMapKey,\r
-                  &EfiDescriptorSize,\r
-                  &EfiDescriptorVersion\r
-                  );\r
-  ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
-\r
-  do {\r
-    //\r
-    // Use size returned back plus 1 descriptor for the AllocatePool.\r
-    // We don't just multiply by 2 since the "for" loop below terminates on\r
-    // EfiMemoryMapEnd which is dependent upon EfiMemoryMapSize. Otherwize\r
-    // we process bogus entries and create bogus E820 entries.\r
-    //\r
-    EfiMemoryMap = (EFI_MEMORY_DESCRIPTOR *) AllocatePool (EfiMemoryMapSize);\r
-    ASSERT (EfiMemoryMap != NULL);\r
-    Status = gBS->GetMemoryMap (\r
-                    &EfiMemoryMapSize,\r
-                    EfiMemoryMap,\r
-                    &EfiMapKey,\r
-                    &EfiDescriptorSize,\r
-                    &EfiDescriptorVersion\r
-                    );\r
-    if (EFI_ERROR (Status)) {\r
-      FreePool (EfiMemoryMap);\r
-    }\r
-  } while (Status == EFI_BUFFER_TOO_SMALL);\r
-\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  //\r
-  // Sort memory map from low to high\r
-  //\r
-  EfiEntry        = EfiMemoryMap;\r
-  NextEfiEntry    = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize);\r
-  EfiMemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) EfiMemoryMap + EfiMemoryMapSize);\r
-  while (EfiEntry < EfiMemoryMapEnd) {\r
-    while (NextEfiEntry < EfiMemoryMapEnd) {\r
-      if (EfiEntry->PhysicalStart > NextEfiEntry->PhysicalStart) {\r
-        CopyMem (&TempEfiEntry, EfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR));\r
-        CopyMem (EfiEntry, NextEfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR));\r
-        CopyMem (NextEfiEntry, &TempEfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR));\r
-      }\r
-\r
-      NextEfiEntry = NEXT_MEMORY_DESCRIPTOR (NextEfiEntry, EfiDescriptorSize);\r
-    }\r
-\r
-    EfiEntry      = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize);\r
-    NextEfiEntry  = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize);\r
-  }\r
-\r
-  //\r
-  //\r
-  //\r
-  DEBUG ((DEBUG_INFO, "MemoryMap:\n"));\r
-  EfiEntry        = EfiMemoryMap;\r
-  EfiMemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) EfiMemoryMap + EfiMemoryMapSize);\r
-  while (EfiEntry < EfiMemoryMapEnd) {\r
-    MemoryBlockLength = (UINT64) (LShiftU64 (EfiEntry->NumberOfPages, 12));\r
-    DEBUG ((DEBUG_INFO, "Entry(0x%02x) 0x%016lx - 0x%016lx\n", EfiEntry->Type, EfiEntry->PhysicalStart, EfiEntry->PhysicalStart + MemoryBlockLength));\r
-    switch (EfiEntry->Type) {\r
-    case EfiLoaderCode:\r
-    case EfiLoaderData:\r
-    case EfiBootServicesCode:\r
-    case EfiBootServicesData:\r
-    case EfiConventionalMemory:\r
-    case EfiRuntimeServicesCode:\r
-    case EfiRuntimeServicesData:\r
-    case EfiACPIReclaimMemory:\r
-    case EfiACPIMemoryNVS:\r
-    case EfiReservedMemoryType:\r
-      if ((EfiEntry->PhysicalStart + MemoryBlockLength) <= BASE_1MB) {\r
-        //\r
-        // Skip the memory block is under 1MB\r
-        //\r
-      } else if (EfiEntry->PhysicalStart >= BASE_4GB) {\r
-        if (*Above4GMemoryLimit < EfiEntry->PhysicalStart + MemoryBlockLength) {\r
-          *Above4GMemoryLimit = EfiEntry->PhysicalStart + MemoryBlockLength;\r
-        }\r
-      } else {\r
-        if (*Below4GMemoryLimit < EfiEntry->PhysicalStart + MemoryBlockLength) {\r
-          *Below4GMemoryLimit = EfiEntry->PhysicalStart + MemoryBlockLength;\r
-        }\r
-      }\r
-      break;\r
-    }\r
-    EfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize);\r
-  }\r
-\r
-  FreePool (EfiMemoryMap);\r
-\r
-  DEBUG ((DEBUG_INFO, "Result:\n"));\r
-  DEBUG ((DEBUG_INFO, "Below4GMemoryLimit:  0x%016lx\n", *Below4GMemoryLimit));\r
-  DEBUG ((DEBUG_INFO, "Above4GMemoryLimit:  0x%016lx\n", *Above4GMemoryLimit));\r
-\r
-  return ;\r
-}\r
-\r
-/**\r
-  The scan bus callback function to always enable page attribute.\r
-\r
-  @param[in]  Context               The context of the callback.\r
-  @param[in]  Segment               The segment of the source.\r
-  @param[in]  Bus                   The bus of the source.\r
-  @param[in]  Device                The device of the source.\r
-  @param[in]  Function              The function of the source.\r
-\r
-  @retval EFI_SUCCESS           The VTd entry is updated to always enable all DMA access for the specific device.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-ScanBusCallbackAlwaysEnablePageAttribute (\r
-  IN VOID           *Context,\r
-  IN UINT16         Segment,\r
-  IN UINT8          Bus,\r
-  IN UINT8          Device,\r
-  IN UINT8          Function\r
-  )\r
-{\r
-  VTD_SOURCE_ID           SourceId;\r
-  EFI_STATUS              Status;\r
-\r
-  SourceId.Bits.Bus = Bus;\r
-  SourceId.Bits.Device = Device;\r
-  SourceId.Bits.Function = Function;\r
-  Status = AlwaysEnablePageAttribute (Segment, SourceId);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Always enable the VTd page attribute for the device in the DeviceScope.\r
-\r
-  @param[in]  DeviceScope  the input device scope data structure\r
-\r
-  @retval EFI_SUCCESS           The VTd entry is updated to always enable all DMA access for the specific device in the device scope.\r
-**/\r
-EFI_STATUS\r
-AlwaysEnablePageAttributeDeviceScope (\r
-  IN  EDKII_PLATFORM_VTD_DEVICE_SCOPE   *DeviceScope\r
-  )\r
-{\r
-  UINT8                             Bus;\r
-  UINT8                             Device;\r
-  UINT8                             Function;\r
-  VTD_SOURCE_ID                     SourceId;\r
-  UINT8                             SecondaryBusNumber;\r
-  EFI_STATUS                        Status;\r
-\r
-  Status = GetPciBusDeviceFunction (DeviceScope->SegmentNumber, &DeviceScope->DeviceScope, &Bus, &Device, &Function);\r
-\r
-  if (DeviceScope->DeviceScope.Type == EFI_ACPI_DEVICE_SCOPE_ENTRY_TYPE_PCI_BRIDGE) {\r
-    //\r
-    // Need scan the bridge and add all devices.\r
-    //\r
-    SecondaryBusNumber = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(DeviceScope->SegmentNumber, Bus, Device, Function, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET));\r
-    Status = ScanPciBus (NULL, DeviceScope->SegmentNumber, SecondaryBusNumber, ScanBusCallbackAlwaysEnablePageAttribute);\r
-    return Status;\r
-  } else {\r
-    SourceId.Bits.Bus      = Bus;\r
-    SourceId.Bits.Device   = Device;\r
-    SourceId.Bits.Function = Function;\r
-    Status = AlwaysEnablePageAttribute (DeviceScope->SegmentNumber, SourceId);\r
-    return Status;\r
-  }\r
-}\r
-\r
-/**\r
-  Always enable the VTd page attribute for the device matching DeviceId.\r
-\r
-  @param[in]  PciDeviceId  the input PCI device ID\r
-\r
-  @retval EFI_SUCCESS           The VTd entry is updated to always enable all DMA access for the specific device matching DeviceId.\r
-**/\r
-EFI_STATUS\r
-AlwaysEnablePageAttributePciDeviceId (\r
-  IN  EDKII_PLATFORM_VTD_PCI_DEVICE_ID   *PciDeviceId\r
-  )\r
-{\r
-  UINTN            VtdIndex;\r
-  UINTN            PciIndex;\r
-  PCI_DEVICE_DATA  *PciDeviceData;\r
-  EFI_STATUS       Status;\r
-\r
-  for (VtdIndex = 0; VtdIndex < mVtdUnitNumber; VtdIndex++) {\r
-    for (PciIndex = 0; PciIndex < mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceDataNumber; PciIndex++) {\r
-      PciDeviceData = &mVtdUnitInformation[VtdIndex].PciDeviceInfo.PciDeviceData[PciIndex];\r
-\r
-      if (((PciDeviceId->VendorId == 0xFFFF) || (PciDeviceId->VendorId == PciDeviceData->PciDeviceId.VendorId)) &&\r
-          ((PciDeviceId->DeviceId == 0xFFFF) || (PciDeviceId->DeviceId == PciDeviceData->PciDeviceId.DeviceId)) &&\r
-          ((PciDeviceId->RevisionId == 0xFF) || (PciDeviceId->RevisionId == PciDeviceData->PciDeviceId.RevisionId)) &&\r
-          ((PciDeviceId->SubsystemVendorId == 0xFFFF) || (PciDeviceId->SubsystemVendorId == PciDeviceData->PciDeviceId.SubsystemVendorId)) &&\r
-          ((PciDeviceId->SubsystemDeviceId == 0xFFFF) || (PciDeviceId->SubsystemDeviceId == PciDeviceData->PciDeviceId.SubsystemDeviceId)) ) {\r
-        Status = AlwaysEnablePageAttribute (mVtdUnitInformation[VtdIndex].Segment, PciDeviceData->PciSourceId);\r
-        if (EFI_ERROR(Status)) {\r
-          continue;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Always enable the VTd page attribute for the device.\r
-\r
-  @param[in]  DeviceInfo  the exception device information\r
-\r
-  @retval EFI_SUCCESS           The VTd entry is updated to always enable all DMA access for the specific device in the device info.\r
-**/\r
-EFI_STATUS\r
-AlwaysEnablePageAttributeExceptionDeviceInfo (\r
-  IN  EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO   *DeviceInfo\r
-  )\r
-{\r
-  switch (DeviceInfo->Type) {\r
-  case EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_DEVICE_SCOPE:\r
-    return AlwaysEnablePageAttributeDeviceScope ((VOID *)(DeviceInfo + 1));\r
-  case EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_PCI_DEVICE_ID:\r
-    return AlwaysEnablePageAttributePciDeviceId ((VOID *)(DeviceInfo + 1));\r
-  default:\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-}\r
-\r
-/**\r
-  Initialize platform VTd policy.\r
-**/\r
-VOID\r
-InitializePlatformVTdPolicy (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS                               Status;\r
-  UINTN                                    DeviceInfoCount;\r
-  VOID                                     *DeviceInfo;\r
-  EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO *ThisDeviceInfo;\r
-  UINTN                                    Index;\r
-\r
-  //\r
-  // It is optional.\r
-  //\r
-  Status = gBS->LocateProtocol (\r
-                  &gEdkiiPlatformVTdPolicyProtocolGuid,\r
-                  NULL,\r
-                  (VOID **)&mPlatformVTdPolicy\r
-                  );\r
-  if (!EFI_ERROR(Status)) {\r
-    DEBUG ((DEBUG_INFO, "InitializePlatformVTdPolicy\n"));\r
-    Status = mPlatformVTdPolicy->GetExceptionDeviceList (mPlatformVTdPolicy, &DeviceInfoCount, &DeviceInfo);\r
-    if (!EFI_ERROR(Status)) {\r
-      ThisDeviceInfo = DeviceInfo;\r
-      for (Index = 0; Index < DeviceInfoCount; Index++) {\r
-        if (ThisDeviceInfo->Type == EDKII_PLATFORM_VTD_EXCEPTION_DEVICE_INFO_TYPE_END) {\r
-          break;\r
-        }\r
-        AlwaysEnablePageAttributeExceptionDeviceInfo (ThisDeviceInfo);\r
-        ThisDeviceInfo = (VOID *)((UINTN)ThisDeviceInfo + ThisDeviceInfo->Length);\r
-      }\r
-      FreePool (DeviceInfo);\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
-  Setup VTd engine.\r
-**/\r
-VOID\r
-SetupVtd (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS      Status;\r
-  VOID            *PciEnumerationComplete;\r
-  UINTN           Index;\r
-  UINT64          Below4GMemoryLimit;\r
-  UINT64          Above4GMemoryLimit;\r
-\r
-  //\r
-  // PCI Enumeration must be done\r
-  //\r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiPciEnumerationCompleteProtocolGuid,\r
-                  NULL,\r
-                  &PciEnumerationComplete\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  ReturnUefiMemoryMap (&Below4GMemoryLimit, &Above4GMemoryLimit);\r
-  Below4GMemoryLimit = ALIGN_VALUE_UP(Below4GMemoryLimit, SIZE_256MB);\r
-  DEBUG ((DEBUG_INFO, " Adjusted Below4GMemoryLimit: 0x%016lx\n", Below4GMemoryLimit));\r
-\r
-  mBelow4GMemoryLimit = Below4GMemoryLimit;\r
-  mAbove4GMemoryLimit = Above4GMemoryLimit;\r
-\r
-  //\r
-  // 1. setup\r
-  //\r
-  DEBUG ((DEBUG_INFO, "GetDmarAcpiTable\n"));\r
-  Status = GetDmarAcpiTable ();\r
-  if (EFI_ERROR (Status)) {\r
-    return;\r
-  }\r
-  DEBUG ((DEBUG_INFO, "ParseDmarAcpiTable\n"));\r
-  Status = ParseDmarAcpiTableDrhd ();\r
-  if (EFI_ERROR (Status)) {\r
-    return;\r
-  }\r
-  DEBUG ((DEBUG_INFO, "PrepareVtdConfig\n"));\r
-  PrepareVtdConfig ();\r
-\r
-  //\r
-  // 2. initialization\r
-  //\r
-  DEBUG ((DEBUG_INFO, "SetupTranslationTable\n"));\r
-  Status = SetupTranslationTable ();\r
-  if (EFI_ERROR (Status)) {\r
-    return;\r
-  }\r
-\r
-  InitializePlatformVTdPolicy ();\r
-\r
-  ParseDmarAcpiTableRmrr ();\r
-\r
-  for (Index = 0; Index < mVtdUnitNumber; Index++) {\r
-    DEBUG ((DEBUG_INFO,"VTD Unit %d (Segment: %04x)\n", Index, mVtdUnitInformation[Index].Segment));\r
-    if (mVtdUnitInformation[Index].ExtRootEntryTable != NULL) {\r
-      DumpDmarExtContextEntryTable (mVtdUnitInformation[Index].ExtRootEntryTable);\r
-    }\r
-    if (mVtdUnitInformation[Index].RootEntryTable != NULL) {\r
-      DumpDmarContextEntryTable (mVtdUnitInformation[Index].RootEntryTable);\r
-    }\r
-  }\r
-\r
-  //\r
-  // 3. enable\r
-  //\r
-  DEBUG ((DEBUG_INFO, "EnableDmar\n"));\r
-  Status = EnableDmar ();\r
-  if (EFI_ERROR (Status)) {\r
-    return;\r
-  }\r
-  DEBUG ((DEBUG_INFO, "DumpVtdRegs\n"));\r
-  DumpVtdRegsAll ();\r
-}\r
-\r
-/**\r
-  ACPI notification function.\r
-\r
-  @param[in] Table    A pointer to the ACPI table header.\r
-  @param[in] Version  The ACPI table's version.\r
-  @param[in] TableKey The table key for this ACPI table.\r
-\r
-  @retval EFI_SUCCESS The notification function is executed.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-AcpiNotificationFunc (\r
-  IN EFI_ACPI_SDT_HEADER    *Table,\r
-  IN EFI_ACPI_TABLE_VERSION Version,\r
-  IN UINTN                  TableKey\r
-  )\r
-{\r
-  if (Table->Signature == EFI_ACPI_4_0_DMA_REMAPPING_TABLE_SIGNATURE) {\r
-    DEBUG((DEBUG_INFO, "Vtd AcpiNotificationFunc\n"));\r
-    SetupVtd ();\r
-  }\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Exit boot service callback function.\r
-\r
-  @param[in]  Event    The event handle.\r
-  @param[in]  Context  The event content.\r
-**/\r
-VOID\r
-EFIAPI\r
-OnExitBootServices (\r
-  IN EFI_EVENT                               Event,\r
-  IN VOID                                    *Context\r
-  )\r
-{\r
-  DEBUG ((DEBUG_INFO, "Vtd OnExitBootServices\n"));\r
-  DumpVtdRegsAll ();\r
-\r
-  if ((PcdGet8(PcdVTdPolicyPropertyMask) & BIT1) == 0) {\r
-    DisableDmar ();\r
-    DumpVtdRegsAll ();\r
-  }\r
-}\r
-\r
-/**\r
-  Legacy boot callback function.\r
-\r
-  @param[in]  Event    The event handle.\r
-  @param[in]  Context  The event content.\r
-**/\r
-VOID\r
-EFIAPI\r
-OnLegacyBoot (\r
-  EFI_EVENT                               Event,\r
-  VOID                                    *Context\r
-  )\r
-{\r
-  DEBUG ((DEBUG_INFO, "Vtd OnLegacyBoot\n"));\r
-  DumpVtdRegsAll ();\r
-  DisableDmar ();\r
-  DumpVtdRegsAll ();\r
-}\r
-\r
-/**\r
-  Initialize DMA protection.\r
-**/\r
-VOID\r
-InitializeDmaProtection (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  EFI_EVENT   ExitBootServicesEvent;\r
-  EFI_EVENT   LegacyBootEvent;\r
-\r
-  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **) &mAcpiSdt);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Status = mAcpiSdt->RegisterNotify (TRUE, AcpiNotificationFunc);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Status = gBS->CreateEventEx (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  OnExitBootServices,\r
-                  NULL,\r
-                  &gEfiEventExitBootServicesGuid,\r
-                  &ExitBootServicesEvent\r
-                  );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Status = EfiCreateEventLegacyBootEx (\r
-             TPL_NOTIFY,\r
-             OnLegacyBoot,\r
-             NULL,\r
-             &LegacyBootEvent\r
-             );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  return ;\r
-}\r