[edk2-devel] [PATCH v3 2/2] MdeModulePkg/AhciPei: Use PCI_DEVICE_PPI to manage AHCI device

Maciej Czajkowski posted 2 patches 1 month, 4 weeks ago
[edk2-devel] [PATCH v3 2/2] MdeModulePkg/AhciPei: Use PCI_DEVICE_PPI to manage AHCI device
Posted by Maciej Czajkowski 1 month, 4 weeks ago
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3907

This change modifies AhciPei library to allow usage both EDKII_PCI_DEVICE_PPI
and EDKII_PEI_ATA_AHCI_HOST_CONTROLLER_PPI to manage ATA HDD working under
AHCI mode.

Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Maciej Czajkowski <maciej.czajkowski@intel.com>
---

Notes:
    v2 changes:
    - added missing function descriptions
    - moved controller initialization from PCI_DEVICE_PPI to seperate funciton
    in order to reduce code duplication
    - added DevicePathLib BASE instance to the MdeModulePkg.dec to allow PEIMs to consume it
    
    v3 changes:
    - removed redundant locate PPI calls (if already installed, NotifyPpi executes callback)
    - aligned enabling HC device from PCI_DEVICE_PPI with flow from AtaAtapiPassThru DXE driver
    - corrected function descriptions

 MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c    | 505 +++++++++++++-------
 MdeModulePkg/Bus/Ata/AhciPei/DevicePath.c |  44 --
 MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h    |  57 ++-
 MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf  |   5 +-
 MdeModulePkg/MdeModulePkg.dsc             |   1 +
 5 files changed, 390 insertions(+), 222 deletions(-)

diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c
index 208b7e9a3606..98dd732a4023 100644
--- a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c
+++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c
@@ -9,6 +9,9 @@
 **/
 
 #include "AhciPei.h"
+#include <Ppi/PciDevice.h>
+#include <Library/DevicePathLib.h>
+#include <IndustryStandard/Pci.h>
 
 EFI_PEI_PPI_DESCRIPTOR  mAhciAtaPassThruPpiListTemplate = {
   (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
@@ -40,6 +43,18 @@ EFI_PEI_NOTIFY_DESCRIPTOR  mAhciEndOfPeiNotifyListTemplate = {
   AhciPeimEndOfPei
 };
 
+EFI_PEI_NOTIFY_DESCRIPTOR  mAtaAhciHostControllerNotify = {
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEdkiiPeiAtaAhciHostControllerPpiGuid,
+  AtaAhciHostControllerPpiInstallationCallback
+};
+
+EFI_PEI_NOTIFY_DESCRIPTOR  mPciDevicePpiNotify = {
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEdkiiPeiPciDevicePpiGuid,
+  AtaAhciPciDevicePpiInstallationCallback
+};
+
 /**
   Free the DMA resources allocated by an ATA AHCI controller.
 
@@ -111,33 +126,30 @@ AhciPeimEndOfPei (
 }
 
 /**
-  Entry point of the PEIM.
+  Initialize and install PrivateData PPIs.
 
-  @param[in] FileHandle     Handle of the file being invoked.
-  @param[in] PeiServices    Describes the list of possible PEI Services.
-
-  @retval EFI_SUCCESS    PPI successfully installed.
+  @param[in] MmioBase            MMIO base address of specific AHCI controller
+  @param[in] DevicePath          A pointer to the EFI_DEVICE_PATH_PROTOCOL
+                                 structure.
+  @param[in] DevicePathLength    Length of the device path.
 
+  @retval EFI_SUCCESS  AHCI controller initialized and PPIs installed
+  @retval others       Failed to initialize AHCI controller
 **/
 EFI_STATUS
-EFIAPI
-AtaAhciPeimEntry (
-  IN EFI_PEI_FILE_HANDLE     FileHandle,
-  IN CONST EFI_PEI_SERVICES  **PeiServices
+AtaAhciInitPrivateData (
+  IN UINTN                     MmioBase,
+  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
+  IN UINTN                     DevicePathLength
   )
 {
-  EFI_STATUS                          Status;
-  EFI_BOOT_MODE                       BootMode;
-  EDKII_ATA_AHCI_HOST_CONTROLLER_PPI  *AhciHcPpi;
-  UINT8                               Controller;
-  UINTN                               MmioBase;
-  UINTN                               DevicePathLength;
-  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;
-  UINT32                              PortBitMap;
-  PEI_AHCI_CONTROLLER_PRIVATE_DATA    *Private;
-  UINT8                               NumberOfPorts;
+  EFI_STATUS                        Status;
+  UINT32                            PortBitMap;
+  UINT8                             NumberOfPorts;
+  PEI_AHCI_CONTROLLER_PRIVATE_DATA  *Private;
+  EFI_BOOT_MODE                     BootMode;
 
-  DEBUG ((DEBUG_INFO, "%a: Enters.\n", __FUNCTION__));
+  DEBUG ((DEBUG_INFO, "Initializing private data for ATA\n"));
 
   //
   // Get the current boot mode.
@@ -149,19 +161,149 @@ AtaAhciPeimEntry (
   }
 
   //
-  // Locate the ATA AHCI host controller PPI.
-  //
-  Status = PeiServicesLocatePpi (
-             &gEdkiiPeiAtaAhciHostControllerPpiGuid,
-             0,
-             NULL,
-             (VOID **)&AhciHcPpi
-             );
+  // Check validity of the device path of the ATA AHCI controller.
+  //
+  Status = AhciIsHcDevicePathValid (DevicePath, DevicePathLength);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: The device path is invalid.\n",
+      __FUNCTION__
+      ));
+    return Status;
+  }
+
+  //
+  // For S3 resume performance consideration, not all ports on an ATA AHCI
+  // controller will be enumerated/initialized. The driver consumes the
+  // content within S3StorageDeviceInitList LockBox to get the ports that
+  // will be enumerated/initialized during S3 resume.
+  //
+  if (BootMode == BOOT_ON_S3_RESUME) {
+    NumberOfPorts = AhciS3GetEumeratePorts (DevicePath, DevicePathLength, &PortBitMap);
+    if (NumberOfPorts == 0) {
+      return EFI_SUCCESS;
+    }
+  } else {
+    PortBitMap = MAX_UINT32;
+  }
+
+  //
+  // Memory allocation for controller private data.
+  //
+  Private = AllocateZeroPool (sizeof (PEI_AHCI_CONTROLLER_PRIVATE_DATA));
+  if (Private == NULL) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: Fail to allocate private data.\n",
+      __FUNCTION__
+      ));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Initialize controller private data.
+  //
+  Private->Signature        = AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE;
+  Private->MmioBase         = MmioBase;
+  Private->DevicePathLength = DevicePathLength;
+  Private->DevicePath       = DevicePath;
+  Private->PortBitMap       = PortBitMap;
+  InitializeListHead (&Private->DeviceList);
+
+  Status = AhciModeInitialization (Private);
   if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "%a: Failed to locate AtaAhciHostControllerPpi.\n", __FUNCTION__));
-    return EFI_UNSUPPORTED;
+    return Status;
+  }
+
+  Private->AtaPassThruMode.Attributes = EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL |
+                                        EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL;
+  Private->AtaPassThruMode.IoAlign      = sizeof (UINTN);
+  Private->AtaPassThruPpi.Revision      = EDKII_PEI_ATA_PASS_THRU_PPI_REVISION;
+  Private->AtaPassThruPpi.Mode          = &Private->AtaPassThruMode;
+  Private->AtaPassThruPpi.PassThru      = AhciAtaPassThruPassThru;
+  Private->AtaPassThruPpi.GetNextPort   = AhciAtaPassThruGetNextPort;
+  Private->AtaPassThruPpi.GetNextDevice = AhciAtaPassThruGetNextDevice;
+  Private->AtaPassThruPpi.GetDevicePath = AhciAtaPassThruGetDevicePath;
+  CopyMem (
+    &Private->AtaPassThruPpiList,
+    &mAhciAtaPassThruPpiListTemplate,
+    sizeof (EFI_PEI_PPI_DESCRIPTOR)
+    );
+  Private->AtaPassThruPpiList.Ppi = &Private->AtaPassThruPpi;
+  PeiServicesInstallPpi (&Private->AtaPassThruPpiList);
+
+  Private->BlkIoPpi.GetNumberOfBlockDevices = AhciBlockIoGetDeviceNo;
+  Private->BlkIoPpi.GetBlockDeviceMediaInfo = AhciBlockIoGetMediaInfo;
+  Private->BlkIoPpi.ReadBlocks              = AhciBlockIoReadBlocks;
+  CopyMem (
+    &Private->BlkIoPpiList,
+    &mAhciBlkIoPpiListTemplate,
+    sizeof (EFI_PEI_PPI_DESCRIPTOR)
+    );
+  Private->BlkIoPpiList.Ppi = &Private->BlkIoPpi;
+  PeiServicesInstallPpi (&Private->BlkIoPpiList);
+
+  Private->BlkIo2Ppi.Revision                = EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION;
+  Private->BlkIo2Ppi.GetNumberOfBlockDevices = AhciBlockIoGetDeviceNo2;
+  Private->BlkIo2Ppi.GetBlockDeviceMediaInfo = AhciBlockIoGetMediaInfo2;
+  Private->BlkIo2Ppi.ReadBlocks              = AhciBlockIoReadBlocks2;
+  CopyMem (
+    &Private->BlkIo2PpiList,
+    &mAhciBlkIo2PpiListTemplate,
+    sizeof (EFI_PEI_PPI_DESCRIPTOR)
+    );
+  Private->BlkIo2PpiList.Ppi = &Private->BlkIo2Ppi;
+  PeiServicesInstallPpi (&Private->BlkIo2PpiList);
+
+  if (Private->TrustComputingDevices != 0) {
+    DEBUG ((
+      DEBUG_INFO,
+      "%a: Security Security Command PPI will be produced.\n",
+      __FUNCTION__
+      ));
+    Private->StorageSecurityPpi.Revision           = EDKII_STORAGE_SECURITY_PPI_REVISION;
+    Private->StorageSecurityPpi.GetNumberofDevices = AhciStorageSecurityGetDeviceNo;
+    Private->StorageSecurityPpi.GetDevicePath      = AhciStorageSecurityGetDevicePath;
+    Private->StorageSecurityPpi.ReceiveData        = AhciStorageSecurityReceiveData;
+    Private->StorageSecurityPpi.SendData           = AhciStorageSecuritySendData;
+    CopyMem (
+      &Private->StorageSecurityPpiList,
+      &mAhciStorageSecurityPpiListTemplate,
+      sizeof (EFI_PEI_PPI_DESCRIPTOR)
+      );
+    Private->StorageSecurityPpiList.Ppi = &Private->StorageSecurityPpi;
+    PeiServicesInstallPpi (&Private->StorageSecurityPpiList);
   }
 
+  CopyMem (
+    &Private->EndOfPeiNotifyList,
+    &mAhciEndOfPeiNotifyListTemplate,
+    sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)
+    );
+  PeiServicesNotifyPpi (&Private->EndOfPeiNotifyList);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize AHCI controller from EDKII_ATA_AHCI_HOST_CONTROLLER_PPI instance.
+
+  @param[in] AhciHcPpi  Pointer to the AHCI Host Controller PPI instance.
+
+  @retval EFI_SUCCESS   PPI successfully installed.
+**/
+EFI_STATUS
+AtaAhciInitPrivateDataFromHostControllerPpi (
+  IN EDKII_ATA_AHCI_HOST_CONTROLLER_PPI  *AhciHcPpi
+  )
+{
+  UINT8                     Controller;
+  UINTN                     MmioBase;
+  UINTN                     DevicePathLength;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  EFI_STATUS                Status;
+
   Controller = 0;
   MmioBase   = 0;
   while (TRUE) {
@@ -193,65 +335,7 @@ AtaAhciPeimEntry (
       return Status;
     }
 
-    //
-    // Check validity of the device path of the ATA AHCI controller.
-    //
-    Status = AhciIsHcDevicePathValid (DevicePath, DevicePathLength);
-    if (EFI_ERROR (Status)) {
-      DEBUG ((
-        DEBUG_ERROR,
-        "%a: The device path is invalid for Controller %d.\n",
-        __FUNCTION__,
-        Controller
-        ));
-      Controller++;
-      continue;
-    }
-
-    //
-    // For S3 resume performance consideration, not all ports on an ATA AHCI
-    // controller will be enumerated/initialized. The driver consumes the
-    // content within S3StorageDeviceInitList LockBox to get the ports that
-    // will be enumerated/initialized during S3 resume.
-    //
-    if (BootMode == BOOT_ON_S3_RESUME) {
-      NumberOfPorts = AhciS3GetEumeratePorts (DevicePath, DevicePathLength, &PortBitMap);
-      if (NumberOfPorts == 0) {
-        //
-        // No ports need to be enumerated for this controller.
-        //
-        Controller++;
-        continue;
-      }
-    } else {
-      PortBitMap = MAX_UINT32;
-    }
-
-    //
-    // Memory allocation for controller private data.
-    //
-    Private = AllocateZeroPool (sizeof (PEI_AHCI_CONTROLLER_PRIVATE_DATA));
-    if (Private == NULL) {
-      DEBUG ((
-        DEBUG_ERROR,
-        "%a: Fail to allocate private data for Controller %d.\n",
-        __FUNCTION__,
-        Controller
-        ));
-      return EFI_OUT_OF_RESOURCES;
-    }
-
-    //
-    // Initialize controller private data.
-    //
-    Private->Signature        = AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE;
-    Private->MmioBase         = MmioBase;
-    Private->DevicePathLength = DevicePathLength;
-    Private->DevicePath       = DevicePath;
-    Private->PortBitMap       = PortBitMap;
-    InitializeListHead (&Private->DeviceList);
-
-    Status = AhciModeInitialization (Private);
+    Status = AtaAhciInitPrivateData (MmioBase, DevicePath, DevicePathLength);
     if (EFI_ERROR (Status)) {
       DEBUG ((
         DEBUG_ERROR,
@@ -260,86 +344,187 @@ AtaAhciPeimEntry (
         Controller,
         Status
         ));
-      Controller++;
-      continue;
-    }
-
-    Private->AtaPassThruMode.Attributes = EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL |
-                                          EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL;
-    Private->AtaPassThruMode.IoAlign      = sizeof (UINTN);
-    Private->AtaPassThruPpi.Revision      = EDKII_PEI_ATA_PASS_THRU_PPI_REVISION;
-    Private->AtaPassThruPpi.Mode          = &Private->AtaPassThruMode;
-    Private->AtaPassThruPpi.PassThru      = AhciAtaPassThruPassThru;
-    Private->AtaPassThruPpi.GetNextPort   = AhciAtaPassThruGetNextPort;
-    Private->AtaPassThruPpi.GetNextDevice = AhciAtaPassThruGetNextDevice;
-    Private->AtaPassThruPpi.GetDevicePath = AhciAtaPassThruGetDevicePath;
-    CopyMem (
-      &Private->AtaPassThruPpiList,
-      &mAhciAtaPassThruPpiListTemplate,
-      sizeof (EFI_PEI_PPI_DESCRIPTOR)
-      );
-    Private->AtaPassThruPpiList.Ppi = &Private->AtaPassThruPpi;
-    PeiServicesInstallPpi (&Private->AtaPassThruPpiList);
-
-    Private->BlkIoPpi.GetNumberOfBlockDevices = AhciBlockIoGetDeviceNo;
-    Private->BlkIoPpi.GetBlockDeviceMediaInfo = AhciBlockIoGetMediaInfo;
-    Private->BlkIoPpi.ReadBlocks              = AhciBlockIoReadBlocks;
-    CopyMem (
-      &Private->BlkIoPpiList,
-      &mAhciBlkIoPpiListTemplate,
-      sizeof (EFI_PEI_PPI_DESCRIPTOR)
-      );
-    Private->BlkIoPpiList.Ppi = &Private->BlkIoPpi;
-    PeiServicesInstallPpi (&Private->BlkIoPpiList);
-
-    Private->BlkIo2Ppi.Revision                = EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION;
-    Private->BlkIo2Ppi.GetNumberOfBlockDevices = AhciBlockIoGetDeviceNo2;
-    Private->BlkIo2Ppi.GetBlockDeviceMediaInfo = AhciBlockIoGetMediaInfo2;
-    Private->BlkIo2Ppi.ReadBlocks              = AhciBlockIoReadBlocks2;
-    CopyMem (
-      &Private->BlkIo2PpiList,
-      &mAhciBlkIo2PpiListTemplate,
-      sizeof (EFI_PEI_PPI_DESCRIPTOR)
-      );
-    Private->BlkIo2PpiList.Ppi = &Private->BlkIo2Ppi;
-    PeiServicesInstallPpi (&Private->BlkIo2PpiList);
-
-    if (Private->TrustComputingDevices != 0) {
+    } else {
       DEBUG ((
         DEBUG_INFO,
-        "%a: Security Security Command PPI will be produced for Controller %d.\n",
+        "%a: Controller %d has been successfully initialized.\n",
         __FUNCTION__,
         Controller
         ));
-      Private->StorageSecurityPpi.Revision           = EDKII_STORAGE_SECURITY_PPI_REVISION;
-      Private->StorageSecurityPpi.GetNumberofDevices = AhciStorageSecurityGetDeviceNo;
-      Private->StorageSecurityPpi.GetDevicePath      = AhciStorageSecurityGetDevicePath;
-      Private->StorageSecurityPpi.ReceiveData        = AhciStorageSecurityReceiveData;
-      Private->StorageSecurityPpi.SendData           = AhciStorageSecuritySendData;
-      CopyMem (
-        &Private->StorageSecurityPpiList,
-        &mAhciStorageSecurityPpiListTemplate,
-        sizeof (EFI_PEI_PPI_DESCRIPTOR)
-        );
-      Private->StorageSecurityPpiList.Ppi = &Private->StorageSecurityPpi;
-      PeiServicesInstallPpi (&Private->StorageSecurityPpiList);
     }
 
-    CopyMem (
-      &Private->EndOfPeiNotifyList,
-      &mAhciEndOfPeiNotifyListTemplate,
-      sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)
-      );
-    PeiServicesNotifyPpi (&Private->EndOfPeiNotifyList);
-
-    DEBUG ((
-      DEBUG_INFO,
-      "%a: Controller %d has been successfully initialized.\n",
-      __FUNCTION__,
-      Controller
-      ));
     Controller++;
   }
 
   return EFI_SUCCESS;
 }
+
+/**
+  Callback for EDKII_ATA_AHCI_HOST_CONTROLLER_PPI installation.
+
+  @param[in] PeiServices         Pointer to PEI Services Table.
+  @param[in] NotifyDescriptor    Pointer to the descriptor for the Notification
+                                 event that caused this function to execute.
+  @param[in] Ppi                 Pointer to the PPI data associated with this function.
+
+  @retval EFI_SUCCESS            The function completes successfully
+  @retval Others                 Cannot initialize AHCI controller from given EDKII_ATA_AHCI_HOST_CONTROLLER_PPI
+
+**/
+EFI_STATUS
+EFIAPI
+AtaAhciHostControllerPpiInstallationCallback (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  )
+{
+  EDKII_ATA_AHCI_HOST_CONTROLLER_PPI  *AhciHcPpi;
+
+  if (Ppi == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  AhciHcPpi = (EDKII_ATA_AHCI_HOST_CONTROLLER_PPI *)Ppi;
+
+  return AtaAhciInitPrivateDataFromHostControllerPpi (AhciHcPpi);
+}
+
+/**
+  Initialize AHCI controller from fiven PCI_DEVICE_PPI.
+
+  @param[in] PciDevice  Pointer to the PCI Device PPI instance.
+
+  @retval EFI_SUCCESS      The function completes successfully
+  @retval Others           Cannot initialize AHCI controller for given device
+**/
+EFI_STATUS
+AtaAhciInitPrivateDataFromPciDevice (
+  EDKII_PCI_DEVICE_PPI  *PciDevice
+  )
+{
+  EFI_STATUS                Status;
+  PCI_TYPE00                PciData;
+  UINTN                     MmioBase;
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+  UINTN                     DevicePathLength;
+  UINT64                    EnabledPciAttributes;
+
+  //
+  // Now further check the PCI header: Base Class (offset 0x0B) and
+  // Sub Class (offset 0x0A). This controller should be an SATA controller
+  //
+  Status = PciDevice->PciIo.Pci.Read (
+                                  &PciDevice->PciIo,
+                                  EfiPciIoWidthUint8,
+                                  PCI_CLASSCODE_OFFSET,
+                                  sizeof (PciData.Hdr.ClassCode),
+                                  PciData.Hdr.ClassCode
+                                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (!IS_PCI_IDE (&PciData) && !IS_PCI_SATADPA (&PciData)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PciDevice->PciIo.Attributes (
+                              &PciDevice->PciIo,
+                              EfiPciIoAttributeOperationSupported,
+                              0,
+                              &EnabledPciAttributes
+                              );
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  } else {
+    EnabledPciAttributes &= (UINT64)EFI_PCI_DEVICE_ENABLE;
+    Status                = PciDevice->PciIo.Attributes (
+                                               &PciDevice->PciIo,
+                                               EfiPciIoAttributeOperationEnable,
+                                               EnabledPciAttributes,
+                                               NULL
+                                               );
+    if (EFI_ERROR (Status)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  Status = PciDevice->PciIo.Pci.Read (
+                                  &PciDevice->PciIo,
+                                  EfiPciIoWidthUint32,
+                                  0x24,
+                                  sizeof (UINTN),
+                                  &MmioBase
+                                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  DevicePathLength = GetDevicePathSize (PciDevice->DevicePath);
+  DevicePath       = PciDevice->DevicePath;
+
+  Status = AtaAhciInitPrivateData (MmioBase, DevicePath, DevicePathLength);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_INFO,
+      "%a: Failed to init controller, with Status - %r\n",
+      __FUNCTION__,
+      Status
+      ));
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Callback for EDKII_PCI_DEVICE_PPI installation.
+
+  @param[in] PeiServices         Pointer to PEI Services Table.
+  @param[in] NotifyDescriptor    Pointer to the descriptor for the Notification
+                                 event that caused this function to execute.
+  @param[in] Ppi                 Pointer to the PPI data associated with this function.
+
+  @retval EFI_SUCCESS            The function completes successfully
+  @retval Others                 Cannot initialize AHCI controller from given PCI_DEVICE_PPI
+
+**/
+EFI_STATUS
+EFIAPI
+AtaAhciPciDevicePpiInstallationCallback (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  )
+{
+  EDKII_PCI_DEVICE_PPI  *PciDevice;
+
+  PciDevice = (EDKII_PCI_DEVICE_PPI *)Ppi;
+
+  return AtaAhciInitPrivateDataFromPciDevice (PciDevice);
+}
+
+/**
+  Entry point of the PEIM.
+
+  @param[in] FileHandle     Handle of the file being invoked.
+  @param[in] PeiServices    Describes the list of possible PEI Services.
+
+  @retval EFI_SUCCESS    PPI successfully installed.
+
+**/
+EFI_STATUS
+EFIAPI
+AtaAhciPeimEntry (
+  IN EFI_PEI_FILE_HANDLE     FileHandle,
+  IN CONST EFI_PEI_SERVICES  **PeiServices
+  )
+{
+  DEBUG ((DEBUG_INFO, "%a: Enters.\n", __FUNCTION__));
+
+  PeiServicesNotifyPpi (&mAtaAhciHostControllerNotify);
+
+  PeiServicesNotifyPpi (&mPciDevicePpiNotify);
+
+  return EFI_SUCCESS;
+}
diff --git a/MdeModulePkg/Bus/Ata/AhciPei/DevicePath.c b/MdeModulePkg/Bus/Ata/AhciPei/DevicePath.c
index 81f8743d40d8..cf0955929dde 100644
--- a/MdeModulePkg/Bus/Ata/AhciPei/DevicePath.c
+++ b/MdeModulePkg/Bus/Ata/AhciPei/DevicePath.c
@@ -38,50 +38,6 @@ EFI_DEVICE_PATH_PROTOCOL  mAhciEndDevicePathNodeTemplate = {
   }
 };
 
-/**
-  Returns the 16-bit Length field of a device path node.
-
-  Returns the 16-bit Length field of the device path node specified by Node.
-  Node is not required to be aligned on a 16-bit boundary, so it is recommended
-  that a function such as ReadUnaligned16() be used to extract the contents of
-  the Length field.
-
-  If Node is NULL, then ASSERT().
-
-  @param  Node      A pointer to a device path node data structure.
-
-  @return The 16-bit Length field of the device path node specified by Node.
-
-**/
-UINTN
-DevicePathNodeLength (
-  IN CONST VOID  *Node
-  )
-{
-  ASSERT (Node != NULL);
-  return ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);
-}
-
-/**
-  Returns a pointer to the next node in a device path.
-
-  If Node is NULL, then ASSERT().
-
-  @param  Node    A pointer to a device path node data structure.
-
-  @return a pointer to the device path node that follows the device path node
-  specified by Node.
-
-**/
-EFI_DEVICE_PATH_PROTOCOL *
-NextDevicePathNode (
-  IN CONST VOID  *Node
-  )
-{
-  ASSERT (Node != NULL);
-  return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + DevicePathNodeLength (Node));
-}
-
 /**
   Get the size of the current device path instance.
 
diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h
index 43ad4639bd77..4aed1cb7ad8a 100644
--- a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h
+++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h
@@ -29,6 +29,7 @@
 #include <Library/BaseMemoryLib.h>
 #include <Library/IoLib.h>
 #include <Library/TimerLib.h>
+#include <Library/DevicePathLib.h>
 
 //
 // Structure forward declarations
@@ -354,6 +355,46 @@ extern UINT32  mMaxTransferBlockNumber[2];
 // Internal functions
 //
 
+/**
+  Callback for EDKII_ATA_AHCI_HOST_CONTROLLER_PPI installation.
+
+  @param[in] PeiServices         Pointer to PEI Services Table.
+  @param[in] NotifyDescriptor    Pointer to the descriptor for the Notification
+                                 event that caused this function to execute.
+  @param[in] Ppi                 Pointer to the PPI data associated with this function.
+
+  @retval EFI_SUCCESS            The function completes successfully
+  @retval Others                 Cannot initialize AHCI controller from given EDKII_ATA_AHCI_HOST_CONTROLLER_PPI
+
+**/
+EFI_STATUS
+EFIAPI
+AtaAhciHostControllerPpiInstallationCallback (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  );
+
+/**
+  Callback for EDKII_PCI_DEVICE_PPI installation.
+
+  @param[in] PeiServices         Pointer to PEI Services Table.
+  @param[in] NotifyDescriptor    Pointer to the descriptor for the Notification
+                                 event that caused this function to execute.
+  @param[in] Ppi                 Pointer to the PPI data associated with this function.
+
+  @retval EFI_SUCCESS            The function completes successfully
+  @retval Others                 Cannot initialize AHCI controller from given PCI_DEVICE_PPI
+
+**/
+EFI_STATUS
+EFIAPI
+AtaAhciPciDevicePpiInstallationCallback (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
+  IN VOID                       *Ppi
+  );
+
 /**
   Allocates pages that are suitable for an OperationBusMasterCommonBuffer or
   OperationBusMasterCommonBuffer64 mapping.
@@ -631,22 +672,6 @@ TrustTransferAtaDevice (
   OUT    UINTN                     *TransferLengthOut
   );
 
-/**
-  Returns a pointer to the next node in a device path.
-
-  If Node is NULL, then ASSERT().
-
-  @param  Node    A pointer to a device path node data structure.
-
-  @return a pointer to the device path node that follows the device path node
-  specified by Node.
-
-**/
-EFI_DEVICE_PATH_PROTOCOL *
-NextDevicePathNode (
-  IN CONST VOID  *Node
-  );
-
 /**
   Get the size of the current device path instance.
 
diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf
index 912ff7a8ba4f..788660b33299 100644
--- a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf
+++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf
@@ -50,11 +50,13 @@ [LibraryClasses]
   TimerLib
   LockBoxLib
   PeimEntryPoint
+  DevicePathLib
 
 [Ppis]
   gEdkiiPeiAtaAhciHostControllerPpiGuid          ## CONSUMES
   gEdkiiIoMmuPpiGuid                             ## CONSUMES
   gEfiEndOfPeiSignalPpiGuid                      ## CONSUMES
+  gEdkiiPeiPciDevicePpiGuid                      ## CONSUMES
   gEdkiiPeiAtaPassThruPpiGuid                    ## SOMETIMES_PRODUCES
   gEfiPeiVirtualBlockIoPpiGuid                   ## SOMETIMES_PRODUCES
   gEfiPeiVirtualBlockIo2PpiGuid                  ## SOMETIMES_PRODUCES
@@ -65,8 +67,7 @@ [Guids]
 
 [Depex]
   gEfiPeiMemoryDiscoveredPpiGuid AND
-  gEfiPeiMasterBootModePpiGuid AND
-  gEdkiiPeiAtaAhciHostControllerPpiGuid
+  gEfiPeiMasterBootModePpiGuid
 
 [UserExtensions.TianoCore."ExtraFiles"]
   AhciPeiExtra.uni
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 90a0a7ec4a7c..45a8ec84ad69 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -117,6 +117,7 @@ [LibraryClasses.common.PEIM]
   MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
   ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
   LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibBase.inf
 
 [LibraryClasses.common.DXE_CORE]
   HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
-- 
2.27.0.windows.1

---------------------------------------------------------------------
Intel Technology Poland sp. z o.o.
ul. Slowackiego 173 | 80-298 Gdansk | Sad Rejonowy Gdansk Polnoc | VII Wydzial Gospodarczy Krajowego Rejestru Sadowego - KRS 101882 | NIP 957-07-52-316 | Kapital zakladowy 200.000 PLN.
Ta wiadomosc wraz z zalacznikami jest przeznaczona dla okreslonego adresata i moze zawierac informacje poufne. W razie przypadkowego otrzymania tej wiadomosci, prosimy o powiadomienie nadawcy oraz trwale jej usuniecie; jakiekolwiek przegladanie lub rozpowszechnianie jest zabronione.
This e-mail and any attachments may contain confidential material for the sole use of the intended recipient(s). If you are not the intended recipient, please contact the sender and delete all copies; any review or distribution by others is strictly prohibited.



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#92017): https://edk2.groups.io/g/devel/message/92017
Mute This Topic: https://groups.io/mt/92752850/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Re: [edk2-devel] [PATCH v3 2/2] MdeModulePkg/AhciPei: Use PCI_DEVICE_PPI to manage AHCI device
Posted by Wu, Hao A 1 month, 4 weeks ago
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>

Best Regards,
Hao Wu

> -----Original Message-----
> From: Czajkowski, Maciej <maciej.czajkowski@intel.com>
> Sent: Tuesday, August 2, 2022 1:00 AM
> To: devel@edk2.groups.io
> Cc: Wu, Hao A <hao.a.wu@intel.com>; Ni, Ray <ray.ni@intel.com>; Gao,
> Liming <gaoliming@byosoft.com.cn>
> Subject: [PATCH v3 2/2] MdeModulePkg/AhciPei: Use PCI_DEVICE_PPI to
> manage AHCI device
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3907
> 
> This change modifies AhciPei library to allow usage both
> EDKII_PCI_DEVICE_PPI and EDKII_PEI_ATA_AHCI_HOST_CONTROLLER_PPI
> to manage ATA HDD working under AHCI mode.
> 
> Cc: Hao A Wu <hao.a.wu@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Signed-off-by: Maciej Czajkowski <maciej.czajkowski@intel.com>
> ---
> 
> Notes:
>     v2 changes:
>     - added missing function descriptions
>     - moved controller initialization from PCI_DEVICE_PPI to seperate funciton
>     in order to reduce code duplication
>     - added DevicePathLib BASE instance to the MdeModulePkg.dec to allow
> PEIMs to consume it
> 
>     v3 changes:
>     - removed redundant locate PPI calls (if already installed, NotifyPpi
> executes callback)
>     - aligned enabling HC device from PCI_DEVICE_PPI with flow from
> AtaAtapiPassThru DXE driver
>     - corrected function descriptions
> 
>  MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c    | 505 +++++++++++++-------
>  MdeModulePkg/Bus/Ata/AhciPei/DevicePath.c |  44 --
>  MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h    |  57 ++-
>  MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf  |   5 +-
>  MdeModulePkg/MdeModulePkg.dsc             |   1 +
>  5 files changed, 390 insertions(+), 222 deletions(-)
> 
> diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c
> b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c
> index 208b7e9a3606..98dd732a4023 100644
> --- a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c
> +++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.c
> @@ -9,6 +9,9 @@
>  **/  #include "AhciPei.h"+#include <Ppi/PciDevice.h>+#include
> <Library/DevicePathLib.h>+#include <IndustryStandard/Pci.h>
> EFI_PEI_PPI_DESCRIPTOR  mAhciAtaPassThruPpiListTemplate =
> {   (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),@@ -40,6 +43,18 @@
> EFI_PEI_NOTIFY_DESCRIPTOR  mAhciEndOfPeiNotifyListTemplate = {
>    AhciPeimEndOfPei }; +EFI_PEI_NOTIFY_DESCRIPTOR
> mAtaAhciHostControllerNotify = {+
> (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),+
> &gEdkiiPeiAtaAhciHostControllerPpiGuid,+
> AtaAhciHostControllerPpiInstallationCallback+};++EFI_PEI_NOTIFY_DESCRIPT
> OR  mPciDevicePpiNotify = {+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
> | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),+
> &gEdkiiPeiPciDevicePpiGuid,+  AtaAhciPciDevicePpiInstallationCallback+};+
> /**   Free the DMA resources allocated by an ATA AHCI controller. @@ -
> 111,33 +126,30 @@ AhciPeimEndOfPei (
>  }  /**-  Entry point of the PEIM.+  Initialize and install PrivateData PPIs. -
> @param[in] FileHandle     Handle of the file being invoked.-  @param[in]
> PeiServices    Describes the list of possible PEI Services.--  @retval
> EFI_SUCCESS    PPI successfully installed.+  @param[in] MmioBase
> MMIO base address of specific AHCI controller+  @param[in] DevicePath
> A pointer to the EFI_DEVICE_PATH_PROTOCOL+                                 structure.+
> @param[in] DevicePathLength    Length of the device path. +  @retval
> EFI_SUCCESS  AHCI controller initialized and PPIs installed+  @retval others
> Failed to initialize AHCI controller **/ EFI_STATUS-EFIAPI-AtaAhciPeimEntry
> (-  IN EFI_PEI_FILE_HANDLE     FileHandle,-  IN CONST EFI_PEI_SERVICES
> **PeiServices+AtaAhciInitPrivateData (+  IN UINTN                     MmioBase,+
> IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,+  IN UINTN
> DevicePathLength   ) {-  EFI_STATUS                          Status;-  EFI_BOOT_MODE
> BootMode;-  EDKII_ATA_AHCI_HOST_CONTROLLER_PPI  *AhciHcPpi;-  UINT8
> Controller;-  UINTN                               MmioBase;-  UINTN
> DevicePathLength;-  EFI_DEVICE_PATH_PROTOCOL            *DevicePath;-
> UINT32                              PortBitMap;-  PEI_AHCI_CONTROLLER_PRIVATE_DATA
> *Private;-  UINT8                               NumberOfPorts;+  EFI_STATUS
> Status;+  UINT32                            PortBitMap;+  UINT8
> NumberOfPorts;+  PEI_AHCI_CONTROLLER_PRIVATE_DATA  *Private;+
> EFI_BOOT_MODE                     BootMode; -  DEBUG ((DEBUG_INFO, "%a:
> Enters.\n", __FUNCTION__));+  DEBUG ((DEBUG_INFO, "Initializing private
> data for ATA\n"));    //   // Get the current boot mode.@@ -149,19 +161,149
> @@ AtaAhciPeimEntry (
>    }    //-  // Locate the ATA AHCI host controller PPI.-  //-  Status =
> PeiServicesLocatePpi (-             &gEdkiiPeiAtaAhciHostControllerPpiGuid,-
> 0,-             NULL,-             (VOID **)&AhciHcPpi-             );+  // Check validity of
> the device path of the ATA AHCI controller.+  //+  Status =
> AhciIsHcDevicePathValid (DevicePath, DevicePathLength);+  if (EFI_ERROR
> (Status)) {+    DEBUG ((+      DEBUG_ERROR,+      "%a: The device path is
> invalid.\n",+      __FUNCTION__+      ));+    return Status;+  }++  //+  // For S3
> resume performance consideration, not all ports on an ATA AHCI+  //
> controller will be enumerated/initialized. The driver consumes the+  //
> content within S3StorageDeviceInitList LockBox to get the ports that+  // will
> be enumerated/initialized during S3 resume.+  //+  if (BootMode ==
> BOOT_ON_S3_RESUME) {+    NumberOfPorts = AhciS3GetEumeratePorts
> (DevicePath, DevicePathLength, &PortBitMap);+    if (NumberOfPorts == 0)
> {+      return EFI_SUCCESS;+    }+  } else {+    PortBitMap = MAX_UINT32;+  }++
> //+  // Memory allocation for controller private data.+  //+  Private =
> AllocateZeroPool (sizeof (PEI_AHCI_CONTROLLER_PRIVATE_DATA));+  if
> (Private == NULL) {+    DEBUG ((+      DEBUG_ERROR,+      "%a: Fail to allocate
> private data.\n",+      __FUNCTION__+      ));+    return
> EFI_OUT_OF_RESOURCES;+  }++  //+  // Initialize controller private data.+  //+
> Private->Signature        =
> AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE;+  Private->MmioBase
> = MmioBase;+  Private->DevicePathLength = DevicePathLength;+  Private-
> >DevicePath       = DevicePath;+  Private->PortBitMap       = PortBitMap;+
> InitializeListHead (&Private->DeviceList);++  Status = AhciModeInitialization
> (Private);   if (EFI_ERROR (Status)) {-    DEBUG ((DEBUG_ERROR, "%a: Failed to
> locate AtaAhciHostControllerPpi.\n", __FUNCTION__));-    return
> EFI_UNSUPPORTED;+    return Status;+  }++  Private-
> >AtaPassThruMode.Attributes =
> EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL |+
> EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL;+  Private-
> >AtaPassThruMode.IoAlign      = sizeof (UINTN);+  Private-
> >AtaPassThruPpi.Revision      = EDKII_PEI_ATA_PASS_THRU_PPI_REVISION;+
> Private->AtaPassThruPpi.Mode          = &Private->AtaPassThruMode;+
> Private->AtaPassThruPpi.PassThru      = AhciAtaPassThruPassThru;+  Private-
> >AtaPassThruPpi.GetNextPort   = AhciAtaPassThruGetNextPort;+  Private-
> >AtaPassThruPpi.GetNextDevice = AhciAtaPassThruGetNextDevice;+
> Private->AtaPassThruPpi.GetDevicePath = AhciAtaPassThruGetDevicePath;+
> CopyMem (+    &Private->AtaPassThruPpiList,+
> &mAhciAtaPassThruPpiListTemplate,+    sizeof
> (EFI_PEI_PPI_DESCRIPTOR)+    );+  Private->AtaPassThruPpiList.Ppi =
> &Private->AtaPassThruPpi;+  PeiServicesInstallPpi (&Private-
> >AtaPassThruPpiList);++  Private->BlkIoPpi.GetNumberOfBlockDevices =
> AhciBlockIoGetDeviceNo;+  Private->BlkIoPpi.GetBlockDeviceMediaInfo =
> AhciBlockIoGetMediaInfo;+  Private->BlkIoPpi.ReadBlocks              =
> AhciBlockIoReadBlocks;+  CopyMem (+    &Private->BlkIoPpiList,+
> &mAhciBlkIoPpiListTemplate,+    sizeof (EFI_PEI_PPI_DESCRIPTOR)+    );+
> Private->BlkIoPpiList.Ppi = &Private->BlkIoPpi;+  PeiServicesInstallPpi
> (&Private->BlkIoPpiList);++  Private->BlkIo2Ppi.Revision                =
> EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION;+  Private-
> >BlkIo2Ppi.GetNumberOfBlockDevices = AhciBlockIoGetDeviceNo2;+
> Private->BlkIo2Ppi.GetBlockDeviceMediaInfo = AhciBlockIoGetMediaInfo2;+
> Private->BlkIo2Ppi.ReadBlocks              = AhciBlockIoReadBlocks2;+  CopyMem
> (+    &Private->BlkIo2PpiList,+    &mAhciBlkIo2PpiListTemplate,+    sizeof
> (EFI_PEI_PPI_DESCRIPTOR)+    );+  Private->BlkIo2PpiList.Ppi = &Private-
> >BlkIo2Ppi;+  PeiServicesInstallPpi (&Private->BlkIo2PpiList);++  if (Private-
> >TrustComputingDevices != 0) {+    DEBUG ((+      DEBUG_INFO,+      "%a:
> Security Security Command PPI will be produced.\n",+
> __FUNCTION__+      ));+    Private->StorageSecurityPpi.Revision           =
> EDKII_STORAGE_SECURITY_PPI_REVISION;+    Private-
> >StorageSecurityPpi.GetNumberofDevices =
> AhciStorageSecurityGetDeviceNo;+    Private-
> >StorageSecurityPpi.GetDevicePath      =
> AhciStorageSecurityGetDevicePath;+    Private-
> >StorageSecurityPpi.ReceiveData        = AhciStorageSecurityReceiveData;+
> Private->StorageSecurityPpi.SendData           =
> AhciStorageSecuritySendData;+    CopyMem (+      &Private-
> >StorageSecurityPpiList,+      &mAhciStorageSecurityPpiListTemplate,+
> sizeof (EFI_PEI_PPI_DESCRIPTOR)+      );+    Private-
> >StorageSecurityPpiList.Ppi = &Private->StorageSecurityPpi;+
> PeiServicesInstallPpi (&Private->StorageSecurityPpiList);   } +  CopyMem (+
> &Private->EndOfPeiNotifyList,+    &mAhciEndOfPeiNotifyListTemplate,+
> sizeof (EFI_PEI_NOTIFY_DESCRIPTOR)+    );+  PeiServicesNotifyPpi (&Private-
> >EndOfPeiNotifyList);++  return EFI_SUCCESS;+}++/**+  Initialize AHCI
> controller from EDKII_ATA_AHCI_HOST_CONTROLLER_PPI instance.++
> @param[in] AhciHcPpi  Pointer to the AHCI Host Controller PPI instance.++
> @retval EFI_SUCCESS   PPI successfully
> installed.+**/+EFI_STATUS+AtaAhciInitPrivateDataFromHostControllerPpi (+
> IN EDKII_ATA_AHCI_HOST_CONTROLLER_PPI  *AhciHcPpi+  )+{+  UINT8
> Controller;+  UINTN                     MmioBase;+  UINTN
> DevicePathLength;+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;+
> EFI_STATUS                Status;+   Controller = 0;   MmioBase   = 0;   while (TRUE)
> {@@ -193,65 +335,7 @@ AtaAhciPeimEntry (
>        return Status;     } -    //-    // Check validity of the device path of the ATA
> AHCI controller.-    //-    Status = AhciIsHcDevicePathValid (DevicePath,
> DevicePathLength);-    if (EFI_ERROR (Status)) {-      DEBUG ((-
> DEBUG_ERROR,-        "%a: The device path is invalid for Controller %d.\n",-
> __FUNCTION__,-        Controller-        ));-      Controller++;-      continue;-    }--
> //-    // For S3 resume performance consideration, not all ports on an ATA
> AHCI-    // controller will be enumerated/initialized. The driver consumes the-
> // content within S3StorageDeviceInitList LockBox to get the ports that-    //
> will be enumerated/initialized during S3 resume.-    //-    if (BootMode ==
> BOOT_ON_S3_RESUME) {-      NumberOfPorts = AhciS3GetEumeratePorts
> (DevicePath, DevicePathLength, &PortBitMap);-      if (NumberOfPorts == 0)
> {-        //-        // No ports need to be enumerated for this controller.-        //-
> Controller++;-        continue;-      }-    } else {-      PortBitMap = MAX_UINT32;-
>     }--    //-    // Memory allocation for controller private data.-    //-    Private =
> AllocateZeroPool (sizeof (PEI_AHCI_CONTROLLER_PRIVATE_DATA));-    if
> (Private == NULL) {-      DEBUG ((-        DEBUG_ERROR,-        "%a: Fail to allocate
> private data for Controller %d.\n",-        __FUNCTION__,-        Controller-
>         ));-      return EFI_OUT_OF_RESOURCES;-    }--    //-    // Initialize controller
> private data.-    //-    Private->Signature        =
> AHCI_PEI_CONTROLLER_PRIVATE_DATA_SIGNATURE;-    Private->MmioBase
> = MmioBase;-    Private->DevicePathLength = DevicePathLength;-    Private-
> >DevicePath       = DevicePath;-    Private->PortBitMap       = PortBitMap;-
> InitializeListHead (&Private->DeviceList);--    Status = AhciModeInitialization
> (Private);+    Status = AtaAhciInitPrivateData (MmioBase, DevicePath,
> DevicePathLength);     if (EFI_ERROR (Status)) {       DEBUG
> ((         DEBUG_ERROR,@@ -260,86 +344,187 @@ AtaAhciPeimEntry (
>          Controller,         Status         ));-      Controller++;-      continue;-    }--
> Private->AtaPassThruMode.Attributes =
> EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL |-
> EFI_ATA_PASS_THRU_ATTRIBUTES_LOGICAL;-    Private-
> >AtaPassThruMode.IoAlign      = sizeof (UINTN);-    Private-
> >AtaPassThruPpi.Revision      = EDKII_PEI_ATA_PASS_THRU_PPI_REVISION;-
> Private->AtaPassThruPpi.Mode          = &Private->AtaPassThruMode;-
> Private->AtaPassThruPpi.PassThru      = AhciAtaPassThruPassThru;-    Private-
> >AtaPassThruPpi.GetNextPort   = AhciAtaPassThruGetNextPort;-    Private-
> >AtaPassThruPpi.GetNextDevice = AhciAtaPassThruGetNextDevice;-
> Private->AtaPassThruPpi.GetDevicePath = AhciAtaPassThruGetDevicePath;-
> CopyMem (-      &Private->AtaPassThruPpiList,-
> &mAhciAtaPassThruPpiListTemplate,-      sizeof (EFI_PEI_PPI_DESCRIPTOR)-
>       );-    Private->AtaPassThruPpiList.Ppi = &Private->AtaPassThruPpi;-
> PeiServicesInstallPpi (&Private->AtaPassThruPpiList);--    Private-
> >BlkIoPpi.GetNumberOfBlockDevices = AhciBlockIoGetDeviceNo;-    Private-
> >BlkIoPpi.GetBlockDeviceMediaInfo = AhciBlockIoGetMediaInfo;-    Private-
> >BlkIoPpi.ReadBlocks              = AhciBlockIoReadBlocks;-    CopyMem (-
> &Private->BlkIoPpiList,-      &mAhciBlkIoPpiListTemplate,-      sizeof
> (EFI_PEI_PPI_DESCRIPTOR)-      );-    Private->BlkIoPpiList.Ppi = &Private-
> >BlkIoPpi;-    PeiServicesInstallPpi (&Private->BlkIoPpiList);--    Private-
> >BlkIo2Ppi.Revision                =
> EFI_PEI_RECOVERY_BLOCK_IO2_PPI_REVISION;-    Private-
> >BlkIo2Ppi.GetNumberOfBlockDevices = AhciBlockIoGetDeviceNo2;-
> Private->BlkIo2Ppi.GetBlockDeviceMediaInfo = AhciBlockIoGetMediaInfo2;-
> Private->BlkIo2Ppi.ReadBlocks              = AhciBlockIoReadBlocks2;-    CopyMem
> (-      &Private->BlkIo2PpiList,-      &mAhciBlkIo2PpiListTemplate,-      sizeof
> (EFI_PEI_PPI_DESCRIPTOR)-      );-    Private->BlkIo2PpiList.Ppi = &Private-
> >BlkIo2Ppi;-    PeiServicesInstallPpi (&Private->BlkIo2PpiList);--    if (Private-
> >TrustComputingDevices != 0) {+    } else {       DEBUG ((         DEBUG_INFO,-
> "%a: Security Security Command PPI will be produced for Controller %d.\n",+
> "%a: Controller %d has been successfully initialized.\n",         __FUNCTION__,
> Controller         ));-      Private->StorageSecurityPpi.Revision           =
> EDKII_STORAGE_SECURITY_PPI_REVISION;-      Private-
> >StorageSecurityPpi.GetNumberofDevices =
> AhciStorageSecurityGetDeviceNo;-      Private-
> >StorageSecurityPpi.GetDevicePath      =
> AhciStorageSecurityGetDevicePath;-      Private-
> >StorageSecurityPpi.ReceiveData        = AhciStorageSecurityReceiveData;-
> Private->StorageSecurityPpi.SendData           = AhciStorageSecuritySendData;-
> CopyMem (-        &Private->StorageSecurityPpiList,-
> &mAhciStorageSecurityPpiListTemplate,-        sizeof
> (EFI_PEI_PPI_DESCRIPTOR)-        );-      Private->StorageSecurityPpiList.Ppi =
> &Private->StorageSecurityPpi;-      PeiServicesInstallPpi (&Private-
> >StorageSecurityPpiList);     } -    CopyMem (-      &Private-
> >EndOfPeiNotifyList,-      &mAhciEndOfPeiNotifyListTemplate,-      sizeof
> (EFI_PEI_NOTIFY_DESCRIPTOR)-      );-    PeiServicesNotifyPpi (&Private-
> >EndOfPeiNotifyList);--    DEBUG ((-      DEBUG_INFO,-      "%a: Controller %d
> has been successfully initialized.\n",-      __FUNCTION__,-      Controller-      ));
> Controller++;   }    return EFI_SUCCESS; }++/**+  Callback for
> EDKII_ATA_AHCI_HOST_CONTROLLER_PPI installation.++  @param[in]
> PeiServices         Pointer to PEI Services Table.+  @param[in] NotifyDescriptor
> Pointer to the descriptor for the Notification+                                 event that
> caused this function to execute.+  @param[in] Ppi                 Pointer to the PPI
> data associated with this function.++  @retval EFI_SUCCESS            The
> function completes successfully+  @retval Others                 Cannot initialize
> AHCI controller from given
> EDKII_ATA_AHCI_HOST_CONTROLLER_PPI++**/+EFI_STATUS+EFIAPI+AtaA
> hciHostControllerPpiInstallationCallback (+  IN EFI_PEI_SERVICES
> **PeiServices,+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,+  IN
> VOID                       *Ppi+  )+{+  EDKII_ATA_AHCI_HOST_CONTROLLER_PPI
> *AhciHcPpi;++  if (Ppi == NULL) {+    return EFI_INVALID_PARAMETER;+  }++
> AhciHcPpi = (EDKII_ATA_AHCI_HOST_CONTROLLER_PPI *)Ppi;++  return
> AtaAhciInitPrivateDataFromHostControllerPpi (AhciHcPpi);+}++/**+  Initialize
> AHCI controller from fiven PCI_DEVICE_PPI.++  @param[in] PciDevice
> Pointer to the PCI Device PPI instance.++  @retval EFI_SUCCESS      The
> function completes successfully+  @retval Others           Cannot initialize AHCI
> controller for given
> device+**/+EFI_STATUS+AtaAhciInitPrivateDataFromPciDevice (+
> EDKII_PCI_DEVICE_PPI  *PciDevice+  )+{+  EFI_STATUS                Status;+
> PCI_TYPE00                PciData;+  UINTN                     MmioBase;+
> EFI_DEVICE_PATH_PROTOCOL  *DevicePath;+  UINTN
> DevicePathLength;+  UINT64                    EnabledPciAttributes;++  //+  // Now
> further check the PCI header: Base Class (offset 0x0B) and+  // Sub Class
> (offset 0x0A). This controller should be an SATA controller+  //+  Status =
> PciDevice->PciIo.Pci.Read (+                                  &PciDevice->PciIo,+
> EfiPciIoWidthUint8,+                                  PCI_CLASSCODE_OFFSET,+
> sizeof (PciData.Hdr.ClassCode),+
> PciData.Hdr.ClassCode+                                  );+  if (EFI_ERROR (Status)) {+
> return EFI_UNSUPPORTED;+  }++  if (!IS_PCI_IDE (&PciData)
> && !IS_PCI_SATADPA (&PciData)) {+    return EFI_UNSUPPORTED;+  }++
> Status = PciDevice->PciIo.Attributes (+                              &PciDevice->PciIo,+
> EfiPciIoAttributeOperationSupported,+                              0,+
> &EnabledPciAttributes+                              );+  if (EFI_ERROR (Status)) {+    return
> EFI_UNSUPPORTED;+  } else {+    EnabledPciAttributes &=
> (UINT64)EFI_PCI_DEVICE_ENABLE;+    Status                = PciDevice-
> >PciIo.Attributes (+                                               &PciDevice->PciIo,+
> EfiPciIoAttributeOperationEnable,+
> EnabledPciAttributes,+
> NULL+                                               );+    if (EFI_ERROR (Status)) {+      return
> EFI_UNSUPPORTED;+    }+  }++  Status = PciDevice->PciIo.Pci.Read (+
> &PciDevice->PciIo,+                                  EfiPciIoWidthUint32,+
> 0x24,+                                  sizeof (UINTN),+
> &MmioBase+                                  );+  if (EFI_ERROR (Status)) {+    return
> EFI_UNSUPPORTED;+  }++  DevicePathLength = GetDevicePathSize
> (PciDevice->DevicePath);+  DevicePath       = PciDevice->DevicePath;++
> Status = AtaAhciInitPrivateData (MmioBase, DevicePath,
> DevicePathLength);+  if (EFI_ERROR (Status)) {+    DEBUG ((+
> DEBUG_INFO,+      "%a: Failed to init controller, with Status - %r\n",+
> __FUNCTION__,+      Status+      ));+  }++  return EFI_SUCCESS;+}++/**+
> Callback for EDKII_PCI_DEVICE_PPI installation.++  @param[in] PeiServices
> Pointer to PEI Services Table.+  @param[in] NotifyDescriptor    Pointer to the
> descriptor for the Notification+                                 event that caused this
> function to execute.+  @param[in] Ppi                 Pointer to the PPI data
> associated with this function.++  @retval EFI_SUCCESS            The function
> completes successfully+  @retval Others                 Cannot initialize AHCI
> controller from given
> PCI_DEVICE_PPI++**/+EFI_STATUS+EFIAPI+AtaAhciPciDevicePpiInstallation
> Callback (+  IN EFI_PEI_SERVICES           **PeiServices,+  IN
> EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,+  IN VOID
> *Ppi+  )+{+  EDKII_PCI_DEVICE_PPI  *PciDevice;++  PciDevice =
> (EDKII_PCI_DEVICE_PPI *)Ppi;++  return
> AtaAhciInitPrivateDataFromPciDevice (PciDevice);+}++/**+  Entry point of
> the PEIM.++  @param[in] FileHandle     Handle of the file being invoked.+
> @param[in] PeiServices    Describes the list of possible PEI Services.++
> @retval EFI_SUCCESS    PPI successfully
> installed.++**/+EFI_STATUS+EFIAPI+AtaAhciPeimEntry (+  IN
> EFI_PEI_FILE_HANDLE     FileHandle,+  IN CONST EFI_PEI_SERVICES
> **PeiServices+  )+{+  DEBUG ((DEBUG_INFO, "%a: Enters.\n",
> __FUNCTION__));++  PeiServicesNotifyPpi
> (&mAtaAhciHostControllerNotify);++  PeiServicesNotifyPpi
> (&mPciDevicePpiNotify);++  return EFI_SUCCESS;+}diff --git
> a/MdeModulePkg/Bus/Ata/AhciPei/DevicePath.c
> b/MdeModulePkg/Bus/Ata/AhciPei/DevicePath.c
> index 81f8743d40d8..cf0955929dde 100644
> --- a/MdeModulePkg/Bus/Ata/AhciPei/DevicePath.c
> +++ b/MdeModulePkg/Bus/Ata/AhciPei/DevicePath.c
> @@ -38,50 +38,6 @@ EFI_DEVICE_PATH_PROTOCOL
> mAhciEndDevicePathNodeTemplate = {
>    } }; -/**-  Returns the 16-bit Length field of a device path node.--  Returns
> the 16-bit Length field of the device path node specified by Node.-  Node is
> not required to be aligned on a 16-bit boundary, so it is recommended-  that
> a function such as ReadUnaligned16() be used to extract the contents of-
> the Length field.--  If Node is NULL, then ASSERT().--  @param  Node      A
> pointer to a device path node data structure.--  @return The 16-bit Length
> field of the device path node specified by Node.--**/-UINTN-
> DevicePathNodeLength (-  IN CONST VOID  *Node-  )-{-  ASSERT (Node !=
> NULL);-  return ReadUnaligned16 ((UINT16
> *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);-}--/**-  Returns
> a pointer to the next node in a device path.--  If Node is NULL, then
> ASSERT().--  @param  Node    A pointer to a device path node data structure.-
> -  @return a pointer to the device path node that follows the device path
> node-  specified by Node.--**/-EFI_DEVICE_PATH_PROTOCOL *-
> NextDevicePathNode (-  IN CONST VOID  *Node-  )-{-  ASSERT (Node !=
> NULL);-  return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) +
> DevicePathNodeLength (Node));-}- /**   Get the size of the current device
> path instance. diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h
> b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h
> index 43ad4639bd77..4aed1cb7ad8a 100644
> --- a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h
> +++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.h
> @@ -29,6 +29,7 @@
>  #include <Library/BaseMemoryLib.h> #include <Library/IoLib.h> #include
> <Library/TimerLib.h>+#include <Library/DevicePathLib.h>  // // Structure
> forward declarations@@ -354,6 +355,46 @@ extern UINT32
> mMaxTransferBlockNumber[2];
>  // Internal functions // +/**+  Callback for
> EDKII_ATA_AHCI_HOST_CONTROLLER_PPI installation.++  @param[in]
> PeiServices         Pointer to PEI Services Table.+  @param[in] NotifyDescriptor
> Pointer to the descriptor for the Notification+                                 event that
> caused this function to execute.+  @param[in] Ppi                 Pointer to the PPI
> data associated with this function.++  @retval EFI_SUCCESS            The
> function completes successfully+  @retval Others                 Cannot initialize
> AHCI controller from given
> EDKII_ATA_AHCI_HOST_CONTROLLER_PPI++**/+EFI_STATUS+EFIAPI+AtaA
> hciHostControllerPpiInstallationCallback (+  IN EFI_PEI_SERVICES
> **PeiServices,+  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,+  IN
> VOID                       *Ppi+  );++/**+  Callback for EDKII_PCI_DEVICE_PPI
> installation.++  @param[in] PeiServices         Pointer to PEI Services Table.+
> @param[in] NotifyDescriptor    Pointer to the descriptor for the Notification+
> event that caused this function to execute.+  @param[in] Ppi                 Pointer
> to the PPI data associated with this function.++  @retval EFI_SUCCESS
> The function completes successfully+  @retval Others                 Cannot
> initialize AHCI controller from given
> PCI_DEVICE_PPI++**/+EFI_STATUS+EFIAPI+AtaAhciPciDevicePpiInstallation
> Callback (+  IN EFI_PEI_SERVICES           **PeiServices,+  IN
> EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,+  IN VOID
> *Ppi+  );+ /**   Allocates pages that are suitable for an
> OperationBusMasterCommonBuffer or
> OperationBusMasterCommonBuffer64 mapping.@@ -631,22 +672,6 @@
> TrustTransferAtaDevice (
>    OUT    UINTN                     *TransferLengthOut   ); -/**-  Returns a pointer to
> the next node in a device path.--  If Node is NULL, then ASSERT().--  @param
> Node    A pointer to a device path node data structure.--  @return a pointer
> to the device path node that follows the device path node-  specified by
> Node.--**/-EFI_DEVICE_PATH_PROTOCOL *-NextDevicePathNode (-  IN
> CONST VOID  *Node-  );- /**   Get the size of the current device path
> instance. diff --git a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf
> b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf
> index 912ff7a8ba4f..788660b33299 100644
> --- a/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf
> +++ b/MdeModulePkg/Bus/Ata/AhciPei/AhciPei.inf
> @@ -50,11 +50,13 @@ [LibraryClasses]
>    TimerLib   LockBoxLib   PeimEntryPoint+  DevicePathLib  [Ppis]
> gEdkiiPeiAtaAhciHostControllerPpiGuid          ## CONSUMES
> gEdkiiIoMmuPpiGuid                             ## CONSUMES
> gEfiEndOfPeiSignalPpiGuid                      ## CONSUMES+
> gEdkiiPeiPciDevicePpiGuid                      ## CONSUMES
> gEdkiiPeiAtaPassThruPpiGuid                    ## SOMETIMES_PRODUCES
> gEfiPeiVirtualBlockIoPpiGuid                   ## SOMETIMES_PRODUCES
> gEfiPeiVirtualBlockIo2PpiGuid                  ## SOMETIMES_PRODUCES@@ -65,8
> +67,7 @@ [Guids]
>   [Depex]   gEfiPeiMemoryDiscoveredPpiGuid AND-
> gEfiPeiMasterBootModePpiGuid AND-
> gEdkiiPeiAtaAhciHostControllerPpiGuid+  gEfiPeiMasterBootModePpiGuid
> [UserExtensions.TianoCore."ExtraFiles"]   AhciPeiExtra.unidiff --git
> a/MdeModulePkg/MdeModulePkg.dsc
> b/MdeModulePkg/MdeModulePkg.dsc
> index 90a0a7ec4a7c..45a8ec84ad69 100644
> --- a/MdeModulePkg/MdeModulePkg.dsc
> +++ b/MdeModulePkg/MdeModulePkg.dsc
> @@ -117,6 +117,7 @@ [LibraryClasses.common.PEIM]
> 
> MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemory
> AllocationLib.inf
> ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiEx
> tractGuidedSectionLib.inf
> LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf
> +
> DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibBase.i
> nf  [LibraryClasses.common.DXE_CORE]
> HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf--
> 2.27.0.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#92038): https://edk2.groups.io/g/devel/message/92038
Mute This Topic: https://groups.io/mt/92752850/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-