13#define ATA_CMD_TRUST_NON_DATA 0x5B
14#define ATA_CMD_TRUST_RECEIVE 0x5C
15#define ATA_CMD_TRUST_SEND 0x5E
20EFI_ATA_PASS_THRU_CMD_PROTOCOL mAtaPassThruCmdProtocols[2] = {
21 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN,
22 EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT
28UINT8 mAtaCommands[2][2] = {
42UINT8 mAtaTrustCommands[2] = {
43 ATA_CMD_TRUST_RECEIVE,
50#define MAX_28BIT_TRANSFER_BLOCK_NUM 0x100
57#define MAX_48BIT_TRANSFER_BLOCK_NUM 0x800
59UINT32 mMaxTransferBlockNumber[2] = {
60 MAX_28BIT_TRANSFER_BLOCK_NUM,
61 MAX_48BIT_TRANSFER_BLOCK_NUM
67#define MAX_28BIT_ADDRESSING_CAPACITY 0xfffffff
183 Delay = (UINT32)(
DivU64x32 (Timeout, 1000) + 1);
188 if (Value == TestValue) {
223 Value = *(
volatile UINT32 *)Address;
226 if (Value == TestValue) {
229 return EFI_NOT_READY;
255 BOOLEAN InfiniteWait;
260 InfiniteWait =
FALSE;
274 Value = *(
volatile UINT32 *)(
UINTN)Address;
277 if (Value == TestValue) {
287 }
while (InfiniteWait || (Delay > 0));
312 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SERR;
318 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_IS;
348 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
349 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_FRE);
377 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
384 if ((Data & (AHCI_PORT_CMD_ST | AHCI_PORT_CMD_CR)) != 0) {
385 return EFI_UNSUPPORTED;
391 if ((Data & AHCI_PORT_CMD_FR) != AHCI_PORT_CMD_FR) {
395 AhciAndReg (AhciBar, Offset, (UINT32) ~(AHCI_PORT_CMD_FRE));
425 IN UINT8 PortMultiplier,
429 IN UINT8 CommandSlotNumber,
430 IN OUT VOID *DataPhysicalAddr,
444 AhciRegisters = &Private->AhciRegisters;
445 AhciBar = Private->MmioBase;
451 (UINT64)DataLength + AHCI_MAX_DATA_PER_PRDT - 1,
452 AHCI_MAX_DATA_PER_PRDT
462 ASSERT (PrdtNumber <= AHCI_MAX_PRDT_NUMBER);
463 if (PrdtNumber > AHCI_MAX_PRDT_NUMBER) {
469 BaseAddr = Data64.Uint64;
475 CommandFis->AhciCFisPmNum = PortMultiplier;
479 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
480 AhciAndReg (AhciBar, Offset, (UINT32) ~(AHCI_PORT_CMD_DLAE | AHCI_PORT_CMD_ATAPI));
482 RemainedData = (
UINTN)DataLength;
483 MemAddr = (
UINTN)DataPhysicalAddr;
484 CommandList->AhciCmdPrdtl = PrdtNumber;
486 for (PrdtIndex = 0; PrdtIndex < PrdtNumber; PrdtIndex++) {
487 if (RemainedData < AHCI_MAX_DATA_PER_PRDT) {
488 AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDbc = (UINT32)RemainedData - 1;
490 AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDbc = AHCI_MAX_DATA_PER_PRDT - 1;
493 Data64.Uint64 = (UINT64)MemAddr;
494 AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDba = Data64.Uint32.Lower32;
495 AhciRegisters->AhciCmdTable->PrdtTable[PrdtIndex].AhciPrdtDbau = Data64.Uint32.Upper32;
496 RemainedData -= AHCI_MAX_DATA_PER_PRDT;
497 MemAddr += AHCI_MAX_DATA_PER_PRDT;
503 if (PrdtNumber > 0) {
504 AhciRegisters->AhciCmdTable->PrdtTable[PrdtNumber - 1].AhciPrdtIoc = 1;
513 Data64.Uint64 = (UINT64)(
UINTN)AhciRegisters->AhciCmdTable;
514 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtba = Data64.Uint32.Lower32;
515 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdCtbau = Data64.Uint32.Upper32;
516 AhciRegisters->AhciCmdList[CommandSlotNumber].AhciCmdPmp = PortMultiplier;
536 CmdFis->AhciCFisType = AHCI_FIS_REGISTER_H2D;
540 CmdFis->AhciCFisCmdInd = 0x1;
541 CmdFis->AhciCFisCmd = AtaCommandBlock->AtaCommand;
543 CmdFis->AhciCFisFeature = AtaCommandBlock->AtaFeatures;
544 CmdFis->AhciCFisFeatureExp = AtaCommandBlock->AtaFeaturesExp;
546 CmdFis->AhciCFisSecNum = AtaCommandBlock->AtaSectorNumber;
547 CmdFis->AhciCFisSecNumExp = AtaCommandBlock->AtaSectorNumberExp;
549 CmdFis->AhciCFisClyLow = AtaCommandBlock->AtaCylinderLow;
550 CmdFis->AhciCFisClyLowExp = AtaCommandBlock->AtaCylinderLowExp;
552 CmdFis->AhciCFisClyHigh = AtaCommandBlock->AtaCylinderHigh;
553 CmdFis->AhciCFisClyHighExp = AtaCommandBlock->AtaCylinderHighExp;
555 CmdFis->AhciCFisSecCount = AtaCommandBlock->AtaSectorCount;
556 CmdFis->AhciCFisSecCountExp = AtaCommandBlock->AtaSectorCountExp;
558 CmdFis->AhciCFisDevHead = (UINT8)(AtaCommandBlock->AtaDeviceHead | 0xE0);
583 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
586 if ((Data & (AHCI_PORT_CMD_ST | AHCI_PORT_CMD_CR)) == 0) {
590 if ((Data & AHCI_PORT_CMD_ST) != 0) {
591 AhciAndReg (AhciBar, Offset, (UINT32) ~(AHCI_PORT_CMD_ST));
620 IN UINT8 CommandSlot,
635 Capability =
AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
637 CmdSlotBit = (UINT32)(1 << CommandSlot);
649 if (EFI_ERROR (Status)) {
653 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
657 if ((PortStatus & AHCI_PORT_CMD_ALPE) != 0) {
659 StartCmd &= ~AHCI_PORT_CMD_ICC_MASK;
660 StartCmd |= AHCI_PORT_CMD_ACTIVE;
663 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
666 if ((PortTfd & (AHCI_PORT_TFD_BSY | AHCI_PORT_TFD_DRQ)) != 0) {
667 if ((Capability & BIT24) != 0) {
668 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
669 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_CLO);
681 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
682 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_ST | StartCmd);
687 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CI;
720 IN UINT8 PortMultiplier,
725 IN OUT VOID *MemoryAddr,
737 BOOLEAN InfiniteWait;
750 BOOLEAN PioFisReceived;
751 BOOLEAN D2hFisReceived;
757 if (DataCount / (UINT32)AHCI_MAX_PRDT_NUMBER > AHCI_MAX_DATA_PER_PRDT) {
760 "%a: Driver only support a maximum of 0x%x PRDT entries, "
761 "current number of data byte 0x%x is too large, maximum allowed is 0x%x.\n",
763 AHCI_MAX_PRDT_NUMBER,
765 AHCI_MAX_PRDT_NUMBER * AHCI_MAX_DATA_PER_PRDT
767 return EFI_UNSUPPORTED;
772 MapLength = DataCount;
780 if (EFI_ERROR (Status) || (MapLength != DataCount)) {
781 DEBUG ((DEBUG_ERROR,
"%a: Fail to map data buffer.\n", __func__));
782 return EFI_OUT_OF_RESOURCES;
785 AhciRegisters = &Private->AhciRegisters;
786 AhciBar = Private->MmioBase;
787 InfiniteWait = (Timeout == 0) ?
TRUE :
FALSE;
792 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
794 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
797 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
799 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
805 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
807 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
809 Data64.Uint64 = (
UINTN)(AhciRegisters->AhciCmdList);
810 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
812 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
822 CmdList.AhciCmdCfl = AHCI_FIS_REGISTER_H2D_LENGTH / 4;
823 CmdList.AhciCmdW = Read ? 0 : 1;
833 (VOID *)(
UINTN)PhyAddr,
843 if (EFI_ERROR (Status)) {
855 Status = EFI_TIMEOUT;
856 Delay = (UINT32)
DivU64x32 (Timeout, 1000) + 1;
858 PioFisReceived =
FALSE;
859 D2hFisReceived =
FALSE;
860 Offset = FisBaseAddr + AHCI_PIO_FIS_OFFSET;
861 Status =
AhciCheckMemSet (Offset, AHCI_FIS_TYPE_MASK, AHCI_FIS_PIO_SETUP);
862 if (!EFI_ERROR (Status)) {
863 DEBUG ((DEBUG_INFO,
"%a: PioFisReceived.\n", __func__));
864 PioFisReceived =
TRUE;
874 Offset = FisBaseAddr + AHCI_D2H_FIS_OFFSET;
875 Status =
AhciCheckMemSet (Offset, AHCI_FIS_TYPE_MASK, AHCI_FIS_REGISTER_D2H);
876 if (!EFI_ERROR (Status)) {
877 DEBUG ((DEBUG_INFO,
"%a: D2hFisReceived.\n", __func__));
878 D2hFisReceived =
TRUE;
881 if (PioFisReceived || D2hFisReceived) {
882 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
887 if ((PortTfd & AHCI_PORT_TFD_ERR) != 0) {
888 Status = EFI_DEVICE_ERROR;
892 PrdCount = *(
volatile UINT32 *)(&(AhciRegisters->AhciCmdList[0].AhciCmdPrdbc));
893 if (PrdCount == DataCount) {
906 Status = EFI_TIMEOUT;
908 }
while (InfiniteWait || (Delay > 0));
913 Offset = FisBaseAddr + AHCI_D2H_FIS_OFFSET;
917 AHCI_FIS_REGISTER_D2H,
920 if (EFI_ERROR (Status)) {
921 DEBUG ((DEBUG_ERROR,
"%a: AhciWaitMemSet (%r)\n", __func__, Status));
925 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
927 if ((PortTfd & AHCI_PORT_TFD_ERR) != 0) {
928 Status = EFI_DEVICE_ERROR;
945 if (MapData !=
NULL) {
949 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
951 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
954 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
956 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
984 IN UINT8 PortMultiplier,
1000 AhciBar = Private->MmioBase;
1001 AhciRegisters = &Private->AhciRegisters;
1010 CmdList.AhciCmdCfl = AHCI_FIS_REGISTER_H2D_LENGTH / 4;
1030 if (EFI_ERROR (Status)) {
1038 Offset = FisBaseAddr + AHCI_D2H_FIS_OFFSET;
1042 AHCI_FIS_REGISTER_D2H,
1046 if (EFI_ERROR (Status)) {
1050 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
1052 if ((PortTfd & AHCI_PORT_TFD_ERR) != 0) {
1053 Status = EFI_DEVICE_ERROR;
1096 Capability =
AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
1101 if ((Capability & AHCI_CAP_SAM) == 0) {
1102 AhciOrReg (AhciBar, AHCI_GHC_OFFSET, AHCI_GHC_ENABLE);
1105 AhciOrReg (AhciBar, AHCI_GHC_OFFSET, AHCI_GHC_RESET);
1107 Delay = (UINT32)(
DivU64x32 (Timeout, 1000) + 1);
1111 if ((Value & AHCI_GHC_RESET) == 0) {
1121 }
while (Delay > 0);
1146 IN UINT8 PortMultiplier,
1155 if (Buffer ==
NULL) {
1156 return EFI_INVALID_PARAMETER;
1163 Acb.AtaSectorCount = 1;
1191 IN UINT32 PortBitMap
1194 UINT8 NumberOfPorts;
1198 while (PortBitMap != 0) {
1199 if ((PortBitMap & ((UINT32)BIT0)) != 0) {
1203 PortBitMap = PortBitMap >> 1;
1206 return NumberOfPorts;
1223 IN UINT32 PortBitMap,
1228 if (PortIndex == 0) {
1229 return EFI_NOT_FOUND;
1234 while (PortBitMap != 0) {
1235 if ((PortBitMap & ((UINT32)BIT0)) != 0) {
1241 if (PortIndex == 0) {
1246 PortBitMap = PortBitMap >> 1;
1250 return EFI_NOT_FOUND;
1274 UINT32 PortImplementBitMap;
1275 UINT8 MaxPortNumber;
1276 UINT8 MaxCommandSlotNumber;
1278 UINTN MaxCmdListSize;
1279 UINTN MaxCmdTableSize;
1281 AhciBar = Private->MmioBase;
1282 AhciRegisters = &Private->AhciRegisters;
1287 Capability =
AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
1292 MaxCommandSlotNumber = (UINT8)(((Capability & 0x1F00) >> 8) + 1);
1293 ASSERT (MaxCommandSlotNumber > 0);
1294 if (MaxCommandSlotNumber == 0) {
1295 return EFI_DEVICE_ERROR;
1302 PortImplementBitMap =
AhciReadReg (AhciBar, AHCI_PI_OFFSET);
1304 if (MaxPortNumber == 0) {
1305 return EFI_DEVICE_ERROR;
1323 if (EFI_ERROR (Status)) {
1324 return EFI_OUT_OF_RESOURCES;
1328 AhciRegisters->AhciRFis = Base;
1329 AhciRegisters->AhciRFisMap = Mapping;
1330 AhciRegisters->MaxRFisSize = MaxRFisSize;
1345 if (EFI_ERROR (Status)) {
1346 Status = EFI_OUT_OF_RESOURCES;
1351 AhciRegisters->AhciCmdList = Base;
1352 AhciRegisters->AhciCmdListMap = Mapping;
1353 AhciRegisters->MaxCmdListSize = MaxCmdListSize;
1367 if (EFI_ERROR (Status)) {
1368 Status = EFI_OUT_OF_RESOURCES;
1373 AhciRegisters->AhciCmdTable = Base;
1374 AhciRegisters->AhciCmdTableMap = Mapping;
1375 AhciRegisters->MaxCmdTableSize = MaxCmdTableSize;
1381 if (AhciRegisters->AhciRFisMap !=
NULL) {
1384 AhciRegisters->AhciRFis,
1385 AhciRegisters->AhciRFisMap
1387 AhciRegisters->AhciRFis =
NULL;
1390 if (AhciRegisters->AhciCmdListMap !=
NULL) {
1393 AhciRegisters->AhciCmdList,
1394 AhciRegisters->AhciCmdListMap
1396 AhciRegisters->AhciCmdList =
NULL;
1423 if ((IdentifyData->command_set_supported_83 & BIT10) == 0) {
1434 for (Index = 0; Index < 4; Index++) {
1438 TmpLba = IdentifyData->maximum_lba_for_48bit_addressing[Index];
1439 Capacity |=
LShiftU64 (TmpLba, 16 * Index);
1472 UINT32 MaxSectorCount;
1473 UINT16 PhyLogicSectorSupport;
1475 IdentifyData = DeviceData->IdentifyData;
1476 Media = &DeviceData->Media;
1478 if ((IdentifyData->
config & BIT15) != 0) {
1481 "%a: Not a hard disk device on Port 0x%x PortMultiplierPort 0x%x\n",
1484 DeviceData->PortMultiplier
1486 return EFI_UNSUPPORTED;
1491 "%a: Identify Device: Port 0x%x PortMultiplierPort 0x%x\n",
1494 DeviceData->PortMultiplier
1506 if (Capacity > MAX_28BIT_ADDRESSING_CAPACITY) {
1510 DeviceData->Lba48Bit =
TRUE;
1515 Capacity = ((UINT32)IdentifyData->user_addressable_sectors_hi << 16) |
1516 IdentifyData->user_addressable_sectors_lo;
1517 DeviceData->Lba48Bit =
FALSE;
1520 if (Capacity == 0) {
1521 DEBUG ((DEBUG_ERROR,
"%a: Invalid Capacity (0) for ATA device.\n", __func__));
1522 return EFI_UNSUPPORTED;
1534 "%a: PhyLogicSectorSupport = 0x%x\n",
1536 PhyLogicSectorSupport
1538 if ((PhyLogicSectorSupport & (BIT14 | BIT15)) == BIT14) {
1542 if ((PhyLogicSectorSupport & BIT12) != 0) {
1551 MaxSectorCount = mMaxTransferBlockNumber[DeviceData->Lba48Bit];
1553 DEBUG ((DEBUG_ERROR,
"%a: Invalid BlockSize (0x%x).\n", __func__, Media->
BlockSize));
1554 return EFI_UNSUPPORTED;
1559 "%a: BlockSize = 0x%x, LastBlock = 0x%lx\n",
1565 if ((IdentifyData->trusted_computing_support & BIT0) != 0) {
1566 DEBUG ((DEBUG_INFO,
"%a: Found Trust Computing feature support.\n", __func__));
1567 DeviceData->TrustComputing =
TRUE;
1606 IN UINT16 PortMultiplier,
1615 if (DeviceData ==
NULL) {
1616 return EFI_OUT_OF_RESOURCES;
1619 if (IdentifyData !=
NULL) {
1621 if (DeviceData->IdentifyData ==
NULL) {
1622 return EFI_OUT_OF_RESOURCES;
1626 DeviceData->Signature = AHCI_PEI_ATA_DEVICE_DATA_SIGNATURE;
1627 DeviceData->Port = Port;
1628 DeviceData->PortMultiplier = PortMultiplier;
1629 DeviceData->FisIndex = FisIndex;
1630 DeviceData->DeviceIndex = DeviceIndex;
1631 DeviceData->Private = Private;
1634 if (EFI_ERROR (Status)) {
1638 if (DeviceData->TrustComputing) {
1639 Private->TrustComputingDevices++;
1640 DeviceData->TrustComputingDeviceIndex = Private->TrustComputingDevices;
1643 Private->ActiveDevices++;
1672 UINT8 MaxPortNumber;
1673 UINT32 PortImplementBitMap;
1674 UINT32 PortInitializeBitMap;
1681 UINT32 PhyDetectDelay;
1685 AhciBar = Private->MmioBase;
1687 Status =
AhciReset (AhciBar, AHCI_PEI_RESET_TIMEOUT);
1688 if (EFI_ERROR (Status)) {
1689 DEBUG ((DEBUG_ERROR,
"%a: AHCI HBA reset failed with %r.\n", __func__, Status));
1690 return EFI_DEVICE_ERROR;
1696 Capability =
AhciReadReg (AhciBar, AHCI_CAPABILITY_OFFSET);
1702 if ((Value & AHCI_GHC_ENABLE) == 0) {
1703 AhciOrReg (AhciBar, AHCI_GHC_OFFSET, AHCI_GHC_ENABLE);
1707 if (EFI_ERROR (Status)) {
1710 "%a: Transfer-related data allocation failed with %r.\n",
1714 return EFI_OUT_OF_RESOURCES;
1720 MaxPortNumber = (UINT8)((Capability & 0x1F) + 1);
1727 PortImplementBitMap =
AhciReadReg (AhciBar, AHCI_PI_OFFSET);
1735 PortInitializeBitMap = Private->PortBitMap & PortImplementBitMap;
1736 AhciRegisters = &Private->AhciRegisters;
1741 for (PortIndex = 1; PortIndex <= MaxPortNumber; PortIndex++) {
1743 if (EFI_ERROR (Status)) {
1750 if ((PortImplementBitMap & (BIT0 << Port)) != 0) {
1755 Data64.Uint64 = (
UINTN)(AhciRegisters->AhciRFis) +
1757 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FB;
1759 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_FBU;
1762 Data64.Uint64 = (
UINTN)(AhciRegisters->AhciCmdList);
1763 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLB;
1765 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CLBU;
1768 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
1770 if ((Data & AHCI_PORT_CMD_CPD) != 0) {
1771 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_POD);
1774 if ((Capability & AHCI_CAP_SSS) != 0) {
1775 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_SUD);
1781 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SCTL;
1782 AhciOrReg (AhciBar, Offset, AHCI_PORT_SCTL_IPM_INIT);
1786 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_IE;
1792 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
1793 AhciOrReg (AhciBar, Offset, AHCI_PORT_CMD_FRE);
1798 PhyDetectDelay = AHCI_BUS_PHY_DETECT_TIMEOUT;
1799 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SSTS;
1801 Data =
AhciReadReg (AhciBar, Offset) & AHCI_PORT_SSTS_DET_MASK;
1802 if ((Data == AHCI_PORT_SSTS_DET_PCE) || (Data == AHCI_PORT_SSTS_DET)) {
1808 }
while (PhyDetectDelay > 0);
1810 if (PhyDetectDelay == 0) {
1815 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_CMD;
1816 AhciAndReg (AhciBar, Offset, (UINT32) ~(AHCI_PORT_CMD_SUD));
1817 DEBUG ((DEBUG_ERROR,
"%a: No device detected at Port %d.\n", __func__, Port));
1825 PhyDetectDelay = 16 * 1000;
1827 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SERR;
1832 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_TFD;
1834 Data =
AhciReadReg (AhciBar, Offset) & AHCI_PORT_TFD_MASK;
1841 }
while (PhyDetectDelay > 0);
1843 if (PhyDetectDelay == 0) {
1846 "%a: Port %d device presence detected but phy not ready (TFD=0x%x).\n",
1857 Offset = AHCI_PORT_START + Port * AHCI_PORT_REG_WIDTH + AHCI_PORT_SIG;
1865 if (EFI_ERROR (Status)) {
1868 "%a: Error occurred when waiting for the first D2H register FIS - %r\n",
1876 if ((Data & AHCI_ATAPI_SIG_MASK) == AHCI_ATA_DEVICE_SIG) {
1877 Status =
AhciIdentify (Private, Port, 0, PortIndex - 1, &IdentifyData);
1878 if (EFI_ERROR (Status)) {
1879 DEBUG ((DEBUG_ERROR,
"%a: AhciIdentify() failed with %r\n", __func__, Status));
1883 DEBUG ((DEBUG_INFO,
"%a: ATA hard disk found on Port %d.\n", __func__, Port));
1926 IN OUT VOID *Buffer,
1928 IN UINT32 TransferLength,
1937 Private = DeviceData->Private;
1938 AtaPassThru = &Private->AtaPassThruPpi;
1943 ASSERT ((
UINTN)DeviceData->Lba48Bit < 2);
1944 ASSERT ((
UINTN)IsWrite < 2);
1945 if (((
UINTN)DeviceData->Lba48Bit >= 2) ||
1946 ((
UINTN)IsWrite >= 2))
1948 return EFI_INVALID_PARAMETER;
1955 Acb.AtaCommand = mAtaCommands[DeviceData->Lba48Bit][IsWrite];
1956 Acb.AtaSectorNumber = (UINT8)StartLba;
1957 Acb.AtaCylinderLow = (UINT8)
RShiftU64 (StartLba, 8);
1958 Acb.AtaCylinderHigh = (UINT8)
RShiftU64 (StartLba, 16);
1959 Acb.AtaDeviceHead = (UINT8)(BIT7 | BIT6 | BIT5 |
1960 (DeviceData->PortMultiplier == 0xFFFF ?
1961 0 : (DeviceData->PortMultiplier << 4)));
1962 Acb.AtaSectorCount = (UINT8)TransferLength;
1963 if (DeviceData->Lba48Bit) {
1964 Acb.AtaSectorNumberExp = (UINT8)
RShiftU64 (StartLba, 24);
1965 Acb.AtaCylinderLowExp = (UINT8)
RShiftU64 (StartLba, 32);
1966 Acb.AtaCylinderHighExp = (UINT8)
RShiftU64 (StartLba, 40);
1967 Acb.AtaSectorCountExp = (UINT8)(TransferLength >> 8);
1969 Acb.AtaDeviceHead = (UINT8)(Acb.AtaDeviceHead |
RShiftU64 (StartLba, 24));
1986 Packet.
Protocol = mAtaPassThruCmdProtocols[IsWrite];
1987 Packet.
Length = EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
2011 Packet.
Timeout = TIMER_PERIOD_SECONDS (
2013 MultU64x32 (TransferLength, DeviceData->Media.BlockSize),
2018 return AtaPassThru->PassThru (
2021 DeviceData->PortMultiplier,
2065 IN OUT VOID *Buffer,
2066 IN UINT8 SecurityProtocolId,
2067 IN UINT16 SecurityProtocolSpecificData,
2069 IN BOOLEAN IsTrustSend,
2081 Private = DeviceData->Private;
2082 AtaPassThru = &Private->AtaPassThruPpi;
2087 ASSERT ((
UINTN)IsTrustSend < 2);
2088 if ((
UINTN)IsTrustSend >= 2) {
2089 return EFI_INVALID_PARAMETER;
2096 if (TransferLength == 0) {
2097 Acb.AtaCommand = ATA_CMD_TRUST_NON_DATA;
2099 Acb.AtaCommand = mAtaTrustCommands[IsTrustSend];
2102 Acb.AtaFeatures = SecurityProtocolId;
2103 Acb.AtaSectorCount = (UINT8)(TransferLength / 512);
2104 Acb.AtaSectorNumber = (UINT8)((TransferLength / 512) >> 8);
2109 Acb.AtaCylinderHigh = (UINT8)SecurityProtocolSpecificData;
2110 Acb.AtaCylinderLow = (UINT8)(SecurityProtocolSpecificData >> 8);
2111 Acb.AtaDeviceHead = (UINT8)(BIT7 | BIT6 | BIT5 |
2112 (DeviceData->PortMultiplier == 0xFFFF ?
2113 0 : (DeviceData->PortMultiplier << 4)));
2119 if (TransferLength == 0) {
2122 Packet.
Protocol = EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA;
2123 }
else if (IsTrustSend) {
2128 if ((AtaPassThru->Mode->IoAlign > 1) &&
2133 AtaPassThru->Mode->IoAlign
2135 if (NewBuffer ==
NULL) {
2136 return EFI_OUT_OF_RESOURCES;
2139 CopyMem (NewBuffer, Buffer, TransferLength);
2145 Packet.
Protocol = mAtaPassThruCmdProtocols[IsTrustSend];
2149 Packet.
Protocol = mAtaPassThruCmdProtocols[IsTrustSend];
2155 Packet.
Length = EFI_ATA_PASS_THRU_LENGTH_BYTES;
2157 Status = AtaPassThru->PassThru (
2160 DeviceData->PortMultiplier,
2163 if (TransferLengthOut !=
NULL) {
VOID AhciClearPortStatus(IN UINTN AhciBar, IN UINT8 Port)
UINT8 AhciGetNumberOfPortsFromMap(IN UINT32 PortBitMap)
VOID AhciOrReg(IN UINTN AhciBar, IN UINT32 Offset, IN UINT32 OrData)
EFI_STATUS AhciModeInitialization(IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private)
EFI_STATUS AhciNonDataTransfer(IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private, IN UINT8 Port, IN UINT8 PortMultiplier, IN UINT8 FisIndex, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN UINT64 Timeout)
VOID AhciBuildCommandFis(IN OUT EFI_AHCI_COMMAND_FIS *CmdFis, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock)
EFI_STATUS CreateNewDevice(IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private, IN UINTN DeviceIndex, IN UINT16 Port, IN UINT16 PortMultiplier, IN UINT8 FisIndex, IN ATA_IDENTIFY_DATA *IdentifyData)
EFI_STATUS TrustTransferAtaDevice(IN PEI_AHCI_ATA_DEVICE_DATA *DeviceData, IN OUT VOID *Buffer, IN UINT8 SecurityProtocolId, IN UINT16 SecurityProtocolSpecificData, IN UINTN TransferLength, IN BOOLEAN IsTrustSend, IN UINT64 Timeout, OUT UINTN *TransferLengthOut)
EFI_STATUS AhciGetPortFromMap(IN UINT32 PortBitMap, IN UINT8 PortIndex, OUT UINT8 *Port)
EFI_STATUS EFIAPI AhciWaitMmioSet(IN UINTN AhciBar, IN UINT32 Offset, IN UINT32 MaskValue, IN UINT32 TestValue, IN UINT64 Timeout)
VOID AhciAndReg(IN UINTN AhciBar, IN UINT32 Offset, IN UINT32 AndData)
EFI_LBA GetAtapi6Capacity(IN ATA_IDENTIFY_DATA *IdentifyData)
EFI_STATUS AhciReset(IN UINTN AhciBar, IN UINT64 Timeout)
VOID AhciWriteReg(IN UINTN AhciBar, IN UINT32 Offset, IN UINT32 Data)
EFI_STATUS AhciPioTransfer(IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private, IN UINT8 Port, IN UINT8 PortMultiplier, IN UINT8 FisIndex, IN BOOLEAN Read, IN EFI_ATA_COMMAND_BLOCK *AtaCommandBlock, IN OUT EFI_ATA_STATUS_BLOCK *AtaStatusBlock, IN OUT VOID *MemoryAddr, IN UINT32 DataCount, IN UINT64 Timeout)
EFI_STATUS AhciCheckMemSet(IN UINTN Address, IN UINT32 MaskValue, IN UINT32 TestValue)
EFI_STATUS IdentifyAtaDevice(IN OUT PEI_AHCI_ATA_DEVICE_DATA *DeviceData)
EFI_STATUS AhciCreateTransferDescriptor(IN OUT PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private)
EFI_STATUS AhciDisableFisReceive(IN UINTN AhciBar, IN UINT8 Port, IN UINT64 Timeout)
EFI_STATUS AhciIdentify(IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private, IN UINT8 Port, IN UINT8 PortMultiplier, IN UINT8 FisIndex, IN ATA_IDENTIFY_DATA *Buffer)
EFI_STATUS AhciStopCommand(IN UINTN AhciBar, IN UINT8 Port, IN UINT64 Timeout)
EFI_STATUS AhciStartCommand(IN UINTN AhciBar, IN UINT8 Port, IN UINT8 CommandSlot, IN UINT64 Timeout)
UINT32 AhciReadReg(IN UINTN AhciBar, IN UINT32 Offset)
EFI_STATUS AhciWaitMemSet(IN EFI_PHYSICAL_ADDRESS Address, IN UINT32 MaskValue, IN UINT32 TestValue, IN UINT64 Timeout)
EFI_STATUS TransferAtaDevice(IN PEI_AHCI_ATA_DEVICE_DATA *DeviceData, IN OUT VOID *Buffer, IN EFI_LBA StartLba, IN UINT32 TransferLength, IN BOOLEAN IsWrite)
EFI_STATUS AhciEnableFisReceive(IN UINTN AhciBar, IN UINT8 Port, IN UINT64 Timeout)
VOID AhciBuildCommand(IN PEI_AHCI_CONTROLLER_PRIVATE_DATA *Private, IN UINT8 Port, IN UINT8 PortMultiplier, IN UINT8 FisIndex, IN EFI_AHCI_COMMAND_FIS *CommandFis, IN EFI_AHCI_COMMAND_LIST *CommandList, IN UINT8 CommandSlotNumber, IN OUT VOID *DataPhysicalAddr, IN UINT32 DataLength)
EFI_STATUS IoMmuUnmap(IN VOID *Mapping)
EFI_STATUS IoMmuAllocateBuffer(IN UINTN Pages, OUT VOID **HostAddress, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
EFI_STATUS IoMmuMap(IN EDKII_IOMMU_OPERATION Operation, IN VOID *HostAddress, IN OUT UINTN *NumberOfBytes, OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, OUT VOID **Mapping)
EFI_STATUS IoMmuFreeBuffer(IN UINTN Pages, IN VOID *HostAddress, IN VOID *Mapping)
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
#define ATA_CMD_READ_SECTORS
defined from ATA-1
#define ATA_CMD_IDENTIFY_DRIVE
defined from ATA-3
#define ATA_CMD_WRITE_SECTORS_EXT
defined from ATA-6
#define ATA_CMD_READ_SECTORS_EXT
defined from ATA-6
#define ATA_CMD_WRITE_SECTORS
defined from ATA-1
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
INTN EFIAPI HighBitSet32(IN UINT32 Operand)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
UINT32 EFIAPI MmioRead32(IN UINTN Address)
UINT32 EFIAPI MmioWrite32(IN UINTN Address, IN UINT32 Value)
#define ADDRESS_IS_ALIGNED(Address, Alignment)
#define DEBUG(Expression)
VOID *EFIAPI AllocateAlignedPages(IN UINTN Pages, IN UINTN Alignment)
@ EdkiiIoMmuOperationBusMasterWrite
@ EdkiiIoMmuOperationBusMasterRead
VOID EFIAPI Exit(IN EFI_STATUS Status)
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_SIZE_TO_PAGES(Size)
UINT16 config
General Configuration.
UINT16 logic_sector_size_lo
word 117
UINT16 phy_logic_sector_support
word 106
UINT16 logic_sector_size_hi
word 118
EFI_ATA_STATUS_BLOCK * Asb
EFI_ATA_PASS_THRU_LENGTH Length
EFI_ATA_PASS_THRU_CMD_PROTOCOL Protocol
EFI_ATA_COMMAND_BLOCK * Acb