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