Leendert, et al I added the 'PciEmulation' clause to be sure the new code was used only as a result of explicitly setting PcdAtaPassThruPciEmulation = TRUE. (And yes, I " wanted to be cautious and not break the other uses of this driver")
Leo -----Original Message----- From: Leendert van Doorn [mailto:leend...@paramecium.org] Sent: Friday, March 25, 2016 3:28 AM To: Tian, Feng; Duran, Leo; edk2-devel@lists.01.org Cc: leif.lindh...@linaro.org; ard.biesheu...@linaro.org Subject: Re: [edk2] [PATCH] MdeModulePkg: support AHCI controller using PCI emulation Wow, this is a blast from the past. One of my Friday afternoon hacking projects is seeing the light of day ☺ Not all of this patch is mine though, I didn’t add the if (PciEmulation) clauses and they aren’t needed as far as I remember. The problem that part of this code solves is that Map() can return a different device address than the input host address. The Arm implementation of DmaLib has cases where this can occur, specifically when I/O needs to use uncached memory and the source is in cached memory. The original AHCI driver however used the host address in places where it should be using the device address. This patch fixes that. On x86 this bug wasn’t a problem because the two are always the same but on ARM systems that may not be the case (See ArmPkg/…/DmaLib). My original patch fixed this driver to consistently use device address as returned by Map(). I’m not sure why the if (PciEmulation) clauses were added. Presumably someone wanted to be cautious and not break the other uses of this driver. The way I remember the driver and DmaLib logic that shouldn’t be necessary. Leendert On 3/24/16, 5:50 PM, "Tian, Feng" <feng.t...@intel.com> wrote: >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|0x0001006 >5 > >+ ## 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|BOOLE >+ A >+ 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