From: Leendert van Doorn <leend...@paramecium.org>

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Leo Duran <leo.du...@amd.com>
---
 MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c   | 88 +++++++++++++++++-----
 .../Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf  |  1 +
 MdeModulePkg/MdeModulePkg.dec                      |  6 ++
 3 files changed, 75 insertions(+), 20 deletions(-)

diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c 
b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
index f64a340..0c8887c 100644
--- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
+++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AhciMode.c
@@ -529,6 +529,7 @@ AhciBuildCommand (
   UINTN      MemAddr;
   DATA_64    Data64;
   UINT32     Offset;
+  BOOLEAN    PciEmulation = PcdGetBool (PcdAtaPassThruPciEmulation);
 
   //
   // Filling the PRDT
@@ -542,22 +543,32 @@ AhciBuildCommand (
   //
   ASSERT (PrdtNumber <= 65535);
 
-  Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFis) + sizeof 
(EFI_AHCI_RECEIVED_FIS) * Port;
+  if (PciEmulation)
+    Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFisPciAddr) + sizeof 
(EFI_AHCI_RECEIVED_FIS) * Port;
+  else
+    Data64.Uint64 = (UINTN) (AhciRegisters->AhciRFis) + sizeof 
(EFI_AHCI_RECEIVED_FIS) * Port;
 
   BaseAddr = Data64.Uint64;
 
   ZeroMem ((VOID *)((UINTN) BaseAddr), sizeof (EFI_AHCI_RECEIVED_FIS));
 
-  ZeroMem (AhciRegisters->AhciCommandTable, sizeof (EFI_AHCI_COMMAND_TABLE));
+  if (PciEmulation)
+    ZeroMem (AhciRegisters->AhciCommandTablePciAddr, sizeof 
(EFI_AHCI_COMMAND_TABLE));
+  else
+    ZeroMem (AhciRegisters->AhciCommandTable, sizeof (EFI_AHCI_COMMAND_TABLE));
 
   CommandFis->AhciCFisPmNum = PortMultiplier;
 
-  CopyMem (&AhciRegisters->AhciCommandTable->CommandFis, CommandFis, sizeof 
(EFI_AHCI_COMMAND_FIS));
+  if (PciEmulation)
+    CopyMem (&AhciRegisters->AhciCommandTablePciAddr->CommandFis, CommandFis, 
sizeof (EFI_AHCI_COMMAND_FIS));
+  else
+    CopyMem (&AhciRegisters->AhciCommandTable->CommandFis, CommandFis, sizeof 
(EFI_AHCI_COMMAND_FIS));
 
   Offset = EFI_AHCI_PORT_START + Port * EFI_AHCI_PORT_REG_WIDTH + 
EFI_AHCI_PORT_CMD;
   if (AtapiCommand != NULL) {
     CopyMem (
-      &AhciRegisters->AhciCommandTable->AtapiCmd,
+      PciEmulation ? &AhciRegisters->AhciCommandTablePciAddr->AtapiCmd :
+                     &AhciRegisters->AhciCommandTable->AtapiCmd,
       AtapiCommand,
       AtapiCommandLength
       );
@@ -576,14 +587,26 @@ AhciBuildCommand (
 
   for (PrdtIndex = 0; PrdtIndex < PrdtNumber; PrdtIndex++) {
     if (RemainedData < EFI_AHCI_MAX_DATA_PER_PRDT) {
-      AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = 
(UINT32)RemainedData - 1;
+      if (PciEmulation)
+        
AhciRegisters->AhciCommandTablePciAddr->PrdtTable[PrdtIndex].AhciPrdtDbc = 
(UINT32)RemainedData - 1;
+      else
+        AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = 
(UINT32)RemainedData - 1;
     } else {
-      AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = 
EFI_AHCI_MAX_DATA_PER_PRDT - 1;
+      if (PciEmulation)
+        
AhciRegisters->AhciCommandTablePciAddr->PrdtTable[PrdtIndex].AhciPrdtDbc = 
EFI_AHCI_MAX_DATA_PER_PRDT - 1;
+      else
+        AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbc = 
EFI_AHCI_MAX_DATA_PER_PRDT - 1;
     }
 
     Data64.Uint64 = (UINT64)MemAddr;
-    AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDba  = 
Data64.Uint32.Lower32;
-    AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbau = 
Data64.Uint32.Upper32;
+    if (PciEmulation) {
+      AhciRegisters->AhciCommandTablePciAddr->PrdtTable[PrdtIndex].AhciPrdtDba 
 = Data64.Uint32.Lower32;
+      
AhciRegisters->AhciCommandTablePciAddr->PrdtTable[PrdtIndex].AhciPrdtDbau = 
Data64.Uint32.Upper32;
+    } else {
+      AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDba  = 
Data64.Uint32.Lower32;
+      AhciRegisters->AhciCommandTable->PrdtTable[PrdtIndex].AhciPrdtDbau = 
Data64.Uint32.Upper32;
+    }
+
     RemainedData -= EFI_AHCI_MAX_DATA_PER_PRDT;
     MemAddr      += EFI_AHCI_MAX_DATA_PER_PRDT;
   }
@@ -592,19 +615,29 @@ AhciBuildCommand (
   // Set the last PRDT to Interrupt On Complete
   //
   if (PrdtNumber > 0) {
-    AhciRegisters->AhciCommandTable->PrdtTable[PrdtNumber - 1].AhciPrdtIoc = 1;
+    if (PciEmulation)
+      AhciRegisters->AhciCommandTablePciAddr->PrdtTable[PrdtNumber - 
1].AhciPrdtIoc = 1;
+    else
+      AhciRegisters->AhciCommandTable->PrdtTable[PrdtNumber - 1].AhciPrdtIoc = 
1;
   }
 
   CopyMem (
-    (VOID *) ((UINTN) AhciRegisters->AhciCmdList + (UINTN) CommandSlotNumber * 
sizeof (EFI_AHCI_COMMAND_LIST)),
+    PciEmulation ? (VOID *) ((UINTN) AhciRegisters->AhciCmdListPciAddr + 
(UINTN) CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)) :
+                   (VOID *) ((UINTN) AhciRegisters->AhciCmdList + (UINTN) 
CommandSlotNumber * sizeof (EFI_AHCI_COMMAND_LIST)),
     CommandList,
     sizeof (EFI_AHCI_COMMAND_LIST)
     );
 
   Data64.Uint64 = (UINT64)(UINTN) AhciRegisters->AhciCommandTablePciAddr;
-  AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba  = 
Data64.Uint32.Lower32;
-  AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtbau = 
Data64.Uint32.Upper32;
-  AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdPmp   = PortMultiplier;
+  if (PciEmulation) {
+    AhciRegisters->AhciCmdListPciAddr[CommandSlotNumber].AhciCmdCtba  = 
Data64.Uint32.Lower32;
+    AhciRegisters->AhciCmdListPciAddr[CommandSlotNumber].AhciCmdCtbau = 
Data64.Uint32.Upper32;
+    AhciRegisters->AhciCmdListPciAddr[CommandSlotNumber].AhciCmdPmp   = 
PortMultiplier;
+  } else {
+    AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba  = 
Data64.Uint32.Lower32;
+    AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtbau = 
Data64.Uint32.Upper32;
+    AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdPmp   = 
PortMultiplier;
+  }
 
 }
 
@@ -707,6 +740,7 @@ AhciPioTransfer (
   BOOLEAN                       InfiniteWait;
   BOOLEAN                       PioFisReceived;
   BOOLEAN                       D2hFisReceived;
+  BOOLEAN                       PciEmulation = PcdGetBool 
(PcdAtaPassThruPciEmulation);
 
   if (Timeout == 0) {
     InfiniteWait = TRUE;
@@ -774,7 +808,10 @@ AhciPioTransfer (
   //
   // Check the status and wait the driver sending data
   //
-  FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof 
(EFI_AHCI_RECEIVED_FIS);
+  if (PciEmulation)
+    FisBaseAddr = (UINTN)AhciRegisters->AhciRFisPciAddr + Port * sizeof 
(EFI_AHCI_RECEIVED_FIS);
+  else
+    FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof 
(EFI_AHCI_RECEIVED_FIS);
 
   if (Read && (AtapiCommand == 0)) {
     //
@@ -814,7 +851,10 @@ AhciPioTransfer (
           break;
         }
 
-        PrdCount = *(volatile UINT32 *) 
(&(AhciRegisters->AhciCmdList[0].AhciCmdPrdbc));
+        if (PciEmulation)
+          PrdCount = *(volatile UINT32 *) 
(&(AhciRegisters->AhciCmdListPciAddr[0].AhciCmdPrdbc));
+        else
+          PrdCount = *(volatile UINT32 *) 
(&(AhciRegisters->AhciCmdList[0].AhciCmdPrdbc));
         if (PrdCount == DataCount) {
           Status = EFI_SUCCESS;
           break;
@@ -930,7 +970,6 @@ AhciDmaTransfer (
   EFI_AHCI_COMMAND_LIST         CmdList;
   UINTN                         FisBaseAddr;
   UINT32                        PortTfd;
-
   EFI_PCI_IO_PROTOCOL           *PciIo;
   EFI_TPL                       OldTpl;
 
@@ -1025,9 +1064,12 @@ AhciDmaTransfer (
   }
 
   //
-  // Wait for command compelte
+  // Wait for command complete
   //
-  FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof 
(EFI_AHCI_RECEIVED_FIS);
+  if (PcdGetBool (PcdAtaPassThruPciEmulation))
+    FisBaseAddr = (UINTN)AhciRegisters->AhciRFisPciAddr + Port * sizeof 
(EFI_AHCI_RECEIVED_FIS);
+  else
+    FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof 
(EFI_AHCI_RECEIVED_FIS);
   Offset      = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;
   if (Task != NULL) {
     //
@@ -1175,7 +1217,10 @@ AhciNonDataTransfer (
   //
   // Wait device sends the Response Fis
   //
-  FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof 
(EFI_AHCI_RECEIVED_FIS);
+  if (PcdGetBool (PcdAtaPassThruPciEmulation))
+    FisBaseAddr = (UINTN)AhciRegisters->AhciRFisPciAddr + Port * sizeof 
(EFI_AHCI_RECEIVED_FIS);
+  else
+    FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof 
(EFI_AHCI_RECEIVED_FIS);
   Offset      = FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET;
   Status      = AhciWaitMemSet (
                   Offset,
@@ -1544,7 +1589,10 @@ AhciAtaSmartReturnStatusCheck (
     (EFI_IO_BUS_ATA_ATAPI | EFI_IOB_ATA_BUS_SMART_ENABLE)
     );
 
-  FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof 
(EFI_AHCI_RECEIVED_FIS);
+  if (PcdGetBool (PcdAtaPassThruPciEmulation))
+    FisBaseAddr = (UINTN)AhciRegisters->AhciRFisPciAddr + Port * sizeof 
(EFI_AHCI_RECEIVED_FIS);
+  else
+    FisBaseAddr = (UINTN)AhciRegisters->AhciRFis + Port * sizeof 
(EFI_AHCI_RECEIVED_FIS);
 
   Value = *(UINT32 *) (FisBaseAddr + EFI_AHCI_D2H_FIS_OFFSET);
 
diff --git a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf 
b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
index 82d5f7a..e999a14 100644
--- a/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+++ b/MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
@@ -70,6 +70,7 @@
 
 [Pcd]
   gEfiMdeModulePkgTokenSpaceGuid.PcdAtaSmartEnable   ## SOMETIMES_CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAtaPassThruPciEmulation ## CONSUMES
 
 # [Event]
 # EVENT_TYPE_PERIODIC_TIMER ## SOMETIMES_CONSUMES
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 61db352..5f96cf1 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -1401,6 +1401,12 @@
   # @Prompt Enable ATA S.M.A.R.T feature.
   gEfiMdeModulePkgTokenSpaceGuid.PcdAtaSmartEnable|TRUE|BOOLEAN|0x00010065
 
+  ## Indicates if PCI emulation is enabled for ATA PassThru.<BR><BR>
+  #   TRUE  - PCI emulation for ATA PassThru is enabled.<BR>
+  #   FALSE - PCI emulation for ATA PassThru is disabled.<BR>
+  # @Prompt Enable PCI emulation for ATA PassThru.
+  
gEfiMdeModulePkgTokenSpaceGuid.PcdAtaPassThruPciEmulation|FALSE|BOOLEAN|0x00010080
+
   ## Indicates if full PCI enumeration is disabled.<BR><BR>
   #   TRUE  - Full PCI enumeration is disabled.<BR>
   #   FALSE - Full PCI enumeration is not disabled.<BR>
-- 
1.9.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to