Duran

Could you explain more about this fix? 

1) What's the meaning of PCI emulation here? 
2) What's the difference between normal case and this PCI emulation?
3) Why this PCI emulation case needs to update driver to directly use PCI 
address for filling transfer descriptor content?

Thanks
Feng

-----Original Message-----
From: edk2-devel [mailto:edk2-devel-boun...@lists.01.org] On Behalf Of Leo Duran
Sent: Friday, March 25, 2016 4:30 AM
To: edk2-devel@lists.01.org
Cc: Leo Duran; Leendert van Doorn; leif.lindh...@linaro.org; 
ard.biesheu...@linaro.org
Subject: [edk2] [PATCH] MdeModulePkg: support AHCI controller using PCI 
emulation

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|BOOLEA
+ N|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
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to