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